From: Georgii Rymar Date: Mon, 23 Nov 2020 13:18:00 +0000 (+0300) Subject: [llvm-readelf/obj] - Refine the implementation of `printGNUVersionSectionProlog` X-Git-Tag: llvmorg-13-init~5274 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6b74eabfddbc6629adbf6358f8e78893c4ee1d12;p=platform%2Fupstream%2Fllvm.git [llvm-readelf/obj] - Refine the implementation of `printGNUVersionSectionProlog` This: 1) Changes its signature. 2) Refines the name of local variable (`SymTabName`->`LinkedSecName`, because SHT_GNU_verneed/SHT_GNU_verdef are linked with the string table, not with the symbol table). 3) Stops using the `unwrapOrError` inside. Differential revision: https://reviews.llvm.org/D91964 --- diff --git a/llvm/test/tools/llvm-readobj/ELF/verdef-invalid.test b/llvm/test/tools/llvm-readobj/ELF/verdef-invalid.test index fc4e691..aa9b7b8 100644 --- a/llvm/test/tools/llvm-readobj/ELF/verdef-invalid.test +++ b/llvm/test/tools/llvm-readobj/ELF/verdef-invalid.test @@ -34,11 +34,11 @@ Sections: ## Check that we report a warning when we can't read the content of the SHT_GNU_verdef section. -# RUN: yaml2obj %s --docnum=2 -o %t3 +# RUN: yaml2obj %s --docnum=2 -DSHOFFSET=0xFFFFFFFF -o %t3 # RUN: llvm-readobj -V %t3 2>&1 | FileCheck %s --check-prefix=INVALID-DATA -DFILE=%t3 # RUN: llvm-readelf -V %t3 2>&1 | FileCheck %s --check-prefix=INVALID-DATA -DFILE=%t3 -# INVALID-DATA: warning: '[[FILE]]': cannot read content of SHT_GNU_verdef section with index 1: section [index 1] has a sh_offset (0xffffffff) + sh_size (0x0) that is greater than the file size (0x228) +# INVALID-DATA: warning: '[[FILE]]': cannot read content of SHT_GNU_verdef section with index 1: section [index 1] has a sh_offset (0xffffffff) + sh_size (0x0) that is greater than the file size (0x230) --- !ELF FileHeader: @@ -51,10 +51,42 @@ Sections: Link: .dynstr Info: 0x0 Entries: [] - ShOffset: 0xFFFFFFFF + ShOffset: [[SHOFFSET=]] + ShName: [[SHNAME=]] + - Name: .dynstr + Type: SHT_STRTAB + ShName: [[DYNSTRNAME=]] DynamicSymbols: - Name: foo +## Check that llvm-readelf reports a warning when the name of the SHT_GNU_verdef section can't be read. + +# RUN: yaml2obj %s --docnum=2 -DSHNAME=0xFF -o %t.invalid.name +# RUN: llvm-readobj -V %t.invalid.name 2>&1 | \ +# RUN: FileCheck %s --check-prefix=INVALID-NAME-LLVM -DFILE=%t.invalid.name --implicit-check-not=warning: +# RUN: llvm-readelf -V %t.invalid.name 2>&1 | \ +# RUN: FileCheck %s --check-prefix=INVALID-NAME-GNU -DFILE=%t.invalid.name --implicit-check-not=warning: + +# INVALID-NAME-LLVM: VersionDefinitions [ +# INVALID-NAME-LLVM-NEXT: ] + +# INVALID-NAME-GNU: warning: '[[FILE]]': unable to get the name of SHT_GNU_verdef section with index 1: a section [index 1] has an invalid sh_name (0xff) offset which goes past the end of the section name string table +# INVALID-NAME-GNU-NEXT: Version definition section '' contains 0 entries: +# INVALID-NAME-GNU-NEXT: Addr: 0000000000000000 Offset: 0x000040 Link: 2 (.dynstr) + +## Check that llvm-readelf reports a warning when we are unable to read the name of +## the section linked with the SHT_GNU_verdef section (usually ".dynstr"). + +# RUN: yaml2obj %s --docnum=2 -DDYNSTRNAME=0xFF -o %t.invalid.name2 +# RUN: llvm-readobj -V %t.invalid.name2 2>&1 | \ +# RUN: FileCheck %s --check-prefix=INVALID-NAME-LLVM -DFILE=%t.invalid.name2 --implicit-check-not=warning: +# RUN: llvm-readelf -V %t.invalid.name2 2>&1 | \ +# RUN: FileCheck %s --check-prefix=INVALID-NAME2-GNU -DFILE=%t.invalid.name2 --implicit-check-not=warning: + +# INVALID-NAME2-GNU: Version definition section '.gnu.version_d' contains 0 entries: +# INVALID-NAME2-GNU-NEXT: warning: '[[FILE]]': unable to get the name of SHT_STRTAB section with index 2: a section [index 2] has an invalid sh_name (0xff) offset which goes past the end of the section name string table +# INVALID-NAME2-GNU-NEXT: Addr: 0000000000000000 Offset: 0x000040 Link: 2 () + ## Check that we report a warning when a SHT_GNU_verdef section contains a version definition ## that goes past the end of the section. diff --git a/llvm/test/tools/llvm-readobj/ELF/verneed-invalid.test b/llvm/test/tools/llvm-readobj/ELF/verneed-invalid.test index 3bb439b..712bdc4 100644 --- a/llvm/test/tools/llvm-readobj/ELF/verneed-invalid.test +++ b/llvm/test/tools/llvm-readobj/ELF/verneed-invalid.test @@ -315,7 +315,7 @@ DynamicSymbols: ## Check that we report a warning when sh_link references a non-existent section. -# RUN: yaml2obj --docnum=6 %s -o %t6 +# RUN: yaml2obj --docnum=6 %s -DLINK=0xFF -o %t6 # RUN: llvm-readobj --sections -V %t6 2>&1 | FileCheck %s -DFILE=%t6 --implicit-check-not="warning:" --check-prefix=INVALID-LINK-LLVM # RUN: llvm-readelf --sections -V %t6 2>&1 | FileCheck %s -DFILE=%t6 --implicit-check-not="warning:" --check-prefix=INVALID-LINK-GNU @@ -349,11 +349,12 @@ FileHeader: Data: ELFDATA2LSB Type: ET_EXEC Sections: - - Name: .gnu.version_r - Type: SHT_GNU_verneed - Flags: [ SHF_ALLOC ] - Info: 1 - Link: 0xFF + - Name: .gnu.version_r + Type: SHT_GNU_verneed + Flags: [ SHF_ALLOC ] + Info: 1 + Link: [[LINK=.dynstr]] + ShName: [[SHNAME=]] Dependencies: - Version: 1 File: foo @@ -362,9 +363,58 @@ Sections: Hash: 0 Flags: 0 Other: 0 + - Name: .dynstr + Type: SHT_STRTAB + ShName: [[DYNSTRNAME=]] DynamicSymbols: - Name: foo +## Check that llvm-readelf reports a warning when the name of the SHT_GNU_verneed section can't be read. + +# RUN: yaml2obj --docnum=6 %s -DSHNAME=0xFFFFFFFF -o %t.invalid.name +# RUN: llvm-readobj -V %t.invalid.name 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t.invalid.name --check-prefix=INVALID-NAME-LLVM --implicit-check-not=warning: +# RUN: llvm-readelf -V %t.invalid.name 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t.invalid.name --check-prefix=INVALID-NAME-GNU --implicit-check-not=warning: + +# INVALID-NAME-LLVM: VersionRequirements [ +# INVALID-NAME-LLVM-NEXT: Dependency { +# INVALID-NAME-LLVM-NEXT: Version: 1 +# INVALID-NAME-LLVM-NEXT: Count: 1 +# INVALID-NAME-LLVM-NEXT: FileName: foo +# INVALID-NAME-LLVM-NEXT: Entries [ +# INVALID-NAME-LLVM-NEXT: Entry { +# INVALID-NAME-LLVM-NEXT: Hash: 0 +# INVALID-NAME-LLVM-NEXT: Flags [ (0x0) +# INVALID-NAME-LLVM-NEXT: ] +# INVALID-NAME-LLVM-NEXT: Index: 0 +# INVALID-NAME-LLVM-NEXT: Name: foo +# INVALID-NAME-LLVM-NEXT: } +# INVALID-NAME-LLVM-NEXT: ] +# INVALID-NAME-LLVM-NEXT: } +# INVALID-NAME-LLVM-NEXT: ] + +# INVALID-NAME-GNU: warning: '[[FILE]]': unable to get the name of SHT_GNU_verneed section with index 1: a section [index 1] has an invalid sh_name (0xffffffff) offset which goes past the end of the section name string table +# INVALID-NAME-GNU-NEXT: Version needs section '' contains 1 entries: +# INVALID-NAME-GNU-NEXT: Addr: 0000000000000000 Offset: 0x000040 Link: 2 (.dynstr) +# INVALID-NAME-GNU-NEXT: 0x0000: Version: 1 File: foo Cnt: 1 +# INVALID-NAME-GNU-NEXT: 0x0010: Name: foo Flags: none Version: 0 + +## Check that llvm-readelf reports a warning when we are unable to read the name of +## the section linked with the SHT_GNU_verneed section (usually ".dynstr"). + +# RUN: yaml2obj --docnum=6 %s -DDYNSTRNAME=0xFFFFFFFF -o %t.invalid.name2 +# RUN: llvm-readobj -V %t.invalid.name2 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t.invalid.name2 --check-prefix=INVALID-NAME-LLVM --implicit-check-not=warning: +# RUN: llvm-readelf -V %t.invalid.name2 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t.invalid.name2 --check-prefix=INVALID-NAME2-GNU --implicit-check-not=warning: + +# INVALID-NAME2-GNU: Version needs section '.gnu.version_r' contains 1 entries: +# INVALID-NAME2-GNU-NEXT: warning: '[[FILE]]': unable to get the name of SHT_STRTAB section with index 2: a section [index 2] has an invalid sh_name (0xffffffff) offset which goes past the end of the section name string table +# INVALID-NAME2-GNU-NEXT: Addr: 0000000000000000 Offset: 0x000040 Link: 2 () +# INVALID-NAME2-GNU-NEXT: 0x0000: Version: 1 File: foo Cnt: 1 +# INVALID-NAME2-GNU-NEXT: 0x0010: Name: foo Flags: none Version: 0 + ## Check that we report a warning when we can't read the content of the SHT_GNU_verneed section. # RUN: yaml2obj --docnum=7 %s -o %t7 diff --git a/llvm/test/tools/llvm-readobj/ELF/versym-invalid.test b/llvm/test/tools/llvm-readobj/ELF/versym-invalid.test index 4064ce7..9b665b9 100644 --- a/llvm/test/tools/llvm-readobj/ELF/versym-invalid.test +++ b/llvm/test/tools/llvm-readobj/ELF/versym-invalid.test @@ -74,12 +74,12 @@ DynamicSymbols: [] ## Check we report a warning when a SHT_GNU_versym section is not correctly aligned in memory. -# RUN: yaml2obj --docnum=3 %s -o %t4 +# RUN: yaml2obj --docnum=3 %s -DSHOFFSET=0xffff -o %t4 # RUN: llvm-readelf -V %t4 2>&1 | FileCheck -DFILE=%t4 %s --check-prefix=MISALIGNED-GNU # RUN: llvm-readobj -V %t4 2>&1 | FileCheck -DFILE=%t4 %s --check-prefix=MISALIGNED-LLVM -# MISALIGNED-GNU: Version symbols section '.gnu.version' contains 0 entries: -# MISALIGNED-GNU-NEXT: Addr: 0000000000000000 Offset: 0x00ffff Link: 0 () +# MISALIGNED-GNU: Version symbols section '.gnu.version' contains 1 entries: +# MISALIGNED-GNU-NEXT: Addr: 0000000000000000 Offset: 0x00ffff Link: 2 (.dynsym) # MISALIGNED-GNU-NEXT: warning: '[[FILE]]': the SHT_GNU_versym section with index 1 is misaligned # MISALIGNED-LLVM: VersionSymbols [ @@ -92,10 +92,50 @@ FileHeader: Data: ELFDATA2LSB Type: ET_EXEC Sections: - - Name: .gnu.version - Type: SHT_GNU_versym - Entries: [ ] - ShOffset: 0xffff + - Name: .gnu.version + Type: SHT_GNU_versym + Entries: [ 0 ] + Link: .dynsym + ShOffset: [[SHOFFSET=]] + ShName: [[SHNAME=]] + - Name: .dynsym + Type: SHT_DYNSYM + ShName: [[DYNSYMNAME=]] +DynamicSymbols: [] + +## Check that llvm-readelf reports a warning when the name of the SHT_GNU_versym section can't be read. + +# RUN: yaml2obj %s --docnum=3 -DSHNAME=0xFF -o %t.invalid.name +# RUN: llvm-readobj -V %t.invalid.name 2>&1 | \ +# RUN: FileCheck %s --check-prefix=INVALID-NAME-LLVM -DFILE=%t.invalid.name --implicit-check-not=warning: +# RUN: llvm-readelf -V %t.invalid.name 2>&1 | \ +# RUN: FileCheck %s --check-prefix=INVALID-NAME-GNU -DFILE=%t.invalid.name --implicit-check-not=warning: + +# INVALID-NAME-LLVM: VersionSymbols [ +# INVALID-NAME-LLVM-NEXT: Symbol { +# INVALID-NAME-LLVM-NEXT: Version: 0 +# INVALID-NAME-LLVM-NEXT: Name: +# INVALID-NAME-LLVM-NEXT: } +# INVALID-NAME-LLVM-NEXT: ] + +# INVALID-NAME-GNU: warning: '[[FILE]]': unable to get the name of SHT_GNU_versym section with index 1: a section [index 1] has an invalid sh_name (0xff) offset which goes past the end of the section name string table +# INVALID-NAME-GNU-NEXT: Version symbols section '' contains 1 entries: +# INVALID-NAME-GNU-NEXT: Addr: 0000000000000000 Offset: 0x000040 Link: 2 (.dynsym) +# INVALID-NAME-GNU-NEXT: 000: 0 (*local*) + +## Check that llvm-readelf reports a warning when we are unable to read the name of +## the section linked with the SHT_GNU_verneed section (usually ".dynsym"). + +# RUN: yaml2obj %s --docnum=3 -DDYNSYMNAME=0xFF -o %t.invalid.name2 +# RUN: llvm-readobj -V %t.invalid.name2 2>&1 | \ +# RUN: FileCheck %s --check-prefix=INVALID-NAME-LLVM -DFILE=%t.invalid.name2 --implicit-check-not=warning: +# RUN: llvm-readelf -V %t.invalid.name2 2>&1 | \ +# RUN: FileCheck %s --check-prefix=INVALID-NAME2-GNU -DFILE=%t.invalid.name2 --implicit-check-not=warning: + +# INVALID-NAME2-GNU: Version symbols section '.gnu.version' contains 1 entries: +# INVALID-NAME2-GNU-NEXT: warning: '[[FILE]]': unable to get the name of SHT_DYNSYM section with index 2: a section [index 2] has an invalid sh_name (0xff) offset which goes past the end of the section name string table +# INVALID-NAME2-GNU-NEXT: Addr: 0000000000000000 Offset: 0x000040 Link: 2 () +# INVALID-NAME2-GNU-NEXT: 000: 0 (*local*) ## Check we report a warning when a SHT_GNU_versym section has an invalid entry size. diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index cdfbd1f..d1a5aa7 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -952,7 +952,7 @@ private: std::string getSymbolSectionNdx(const Elf_Sym &Symbol, unsigned SymIndex); void printProgramHeaders(); void printSectionMapping(); - void printGNUVersionSectionProlog(const typename ELFT::Shdr *Sec, + void printGNUVersionSectionProlog(const typename ELFT::Shdr &Sec, const Twine &Label, unsigned EntriesNum); }; @@ -4718,26 +4718,25 @@ template void DumpStyle::printDynamicRelocationsHelper() { template void GNUStyle::printGNUVersionSectionProlog( - const typename ELFT::Shdr *Sec, const Twine &Label, unsigned EntriesNum) { - StringRef SecName = - unwrapOrError(this->FileName, this->Obj.getSectionName(*Sec)); + const typename ELFT::Shdr &Sec, const Twine &Label, unsigned EntriesNum) { + // Don't inline the SecName, because it might report a warning to stderr and + // corrupt the output. + StringRef SecName = this->getPrintableSectionName(Sec); OS << Label << " section '" << SecName << "' " << "contains " << EntriesNum << " entries:\n"; - StringRef SymTabName = ""; - Expected SymTabOrErr = - this->Obj.getSection(Sec->sh_link); - if (SymTabOrErr) - SymTabName = - unwrapOrError(this->FileName, this->Obj.getSectionName(**SymTabOrErr)); + StringRef LinkedSecName = ""; + if (Expected LinkedSecOrErr = + this->Obj.getSection(Sec.sh_link)) + LinkedSecName = this->getPrintableSectionName(**LinkedSecOrErr); else - this->reportUniqueWarning(createError("invalid section linked to " + - describe(this->Obj, *Sec) + ": " + - toString(SymTabOrErr.takeError()))); + this->reportUniqueWarning( + createError("invalid section linked to " + describe(this->Obj, Sec) + + ": " + toString(LinkedSecOrErr.takeError()))); - OS << " Addr: " << format_hex_no_prefix(Sec->sh_addr, 16) - << " Offset: " << format_hex(Sec->sh_offset, 8) - << " Link: " << Sec->sh_link << " (" << SymTabName << ")\n"; + OS << " Addr: " << format_hex_no_prefix(Sec.sh_addr, 16) + << " Offset: " << format_hex(Sec.sh_offset, 8) + << " Link: " << Sec.sh_link << " (" << LinkedSecName << ")\n"; } template @@ -4745,7 +4744,7 @@ void GNUStyle::printVersionSymbolSection(const Elf_Shdr *Sec) { if (!Sec) return; - printGNUVersionSectionProlog(Sec, "Version symbols", + printGNUVersionSectionProlog(*Sec, "Version symbols", Sec->sh_size / sizeof(Elf_Versym)); Expected> VerTableOrErr = this->dumper().getVersionTable(*Sec, /*SymTab=*/nullptr, @@ -4818,7 +4817,7 @@ void GNUStyle::printVersionDefinitionSection(const Elf_Shdr *Sec) { if (!Sec) return; - printGNUVersionSectionProlog(Sec, "Version definition", Sec->sh_info); + printGNUVersionSectionProlog(*Sec, "Version definition", Sec->sh_info); Expected> V = this->dumper().getVersionDefinitions(*Sec); if (!V) { @@ -4846,7 +4845,7 @@ void GNUStyle::printVersionDependencySection(const Elf_Shdr *Sec) { return; unsigned VerneedNum = Sec->sh_info; - printGNUVersionSectionProlog(Sec, "Version needs", VerneedNum); + printGNUVersionSectionProlog(*Sec, "Version needs", VerneedNum); Expected> V = this->dumper().getVersionDependencies(*Sec);