Index: ELF/InputFiles.cpp =================================================================== --- ELF/InputFiles.cpp +++ ELF/InputFiles.cpp @@ -82,7 +82,7 @@ Elf_Sym_Range Syms = ELFObj.symbols(Symtab); uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); uint32_t FirstNonLocal = Symtab->sh_info; - if (FirstNonLocal > NumSymbols) + if (FirstNonLocal == 0 || (FirstNonLocal > NumSymbols)) fatal(getFilename(this) + ": invalid sh_info in symbol table"); if (OnlyGlobals) Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -382,6 +382,9 @@ for (elf::ObjectFile *F : Symtab::X->getObjectFiles()) { StringRef StrTab = F->getStringTable(); for (SymbolBody *B : F->getLocalSymbols()) { + if (!B->IsLocal) + fatal(getFilename(F) + ": invalid sh_info in symbol table"); + auto *DR = dyn_cast>(B); // No reason to keep local undefined symbol in symtab. if (!DR) Index: test/ELF/invalid/invalid-elf.test =================================================================== --- test/ELF/invalid/invalid-elf.test +++ test/ELF/invalid/invalid-elf.test @@ -8,10 +8,6 @@ # RUN: FileCheck --check-prefix=INVALID-FILE-CLASS %s # INVALID-FILE-CLASS: invalid file class: test.o -# RUN: not ld.lld %p/Inputs/symtab-sh_info.elf -o %t2 2>&1 | \ -# RUN: FileCheck --check-prefix=INVALID-SYMTAB-SHINFO %s -# INVALID-SYMTAB-SHINFO: invalid sh_info in symbol table - # RUN: not ld.lld %p/Inputs/binding.elf -o %t2 2>&1 | \ # RUN: FileCheck --check-prefix=INVALID-BINDING %s # INVALID-BINDING: unexpected binding Index: test/ELF/invalid/invalid-symtab-sh-info.s =================================================================== --- test/ELF/invalid/invalid-symtab-sh-info.s +++ test/ELF/invalid/invalid-symtab-sh-info.s @@ -0,0 +1,13 @@ +## sh_info contains value greater than total amount of symbols. +# RUN: not ld.lld %p/Inputs/symtab-sh_info.elf -o %t2 2>&1 | \ +# RUN: FileCheck --check-prefix=INVALID-SYMTAB-SHINFO %s +# INVALID-SYMTAB-SHINFO: invalid sh_info in symbol table + +## sh_info contains invalid value saying non-local symbol is local. +# RUN: not ld.lld %p/Inputs/symtab-sh_info2.elf -o %t2 2>&1 | \ +# RUN: FileCheck --check-prefix=INVALID-SYMTAB-SHINFO %s + +## sh_info contains zero value. First entry in a symbol table is always completely zeroed, +## so sh_info should be at least 1 in a valid ELF. +# RUN: not ld.lld %p/Inputs/symtab-sh_info3.elf -o %t2 2>&1 | \ +# RUN: FileCheck --check-prefix=INVALID-SYMTAB-SHINFO %s