[lld] 509153f - [ELF] ObjFile<ELFT>::initializeSymbols: Batch allocate local symbols

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 15 12:54:44 PST 2021


Author: Fangrui Song
Date: 2021-12-15T12:54:39-08:00
New Revision: 509153f1e7d1a50e24a057627643ad7dcd3384c5

URL: https://github.com/llvm/llvm-project/commit/509153f1e7d1a50e24a057627643ad7dcd3384c5
DIFF: https://github.com/llvm/llvm-project/commit/509153f1e7d1a50e24a057627643ad7dcd3384c5.diff

LOG: [ELF] ObjFile<ELFT>::initializeSymbols: Batch allocate local symbols

and detangle local/global symbol initialization.

My x86-64 lld executable is 8k smaller due to the removal of SpecificAlloc<Undefined>.

Added: 
    

Modified: 
    lld/ELF/InputFiles.cpp
    lld/test/ELF/invalid/symtab-sh-info-dup.test

Removed: 
    


################################################################################
diff  --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index ddfa1c9bccd4..81cac483fc92 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -1047,33 +1047,18 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(uint32_t idx,
 template <class ELFT> void ObjFile<ELFT>::initializeSymbols() {
   ArrayRef<Elf_Sym> eSyms = this->getELFSyms<ELFT>();
   this->symbols.resize(eSyms.size());
+  SymbolUnion *locals =
+      getSpecificAllocSingleton<SymbolUnion>().Allocate(firstGlobal);
 
-  // Fill in InputFile::symbols. Some entries have been initialized
-  // because of LazyObjFile.
-  for (size_t i = 0, end = eSyms.size(); i != end; ++i) {
-    if (this->symbols[i])
-      continue;
+  for (size_t i = 0; i != firstGlobal; ++i) {
     const Elf_Sym &eSym = eSyms[i];
     uint32_t secIdx = getSectionIndex(eSym);
     if (secIdx >= this->sections.size())
       fatal(toString(this) + ": invalid section index: " + Twine(secIdx));
-    if (eSym.getBinding() != STB_LOCAL) {
-      if (i < firstGlobal)
-        error(toString(this) + ": non-local symbol (" + Twine(i) +
-              ") found at index < .symtab's sh_info (" + Twine(firstGlobal) +
-              ")");
-      this->symbols[i] =
-          symtab->insert(CHECK(eSyms[i].getName(this->stringTable), this));
-      continue;
-    }
-
-    // Handle local symbols. Local symbols are not added to the symbol
-    // table because they are not visible from other object files. We
-    // allocate symbol instances and add their pointers to symbols.
-    if (i >= firstGlobal)
-      errorOrWarn(toString(this) + ": STB_LOCAL symbol (" + Twine(i) +
-                  ") found at index >= .symtab's sh_info (" +
-                  Twine(firstGlobal) + ")");
+    if (eSym.getBinding() != STB_LOCAL)
+      error(toString(this) + ": non-local symbol (" + Twine(i) +
+            ") found at index < .symtab's sh_info (" + Twine(firstGlobal) +
+            ")");
 
     InputSectionBase *sec = this->sections[secIdx];
     uint8_t type = eSym.getType();
@@ -1083,27 +1068,36 @@ template <class ELFT> void ObjFile<ELFT>::initializeSymbols() {
       fatal(toString(this) + ": invalid symbol name offset");
     StringRefZ name = this->stringTable.data() + eSym.st_name;
 
-    if (eSym.st_shndx == SHN_UNDEF)
-      this->symbols[i] =
-          make<Undefined>(this, name, STB_LOCAL, eSym.st_other, type);
-    else if (sec == &InputSection::discarded)
-      this->symbols[i] =
-          make<Undefined>(this, name, STB_LOCAL, eSym.st_other, type,
-                          /*discardedSecIdx=*/secIdx);
+    this->symbols[i] = reinterpret_cast<Symbol *>(locals + i);
+    if (eSym.st_shndx == SHN_UNDEF || sec == &InputSection::discarded)
+      new (this->symbols[i])
+          Undefined(this, name, STB_LOCAL, eSym.st_other, type,
+                    /*discardedSecIdx=*/secIdx);
     else
-      this->symbols[i] = make<Defined>(this, name, STB_LOCAL, eSym.st_other,
-                                       type, eSym.st_value, eSym.st_size, sec);
+      new (this->symbols[i]) Defined(this, name, STB_LOCAL, eSym.st_other, type,
+                                     eSym.st_value, eSym.st_size, sec);
   }
 
-  // Symbol resolution of non-local symbols.
+  // Some entries have been filled by LazyObjFile.
+  for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i)
+    if (!this->symbols[i])
+      this->symbols[i] =
+          symtab->insert(CHECK(eSyms[i].getName(this->stringTable), this));
+
+  // Perform symbol resolution on non-local symbols.
   SmallVector<unsigned, 32> undefineds;
   for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i) {
     const Elf_Sym &eSym = eSyms[i];
     uint8_t binding = eSym.getBinding();
-    if (binding == STB_LOCAL)
-      continue; // Errored above.
-
+    if (binding == STB_LOCAL) {
+      errorOrWarn(toString(this) + ": STB_LOCAL symbol (" + Twine(i) +
+                  ") found at index >= .symtab's sh_info (" +
+                  Twine(firstGlobal) + ")");
+      continue;
+    }
     uint32_t secIdx = getSectionIndex(eSym);
+    if (secIdx >= this->sections.size())
+      fatal(toString(this) + ": invalid section index: " + Twine(secIdx));
     InputSectionBase *sec = this->sections[secIdx];
     uint8_t stOther = eSym.st_other;
     uint8_t type = eSym.getType();
@@ -1111,13 +1105,11 @@ template <class ELFT> void ObjFile<ELFT>::initializeSymbols() {
     uint64_t size = eSym.st_size;
     StringRefZ name = this->stringTable.data() + eSym.st_name;
 
-    // Handle global undefined symbols.
     if (eSym.st_shndx == SHN_UNDEF) {
       undefineds.push_back(i);
       continue;
     }
 
-    // Handle global common symbols.
     if (eSym.st_shndx == SHN_COMMON) {
       if (value == 0 || value >= UINT32_MAX)
         fatal(toString(this) + ": common symbol '" + StringRef(name.data) +

diff  --git a/lld/test/ELF/invalid/symtab-sh-info-dup.test b/lld/test/ELF/invalid/symtab-sh-info-dup.test
index 130366beda20..36c7af0d66c6 100644
--- a/lld/test/ELF/invalid/symtab-sh-info-dup.test
+++ b/lld/test/ELF/invalid/symtab-sh-info-dup.test
@@ -9,10 +9,11 @@
 # 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-NEXT: error: duplicate symbol: _start
 # CHECK-NEXT: >>> defined at {{.*}}.o:(.text+0x0)
 # CHECK-NEXT: >>> defined at {{.*}}.o:(.text+0x0)
+# CHECK-EMPTY:
+# CHECK-NEXT: error: {{.*}}.o: STB_LOCAL symbol (2) found at index >= .symtab's sh_info (1)
 
 # 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)


        


More information about the llvm-commits mailing list