diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h --- a/llvm/include/llvm/Object/ELFObjectFile.h +++ b/llvm/include/llvm/Object/ELFObjectFile.h @@ -625,11 +625,17 @@ if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION) Result |= SymbolRef::SF_FormatSpecific; - auto DotSymtabSecSyms = EF.symbols(DotSymtabSec); - if (DotSymtabSecSyms && ESym == (*DotSymtabSecSyms).begin()) - Result |= SymbolRef::SF_FormatSpecific; - auto DotDynSymSecSyms = EF.symbols(DotDynSymSec); - if (DotDynSymSecSyms && ESym == (*DotDynSymSecSyms).begin()) + auto IsNULLSymbol = [this](const Elf_Sym *Sym, const Elf_Shdr *SymSec) { + Expected SymbolsOrErr = EF.symbols(SymSec); + if (!SymbolsOrErr) { + // TODO: Actually report errors helpfully. + consumeError(SymbolsOrErr.takeError()); + return false; + } + return Sym == SymbolsOrErr->begin(); + }; + + if (IsNULLSymbol(ESym, DotSymtabSec) || IsNULLSymbol(ESym, DotDynSymSec)) Result |= SymbolRef::SF_FormatSpecific; if (EF.getHeader()->e_machine == ELF::EM_ARM) { diff --git a/llvm/test/Object/invalid-symtab-size.test b/llvm/test/Object/invalid-symtab-size.test new file mode 100644 --- /dev/null +++ b/llvm/test/Object/invalid-symtab-size.test @@ -0,0 +1,36 @@ +## This test ensures llvm will not crash when dumping a symbol table +## whose sh_size isn't a multiple of the symbol size (sh_size % sizeof(Elf_Sym) != 0). +## TODO: It would be helpful if we could warn about this in future. + +# RUN: yaml2obj -DBITS=32 -DSIZE=33 %s -o %t.32-bit.o +# RUN: llvm-nm %t.32-bit.o 2>&1 | FileCheck --implicit-check-not=warning %s +# RUN: yaml2obj -DBITS=64 -DSIZE=49 %s -o %t.64-bit.o +# RUN: llvm-nm %t.64-bit.o 2>&1 | FileCheck --implicit-check-not=warning %s + +# CHECK: U +# CHECK-EMPTY: + +## TODO: Currently, llvm-nm will print 0-index NULL symbol from .dynsym. We should correct this behavior in future. +# RUN: llvm-nm --dynamic %t.32-bit.o 2>&1 | FileCheck --implicit-check-not=warning --check-prefix=DYN %s +# RUN: llvm-nm --dynamic %t.64-bit.o 2>&1 | FileCheck --implicit-check-not=warning --check-prefix=DYN %s + +# DYN: U +# DYN-NEXT: U +# DYN-EMPTY: + +--- !ELF +FileHeader: + Class: ELFCLASS[[BITS]] + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_386 +Sections: + - Name: .dynstr + Type: SHT_STRTAB + Content: "00" + - Name: .symtab + Type: SHT_SYMTAB + Size: [[SIZE]] + - Name: .dynsym + Type: SHT_DYNSYM + Size: [[SIZE]]