diff options
| -rw-r--r-- | llvm/test/tools/llvm-readobj/elf-verdef-invalid.test | 10 | ||||
| -rw-r--r-- | llvm/tools/llvm-readobj/ELFDumper.cpp | 40 |
2 files changed, 29 insertions, 21 deletions
diff --git a/llvm/test/tools/llvm-readobj/elf-verdef-invalid.test b/llvm/test/tools/llvm-readobj/elf-verdef-invalid.test index 493537464a0..3a4de369838 100644 --- a/llvm/test/tools/llvm-readobj/elf-verdef-invalid.test +++ b/llvm/test/tools/llvm-readobj/elf-verdef-invalid.test @@ -3,14 +3,14 @@ ## Check that we report a warning when sh_link references a non-existent section. # RUN: yaml2obj %s --docnum=1 -o %t1 -# RUN: llvm-readobj -V %t1 2>&1 | FileCheck %s --check-prefix=INVALID-LINK-LLVM -DFILE=%t1 -# RUN: not llvm-readelf -V %t1 2>&1 | FileCheck %s --check-prefix=INVALID-LINK-GNU -DFILE=%t1 +# RUN: llvm-readobj -V %t1 2>&1 | FileCheck %s --check-prefix=INVALID-LINK-LLVM --implicit-check-not="warning:" -DFILE=%t1 +# RUN: llvm-readelf -V %t1 2>&1 | FileCheck %s --check-prefix=INVALID-LINK-GNU --implicit-check-not="warning:" -DFILE=%t1 # INVALID-LINK-LLVM: warning: '[[FILE]]': invalid section linked to SHT_GNU_verdef section with index 1: invalid section index: 255 -## TODO: llvm-readelf should also report a meaningful warning instead of an error. -# INVALID-LINK-GNU: Version definition -# INVALID-LINK-GNU: error: '[[FILE]]': invalid section index: 255 +# INVALID-LINK-GNU: Version definition section '.gnu.version_d' contains 0 entries: +# INVALID-LINK-GNU: warning: '[[FILE]]': invalid section linked to SHT_GNU_verdef section with index 1: invalid section index: 255 +# INVALID-LINK-GNU-NEXT: Addr: 0000000000000000 Offset: 0x000040 Link: 255 (<corrupt>) --- !ELF FileHeader: diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index b7bd35e7c95..79d08d379a1 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -672,6 +672,9 @@ private: bool checkPTDynamic(const Elf_Phdr &Phdr, const Elf_Shdr &Sec); void printProgramHeaders(const ELFO *Obj); void printSectionMapping(const ELFO *Obj); + void printGNUVersionSectionProlog(const ELFFile<ELFT> *Obj, + const typename ELFT::Shdr *Sec, + const Twine &Label, unsigned EntriesNum); }; template <class ELFT> @@ -3921,18 +3924,26 @@ void GNUStyle<ELFT>::printDynamicRelocations(const ELFO *Obj) { } template <class ELFT> -static void printGNUVersionSectionProlog(formatted_raw_ostream &OS, - const Twine &Name, unsigned EntriesNum, - const ELFFile<ELFT> *Obj, - const typename ELFT::Shdr *Sec, - StringRef FileName) { - StringRef SecName = unwrapOrError(FileName, Obj->getSectionName(Sec)); - OS << Name << " section '" << SecName << "' " +void GNUStyle<ELFT>::printGNUVersionSectionProlog( + const ELFFile<ELFT> *Obj, const typename ELFT::Shdr *Sec, + const Twine &Label, unsigned EntriesNum) { + StringRef SecName = unwrapOrError(this->FileName, Obj->getSectionName(Sec)); + OS << Label << " section '" << SecName << "' " << "contains " << EntriesNum << " entries:\n"; - const typename ELFT::Shdr *SymTab = - unwrapOrError(FileName, Obj->getSection(Sec->sh_link)); - StringRef SymTabName = unwrapOrError(FileName, Obj->getSectionName(SymTab)); + unsigned SecNdx = Sec - &cantFail(Obj->sections()).front(); + StringRef SymTabName = "<corrupt>"; + + Expected<const typename ELFT::Shdr *> SymTabOrErr = + Obj->getSection(Sec->sh_link); + if (SymTabOrErr) + SymTabName = + unwrapOrError(this->FileName, Obj->getSectionName(*SymTabOrErr)); + else + this->reportUniqueWarning(createError( + "invalid section linked to SHT_GNU_verdef section with index " + + Twine(SecNdx) + ": " + toString(SymTabOrErr.takeError()))); + OS << " Addr: " << format_hex_no_prefix(Sec->sh_addr, 16) << " Offset: " << format_hex(Sec->sh_offset, 8) << " Link: " << Sec->sh_link << " (" << SymTabName << ")\n"; @@ -3945,8 +3956,7 @@ void GNUStyle<ELFT>::printVersionSymbolSection(const ELFFile<ELFT> *Obj, return; unsigned Entries = Sec->sh_size / sizeof(Elf_Versym); - printGNUVersionSectionProlog(OS, "Version symbols", Entries, Obj, Sec, - this->FileName); + printGNUVersionSectionProlog(Obj, Sec, "Version symbols", Entries); const uint8_t *VersymBuf = reinterpret_cast<const uint8_t *>(Obj->base() + Sec->sh_offset); @@ -4017,8 +4027,7 @@ void GNUStyle<ELFT>::printVersionDefinitionSection(const ELFFile<ELFT> *Obj, if (!Sec) return; - printGNUVersionSectionProlog(OS, "Version definition", Sec->sh_info, Obj, Sec, - this->FileName); + printGNUVersionSectionProlog(Obj, Sec, "Version definition", Sec->sh_info); Expected<std::vector<VerDef>> V = this->dumper()->getVersionDefinitions(Sec); if (!V) { @@ -4047,8 +4056,7 @@ void GNUStyle<ELFT>::printVersionDependencySection(const ELFFile<ELFT> *Obj, return; unsigned VerneedNum = Sec->sh_info; - printGNUVersionSectionProlog(OS, "Version needs", VerneedNum, Obj, Sec, - this->FileName); + printGNUVersionSectionProlog(Obj, Sec, "Version needs", VerneedNum); ArrayRef<uint8_t> SecData = unwrapOrError(this->FileName, Obj->getSectionContents(Sec)); |

