## Check that llvm-readobj reports an error if .symtab has an invalid sh_entsize.
# RUN: yaml2obj %s --docnum=6 -o %t6
-# RUN: not llvm-readobj --symbols %t6 2>&1 | FileCheck -DFILE=%t6 --check-prefix=INVALID-SYM-SIZE %s
+# RUN: llvm-readobj --symbols %t6 2>&1 | FileCheck -DFILE=%t6 --check-prefix=INVALID-SYM-SIZE %s
-# INVALID-SYM-SIZE: error: '[[FILE]]': section [index 1] has an invalid sh_entsize: 32
+# INVALID-SYM-SIZE: warning: '[[FILE]]': unable to read symbols from the SHT_SYMTAB section: section [index 1] has an invalid sh_entsize: 32
--- !ELF
FileHeader:
DynamicSymbols:
- Name: foo
-## Check that llvm-readobj reports an error if .symtab has an invalid sh_link value,
+## Check that llvm-readobj reports a warning if .symtab has an invalid sh_link value,
## which is greater than number of sections.
# RUN: yaml2obj %s --docnum=8 -o %t8
-# RUN: not llvm-readobj --symbols %t8 2>&1 | FileCheck -DFILE=%t8 --check-prefix=INVALID-SYMTAB-LINK %s
+# RUN: llvm-readobj --symbols %t8 2>&1 | FileCheck -DFILE=%t8 --check-prefix=INVALID-SYMTAB-LINK %s
-# INVALID-SYMTAB-LINK: error: '[[FILE]]': invalid section index: 255
+# INVALID-SYMTAB-LINK: warning: '[[FILE]]': unable to get the string table for the SHT_SYMTAB section: invalid section index: 255
--- !ELF
FileHeader:
Machine: EM_X86_64
SHEntSize: 1
-## Check that llvm-readobj reports an error if .symtab has sh_size
+## Check that llvm-readobj reports a warning if .symtab has sh_size
## that is not a multiple of sh_entsize.
# RUN: yaml2obj %s --docnum=10 -o %t10
-# RUN: not llvm-readobj --symbols %t10 2>&1 | FileCheck -DFILE=%t10 --check-prefix=INVALID-SYMTAB-SIZE %s
+# RUN: llvm-readobj --symbols %t10 2>&1 | FileCheck -DFILE=%t10 --check-prefix=INVALID-SYMTAB-SIZE %s
-# INVALID-SYMTAB-SIZE: error: '[[FILE]]': section [index 1] has an invalid sh_size (1) which is not a multiple of its sh_entsize (24)
+# INVALID-SYMTAB-SIZE: warning: '[[FILE]]': unable to read symbols from the SHT_SYMTAB section: section [index 1] has an invalid sh_size (1) which is not a multiple of its sh_entsize (24)
--- !ELF
FileHeader:
Type: SHT_RELA
ShOffset: 0x10000
-## Check that llvm-objdump reports an error when we try to print symbols and
+## Check that llvm-objdump reports a warning when we try to print symbols and
## .shstrtab has a broken sh_offset so large that sh_offset + sh_size overflows the platform address size type.
# RUN: yaml2obj %s --docnum=14 -o %t14
-# RUN: not llvm-readobj --symbols %t14 2>&1 | FileCheck -DFILE=%t14 --check-prefix=INVALID-SECTION-SIZE2 %s
+# RUN: llvm-readobj --symbols %t14 2>&1 | FileCheck -DFILE=%t14 --check-prefix=INVALID-SECTION-SIZE2 %s
-# INVALID-SECTION-SIZE2: error: '[[FILE]]': section [index 1] has a sh_offset (0xffffffff) + sh_size (0x1b) that cannot be represented
+# INVALID-SECTION-SIZE2: warning: '[[FILE]]': unable to get the name of the SHT_SYMTAB section: section [index 1] has a sh_offset (0xffffffff) + sh_size (0x1b) that cannot be represented
--- !ELF
FileHeader:
Type: SHT_PROGBITS
ShOffset: 0xFFFF0000
-## Check that llvm-readobj reports an error if symbol name
+## Check that llvm-readobj reports a warning if symbol name
## offset goes past the end of the symbol string table.
# RUN: yaml2obj %s --docnum=18 -o %t18
-# RUN: not llvm-readobj --symbols %t18 2>&1 | FileCheck -DFILE=%t18 --check-prefix=INVALID-SYM-NAME %s
+# RUN: llvm-readobj --symbols %t18 2>&1 | FileCheck -DFILE=%t18 --check-prefix=INVALID-SYM-NAME %s
-# INVALID-SYM-NAME: error: '[[FILE]]': st_name (0x1) is past the end of the string table of size 0x1
+# INVALID-SYM-NAME: warning: '[[FILE]]': st_name (0x1) is past the end of the string table of size 0x1
--- !ELF
FileHeader:
## table goes past the end of the file. Document we stop dumping symbols and report an error.
# RUN: yaml2obj %s --docnum=13 -o %t14
-# RUN: not llvm-readobj --dyn-symbols %t14 2>&1 | \
+# RUN: llvm-readobj --dyn-symbols %t14 2>&1 | \
# RUN: FileCheck %s -DFILE=%t14 --check-prefix=DYNSTR-INVALID-LLVM
-# RUN: not llvm-readelf --dyn-symbols %t14 2>&1 | \
+# RUN: llvm-readelf --dyn-symbols %t14 2>&1 | \
# RUN: FileCheck %s -DFILE=%t14 --check-prefix=DYNSTR-INVALID-GNU
# DYNSTR-INVALID-LLVM: warning: '[[FILE]]': the dynamic string table at 0x78 goes past the end of the file (0x2a8) with DT_STRSZ = 0xffffffff
# DYNSTR-INVALID-LLVM-NEXT: Other: 0
# DYNSTR-INVALID-LLVM-NEXT: Section: Undefined (0x0)
# DYNSTR-INVALID-LLVM-NEXT: }
-# DYNSTR-INVALID-LLVM-NEXT: error: '[[FILE]]': st_name (0xffffff00) is past the end of the string table of size 0x6
+# DYNSTR-INVALID-LLVM-NEXT: warning: '[[FILE]]': st_name (0xffffff00) is past the end of the string table of size 0x6
+# DYNSTR-INVALID-LLVM-NEXT: Symbol {
+# DYNSTR-INVALID-LLVM-NEXT: Name: <?> (4294967040)
+# DYNSTR-INVALID-LLVM-NEXT: Value: 0x0
+# DYNSTR-INVALID-LLVM-NEXT: Size: 0
+# DYNSTR-INVALID-LLVM-NEXT: Binding: Local (0x0)
+# DYNSTR-INVALID-LLVM-NEXT: Type: None (0x0)
+# DYNSTR-INVALID-LLVM-NEXT: Other: 0
+# DYNSTR-INVALID-LLVM-NEXT: Section: Undefined (0x0)
+# DYNSTR-INVALID-LLVM-NEXT: }
+# DYNSTR-INVALID-LLVM-NEXT: Symbol {
+# DYNSTR-INVALID-LLVM-NEXT: Name: test (1)
+# DYNSTR-INVALID-LLVM-NEXT: Value: 0x0
+# DYNSTR-INVALID-LLVM-NEXT: Size: 0
+# DYNSTR-INVALID-LLVM-NEXT: Binding: Local (0x0)
+# DYNSTR-INVALID-LLVM-NEXT: Type: None (0x0)
+# DYNSTR-INVALID-LLVM-NEXT: Other: 0
+# DYNSTR-INVALID-LLVM-NEXT: Section: Undefined (0x0)
+# DYNSTR-INVALID-LLVM-NEXT: }
+# DYNSTR-INVALID-LLVM-NEXT: ]
# DYNSTR-INVALID-GNU: warning: '[[FILE]]': the dynamic string table at 0x78 goes past the end of the file (0x2a8) with DT_STRSZ = 0xffffffff
# DYNSTR-INVALID-GNU: Symbol table '.dynsym' contains 3 entries:
# DYNSTR-INVALID-GNU-NEXT: Num: Value Size Type Bind Vis Ndx Name
# DYNSTR-INVALID-GNU-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
-# DYNSTR-INVALID-GNU-NEXT: error: '[[FILE]]': st_name (0xffffff00) is past the end of the string table of size 0x6
+# DYNSTR-INVALID-GNU-NEXT: warning: '[[FILE]]': st_name (0xffffff00) is past the end of the string table of size 0x6
+# DYNSTR-INVALID-GNU-NEXT: 1: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND <?>
+# DYNSTR-INVALID-GNU-NEXT: 2: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND test
--- !ELF
FileHeader:
Value: 0x2
DynamicSymbols:
- Name: zed
+
+## Check the behavior when we are unable to print symbols due to an error.
+
+## Case 1: check we are able to dump symbols even when can't get the string table for the
+## SHT_SYMTAB section because of invalid sh_link value.
+# RUN: yaml2obj --docnum=2 -DLINK=0xff %s -o %t64.err1
+# RUN: llvm-readobj --symbols %t64.err1 2>&1 | \
+# RUN: FileCheck %s -DFILE=%t64.err1 --check-prefix=STRTAB-LINK-ERR-LLVM
+# RUN: llvm-readelf --symbols %t64.err1 2>&1 | \
+# RUN: FileCheck %s -DFILE=%t64.err1 --check-prefix=STRTAB-LINK-ERR-GNU
+
+# STRTAB-LINK-ERR-LLVM: Symbols [
+# STRTAB-LINK-ERR-LLVM-NEXT: warning: '[[FILE]]': unable to get the string table for the SHT_SYMTAB section: invalid section index: 255
+# STRTAB-LINK-ERR-LLVM-NEXT: warning: '[[FILE]]': st_name (0x0) is past the end of the string table of size 0x0
+# STRTAB-LINK-ERR-LLVM-NEXT: Symbol {
+# STRTAB-LINK-ERR-LLVM-NEXT: Name: <?> (0)
+# STRTAB-LINK-ERR-LLVM-NEXT: Value: 0x0
+# STRTAB-LINK-ERR-LLVM-NEXT: Size: 0
+# STRTAB-LINK-ERR-LLVM-NEXT: Binding: Local (0x0)
+# STRTAB-LINK-ERR-LLVM-NEXT: Type: None (0x0)
+# STRTAB-LINK-ERR-LLVM-NEXT: Other: 0
+# STRTAB-LINK-ERR-LLVM-NEXT: Section: Undefined (0x0)
+# STRTAB-LINK-ERR-LLVM-NEXT: }
+# STRTAB-LINK-ERR-LLVM-NEXT: warning: '[[FILE]]': st_name (0x1) is past the end of the string table of size 0x0
+# STRTAB-LINK-ERR-LLVM-NEXT: Symbol {
+# STRTAB-LINK-ERR-LLVM-NEXT: Name: <?> (1)
+# STRTAB-LINK-ERR-LLVM-NEXT: Value: 0x1
+# STRTAB-LINK-ERR-LLVM-NEXT: Size: 0
+# STRTAB-LINK-ERR-LLVM-NEXT: Binding: Global (0x1)
+# STRTAB-LINK-ERR-LLVM-NEXT: Type: None (0x0)
+# STRTAB-LINK-ERR-LLVM-NEXT: Other: 0
+# STRTAB-LINK-ERR-LLVM-NEXT: Section: .symtab (0x1)
+# STRTAB-LINK-ERR-LLVM-NEXT: }
+# STRTAB-LINK-ERR-LLVM-NEXT: ]
+
+# STRTAB-LINK-ERR-GNU: warning: '[[FILE]]': unable to get the string table for the SHT_SYMTAB section: invalid section index: 255
+# STRTAB-LINK-ERR-GNU: Symbol table '.symtab' contains 2 entries:
+# STRTAB-LINK-ERR-GNU-NEXT: Num: Value Size Type Bind Vis Ndx Name
+# STRTAB-LINK-ERR-GNU-NEXT: warning: '[[FILE]]': st_name (0x0) is past the end of the string table of size 0x0
+# STRTAB-LINK-ERR-GNU-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND <?>
+# STRTAB-LINK-ERR-GNU-NEXT: warning: '[[FILE]]': st_name (0x1) is past the end of the string table of size 0x0
+# STRTAB-LINK-ERR-GNU-NEXT: 1: 0000000000000001 0 NOTYPE GLOBAL DEFAULT 1 <?>
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+ SHStrNdx: [[SHSTRTAB=2]]
+Sections:
+ - Name: .symtab
+ Type: SHT_SYMTAB
+ Link: [[LINK=.strtab]]
+ EntSize: [[ENTSIZE=0x18]]
+## Define the .shstrtab section to reveal its position.
+ - Name: .shstrtab
+ Type: SHT_STRTAB
+Symbols:
+ - Name: foo
+ Value: 0x1
+ Binding: STB_GLOBAL
+ Index: 1
+
+## Case 2: check we report a warning when we are unable to read symbols
+## from the the SHT_SYMTAB section.
+# RUN: yaml2obj --docnum=2 -DENTSIZE=0xFF %s -o %t64.err2
+# RUN: llvm-readobj --symbols %t64.err2 2>&1 | \
+# RUN: FileCheck %s -DFILE=%t64.err2 --check-prefix=SYMTAB-ENTSIZE-ERR-LLVM
+# RUN: llvm-readelf --symbols %t64.err2 2>&1 | \
+# RUN: FileCheck %s -DFILE=%t64.err2 --check-prefix=SYMTAB-ENTSIZE-ERR-GNU
+
+# SYMTAB-ENTSIZE-ERR-LLVM: Symbols [
+# SYMTAB-ENTSIZE-ERR-LLVM-NEXT: warning: '[[FILE]]': unable to read symbols from the SHT_SYMTAB section: section [index 1] has an invalid sh_entsize: 255
+# SYMTAB-ENTSIZE-ERR-LLVM: ]
+
+# SYMTAB-ENTSIZE-ERR-GNU: warning: '[[FILE]]': unable to read symbols from the SHT_SYMTAB section: section [index 1] has an invalid sh_entsize: 255
+# SYMTAB-ENTSIZE-ERR-GNU-NOT: {{.}}
+
+## Case 3: check we report a warning, but continue dumping, when we are unable to read the name of the SHT_SYMTAB section.
+## In this case we set the e_shstrndx field to an invalid index so that the .shstrtab section can't be located.
+# RUN: yaml2obj --docnum=2 -DSHSTRTAB=0xff %s -o %t64.err3
+# RUN: llvm-readobj --symbols %t64.err3 2>&1 | \
+# RUN: FileCheck %s -DFILE=%t64.err3 --check-prefix=SYMTAB-SHSTRTAB-ERR-LLVM
+# RUN: llvm-readelf --symbols %t64.err3 2>&1 | \
+# RUN: FileCheck %s -DFILE=%t64.err3 --check-prefix=SYMTAB-SHSTRTAB-ERR-GNU
+
+# SYMTAB-SHSTRTAB-ERR-LLVM: Symbols [
+# SYMTAB-SHSTRTAB-ERR-LLVM-NEXT: warning: '[[FILE]]': unable to get the name of the SHT_SYMTAB section: section header string table index 255 does not exist
+# SYMTAB-SHSTRTAB-ERR-LLVM-NEXT: Symbol {
+# SYMTAB-SHSTRTAB-ERR-LLVM-NEXT: Name: (0)
+# SYMTAB-SHSTRTAB-ERR-LLVM-NEXT: Value: 0x0
+# SYMTAB-SHSTRTAB-ERR-LLVM-NEXT: Size: 0
+# SYMTAB-SHSTRTAB-ERR-LLVM-NEXT: Binding: Local (0x0)
+# SYMTAB-SHSTRTAB-ERR-LLVM-NEXT: Type: None (0x0)
+# SYMTAB-SHSTRTAB-ERR-LLVM-NEXT: Other: 0
+# SYMTAB-SHSTRTAB-ERR-LLVM-NEXT: Section: Undefined (0x0)
+# SYMTAB-SHSTRTAB-ERR-LLVM-NEXT: }
+# SYMTAB-SHSTRTAB-ERR-LLVM-NEXT: Symbol {
+# SYMTAB-SHSTRTAB-ERR-LLVM-NEXT: Name: foo (1)
+# SYMTAB-SHSTRTAB-ERR-LLVM-NEXT: Value: 0x1
+# SYMTAB-SHSTRTAB-ERR-LLVM-NEXT: Size: 0
+# SYMTAB-SHSTRTAB-ERR-LLVM-NEXT: Binding: Global (0x1)
+# SYMTAB-SHSTRTAB-ERR-LLVM-NEXT: Type: None (0x0)
+# SYMTAB-SHSTRTAB-ERR-LLVM-NEXT: Other: 0
+# SYMTAB-SHSTRTAB-ERR-LLVM-NEXT: warning: '[[FILE]]': section header string table index 255 does not exist
+# SYMTAB-SHSTRTAB-ERR-LLVM-NEXT: Section: <?> (0x1)
+# SYMTAB-SHSTRTAB-ERR-LLVM-NEXT: }
+# SYMTAB-SHSTRTAB-ERR-LLVM-NEXT: ]
+
+# SYMTAB-SHSTRTAB-ERR-GNU: warning: '[[FILE]]': unable to get the name of the SHT_SYMTAB section: section header string table index 255 does not exist
+# SYMTAB-SHSTRTAB-ERR-GNU: Symbol table '<?>' contains 2 entries:
+# SYMTAB-SHSTRTAB-ERR-GNU-NEXT: Num: Value Size Type Bind Vis Ndx Name
+# SYMTAB-SHSTRTAB-ERR-GNU-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
+# SYMTAB-SHSTRTAB-ERR-GNU-NEXT: 1: 0000000000000001 0 NOTYPE GLOBAL DEFAULT 1 foo
} else {
if (!DotSymtabSec)
return;
- StrTable = unwrapOrError(ObjF->getFileName(),
- Obj->getStringTableForSymtab(*DotSymtabSec));
- Syms = unwrapOrError(ObjF->getFileName(), Obj->symbols(DotSymtabSec));
- SymtabName =
- unwrapOrError(ObjF->getFileName(), Obj->getSectionName(DotSymtabSec));
+
+ if (Expected<StringRef> StrTableOrErr =
+ Obj->getStringTableForSymtab(*DotSymtabSec))
+ StrTable = *StrTableOrErr;
+ else
+ reportUniqueWarning(createError(
+ "unable to get the string table for the SHT_SYMTAB section: " +
+ toString(StrTableOrErr.takeError())));
+
+ if (Expected<Elf_Sym_Range> SymsOrErr = Obj->symbols(DotSymtabSec))
+ Syms = *SymsOrErr;
+ else
+ reportUniqueWarning(
+ createError("unable to read symbols from the SHT_SYMTAB section: " +
+ toString(SymsOrErr.takeError())));
+
+ if (Expected<StringRef> SymtabNameOrErr =
+ Obj->getSectionName(DotSymtabSec)) {
+ SymtabName = *SymtabNameOrErr;
+ } else {
+ reportUniqueWarning(
+ createError("unable to get the name of the SHT_SYMTAB section: " +
+ toString(SymtabNameOrErr.takeError())));
+ SymtabName = "<?>";
+ }
+
Entries = DotSymtabSec->getEntityCount();
}
if (Syms.begin() == Syms.end())
std::string ELFDumper<ELFT>::getFullSymbolName(const Elf_Sym *Symbol,
StringRef StrTable,
bool IsDynamic) const {
- std::string SymbolName = maybeDemangle(
- unwrapOrError(ObjF->getFileName(), Symbol->getName(StrTable)));
+ std::string SymbolName;
+ if (Expected<StringRef> NameOrErr = Symbol->getName(StrTable)) {
+ SymbolName = maybeDemangle(*NameOrErr);
+ } else {
+ reportUniqueWarning(NameOrErr.takeError());
+ return "<?>";
+ }
if (SymbolName.empty() && Symbol->getType() == ELF::STT_SECTION) {
Elf_Sym_Range Syms = unwrapOrError(