diff --git a/llvm/test/tools/llvm-nm/invalid-symbol-table-size.test b/llvm/test/tools/llvm-nm/invalid-symbol-table-size.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-nm/invalid-symbol-table-size.test @@ -0,0 +1,29 @@ +## This test ensures llvm-nm will emit a helpful error message when dumping a symbol table +## whose sh_size isn't a multiple of the symbol size (sh_size % sizeof(Elf_Sym) != 0). + +# RUN: yaml2obj -DBITS=32 -DSIZE=33 %s -o %t.32-bit.o +# RUN: not llvm-nm %t.32-bit.o 2>&1 | FileCheck -DSIZE=33 -DSYMSIZE=16 %s +# RUN: yaml2obj -DBITS=64 -DSIZE=49 %s -o %t.64-bit.o +# RUN: not llvm-nm %t.64-bit.o 2>&1 | FileCheck -DSIZE=49 -DSYMSIZE=24 %s + +# RUN: not llvm-nm --dynamic %t.32-bit.o 2>&1 | FileCheck -DSIZE=33 -DSYMSIZE=16 %s +# RUN: not llvm-nm --dynamic %t.64-bit.o 2>&1 | FileCheck -DSIZE=49 -DSYMSIZE=24 %s + +# CHECK: error: {{.*}} section [index 2] has an invalid sh_size ([[SIZE]]) which is not a multiple of its sh_entsize ([[SYMSIZE]]) + +--- !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]] diff --git a/llvm/test/tools/llvm-objdump/invalid-symbol-table-size.test b/llvm/test/tools/llvm-objdump/invalid-symbol-table-size.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/invalid-symbol-table-size.test @@ -0,0 +1,29 @@ +## This test ensures llvm-objdump will emit a helpful error message when dumping a symbol table +## whose sh_size isn't a multiple of the symbol size (sh_size % sizeof(Elf_Sym) != 0). + +# RUN: yaml2obj -DBITS=32 -DSIZE=33 %s -o %t.32-bit.o +# RUN: not llvm-objdump --syms %t.32-bit.o 2>&1 | FileCheck -DSIZE=33 -DSYMSIZE=16 %s +# RUN: yaml2obj -DBITS=64 -DSIZE=49 %s -o %t.64-bit.o +# RUN: not llvm-objdump --syms %t.64-bit.o 2>&1 | FileCheck -DSIZE=49 -DSYMSIZE=24 %s + +# RUN: not llvm-objdump --dynamic-syms %t.32-bit.o 2>&1 | FileCheck -DSIZE=33 -DSYMSIZE=16 %s +# RUN: not llvm-objdump --dynamic-syms %t.64-bit.o 2>&1 | FileCheck -DSIZE=49 -DSYMSIZE=24 %s + +# CHECK: error: {{.*}} section [index 2] has an invalid sh_size ([[SIZE]]) which is not a multiple of its sh_entsize ([[SYMSIZE]]) + +--- !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]] diff --git a/llvm/test/tools/llvm-size/invalid-symbol-table-size.test b/llvm/test/tools/llvm-size/invalid-symbol-table-size.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-size/invalid-symbol-table-size.test @@ -0,0 +1,20 @@ +## This test ensures llvm-size will emit a helpful error message when dumping a symbol table +## whose sh_size isn't a multiple of the symbol size (sh_size % sizeof(Elf_Sym) != 0). + +# RUN: yaml2obj -DBITS=32 -DSIZE=33 %s -o %t.32-bit.o +# RUN: not llvm-size --common %t.32-bit.o 2>&1 | FileCheck -DSIZE=33 -DSYMSIZE=16 %s +# RUN: yaml2obj -DBITS=64 -DSIZE=49 %s -o %t.64-bit.o +# RUN: not llvm-size --common %t.64-bit.o 2>&1 | FileCheck -DSIZE=49 -DSYMSIZE=24 %s + +# CHECK: error: '{{.*}}': section [index 1] has an invalid sh_size ([[SIZE]]) which is not a multiple of its sh_entsize ([[SYMSIZE]]) + +--- !ELF +FileHeader: + Class: ELFCLASS[[BITS]] + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_386 +Sections: + - Name: .symtab + Type: SHT_SYMTAB + Size: [[SIZE]] diff --git a/llvm/tools/llvm-nm/llvm-nm.cpp b/llvm/tools/llvm-nm/llvm-nm.cpp --- a/llvm/tools/llvm-nm/llvm-nm.cpp +++ b/llvm/tools/llvm-nm/llvm-nm.cpp @@ -806,9 +806,10 @@ } if (S.Sym.getRawDataRefImpl().p) { Expected SymFlagsOrErr = S.Sym.getFlags(); - if (!SymFlagsOrErr) - // TODO: This error should be reported and tested properly. - report_fatal_error(SymFlagsOrErr.takeError()); + if (!SymFlagsOrErr) { + error(SymFlagsOrErr.takeError(), Obj.getFileName()); + return; + } SymFlags = *SymFlagsOrErr; } else SymFlags = S.SymFlags; @@ -1229,9 +1230,10 @@ if (!(MachO && DyldInfoOnly)) { for (BasicSymbolRef Sym : Symbols) { Expected SymFlagsOrErr = Sym.getFlags(); - if (!SymFlagsOrErr) - // TODO: This error should be reported and tested properly. - report_fatal_error(SymFlagsOrErr.takeError()); + if (!SymFlagsOrErr) { + error(SymFlagsOrErr.takeError(), Obj.getFileName()); + return; + } if (!DebugSyms && (*SymFlagsOrErr & SymbolRef::SF_FormatSpecific)) continue; if (WithoutAliases && (*SymFlagsOrErr & SymbolRef::SF_Indirect)) diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -1930,11 +1930,8 @@ return; SymbolRef::Type Type = unwrapOrError(Symbol.getType(), FileName, ArchiveName, ArchitectureName); - Expected FlagsOrErr = Symbol.getFlags(); - if (!FlagsOrErr) - // TODO: This error should be reported and tested properly. - report_fatal_error(FlagsOrErr.takeError()); - uint32_t Flags = *FlagsOrErr; + uint32_t Flags = + unwrapOrError(Symbol.getFlags(), FileName, ArchiveName, ArchitectureName); // Don't ask a Mach-O STAB symbol for its section unless you know that // STAB symbol's section field refers to a valid section index. Otherwise diff --git a/llvm/tools/llvm-size/llvm-size.cpp b/llvm/tools/llvm-size/llvm-size.cpp --- a/llvm/tools/llvm-size/llvm-size.cpp +++ b/llvm/tools/llvm-size/llvm-size.cpp @@ -196,13 +196,12 @@ } /// Total size of all ELF common symbols -static uint64_t getCommonSize(ObjectFile *Obj) { +static Expected getCommonSize(ObjectFile *Obj) { uint64_t TotalCommons = 0; for (auto &Sym : Obj->symbols()) { auto SymFlagsOrErr = Obj->getSymbolFlags(Sym.getRawDataRefImpl()); if (!SymFlagsOrErr) - // TODO: This error should be reported and tested properly. - report_fatal_error(SymFlagsOrErr.takeError()); + return SymFlagsOrErr.takeError(); if (*SymFlagsOrErr & SymbolRef::SF_Common) TotalCommons += Obj->getCommonSymbolSize(Sym.getRawDataRefImpl()); } @@ -440,10 +439,14 @@ } if (ELFCommons) { - uint64_t CommonSize = getCommonSize(Obj); - total += CommonSize; + Expected CommonSizeOrErr = getCommonSize(Obj); + if (!CommonSizeOrErr) { + error(CommonSizeOrErr.takeError(), Obj->getFileName()); + return; + } + total += *CommonSizeOrErr; outs() << format(fmt.str().c_str(), std::string("*COM*").c_str(), - CommonSize, static_cast(0)); + *CommonSizeOrErr, static_cast(0)); } // Print total. @@ -474,8 +477,14 @@ total_bss += size; } - if (ELFCommons) - total_bss += getCommonSize(Obj); + if (ELFCommons) { + Expected CommonSizeOrErr = getCommonSize(Obj); + if (!CommonSizeOrErr) { + error(CommonSizeOrErr.takeError(), Obj->getFileName()); + return; + } + total_bss += *CommonSizeOrErr; + } total = total_text + total_data + total_bss;