[lld] r329787 - [ELF] - Reorder local symbols.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 11 02:24:28 PDT 2018


Author: grimar
Date: Wed Apr 11 02:24:27 2018
New Revision: 329787

URL: http://llvm.org/viewvc/llvm-project?rev=329787&view=rev
Log:
[ELF] - Reorder local symbols.

This fixes PR36716 (https://bugs.llvm.org/show_bug.cgi?id=36716),

Patch sorts local symbols to match the
following order: file1, local1, hidden1, file2, local2, hidden2 ...

Differential revision: https://reviews.llvm.org/D45325

Modified:
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/ELF/local-symbols-order.s
    lld/trunk/test/ELF/relocatable-comdat-multiple.s

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=329787&r1=329786&r2=329787&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Wed Apr 11 02:24:27 2018
@@ -1545,16 +1545,35 @@ void SymbolTableBaseSection::finalizeCon
 // The ELF spec requires that all local symbols precede global symbols, so we
 // sort symbol entries in this function. (For .dynsym, we don't do that because
 // symbols for dynamic linking are inherently all globals.)
+//
+// Aside from above, we put local symbols in groups starting with the STT_FILE
+// symbol. That is convenient for purpose of identifying where are local symbols
+// coming from.
 void SymbolTableBaseSection::postThunkContents() {
   if (this->Type == SHT_DYNSYM)
     return;
-  // move all local symbols before global symbols.
-  auto It = std::stable_partition(
+
+  // Move all local symbols before global symbols.
+  auto E = std::stable_partition(
       Symbols.begin(), Symbols.end(), [](const SymbolTableEntry &S) {
         return S.Sym->isLocal() || S.Sym->computeBinding() == STB_LOCAL;
       });
-  size_t NumLocals = It - Symbols.begin();
+  size_t NumLocals = E - Symbols.begin();
   getParent()->Info = NumLocals + 1;
+
+  // Assign the growing unique ID for each local symbol's file.
+  DenseMap<InputFile *, unsigned> FileIDs;
+  for (auto I = Symbols.begin(); I != E; ++I)
+    FileIDs.insert({I->Sym->File, FileIDs.size()});
+
+  // Sort the local symbols to group them by file. We do not need to care about
+  // the STT_FILE symbols, they are already naturally placed first in each group.
+  // That happens because STT_FILE is always the first symbol in the object and
+  // hence precede all other local symbols we add for a file.
+  std::stable_sort(Symbols.begin(), E,
+                   [&](const SymbolTableEntry &L, const SymbolTableEntry &R) {
+                     return FileIDs[L.Sym->File] < FileIDs[R.Sym->File];
+                   });
 }
 
 void SymbolTableBaseSection::addSymbol(Symbol *B) {

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=329787&r1=329786&r2=329787&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Apr 11 02:24:27 2018
@@ -1673,15 +1673,15 @@ template <class ELFT> void Writer<ELFT>:
     } while (Changed);
   }
 
+  // createThunks may have added local symbols to the static symbol table
+  applySynthetic({InX::SymTab},
+                 [](SyntheticSection *SS) { SS->postThunkContents(); });
+
   // Fill other section headers. The dynamic table is finalized
   // at the end because some tags like RELSZ depend on result
   // of finalizing other sections.
   for (OutputSection *Sec : OutputSections)
     Sec->finalize<ELFT>();
-
-  // createThunks may have added local symbols to the static symbol table
-  applySynthetic({InX::SymTab},
-                 [](SyntheticSection *SS) { SS->postThunkContents(); });
 }
 
 // The linker is expected to define SECNAME_start and SECNAME_end

Modified: lld/trunk/test/ELF/local-symbols-order.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/local-symbols-order.s?rev=329787&r1=329786&r2=329787&view=diff
==============================================================================
--- lld/trunk/test/ELF/local-symbols-order.s (original)
+++ lld/trunk/test/ELF/local-symbols-order.s Wed Apr 11 02:24:27 2018
@@ -1,22 +1,32 @@
 # REQUIRES: x86
 
-# RUN: echo '.file "file2"; foo2:; .global bar2; .hidden bar2; bar2:' > %t2.s
+# RUN: echo '.data; .file "file2"; foo2:; .global bar2; .hidden bar2; bar2:' > %t2.s
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t2.s -o %t2.o
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
 
-# RUN: ld.lld -o %t %t1.o %t2.o
-# RUN: llvm-readobj -symbols -elf-output-style=GNU %t | FileCheck %s
+# RUN: ld.lld -o %t %t1.o %t2.o --emit-relocs
+# RUN: llvm-readobj -symbols -sections -elf-output-style=GNU %t | FileCheck %s
 
-## Show the order of the local symbols produced currently by LLD.
+## Check we sort local symbols to match the following order: 
+## file1, local1, section1, hidden1, file2, local2, section2, hidden2 ...
+
+# CHECK: Section Headers:
+# CHECK:   [Nr] Name
+# CHECK:   [ [[ST:.*]]] .text
+# CHECK:   [ [[SD:.*]]] .data
+# CHECK:   [ [[SC:.*]]] .comment
 
 # CHECK:      Num:    Value          Size Type    Bind   Vis      Ndx Name
 # CHECK-NEXT:   0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
 # CHECK-NEXT:   1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS file1
 # CHECK-NEXT:   2: 0000000000201000     0 NOTYPE  LOCAL  DEFAULT    1 foo1
-# CHECK-NEXT:   3: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS file2
-# CHECK-NEXT:   4: 0000000000201000     0 NOTYPE  LOCAL  DEFAULT    1 foo2
-# CHECK-NEXT:   5: 0000000000201000     0 NOTYPE  LOCAL  HIDDEN     1 bar1
-# CHECK-NEXT:   6: 0000000000201000     0 NOTYPE  LOCAL  HIDDEN     1 bar2
+# CHECK-NEXT:   3: 0000000000201000     0 SECTION LOCAL  DEFAULT    [[ST]]
+# CHECK-NEXT:   4: 0000000000201000     0 NOTYPE  LOCAL  HIDDEN     1 bar1
+# CHECK-NEXT:   5: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS file2
+# CHECK-NEXT:   6: 0000000000201000     0 NOTYPE  LOCAL  DEFAULT    2 foo2
+# CHECK-NEXT:   7: 0000000000201000     0 SECTION LOCAL  DEFAULT    [[SD]]
+# CHECK-NEXT:   8: 0000000000201000     0 NOTYPE  LOCAL  HIDDEN     2 bar2
+# CHECK-NEXT:   9: 0000000000000000     0 SECTION LOCAL  DEFAULT    [[SC]]
 
 foo1:
 

Modified: lld/trunk/test/ELF/relocatable-comdat-multiple.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/relocatable-comdat-multiple.s?rev=329787&r1=329786&r2=329787&view=diff
==============================================================================
--- lld/trunk/test/ELF/relocatable-comdat-multiple.s (original)
+++ lld/trunk/test/ELF/relocatable-comdat-multiple.s Wed Apr 11 02:24:27 2018
@@ -21,7 +21,7 @@
 # CHECK-NEXT:     Name: .group
 # CHECK-NEXT:     Index: 5
 # CHECK-NEXT:     Link: 8
-# CHECK-NEXT:     Info: 2
+# CHECK-NEXT:     Info: 6
 # CHECK-NEXT:     Type: COMDAT
 # CHECK-NEXT:     Signature: bbb
 # CHECK-NEXT:     Section(s) in group [




More information about the llvm-commits mailing list