diff --git a/llvm/test/Object/invalid.test b/llvm/test/Object/invalid.test --- a/llvm/test/Object/invalid.test +++ b/llvm/test/Object/invalid.test @@ -137,7 +137,7 @@ # RUN: yaml2obj %s --docnum=7 -o %t7 # RUN: llvm-readobj --dyn-symbols %t7 2>&1 | FileCheck -DFILE=%t7 --check-prefix=INVALID-DYNSYM-SIZE %s -# INVALID-DYNSYM-SIZE: warning: '[[FILE]]': section with index 1 has invalid size (0x30) or entry size (0x20) +# INVALID-DYNSYM-SIZE: warning: '[[FILE]]': SHT_DYNSYM section with index 1 has invalid size (0x30) or entry size (0x20) --- !ELF FileHeader: @@ -458,7 +458,7 @@ # RUN: yaml2obj %s --docnum=21 -o %t21 # RUN: llvm-readobj --dyn-relocations %t21 2>&1 | FileCheck -DFILE=%t21 --check-prefix=DYN-TABLE-SIZE %s -# DYN-TABLE-SIZE: warning: '[[FILE]]': section with index 1 has invalid size (0x1){{$}} +# DYN-TABLE-SIZE: warning: '[[FILE]]': SHT_DYNAMIC section with index 1 has invalid size (0x1){{$}} --- !ELF FileHeader: diff --git a/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test b/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test --- a/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test +++ b/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test @@ -408,7 +408,7 @@ # RUN: llvm-readobj --dyn-symbols %t10 2>&1 | FileCheck %s -DFILE=%t10 --check-prefix=DYNSYM-SIZE-INVALID1 # RUN: llvm-readelf --dyn-symbols %t10 2>&1 | FileCheck %s -DFILE=%t10 --check-prefix=DYNSYM-SIZE-INVALID1 -# DYNSYM-SIZE-INVALID1: warning: '[[FILE]]': section with index 1 has invalid size (0x1) or entry size (0x10) +# DYNSYM-SIZE-INVALID1: warning: '[[FILE]]': SHT_DYNSYM section with index 1 has invalid size (0x1) or entry size (0x10) ## b) The same, but the DT_SYMTAB tag is present. In this case the dynamic tag has priority over the ## information about a location and an entity size of the dynamic symbol table from the section header. @@ -418,7 +418,7 @@ # RUN: llvm-readobj --dyn-symbols %t11 2>&1 | FileCheck %s -DFILE=%t11 --check-prefix=DYNSYM-SIZE-INVALID2 # RUN: llvm-readelf --dyn-symbols %t11 2>&1 | FileCheck %s -DFILE=%t11 --check-prefix=DYNSYM-SIZE-INVALID2 -# DYNSYM-SIZE-INVALID2: warning: '[[FILE]]': section with index 2 has invalid size (0x1){{$}} +# DYNSYM-SIZE-INVALID2: warning: '[[FILE]]': SHT_DYNSYM section with index 2 has invalid size (0x1){{$}} ## c) In the case when the DT_SYMENT tag is present, we report when it's value does not match the # value of the symbol size for the platform. @@ -571,10 +571,10 @@ # RUN: FileCheck %s -DFILE=%t15 --check-prefix=DYNSYM-ZERO-ENTSIZE-GNU --implicit-check-not="Symbol table" # DYNSYM-ZERO-ENTSIZE-LLVM: DynamicSymbols [ -# DYNSYM-ZERO-ENTSIZE-LLVM-NEXT: warning: '[[FILE]]': section with index 1 has invalid size (0x10) or entry size (0x0) +# DYNSYM-ZERO-ENTSIZE-LLVM-NEXT: warning: '[[FILE]]': SHT_DYNSYM section with index 1 has invalid size (0x10) or entry size (0x0) # DYNSYM-ZERO-ENTSIZE-LLVM-NEXT: ] -# DYNSYM-ZERO-ENTSIZE-GNU: warning: '[[FILE]]': section with index 1 has invalid size (0x10) or entry size (0x0) +# DYNSYM-ZERO-ENTSIZE-GNU: warning: '[[FILE]]': SHT_DYNSYM section with index 1 has invalid size (0x10) or entry size (0x0) --- !ELF FileHeader: 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 @@ -8,7 +8,7 @@ # RUN: | FileCheck %s -DFILE=%t.bad-size --implicit-check-not=warning: --check-prefix WARN-GNU # WARN: warning: '[[FILE]]': invalid PT_DYNAMIC size (0x4){{$}} -# WARN: warning: '[[FILE]]': section with index 1 has invalid size (0x4){{$}} +# WARN: warning: '[[FILE]]': SHT_DYNAMIC section with index 1 has invalid size (0x4){{$}} # WARN: warning: '[[FILE]]': no valid dynamic table was found # WARN-EMPTY: # WARN: File: @@ -17,7 +17,7 @@ # WARN: ] # WARN-GNU: warning: '[[FILE]]': invalid PT_DYNAMIC size (0x4){{$}} -# WARN-GNU: warning: '[[FILE]]': section with index 1 has invalid size (0x4){{$}} +# WARN-GNU: warning: '[[FILE]]': SHT_DYNAMIC section with index 1 has invalid size (0x4){{$}} # WARN-GNU: warning: '[[FILE]]': no valid dynamic table was found # WARN-GNU-NEXT: ELF Header: # WARN-GNU: Symbol table '.symtab' contains 1 entries: diff --git a/llvm/test/tools/llvm-readobj/ELF/mips-plt.test b/llvm/test/tools/llvm-readobj/ELF/mips-plt.test --- a/llvm/test/tools/llvm-readobj/ELF/mips-plt.test +++ b/llvm/test/tools/llvm-readobj/ELF/mips-plt.test @@ -134,9 +134,9 @@ # RUN: yaml2obj --docnum=2 -DVAL2=0x100 -DLINK=0xaaaaaaaa %s -o %t.err6.o # RUN: not llvm-readobj -A %t.err6.o 2>&1 | FileCheck %s -DFILE=%t.err6.o -check-prefix ERR6 -# ERR6: error: '[[FILE]]': unable to get a symbol table linked to the RELPLT section with index 2: invalid section index: 2863311530 +# ERR6: error: '[[FILE]]': unable to get a symbol table linked to the SHT_PROGBITS section with index 2: invalid section index: 2863311530 # RUN: yaml2obj --docnum=2 -DVAL2=0x100 %s -o %t.err7.o # RUN: not llvm-readobj -A %t.err7.o 2>&1 | FileCheck %s -DFILE=%t.err7.o -check-prefix ERR7 -# ERR7: error: '[[FILE]]': unable to get a string table for the symbol table with index 1: invalid sh_type for symbol table, expected SHT_SYMTAB or SHT_DYNSYM +# ERR7: error: '[[FILE]]': unable to get a string table for the SHT_DYNAMIC section with index 1: invalid sh_type for symbol table, expected SHT_SYMTAB or SHT_DYNSYM 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 @@ -309,6 +309,8 @@ std::unordered_set Warnings; + std::string describe(const Elf_Shdr &Sec) const; + public: Elf_Dyn_Range dynamic_table() const { // A valid .dynamic section contains an array of entries terminated @@ -380,26 +382,34 @@ void reportUniqueWarning(Error Err) const; }; +template +static std::string describe(const ELFFile *Obj, + const typename ELFT::Shdr &Sec) { + unsigned SecNdx = &Sec - &cantFail(Obj->sections()).front(); + return (object::getELFSectionTypeName(Obj->getHeader()->e_machine, + Sec.sh_type) + + " section with index " + Twine(SecNdx)) + .str(); +} + +template +std::string ELFDumper::describe(const Elf_Shdr &Sec) const { + return ::describe(ObjF->getELFFile(), Sec); +} + template static Expected getLinkAsStrtab(const ELFFile *Obj, - const typename ELFT::Shdr *Sec, - unsigned SecNdx) { + const typename ELFT::Shdr *Sec) { Expected StrTabSecOrErr = Obj->getSection(Sec->sh_link); if (!StrTabSecOrErr) - return createError("invalid section linked to " + - object::getELFSectionTypeName( - Obj->getHeader()->e_machine, Sec->sh_type) + - " section with index " + Twine(SecNdx) + ": " + - toString(StrTabSecOrErr.takeError())); + return createError("invalid section linked to " + describe(Obj, *Sec) + + ": " + toString(StrTabSecOrErr.takeError())); Expected StrTabOrErr = Obj->getStringTable(*StrTabSecOrErr); if (!StrTabOrErr) - return createError("invalid string table linked to " + - object::getELFSectionTypeName( - Obj->getHeader()->e_machine, Sec->sh_type) + - " section with index " + Twine(SecNdx) + ": " + - toString(StrTabOrErr.takeError())); + return createError("invalid string table linked to " + describe(Obj, *Sec) + + ": " + toString(StrTabOrErr.takeError())); return *StrTabOrErr; } @@ -407,43 +417,33 @@ template static Expected> getLinkAsSymtab(const ELFFile *Obj, const typename ELFT::Shdr *Sec, - unsigned SecNdx, unsigned ExpectedType) { + unsigned ExpectedType) { Expected SymtabOrErr = Obj->getSection(Sec->sh_link); if (!SymtabOrErr) - return createError("invalid section linked to " + - object::getELFSectionTypeName( - Obj->getHeader()->e_machine, Sec->sh_type) + - " section with index " + Twine(SecNdx) + ": " + - toString(SymtabOrErr.takeError())); + return createError("invalid section linked to " + describe(Obj, *Sec) + + ": " + toString(SymtabOrErr.takeError())); if ((*SymtabOrErr)->sh_type != ExpectedType) return createError( - "invalid section linked to " + - object::getELFSectionTypeName(Obj->getHeader()->e_machine, - Sec->sh_type) + - " section with index " + Twine(SecNdx) + ": expected " + + "invalid section linked to " + describe(Obj, *Sec) + ": expected " + object::getELFSectionTypeName(Obj->getHeader()->e_machine, ExpectedType) + ", but got " + object::getELFSectionTypeName(Obj->getHeader()->e_machine, (*SymtabOrErr)->sh_type)); - Expected StrTabOrErr = - getLinkAsStrtab(Obj, *SymtabOrErr, Sec->sh_link); + Expected StrTabOrErr = getLinkAsStrtab(Obj, *SymtabOrErr); if (!StrTabOrErr) return createError( "can't get a string table for the symbol table linked to " + - object::getELFSectionTypeName(Obj->getHeader()->e_machine, - Sec->sh_type) + - " section with index " + Twine(SecNdx) + ": " + - toString(StrTabOrErr.takeError())); + describe(Obj, *Sec) + ": " + toString(StrTabOrErr.takeError())); Expected SymsOrErr = Obj->symbols(*SymtabOrErr); if (!SymsOrErr) - return createError( - "unable to read symbols from the symbol table with index " + - Twine(Sec->sh_link) + ": " + toString(SymsOrErr.takeError())); + return createError("unable to read symbols from the " + + describe(Obj, *Sec) + ": " + + toString(SymsOrErr.takeError())); return std::make_pair(*SymsOrErr, *StrTabOrErr); } @@ -454,21 +454,18 @@ StringRef *StrTab) const { assert((!SymTab && !StrTab) || (SymTab && StrTab)); const ELFFile *Obj = ObjF->getELFFile(); - unsigned SecNdx = Sec - &cantFail(Obj->sections()).front(); if (uintptr_t(Obj->base() + Sec->sh_offset) % sizeof(uint16_t) != 0) - return createError("the SHT_GNU_versym section with index " + - Twine(SecNdx) + " is misaligned"); + return createError("the " + describe(*Sec) + " is misaligned"); Expected> VersionsOrErr = Obj->template getSectionContentsAsArray(Sec); if (!VersionsOrErr) - return createError( - "cannot read content of SHT_GNU_versym section with index " + - Twine(SecNdx) + ": " + toString(VersionsOrErr.takeError())); + return createError("cannot read content of " + describe(*Sec) + ": " + + toString(VersionsOrErr.takeError())); Expected, StringRef>> SymTabOrErr = - getLinkAsSymtab(Obj, Sec, SecNdx, SHT_DYNSYM); + getLinkAsSymtab(Obj, Sec, SHT_DYNSYM); if (!SymTabOrErr) { reportUniqueWarning(SymTabOrErr.takeError()); return *VersionsOrErr; @@ -476,8 +473,8 @@ if (SymTabOrErr->first.size() != VersionsOrErr->size()) reportUniqueWarning( - createError("SHT_GNU_versym section with index " + Twine(SecNdx) + - ": the number of entries (" + Twine(VersionsOrErr->size()) + + createError(describe(*Sec) + ": the number of entries (" + + Twine(VersionsOrErr->size()) + ") does not match the number of symbols (" + Twine(SymTabOrErr->first.size()) + ") in the symbol table with index " + Twine(Sec->sh_link))); @@ -491,17 +488,15 @@ Expected> ELFDumper::getVersionDefinitions(const Elf_Shdr *Sec) const { const ELFFile *Obj = ObjF->getELFFile(); - unsigned SecNdx = Sec - &cantFail(Obj->sections()).front(); - Expected StrTabOrErr = getLinkAsStrtab(Obj, Sec, SecNdx); + Expected StrTabOrErr = getLinkAsStrtab(Obj, Sec); if (!StrTabOrErr) return StrTabOrErr.takeError(); Expected> ContentsOrErr = Obj->getSectionContents(Sec); if (!ContentsOrErr) - return createError( - "cannot read content of SHT_GNU_verdef section with index " + - Twine(SecNdx) + ": " + toString(ContentsOrErr.takeError())); + return createError("cannot read content of " + describe(*Sec) + ": " + + toString(ContentsOrErr.takeError())); const uint8_t *Start = ContentsOrErr->data(); const uint8_t *End = Start + ContentsOrErr->size(); @@ -509,8 +504,7 @@ auto ExtractNextAux = [&](const uint8_t *&VerdauxBuf, unsigned VerDefNdx) -> Expected { if (VerdauxBuf + sizeof(Elf_Verdaux) > End) - return createError("invalid SHT_GNU_verdef section with index " + - Twine(SecNdx) + ": version definition " + + return createError("invalid " + describe(*Sec) + ": version definition " + Twine(VerDefNdx) + " refers to an auxiliary entry that goes past the end " "of the section"); @@ -531,21 +525,19 @@ const uint8_t *VerdefBuf = Start; for (unsigned I = 1; I <= /*VerDefsNum=*/Sec->sh_info; ++I) { if (VerdefBuf + sizeof(Elf_Verdef) > End) - return createError("invalid SHT_GNU_verdef section with index " + - Twine(SecNdx) + ": version definition " + Twine(I) + - " goes past the end of the section"); + return createError("invalid " + describe(*Sec) + ": version definition " + + Twine(I) + " goes past the end of the section"); if (uintptr_t(VerdefBuf) % sizeof(uint32_t) != 0) return createError( - "invalid SHT_GNU_verdef section with index " + Twine(SecNdx) + + "invalid " + describe(*Sec) + ": found a misaligned version definition entry at offset 0x" + Twine::utohexstr(VerdefBuf - Start)); unsigned Version = *reinterpret_cast(VerdefBuf); if (Version != 1) - return createError("unable to dump SHT_GNU_verdef section with index " + - Twine(SecNdx) + ": version " + Twine(Version) + - " is not yet supported"); + return createError("unable to dump " + describe(*Sec) + ": version " + + Twine(Version) + " is not yet supported"); const Elf_Verdef *D = reinterpret_cast(VerdefBuf); VerDef &VD = *Ret.emplace(Ret.end()); @@ -559,8 +551,7 @@ const uint8_t *VerdauxBuf = VerdefBuf + D->vd_aux; for (unsigned J = 0; J < D->vd_cnt; ++J) { if (uintptr_t(VerdauxBuf) % sizeof(uint32_t) != 0) - return createError("invalid SHT_GNU_verdef section with index " + - Twine(SecNdx) + + return createError("invalid " + describe(*Sec) + ": found a misaligned auxiliary entry at offset 0x" + Twine::utohexstr(VerdauxBuf - Start)); @@ -584,10 +575,8 @@ Expected> ELFDumper::getVersionDependencies(const Elf_Shdr *Sec) const { const ELFFile *Obj = ObjF->getELFFile(); - unsigned SecNdx = Sec - &cantFail(Obj->sections()).front(); - StringRef StrTab; - Expected StrTabOrErr = getLinkAsStrtab(Obj, Sec, SecNdx); + Expected StrTabOrErr = getLinkAsStrtab(Obj, Sec); if (!StrTabOrErr) reportUniqueWarning(StrTabOrErr.takeError()); else @@ -595,9 +584,8 @@ Expected> ContentsOrErr = Obj->getSectionContents(Sec); if (!ContentsOrErr) - return createError( - "cannot read content of SHT_GNU_verneed section with index " + - Twine(SecNdx) + ": " + toString(ContentsOrErr.takeError())); + return createError("cannot read content of " + describe(*Sec) + ": " + + toString(ContentsOrErr.takeError())); const uint8_t *Start = ContentsOrErr->data(); const uint8_t *End = Start + ContentsOrErr->size(); @@ -606,21 +594,19 @@ std::vector Ret; for (unsigned I = 1; I <= /*VerneedNum=*/Sec->sh_info; ++I) { if (VerneedBuf + sizeof(Elf_Verdef) > End) - return createError("invalid SHT_GNU_verneed section with index " + - Twine(SecNdx) + ": version dependency " + Twine(I) + - " goes past the end of the section"); + return createError("invalid " + describe(*Sec) + ": version dependency " + + Twine(I) + " goes past the end of the section"); if (uintptr_t(VerneedBuf) % sizeof(uint32_t) != 0) return createError( - "invalid SHT_GNU_verneed section with index " + Twine(SecNdx) + + "invalid " + describe(*Sec) + ": found a misaligned version dependency entry at offset 0x" + Twine::utohexstr(VerneedBuf - Start)); unsigned Version = *reinterpret_cast(VerneedBuf); if (Version != 1) - return createError("unable to dump SHT_GNU_verneed section with index " + - Twine(SecNdx) + ": version " + Twine(Version) + - " is not yet supported"); + return createError("unable to dump " + describe(*Sec) + ": version " + + Twine(Version) + " is not yet supported"); const Elf_Verneed *Verneed = reinterpret_cast(VerneedBuf); @@ -638,15 +624,13 @@ const uint8_t *VernauxBuf = VerneedBuf + Verneed->vn_aux; for (unsigned J = 0; J < Verneed->vn_cnt; ++J) { if (uintptr_t(VernauxBuf) % sizeof(uint32_t) != 0) - return createError("invalid SHT_GNU_verneed section with index " + - Twine(SecNdx) + + return createError("invalid " + describe(*Sec) + ": found a misaligned auxiliary entry at offset 0x" + Twine::utohexstr(VernauxBuf - Start)); if (VernauxBuf + sizeof(Elf_Vernaux) > End) return createError( - "invalid SHT_GNU_verneed section with index " + Twine(SecNdx) + - ": version dependency " + Twine(I) + + "invalid " + describe(*Sec) + ": version dependency " + Twine(I) + " refers to an auxiliary entry that goes past the end " "of the section"); @@ -2001,9 +1985,7 @@ FromSec = checkDRI({ObjF->getELFFile()->base() + DynamicSec->sh_offset, DynamicSec->sh_size, sizeof(Elf_Dyn), ObjF->getFileName()}); - FromSec.Context = ("section with index " + - Twine(DynamicSec - &cantFail(Obj->sections()).front())) - .str(); + FromSec.Context = describe(*DynamicSec); FromSec.EntSizePrintName = ""; IsSecTableValid = !FromSec.getAsArrayRef().empty(); @@ -2091,8 +2073,7 @@ if (!DynSymRegion) { DynSymRegion = createDRIFrom(&Sec); - DynSymRegion->Context = - ("section with index " + Twine(&Sec - &Sections.front())).str(); + DynSymRegion->Context = describe(Sec); if (Expected E = Obj->getStringTableForSymtab(Sec)) DynamicStringTable = *E; @@ -3130,25 +3111,20 @@ toString(PltContentOrErr.takeError())); if (Expected PltSymTableOrErr = - Obj->getSection(PltRelSec->sh_link)) { + Obj->getSection(PltRelSec->sh_link)) PltSymTable = *PltSymTableOrErr; - } else { - unsigned SecNdx = PltRelSec - &cantFail(Obj->sections()).front(); - return createError("unable to get a symbol table linked to the RELPLT " - "section with index " + - Twine(SecNdx) + ": " + + else + return createError("unable to get a symbol table linked to the " + + describe(Obj, *PltRelSec) + ": " + toString(PltSymTableOrErr.takeError())); - } if (Expected StrTabOrErr = - Obj->getStringTableForSymtab(*PltSymTable)) { + Obj->getStringTableForSymtab(*PltSymTable)) PltStrTable = *StrTabOrErr; - } else { - unsigned SecNdx = PltSymTable - &cantFail(Obj->sections()).front(); - return createError( - "unable to get a string table for the symbol table with index " + - Twine(SecNdx) + ": " + toString(StrTabOrErr.takeError())); - } + else + return createError("unable to get a string table for the " + + describe(Obj, *PltSymTable) + ": " + + toString(StrTabOrErr.takeError())); return Error::success(); } @@ -4627,21 +4603,16 @@ OS << Label << " section '" << SecName << "' " << "contains " << EntriesNum << " entries:\n"; - unsigned SecNdx = Sec - &cantFail(Obj->sections()).front(); StringRef SymTabName = ""; - Expected SymTabOrErr = Obj->getSection(Sec->sh_link); if (SymTabOrErr) SymTabName = unwrapOrError(this->FileName, Obj->getSectionName(*SymTabOrErr)); else - this->reportUniqueWarning( - createError("invalid section linked to " + - object::getELFSectionTypeName(Obj->getHeader()->e_machine, - Sec->sh_type) + - " section with index " + Twine(SecNdx) + ": " + - toString(SymTabOrErr.takeError()))); + this->reportUniqueWarning(createError("invalid section linked to " + + describe(Obj, *Sec) + ": " + + toString(SymTabOrErr.takeError()))); OS << " Addr: " << format_hex_no_prefix(Sec->sh_addr, 16) << " Offset: " << format_hex(Sec->sh_offset, 8) @@ -4677,13 +4648,10 @@ Expected NameOrErr = this->dumper()->getSymbolVersionByIndex(Ndx, IsDefault); if (!NameOrErr) { - if (!NameOrErr) { - unsigned SecNdx = Sec - &cantFail(Obj->sections()).front(); + if (!NameOrErr) this->reportUniqueWarning(createError( - "unable to get a version for entry " + Twine(I) + - " of SHT_GNU_versym section with index " + Twine(SecNdx) + ": " + - toString(NameOrErr.takeError()))); - } + "unable to get a version for entry " + Twine(I) + " of " + + describe(Obj, *Sec) + ": " + toString(NameOrErr.takeError()))); Versions.emplace_back(""); continue; }