diff --git a/llvm/test/tools/llvm-readobj/ELF/dynamic-malformed.test b/llvm/test/tools/llvm-readobj/ELF/dynamic-malformed.test --- a/llvm/test/tools/llvm-readobj/ELF/dynamic-malformed.test +++ b/llvm/test/tools/llvm-readobj/ELF/dynamic-malformed.test @@ -90,26 +90,54 @@ ## Test handling of string references pointing past the end of the dynamic string table. # RUN: yaml2obj %s --docnum=3 -o %t.bad-string -# RUN: llvm-readobj --dynamic-table %t.bad-string | FileCheck %s --check-prefix BAD-STRING-LLVM -# RUN: llvm-readelf --dynamic-table %t.bad-string | FileCheck %s --check-prefix BAD-STRING-GNU - -# BAD-STRING-LLVM: 0x000000000000000A STRSZ 1 (bytes) -# BAD-STRING-LLVM: 0x0000000000000001 NEEDED Shared library: [] -# BAD-STRING-LLVM: 0x000000007FFFFFFF FILTER Filter library: [] -# BAD-STRING-LLVM: 0x000000007FFFFFFD AUXILIARY Auxiliary library: [] -# BAD-STRING-LLVM: 0x000000007FFFFFFE USED Not needed object: [] -# BAD-STRING-LLVM: 0x000000000000000E SONAME Library soname: [] -# BAD-STRING-LLVM: 0x000000000000000F RPATH Library rpath: [] -# BAD-STRING-LLVM: 0x000000000000001D RUNPATH Library runpath: [] - -# BAD-STRING-GNU: 0x000000000000000a (STRSZ) 1 (bytes) -# BAD-STRING-GNU: 0x0000000000000001 (NEEDED) Shared library: [] -# BAD-STRING-GNU: 0x000000007fffffff (FILTER) Filter library: [] -# BAD-STRING-GNU: 0x000000007ffffffd (AUXILIARY) Auxiliary library: [] -# BAD-STRING-GNU: 0x000000007ffffffe (USED) Not needed object: [] -# BAD-STRING-GNU: 0x000000000000000e (SONAME) Library soname: [] -# BAD-STRING-GNU: 0x000000000000000f (RPATH) Library rpath: [] -# BAD-STRING-GNU: 0x000000000000001d (RUNPATH) Library runpath: [] +# RUN: llvm-readobj --dynamic-table %t.bad-string 2>&1 | \ +# RUN: FileCheck %s --implicit-check-not=warning: --check-prefix BAD-STRING-LLVM -DFILE=%t.bad-string +# RUN: llvm-readelf --dynamic-table %t.bad-string 2>&1 | \ +# RUN: FileCheck %s --implicit-check-not=warning: --check-prefix BAD-STRING-GNU -DFILE=%t.bad-string + +# BAD-STRING-LLVM: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb6, it goes past the end of the table (0xb1) +# BAD-STRING-LLVM: LoadName: +# BAD-STRING-LLVM: DynamicSection [ (10 entries) +# BAD-STRING-LLVM-NEXT: Tag Type Name/Value +# BAD-STRING-LLVM-NEXT: 0x0000000000000005 STRTAB 0x1000 +# BAD-STRING-LLVM-NEXT: 0x000000000000000A STRSZ 1 (bytes) +# BAD-STRING-LLVM-NEXT: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb2, it goes past the end of the table (0xb1) +# BAD-STRING-LLVM-NEXT: 0x0000000000000001 NEEDED Shared library: [] +# BAD-STRING-LLVM-NEXT: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb3, it goes past the end of the table (0xb1) +# BAD-STRING-LLVM-NEXT: 0x000000007FFFFFFF FILTER Filter library: [] +# BAD-STRING-LLVM-NEXT: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb4, it goes past the end of the table (0xb1) +# BAD-STRING-LLVM-NEXT: 0x000000007FFFFFFD AUXILIARY Auxiliary library: [] +# BAD-STRING-LLVM-NEXT: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb5, it goes past the end of the table (0xb1) +# BAD-STRING-LLVM-NEXT: 0x000000007FFFFFFE USED Not needed object: [] +## Note: there is no "string table at offset 0xb0..." warning here, because it was printed earlier. +# BAD-STRING-LLVM-NEXT: 0x000000000000000E SONAME Library soname: [] +# BAD-STRING-LLVM-NEXT: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb7, it goes past the end of the table (0xb1) +# BAD-STRING-LLVM-NEXT: 0x000000000000000F RPATH Library rpath: [] +# BAD-STRING-LLVM-NEXT: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb8, it goes past the end of the table (0xb1) +# BAD-STRING-LLVM-NEXT: 0x000000000000001D RUNPATH Library runpath: [] +# BAD-STRING-LLVM-NEXT: 0x0000000000000000 NULL 0x0 +# BAD-STRING-LLVM-NEXT: ] + +# BAD-STRING-GNU: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb6, it goes past the end of the table (0xb1) +# BAD-STRING-GNU-NEXT: Dynamic section at offset 0xb1 contains 10 entries: +# BAD-STRING-GNU-NEXT: Tag Type Name/Value +# BAD-STRING-GNU-NEXT: 0x0000000000000005 (STRTAB) 0x1000 +# BAD-STRING-GNU-NEXT: 0x000000000000000a (STRSZ) 1 (bytes) +# BAD-STRING-GNU-NEXT: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb2, it goes past the end of the table (0xb1) +# BAD-STRING-GNU-NEXT: 0x0000000000000001 (NEEDED) Shared library: [] +# BAD-STRING-GNU-NEXT: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb3, it goes past the end of the table (0xb1) +# BAD-STRING-GNU-NEXT: 0x000000007fffffff (FILTER) Filter library: [] +# BAD-STRING-GNU-NEXT: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb4, it goes past the end of the table (0xb1) +# BAD-STRING-GNU-NEXT: 0x000000007ffffffd (AUXILIARY) Auxiliary library: [] +# BAD-STRING-GNU-NEXT: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb5, it goes past the end of the table (0xb1) +# BAD-STRING-GNU-NEXT: 0x000000007ffffffe (USED) Not needed object: [] +## Note: there is no "string table at offset 0xb6..." warning here, because it was printed earlier. +# BAD-STRING-GNU-NEXT: 0x000000000000000e (SONAME) Library soname: [] +# BAD-STRING-GNU-NEXT: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb7, it goes past the end of the table (0xb1) +# BAD-STRING-GNU-NEXT: 0x000000000000000f (RPATH) Library rpath: [] +# BAD-STRING-GNU-NEXT: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb8, it goes past the end of the table (0xb1) +# BAD-STRING-GNU-NEXT: 0x000000000000001d (RUNPATH) Library runpath: [] +# BAD-STRING-GNU-NEXT: 0x0000000000000000 (NULL) 0x0 --- !ELF FileHeader: @@ -130,19 +158,19 @@ - Tag: DT_STRSZ Value: 1 - Tag: DT_NEEDED - Value: 1 + Value: 2 - Tag: DT_FILTER - Value: 1 + Value: 3 - Tag: DT_AUXILIARY - Value: 1 + Value: 4 - Tag: DT_USED - Value: 1 + Value: 5 - Tag: DT_SONAME - Value: 1 + Value: 6 - Tag: DT_RPATH - Value: 1 + Value: 7 - Tag: DT_RUNPATH - Value: 1 + Value: 8 - Tag: DT_NULL Value: 0 Symbols: [] @@ -160,17 +188,23 @@ ## Test handling of DT_STRTAB pointing outside the file's address space. # RUN: yaml2obj %s --docnum=4 -o %t.bad-strtab -# RUN: llvm-readobj --dynamic-table %t.bad-strtab 2>&1 >/dev/null | FileCheck -DFILE=%t.bad-strtab %s --check-prefix BAD-STRTAB-ERR -# RUN: llvm-readelf --dynamic-table %t.bad-strtab 2>&1 >/dev/null | FileCheck -DFILE=%t.bad-strtab %s --check-prefix BAD-STRTAB-ERR +# RUN: llvm-readobj --dynamic-table %t.bad-strtab 2>&1 >/dev/null | \ +# RUN: FileCheck -DFILE=%t.bad-strtab %s --check-prefix BAD-STRTAB-ERR +# RUN: llvm-readelf --dynamic-table %t.bad-strtab 2>&1 >/dev/null | \ +# RUN: FileCheck -DFILE=%t.bad-strtab %s --check-prefix BAD-STRTAB-ERR # BAD-STRTAB-ERR: warning: '[[FILE]]': Unable to parse DT_STRTAB: virtual address is not in any segment: 0x2000000 +# BAD-STRTAB-ERR: warning: '[[FILE]]': string table was not found + +# RUN: llvm-readobj --dynamic-table --needed-libs %t.bad-strtab 2>&1 | \ +# RUN: FileCheck -DFILE=%t.bad-strtab %s --check-prefixes=BAD-STRTAB-ERR,BAD-STRTAB,BAD-STRTAB-LLVM +# RUN: llvm-readelf --dynamic-table --needed-libs %t.bad-strtab 2>&1 | \ +# RUN: FileCheck -DFILE=%t.bad-strtab %s --check-prefixes=BAD-STRTAB-ERR,BAD-STRTAB,BAD-STRTAB-GNU -# RUN: llvm-readobj --dynamic-table --needed-libs %t.bad-strtab | FileCheck %s --check-prefixes=BAD-STRTAB,BAD-STRTAB-LLVM -# RUN: llvm-readelf --dynamic-table --needed-libs %t.bad-strtab | FileCheck %s --check-prefixes=BAD-STRTAB,BAD-STRTAB-GNU -# BAD-STRTAB-LLVM: LoadName: -# BAD-STRTAB-LLVM: 0x0000000000000001 NEEDED Shared library: [] -# BAD-STRTAB-GNU: 0x0000000000000001 (NEEDED) Shared library: [] +# BAD-STRTAB-LLVM: LoadName: +# BAD-STRTAB-LLVM: 0x0000000000000001 NEEDED Shared library: [] +# BAD-STRTAB-GNU: 0x0000000000000001 (NEEDED) Shared library: [] # BAD-STRTAB: NeededLibraries [ -# BAD-STRTAB: +# BAD-STRTAB: # BAD-STRTAB: ] --- !ELF diff --git a/llvm/test/tools/llvm-readobj/ELF/loadname.test b/llvm/test/tools/llvm-readobj/ELF/loadname.test --- a/llvm/test/tools/llvm-readobj/ELF/loadname.test +++ b/llvm/test/tools/llvm-readobj/ELF/loadname.test @@ -61,5 +61,6 @@ # RUN: llvm-readelf --dynamic-table %t.err.1.o 2>&1 | FileCheck %s -DFILE=%t.err.1.o --check-prefixes=BROKEN-OFFSET,BROKEN-OFFSET-GNU # BROKEN-OFFSET: warning: '[[FILE]]': Unable to parse DT_STRTAB: can't map virtual address 0xfffe to the segment with index 1: the segment ends at 0x10077, which is greater than the file size (0x228) -# BROKEN-OFFSET-LLVM: LoadName: -# BROKEN-OFFSET-GNU: 0x000000000000000e (SONAME) Library soname: [] +# BROKEN-OFFSET: warning: '[[FILE]]': string table was not found +# BROKEN-OFFSET-LLVM: LoadName: +# BROKEN-OFFSET-GNU: 0x000000000000000e (SONAME) Library soname: [] diff --git a/llvm/test/tools/llvm-readobj/ELF/needed-libs.test b/llvm/test/tools/llvm-readobj/ELF/needed-libs.test --- a/llvm/test/tools/llvm-readobj/ELF/needed-libs.test +++ b/llvm/test/tools/llvm-readobj/ELF/needed-libs.test @@ -1,21 +1,23 @@ ## In this test we check the --needed-libs option. # RUN: yaml2obj %s --docnum=1 -o %t1 -# RUN: llvm-readobj --needed-libs %t1 \ -# RUN: | FileCheck %s --strict-whitespace --match-full-lines --check-prefix=NEEDED-LIBS -# RUN: llvm-readelf --needed-libs %t1 \ -# RUN: | FileCheck %s --strict-whitespace --match-full-lines --check-prefix=NEEDED-LIBS +# RUN: llvm-readobj --needed-libs %t1 2>&1 \ +# RUN: | FileCheck %s -DFILE=%t1 --implicit-check-not=warning: --strict-whitespace --check-prefix=NEEDED-LIBS +# RUN: llvm-readelf --needed-libs %t1 2>&1 \ +# RUN: | FileCheck %s -DFILE=%t1 --implicit-check-not=warning: --strict-whitespace --check-prefix=NEEDED-LIBS ## Check that library names are sorted when printed. ## Document that we also sort error entries. -# NEEDED-LIBS:NeededLibraries [ -# NEEDED-LIBS-NEXT: -# NEEDED-LIBS-NEXT: -# NEEDED-LIBS-NEXT: aaa -# NEEDED-LIBS-NEXT: bbb -# NEEDED-LIBS-NEXT: ccc -# NEEDED-LIBS-NEXT:] +# NEEDED-LIBS:{{^}}NeededLibraries [{{$}} +# NEEDED-LIBS-NEXT: warning: '[[FILE]]': string table at offset 0x78: unable to read the string at 0x9999a11, it goes past the end of the table (0x85){{$}} +# NEEDED-LIBS-NEXT: warning: '[[FILE]]': string table at offset 0x78: unable to read the string at 0x1111189, it goes past the end of the table (0x85){{$}} +# NEEDED-LIBS-NEXT:{{^}} {{$}} +# NEEDED-LIBS-NEXT:{{^}} {{$}} +# NEEDED-LIBS-NEXT:{{^}} aaa{{$}} +# NEEDED-LIBS-NEXT:{{^}} bbb{{$}} +# NEEDED-LIBS-NEXT:{{^}} ccc{{$}} +# NEEDED-LIBS-NEXT:{{^}}]{{$}} --- !ELF FileHeader: @@ -56,11 +58,18 @@ ## Check what we print when the dynamic string table is empty. # RUN: yaml2obj %s --docnum=2 -o %t2 -# RUN: llvm-readobj --needed-libs %t2 | FileCheck %s --check-prefix=EMPTY-DYNSTR -# RUN: llvm-readelf --needed-libs %t2 | FileCheck %s --check-prefix=EMPTY-DYNSTR +# RUN: llvm-readobj --needed-libs %t2 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t2 --implicit-check-not=warning: --check-prefixes=EMPTY-DYNSTR,EMPTY-DYNSTR-LLVM +# RUN: llvm-readelf --needed-libs %t2 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t2 --implicit-check-not=warning: --check-prefix=EMPTY-DYNSTR +# EMPTY-DYNSTR: warning: '[[FILE]]': string table at offset 0x78: unable to read the string at 0x78, it goes past the end of the table (0x78) +# EMPTY-DYNSTR-LLVM: LoadName: # EMPTY-DYNSTR: NeededLibraries [ -# EMPTY-DYNSTR-NEXT: +# EMPTY-DYNSTR-NEXT: warning: '[[FILE]]': string table at offset 0x78: unable to read the string at 0x79, it goes past the end of the table (0x78) +# EMPTY-DYNSTR-NEXT: warning: '[[FILE]]': string table at offset 0x78: unable to read the string at 0x7a, it goes past the end of the table (0x78) +# EMPTY-DYNSTR-NEXT: +# EMPTY-DYNSTR-NEXT: # EMPTY-DYNSTR-NEXT: ] --- !ELF @@ -82,6 +91,8 @@ Value: 0x0000000000000000 - Tag: DT_NEEDED Value: 1 + - Tag: DT_NEEDED + Value: 2 - Tag: DT_STRSZ Value: 0x0 - Tag: DT_NULL diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -288,7 +288,7 @@ Optional DynSymRegion; DynRegionInfo DynamicTable; StringRef DynamicStringTable; - std::string SOName = ""; + StringRef SOName = ""; const Elf_Hash *HashTable = nullptr; const Elf_GnuHash *GnuHashTable = nullptr; const Elf_Shdr *DotSymtabSec = nullptr; @@ -341,12 +341,12 @@ Expected getSymbolSectionName(const Elf_Sym *Symbol, unsigned SectionIndex) const; Expected getStaticSymbolName(uint32_t Index) const; - std::string getDynamicString(uint64_t Value) const; + StringRef getDynamicString(uint64_t Value) const; Expected getSymbolVersionByIndex(uint32_t VersionSymbolIndex, bool &IsDefault) const; void printSymbolsHelper(bool IsDynamic) const; - void printDynamicEntry(raw_ostream &OS, uint64_t Type, uint64_t Value) const; + std::string getDynamicEntry(uint64_t Type, uint64_t Value) const; const Elf_Shdr *getDotSymtabSec() const { return DotSymtabSec; } const Elf_Shdr *getDotCGProfileSec() const { return DotCGProfileSec; } @@ -2387,10 +2387,24 @@ } template -void ELFDumper::printDynamicEntry(raw_ostream &OS, uint64_t Type, - uint64_t Value) const { - const char *ConvChar = - (opts::Output == opts::GNU) ? "0x%" PRIx64 : "0x%" PRIX64; +std::string ELFDumper::getDynamicEntry(uint64_t Type, + uint64_t Value) const { + auto FormatHexValue = [](uint64_t V) { + std::string Str; + raw_string_ostream OS(Str); + const char *ConvChar = + (opts::Output == opts::GNU) ? "0x%" PRIx64 : "0x%" PRIX64; + OS << format(ConvChar, V); + return OS.str(); + }; + + auto FormatFlags = [](uint64_t V, + llvm::ArrayRef> Array) { + std::string Str; + raw_string_ostream OS(Str); + printFlags(V, Array, OS); + return OS.str(); + }; // Handle custom printing of architecture specific tags switch (ObjF->getELFFile()->getHeader()->e_machine) { @@ -2398,8 +2412,7 @@ switch (Type) { case DT_AARCH64_BTI_PLT: case DT_AARCH64_PAC_PLT: - OS << Value; - return; + return std::to_string(Value); default: break; } @@ -2407,12 +2420,10 @@ case EM_HEXAGON: switch (Type) { case DT_HEXAGON_VER: - OS << Value; - return; + return std::to_string(Value); case DT_HEXAGON_SYMSZ: case DT_HEXAGON_PLT: - OS << format(ConvChar, Value); - return; + return FormatHexValue(Value); default: break; } @@ -2423,8 +2434,7 @@ case DT_MIPS_LOCAL_GOTNO: case DT_MIPS_SYMTABNO: case DT_MIPS_UNREFEXTNO: - OS << Value; - return; + return std::to_string(Value); case DT_MIPS_TIME_STAMP: case DT_MIPS_ICHECKSUM: case DT_MIPS_IVERSION: @@ -2465,11 +2475,9 @@ case DT_MIPS_PLTGOT: case DT_MIPS_RWPLT: case DT_MIPS_RLD_MAP_REL: - OS << format(ConvChar, Value); - return; + return FormatHexValue(Value); case DT_MIPS_FLAGS: - printFlags(Value, makeArrayRef(ElfDynamicDTMipsFlags), OS); - return; + return FormatFlags(Value, makeArrayRef(ElfDynamicDTMipsFlags)); default: break; } @@ -2480,13 +2488,10 @@ switch (Type) { case DT_PLTREL: - if (Value == DT_REL) { - OS << "REL"; - break; - } else if (Value == DT_RELA) { - OS << "RELA"; - break; - } + if (Value == DT_REL) + return "REL"; + if (Value == DT_RELA) + return "RELA"; LLVM_FALLTHROUGH; case DT_PLTGOT: case DT_HASH: @@ -2506,14 +2511,12 @@ case DT_VERSYM: case DT_GNU_HASH: case DT_NULL: - OS << format(ConvChar, Value); - break; + return FormatHexValue(Value); case DT_RELACOUNT: case DT_RELCOUNT: case DT_VERDEFNUM: case DT_VERNEEDNUM: - OS << Value; - break; + return std::to_string(Value); case DT_PLTRELSZ: case DT_RELASZ: case DT_RELAENT: @@ -2526,8 +2529,7 @@ case DT_PREINIT_ARRAYSZ: case DT_ANDROID_RELSZ: case DT_ANDROID_RELASZ: - OS << Value << " (bytes)"; - break; + return std::to_string(Value) + " (bytes)"; case DT_NEEDED: case DT_SONAME: case DT_AUXILIARY: @@ -2535,37 +2537,45 @@ case DT_FILTER: case DT_RPATH: case DT_RUNPATH: { - const std::map TagNames = { - {DT_NEEDED, "Shared library"}, - {DT_SONAME, "Library soname"}, - {DT_AUXILIARY, "Auxiliary library"}, - {DT_USED, "Not needed object"}, - {DT_FILTER, "Filter library"}, - {DT_RPATH, "Library rpath"}, - {DT_RUNPATH, "Library runpath"}, + const std::map TagNames = { + {DT_NEEDED, "Shared library"}, {DT_SONAME, "Library soname"}, + {DT_AUXILIARY, "Auxiliary library"}, {DT_USED, "Not needed object"}, + {DT_FILTER, "Filter library"}, {DT_RPATH, "Library rpath"}, + {DT_RUNPATH, "Library runpath"}, }; - OS << TagNames.at(Type) << ": [" << getDynamicString(Value) << "]"; - break; + + return (Twine(TagNames.at(Type)) + ": [" + getDynamicString(Value) + "]") + .str(); } case DT_FLAGS: - printFlags(Value, makeArrayRef(ElfDynamicDTFlags), OS); - break; + return FormatFlags(Value, makeArrayRef(ElfDynamicDTFlags)); case DT_FLAGS_1: - printFlags(Value, makeArrayRef(ElfDynamicDTFlags1), OS); - break; + return FormatFlags(Value, makeArrayRef(ElfDynamicDTFlags1)); default: - OS << format(ConvChar, Value); - break; + return FormatHexValue(Value); } } template -std::string ELFDumper::getDynamicString(uint64_t Value) const { - if (DynamicStringTable.empty()) - return ""; +StringRef ELFDumper::getDynamicString(uint64_t Value) const { + auto WarnAndReturn = [this](const Twine &Msg) { + reportUniqueWarning(createError(Msg)); + return ""; + }; + + if (DynamicStringTable.empty() && !DynamicStringTable.data()) + return WarnAndReturn("string table was not found"); + if (Value < DynamicStringTable.size()) return DynamicStringTable.data() + Value; - return Twine("").str(); + + const uint64_t Offset = + (const uint8_t *)DynamicStringTable.data() - ObjF->getELFFile()->base(); + return WarnAndReturn( + "string table at offset 0x" + Twine::utohexstr(Offset) + + ": unable to read the string at 0x" + Twine::utohexstr(Offset + Value) + + ", it goes past the end of the table (0x" + + Twine::utohexstr(Offset + DynamicStringTable.size()) + ")"); } template void ELFDumper::printUnwindInfo() { @@ -2596,14 +2606,14 @@ template void ELFDumper::printNeededLibraries() { ListScope D(W, "NeededLibraries"); - std::vector Libs; + std::vector Libs; for (const auto &Entry : dynamic_table()) if (Entry.d_tag == ELF::DT_NEEDED) Libs.push_back(getDynamicString(Entry.d_un.d_val)); llvm::sort(Libs); - for (const std::string &L : Libs) + for (StringRef L : Libs) W.startLine() << L << "\n"; } @@ -4235,12 +4245,11 @@ std::string ValueFmt = " %-" + std::to_string(MaxTagSize) + "s "; for (auto Entry : Table) { uintX_t Tag = Entry.getTag(); - std::string TypeString = + std::string Type = std::string("(") + Obj->getDynamicTagAsString(Tag).c_str() + ")"; + std::string Value = this->dumper()->getDynamicEntry(Tag, Entry.getVal()); OS << " " << format_hex(Tag, ELFT::Is64Bits ? 18 : 10) - << format(ValueFmt.c_str(), TypeString.c_str()); - this->dumper()->printDynamicEntry(OS, Tag, Entry.getVal()); - OS << "\n"; + << format(ValueFmt.c_str(), Type.c_str()) << Value << "\n"; } } @@ -6051,7 +6060,6 @@ if (Table.empty()) return; - raw_ostream &OS = W.getOStream(); W.startLine() << "DynamicSection [ (" << Table.size() << " entries)\n"; size_t MaxTagSize = getMaxDynamicTagSize(Obj, Table); @@ -6064,12 +6072,12 @@ std::string ValueFmt = "%-" + std::to_string(MaxTagSize) + "s "; for (auto Entry : Table) { uintX_t Tag = Entry.getTag(); + std::string Value = this->dumper()->getDynamicEntry(Tag, Entry.getVal()); W.startLine() << " " << format_hex(Tag, ELFT::Is64Bits ? 18 : 10, true) << " " << format(ValueFmt.c_str(), - Obj->getDynamicTagAsString(Tag).c_str()); - this->dumper()->printDynamicEntry(OS, Tag, Entry.getVal()); - OS << "\n"; + Obj->getDynamicTagAsString(Tag).c_str()) + << Value << "\n"; } W.startLine() << "]\n"; }