diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 362263e890062..1bce8de193bb7 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -1025,19 +1025,13 @@ void ObjFile::initializeSymbols(const object::ELFFile &obj) { SmallVector undefineds; for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i) { const Elf_Sym &eSym = eSyms[i]; - uint8_t binding = eSym.getBinding(); - if (LLVM_UNLIKELY(binding == STB_LOCAL)) { - errorOrWarn(toString(this) + ": STB_LOCAL symbol (" + Twine(i) + - ") found at index >= .symtab's sh_info (" + - Twine(firstGlobal) + ")"); - continue; - } uint32_t secIdx = eSym.st_shndx; if (secIdx == SHN_UNDEF) { undefineds.push_back(i); continue; } + uint8_t binding = eSym.getBinding(); uint8_t stOther = eSym.st_other; uint8_t type = eSym.getType(); uint64_t value = eSym.st_value; @@ -1056,14 +1050,8 @@ void ObjFile::initializeSymbols(const object::ELFFile &obj) { } // Handle global defined symbols. Defined::section will be set in postParse. - if (binding == STB_GLOBAL || binding == STB_WEAK || - binding == STB_GNU_UNIQUE) { - sym->resolve(Defined{this, StringRef(), binding, stOther, type, value, - size, nullptr}); - continue; - } - - fatal(toString(this) + ": unexpected binding: " + Twine((int)binding)); + sym->resolve(Defined{this, StringRef(), binding, stOther, type, value, size, + nullptr}); } // Undefined symbols (excluding those defined relative to non-prevailing @@ -1130,6 +1118,11 @@ template void ObjFile::postParse() { const Elf_Sym &eSym = eSyms[i]; Symbol &sym = *symbols[i]; uint32_t secIdx = eSym.st_shndx; + uint8_t binding = eSym.getBinding(); + if (LLVM_UNLIKELY(binding != STB_GLOBAL && binding != STB_WEAK && + binding != STB_GNU_UNIQUE)) + errorOrWarn(toString(this) + ": symbol (" + Twine(i) + + ") has invalid binding: " + Twine((int)binding)); // st_value of STT_TLS represents the assigned offset, not the actual // address which is used by STT_FUNC and STT_OBJECT. STT_TLS symbols can @@ -1171,7 +1164,7 @@ template void ObjFile::postParse() { continue; } - if (eSym.getBinding() == STB_WEAK) + if (binding == STB_WEAK) continue; std::lock_guard lock(mu); ctx->duplicates.push_back({&sym, this, sec, eSym.st_value}); diff --git a/lld/test/ELF/invalid/invalid-binding.test b/lld/test/ELF/invalid/invalid-binding.test index 4d8963367e756..75ec32f91e714 100644 --- a/lld/test/ELF/invalid/invalid-binding.test +++ b/lld/test/ELF/invalid/invalid-binding.test @@ -1,6 +1,6 @@ # RUN: yaml2obj %s -o %t.o # RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s -# CHECK: error: {{.*}}.o: unexpected binding: 9 +# CHECK: error: {{.*}}.o: symbol (1) has invalid binding: 9 --- !ELF FileHeader: diff --git a/lld/test/ELF/invalid/symtab-sh-info-dup.test b/lld/test/ELF/invalid/symtab-sh-info-dup.test index 8b0833d67bbb2..f48938d5b6ea8 100644 --- a/lld/test/ELF/invalid/symtab-sh-info-dup.test +++ b/lld/test/ELF/invalid/symtab-sh-info-dup.test @@ -8,15 +8,19 @@ # RUN: yaml2obj %s -o %t.o # RUN: not ld.lld %t.o %t.o -o /dev/null 2>&1 | FileCheck %s -# CHECK: error: {{.*}}.o: STB_LOCAL symbol (2) found at index >= .symtab's sh_info (1) -# CHECK-NEXT: error: {{.*}}.o: STB_LOCAL symbol (2) found at index >= .symtab's sh_info (1) +# CHECK: error: {{.*}}.o: symbol (2) has invalid binding: 0 +# CHECK-NEXT: error: {{.*}}.o: symbol (2) has invalid binding: 0 # CHECK-NEXT: error: duplicate symbol: _start # CHECK-NEXT: >>> defined at {{.*}}.o:(.text+0x0) # CHECK-NEXT: >>> defined at {{.*}}.o:(.text+0x0) # CHECK-EMPTY: +# CHECK-NEXT: error: duplicate symbol: local +# CHECK-NEXT: >>> defined at {{.*}}.o:(.text+0x0) +# CHECK-NEXT: >>> defined at {{.*}}.o:(.text+0x0) +# CHECK-EMPTY: # RUN: ld.lld --noinhibit-exec %t.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=WARN -# WARN: warning: {{.*}}.o: STB_LOCAL symbol (2) found at index >= .symtab's sh_info (1) +# WARN: warning: {{.*}}.o: symbol (2) has invalid binding: 0 !ELF FileHeader: