forked from OSchip/llvm-project
[llvm-readobj] Change errors to warnings for symbol section name dumping
Also only print each such warning once. LLVM-style output will now print "<?>" for sections it cannot identify, e.g. because the section index is invalid. GNU output continues to print the raw index. In both cases where the st_shndx value is SHN_XINDEX and the index cannot be looked up in the SHT_SYMTAB_SHNDX section (e.g. because it is missing), the symbol is printed like other symbols with st_shndx >= SHN_LORESERVE. Reviewed by: grimar, MaskRay Differential Revision: https://reviews.llvm.org/D69671
This commit is contained in:
parent
31ed36d044
commit
ef85f47595
|
@ -235,13 +235,14 @@ Symbols: []
|
|||
|
||||
# INVALID-PH-ENTSIZE: error: '[[FILE]]': invalid e_phentsize: 12336
|
||||
|
||||
## Check that llvm-readobj reports an error when we have no SHT_SYMTAB_SHNDX section,
|
||||
## Check that llvm-readobj reports a warning when we have no SHT_SYMTAB_SHNDX section,
|
||||
## but have a symbol referencing it.
|
||||
|
||||
# RUN: not llvm-readobj --symbols %p/Inputs/invalid-ext-symtab-index.elf-x86-64 2>&1 | \
|
||||
# RUN: llvm-readobj --symbols %p/Inputs/invalid-ext-symtab-index.elf-x86-64 2>&1 | \
|
||||
# RUN: FileCheck -DFILE=%p/Inputs/invalid-ext-symtab-index.elf-x86-64 --check-prefix=INVALID-EXT-SYMTAB-INDEX %s
|
||||
|
||||
# INVALID-EXT-SYMTAB-INDEX: error: '[[FILE]]': extended symbol index (0) is past the end of the SHT_SYMTAB_SHNDX section of size 0
|
||||
# INVALID-EXT-SYMTAB-INDEX: warning: '[[FILE]]': extended symbol index (0) is past the end of the SHT_SYMTAB_SHNDX section of size 0
|
||||
# INVALID-EXT-SYMTAB-INDEX: Section: Reserved (0xFFFF)
|
||||
|
||||
## Check that llvm-readobj reports an error if a relocation section
|
||||
## has a broken sh_offset (past the end of the file).
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
## ELF section symbols use the section names when printing. This test verifies
|
||||
## this and also that appropriate things are printed if the section is somehow
|
||||
## invalid.
|
||||
|
||||
# RUN: yaml2obj %s -o %t1
|
||||
# RUN: llvm-readobj %t1 --symbols 2> %t.llvm.err1 | FileCheck %s --check-prefix=LLVM1
|
||||
# RUN: FileCheck %s --input-file %t.llvm.err1 --check-prefix=WARN1 --implicit-check-not=warning
|
||||
# RUN: llvm-readelf %t1 --symbols 2> %t.gnu.err1 | FileCheck %s --check-prefix=GNU1
|
||||
# RUN: FileCheck %s --input-file %t.gnu.err1 --check-prefix=WARN1 --implicit-check-not=warning
|
||||
|
||||
# LLVM1: Name: (0)
|
||||
# LLVM1: Name: .foo (0)
|
||||
# LLVM1: Name: <section 67> (0)
|
||||
# LLVM1: Name: .bar (0)
|
||||
# LLVM1: Name: <section 66> (0)
|
||||
|
||||
# GNU1: Symbol table '.symtab' contains 5 entries:
|
||||
# GNU1-NEXT: Num: {{.*}} Type {{.*}} Ndx Name
|
||||
# GNU1-NEXT: 0: {{.*}} NOTYPE {{.*}} UND {{$}}
|
||||
# GNU1-NEXT: 1: {{.*}} SECTION {{.*}} 1 .foo
|
||||
# GNU1-NEXT: 2: {{.*}} SECTION {{.*}} 67 <section 67>
|
||||
# GNU1-NEXT: 3: {{.*}} SECTION {{.*}} 2 .bar
|
||||
# GNU1-NEXT: 4: {{.*}} SECTION {{.*}} 66 <section 66>
|
||||
|
||||
# WARN1: warning: '{{.*}}.tmp1': invalid section index: 67
|
||||
# WARN1: warning: '{{.*}}.tmp1': invalid section index: 66
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS32
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_386
|
||||
Sections:
|
||||
- Name: .foo
|
||||
Type: SHT_PROGBITS
|
||||
- Name: .bar
|
||||
Type: SHT_PROGBITS
|
||||
- Name: .symtab_shndx
|
||||
Type: SHT_SYMTAB_SHNDX
|
||||
Link: .symtab
|
||||
Entries: [ 0, 0, 0, 2, 0x42 ]
|
||||
Symbols:
|
||||
- Name: ""
|
||||
Section: .foo
|
||||
Type: STT_SECTION
|
||||
- Name: ""
|
||||
Index: 0x43
|
||||
Type: STT_SECTION
|
||||
# Section symbol via SHT_SYMTAB_SHNDX.
|
||||
- Name: ""
|
||||
Index: SHN_XINDEX
|
||||
Type: STT_SECTION
|
||||
# Section symbol via SHT_SYMTAB_SHNDX with invalid index.
|
||||
- Name: ""
|
||||
Index: SHN_XINDEX
|
||||
Type: STT_SECTION
|
||||
|
||||
# RUN: yaml2obj %s --docnum=2 -o %t2
|
||||
# RUN: llvm-readobj %t2 --symbols 2> %t.llvm.err2 | FileCheck %s --check-prefix=LLVM2
|
||||
# RUN: FileCheck %s --input-file %t.llvm.err2 --check-prefix=WARN2 --implicit-check-not=warning
|
||||
# RUN: llvm-readelf %t2 --symbols 2> %t.gnu.err2 | FileCheck %s --check-prefix=GNU2
|
||||
# RUN: FileCheck %s --input-file %t.gnu.err2 --check-prefix=WARN2 --implicit-check-not=warning
|
||||
|
||||
# LLVM2: Name: (0)
|
||||
# LLVM2: Name: <?> (0)
|
||||
|
||||
# GNU2: Symbol table '.symtab' contains 2 entries:
|
||||
# GNU2-NEXT: Num: {{.*}} Type {{.*}} Ndx Name
|
||||
# GNU2-NEXT: 0: {{.*}} NOTYPE {{.*}} UND {{$}}
|
||||
# GNU2-NEXT: 1: {{.*}} SECTION {{.*}} RSV[0xffff] <?>
|
||||
|
||||
# WARN2: warning: '{{.*}}.tmp2': extended symbol index (1) is past the end of the SHT_SYMTAB_SHNDX section of size 0
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS32
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_386
|
||||
Symbols:
|
||||
# Section symbol via SHT_SYMTAB_SHNDX when SHT_SYMTAB_SHNDX is missing.
|
||||
- Name: ""
|
||||
Index: SHN_XINDEX
|
||||
Type: STT_SECTION
|
|
@ -1,17 +1,12 @@
|
|||
# Show that llvm-readobj prints symbol shndxes correctly, for valid indexes,
|
||||
# invalid indexes (i.e. section indexes that don't correspond to a real
|
||||
# section), reserved values and processor/os-specific index values, for both GNU
|
||||
# and LLVM styles.
|
||||
## Show that llvm-readobj prints symbol shndxes correctly, for valid indexes,
|
||||
## invalid indexes (i.e. section indexes that don't correspond to a real
|
||||
## section), reserved values and processor/os-specific index values, for both GNU
|
||||
## and LLVM styles.
|
||||
|
||||
# RUN: yaml2obj --docnum=1 %s > %t1
|
||||
# RUN: llvm-readobj --symbols %t1 | FileCheck %s --check-prefix=LLVM1
|
||||
# RUN: llvm-readelf --symbols %t1 | FileCheck %s --check-prefix=GNU1
|
||||
|
||||
# llvm-readobj doesn't accept shndx values that are not valid section indexes
|
||||
# for LLVM style, so only test GNU output in this case.
|
||||
# RUN: yaml2obj --docnum=2 %s > %t2
|
||||
# RUN: llvm-readelf --symbols %t2 | FileCheck %s --check-prefix=GNU2
|
||||
|
||||
# LLVM1: Name: undef
|
||||
# LLVM1: Section:
|
||||
# LLVM1-SAME: Undefined (0x0)
|
||||
|
@ -49,11 +44,6 @@
|
|||
# GNU1-NEXT: 7: {{.*}} RSV[0xfffe] reserved
|
||||
# GNU1-NEXT: 8: {{.*}} 1 xindex
|
||||
|
||||
# GNU2: Symbol table '.symtab' contains 2 entries:
|
||||
# GNU2-NEXT: Num: {{.*}} Ndx Name
|
||||
# GNU2-NEXT: 0: {{.*}} UND
|
||||
# GNU2-NEXT: 1: {{.*}} 66 bad
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS32
|
||||
|
@ -92,6 +82,98 @@ Symbols:
|
|||
Index: SHN_XINDEX
|
||||
Binding: STB_GLOBAL
|
||||
|
||||
## In this case, the index does not correspond to a real section. Check that GNU
|
||||
## style just prints the section index as normal and LLVM style prints a warning
|
||||
## (but only once for each warning).
|
||||
# RUN: yaml2obj --docnum=2 %s > %t2
|
||||
# RUN: llvm-readobj --symbols %t2 2> %t2.llvm.err | FileCheck %s --check-prefix=LLVM2
|
||||
# RUN: FileCheck %s --input-file=%t2.llvm.err --check-prefix=BAD-SHNDX --implicit-check-not=warning
|
||||
# RUN: llvm-readelf --symbols %t2 2> %t2.gnu.err | FileCheck %s --check-prefix=GNU2
|
||||
# RUN: FileCheck %s --input-file=%t2.gnu.err --allow-empty --implicit-check-not={{.}}
|
||||
|
||||
# LLVM2: Name: bad
|
||||
# LLVM2: Section:
|
||||
# LLVM2-SAME: <?> (0x42)
|
||||
# LLVM2: Name: bad2
|
||||
# LLVM2: Section:
|
||||
# LLVM2-SAME: <?> (0x42)
|
||||
# LLVM2: Name: bad3
|
||||
# LLVM2: Section:
|
||||
# LLVM2-SAME: <?> (0x43)
|
||||
# LLVM2: Name: invalid_shndx
|
||||
# LLVM2: Section:
|
||||
# LLVM2-SAME: <?> (0x9)
|
||||
# LLVM2: Name: invalid_shndx2
|
||||
# LLVM2: Section:
|
||||
# LLVM2-SAME: <?> (0x9)
|
||||
# LLVM2: Name: invalid_shndx3
|
||||
# LLVM2: Section:
|
||||
# LLVM2-SAME: <?> (0xA)
|
||||
|
||||
# GNU2: Symbol table '.symtab' contains 7 entries:
|
||||
# GNU2-NEXT: Num: {{.*}} Ndx Name
|
||||
# GNU2-NEXT: 0: {{.*}} UND
|
||||
# GNU2-NEXT: 1: {{.*}} 66 bad
|
||||
# GNU2-NEXT: 2: {{.*}} 66 bad2
|
||||
# GNU2-NEXT: 3: {{.*}} 67 bad3
|
||||
# GNU2-NEXT: 4: {{.*}} 9 invalid_shndx
|
||||
# GNU2-NEXT: 5: {{.*}} 9 invalid_shndx2
|
||||
# GNU2-NEXT: 6: {{.*}} 10 invalid_shndx3
|
||||
|
||||
# BAD-SHNDX: warning: '{{.*}}tmp2': invalid section index: 66
|
||||
# BAD-SHNDX: warning: '{{.*}}tmp2': invalid section index: 67
|
||||
# BAD-SHNDX: warning: '{{.*}}tmp2': invalid section index: 9
|
||||
# BAD-SHNDX: warning: '{{.*}}tmp2': invalid section index: 10
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS32
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_386
|
||||
Sections:
|
||||
- Name: .symtab_shndx
|
||||
Type: SHT_SYMTAB_SHNDX
|
||||
Link: .symtab
|
||||
Entries: [ 0, 0, 0, 0, 9, 9, 10 ]
|
||||
Symbols:
|
||||
- Name: bad
|
||||
Index: 0x42
|
||||
- Name: bad2
|
||||
Index: 0x42
|
||||
- Name: bad3
|
||||
Index: 0x43
|
||||
- Name: invalid_shndx
|
||||
Index: SHN_XINDEX
|
||||
- Name: invalid_shndx2
|
||||
Index: SHN_XINDEX
|
||||
- Name: invalid_shndx3
|
||||
Index: SHN_XINDEX
|
||||
|
||||
## In this case, the symtab shndx section is missing, so symbols with section
|
||||
## indexes of SHN_XINDEX print as Reserved symbols.
|
||||
# RUN: yaml2obj --docnum=3 %s > %t3
|
||||
# RUN: llvm-readobj --symbols %t3 2> %t3.llvm.err | FileCheck %s --check-prefix=LLVM3
|
||||
# RUN: FileCheck %s --input-file=%t3.llvm.err --check-prefix=NO-SYMTAB-SHNDX --implicit-check-not=warning
|
||||
# RUN: llvm-readelf --symbols %t3 2> %t3.gnu.err | FileCheck %s --check-prefix=GNU3
|
||||
# RUN: FileCheck %s --input-file=%t3.gnu.err --check-prefix=NO-SYMTAB-SHNDX --implicit-check-not=warning
|
||||
|
||||
# LLVM3: Name: no_shndx
|
||||
# LLVM3: Section:
|
||||
# LLVM3-SAME: Reserved (0xFFFF)
|
||||
# LLVM3: Name: no_shndx2
|
||||
# LLVM3: Section:
|
||||
# LLVM3-SAME: Reserved (0xFFFF)
|
||||
|
||||
# GNU3: Symbol table '.symtab' contains 3 entries:
|
||||
# GNU3-NEXT: Num: {{.*}} Ndx Name
|
||||
# GNU3-NEXT: 0: {{.*}} UND
|
||||
# GNU3-NEXT: 1: {{.*}} RSV[0xffff] no_shndx
|
||||
# GNU3-NEXT: 2: {{.*}} RSV[0xffff] no_shndx2
|
||||
|
||||
# NO-SYMTAB-SHNDX: warning: '{{.*}}tmp3': extended symbol index (1) is past the end of the SHT_SYMTAB_SHNDX section of size 0
|
||||
# NO-SYMTAB-SHNDX: warning: '{{.*}}tmp3': extended symbol index (2) is past the end of the SHT_SYMTAB_SHNDX section of size 0
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS32
|
||||
|
@ -99,6 +181,7 @@ FileHeader:
|
|||
Type: ET_REL
|
||||
Machine: EM_386
|
||||
Symbols:
|
||||
- Name: bad
|
||||
Index: 0x42
|
||||
Binding: STB_GLOBAL
|
||||
- Name: no_shndx
|
||||
Index: SHN_XINDEX
|
||||
- Name: no_shndx2
|
||||
Index: SHN_XINDEX
|
||||
|
|
|
@ -44,7 +44,7 @@ DynamicSymbols:
|
|||
## Check we can use numeric values to refer to sections.
|
||||
|
||||
# RUN: yaml2obj --docnum=2 %s -o %t2
|
||||
# RUN: not llvm-readobj --dyn-symbols %t2 2>&1 | FileCheck -DFILE=%t2 %s --check-prefix=NUM
|
||||
# RUN: llvm-readobj --dyn-symbols %t2 2>&1 | FileCheck -DFILE=%t2 %s --check-prefix=NUM
|
||||
|
||||
# NUM: Name: foo
|
||||
# NUM: Section:
|
||||
|
@ -54,7 +54,10 @@ DynamicSymbols:
|
|||
# NUM: Section:
|
||||
# NUM-SAME: .strtab (0x2)
|
||||
|
||||
# NUM: error: '[[FILE]]': invalid section index: 255
|
||||
# NUM: Name: zed
|
||||
# NUM: warning: '[[FILE]]': invalid section index: 255
|
||||
# NUM: Section:
|
||||
# NUM-SAME: <?> (0xFF)
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
## but no SHT_SYMTAB_SHNDX section is defined.
|
||||
|
||||
# RUN: yaml2obj --docnum=1 %s -o %t1
|
||||
# RUN: not llvm-readobj --symbols 2>&1 %t1 | FileCheck -DFILE=%t1 %s --check-prefix=CASE1
|
||||
# RUN: llvm-readobj --symbols 2>&1 %t1 | FileCheck -DFILE=%t1 %s --check-prefix=CASE1
|
||||
|
||||
# CASE1: error: '[[FILE]]': extended symbol index (1) is past the end of the SHT_SYMTAB_SHNDX section of size 0
|
||||
# CASE1: warning: '[[FILE]]': extended symbol index (1) is past the end of the SHT_SYMTAB_SHNDX section of size 0
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
|
@ -71,9 +71,9 @@ Symbols:
|
|||
## which is larger than the total number of sections in the file).
|
||||
|
||||
# RUN: yaml2obj --docnum=3 %s -o %t3
|
||||
# RUN: not llvm-readobj --symbols 2>&1 %t3 | FileCheck %s -DFILE=%t3 --check-prefix=CASE3
|
||||
# RUN: llvm-readobj --symbols 2>&1 %t3 | FileCheck %s -DFILE=%t3 --check-prefix=CASE3
|
||||
|
||||
# CASE3: error: '[[FILE]]': invalid section index: 255
|
||||
# CASE3: warning: '[[FILE]]': invalid section index: 255
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
|
|
|
@ -433,6 +433,8 @@ public:
|
|||
virtual void printMipsABIFlags(const ELFObjectFile<ELFT> *Obj) = 0;
|
||||
const ELFDumper<ELFT> *dumper() const { return Dumper; }
|
||||
|
||||
void reportUniqueWarning(Error Err) const;
|
||||
|
||||
protected:
|
||||
std::function<Error(const Twine &Msg)> WarningHandler;
|
||||
StringRef FileName;
|
||||
|
@ -556,6 +558,14 @@ private:
|
|||
void printSectionMapping(const ELFO *Obj);
|
||||
};
|
||||
|
||||
template <class ELFT>
|
||||
void DumpStyle<ELFT>::reportUniqueWarning(Error Err) const {
|
||||
handleAllErrors(std::move(Err), [&](const ErrorInfoBase &EI) {
|
||||
cantFail(WarningHandler(EI.message()),
|
||||
"WarningHandler should always return ErrorSuccess");
|
||||
});
|
||||
}
|
||||
|
||||
template <typename ELFT> class LLVMStyle : public DumpStyle<ELFT> {
|
||||
public:
|
||||
TYPEDEF_ELF_TYPES(ELFT)
|
||||
|
@ -824,10 +834,18 @@ std::string ELFDumper<ELFT>::getFullSymbolName(const Elf_Sym *Symbol,
|
|||
if (SymbolName.empty() && Symbol->getType() == ELF::STT_SECTION) {
|
||||
Elf_Sym_Range Syms = unwrapOrError(
|
||||
ObjF->getFileName(), ObjF->getELFFile()->symbols(DotSymtabSec));
|
||||
unsigned SectionIndex = unwrapOrError(
|
||||
ObjF->getFileName(), getSymbolSectionIndex(Symbol, Syms.begin()));
|
||||
return unwrapOrError(ObjF->getFileName(),
|
||||
getSymbolSectionName(Symbol, SectionIndex));
|
||||
Expected<unsigned> SectionIndex =
|
||||
getSymbolSectionIndex(Symbol, Syms.begin());
|
||||
if (!SectionIndex) {
|
||||
ELFDumperStyle->reportUniqueWarning(SectionIndex.takeError());
|
||||
return "<?>";
|
||||
}
|
||||
Expected<StringRef> NameOrErr = getSymbolSectionName(Symbol, *SectionIndex);
|
||||
if (!NameOrErr) {
|
||||
ELFDumperStyle->reportUniqueWarning(NameOrErr.takeError());
|
||||
return ("<section " + Twine(*SectionIndex) + ">").str();
|
||||
}
|
||||
return *NameOrErr;
|
||||
}
|
||||
|
||||
if (!IsDynamic)
|
||||
|
@ -3298,12 +3316,18 @@ std::string GNUStyle<ELFT>::getSymbolSectionNdx(const ELFO *Obj,
|
|||
return "ABS";
|
||||
case ELF::SHN_COMMON:
|
||||
return "COM";
|
||||
case ELF::SHN_XINDEX:
|
||||
return to_string(format_decimal(
|
||||
unwrapOrError(this->FileName,
|
||||
object::getExtendedSymbolTableIndex<ELFT>(
|
||||
Symbol, FirstSym, this->dumper()->getShndxTable())),
|
||||
3));
|
||||
case ELF::SHN_XINDEX: {
|
||||
Expected<uint32_t> IndexOrErr = object::getExtendedSymbolTableIndex<ELFT>(
|
||||
Symbol, FirstSym, this->dumper()->getShndxTable());
|
||||
if (!IndexOrErr) {
|
||||
assert(Symbol->st_shndx == SHN_XINDEX &&
|
||||
"getSymbolSectionIndex should only fail due to an invalid "
|
||||
"SHT_SYMTAB_SHNDX table/reference");
|
||||
this->reportUniqueWarning(IndexOrErr.takeError());
|
||||
return "RSV[0xffff]";
|
||||
}
|
||||
return to_string(format_decimal(*IndexOrErr, 3));
|
||||
}
|
||||
default:
|
||||
// Find if:
|
||||
// Processor specific
|
||||
|
@ -5454,11 +5478,25 @@ void LLVMStyle<ELFT>::printSectionHeaders(const ELFO *Obj) {
|
|||
template <class ELFT>
|
||||
void LLVMStyle<ELFT>::printSymbolSection(const Elf_Sym *Symbol,
|
||||
const Elf_Sym *First) {
|
||||
unsigned SectionIndex = unwrapOrError(
|
||||
this->FileName, this->dumper()->getSymbolSectionIndex(Symbol, First));
|
||||
StringRef SectionName = unwrapOrError(
|
||||
this->FileName, this->dumper()->getSymbolSectionName(Symbol, SectionIndex));
|
||||
W.printHex("Section", SectionName, SectionIndex);
|
||||
Expected<unsigned> SectionIndex =
|
||||
this->dumper()->getSymbolSectionIndex(Symbol, First);
|
||||
if (!SectionIndex) {
|
||||
assert(Symbol->st_shndx == SHN_XINDEX &&
|
||||
"getSymbolSectionIndex should only fail due to an invalid "
|
||||
"SHT_SYMTAB_SHNDX table/reference");
|
||||
this->reportUniqueWarning(SectionIndex.takeError());
|
||||
W.printHex("Section", "Reserved", SHN_XINDEX);
|
||||
return;
|
||||
}
|
||||
|
||||
Expected<StringRef> SectionName =
|
||||
this->dumper()->getSymbolSectionName(Symbol, *SectionIndex);
|
||||
if (!SectionName) {
|
||||
this->reportUniqueWarning(SectionName.takeError());
|
||||
W.printHex("Section", "<?>", *SectionIndex);
|
||||
} else {
|
||||
W.printHex("Section", *SectionName, *SectionIndex);
|
||||
}
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
|
|
Loading…
Reference in New Issue