[lld] r265354 - ELF: Create dynamic symbols for symbol aliases of copy relocations.

Peter Collingbourne via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 4 15:29:25 PDT 2016


Author: pcc
Date: Mon Apr  4 17:29:24 2016
New Revision: 265354

URL: http://llvm.org/viewvc/llvm-project?rev=265354&view=rev
Log:
ELF: Create dynamic symbols for symbol aliases of copy relocations.

For each copy relocation that we create, look through the DSO's symbol table
for aliases and create a dynamic symbol for each one. This causes the copy
relocation to correctly interpose any aliases.

Copy relocations are relatively uncommon (on my machine, 56% of binaries in
/usr/bin have no copy relocations probably due to being PIEs, 97% of them
have <10, and the binary with the largest number of them has 97) so it's
probably fine to do this in a relatively inefficient way.

Differential Revision: http://reviews.llvm.org/D18731

Added:
    lld/trunk/test/ELF/Inputs/relocation-copy-alias.s
    lld/trunk/test/ELF/relocation-copy-alias.s
Modified:
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=265354&r1=265353&r2=265354&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Mon Apr  4 17:29:24 2016
@@ -839,7 +839,7 @@ static int getPriority(StringRef S) {
 // This function is called after we sort input sections
 // and scan relocations to setup sections' offsets.
 template <class ELFT> void OutputSection<ELFT>::assignOffsets() {
-  uintX_t Off = 0;
+  uintX_t Off = this->Header.sh_size;
   for (InputSection<ELFT> *S : Sections) {
     Off = alignTo(Off, S->Align);
     S->OutSecOff = Off;

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=265354&r1=265353&r2=265354&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Mon Apr  4 17:29:24 2016
@@ -96,7 +96,7 @@ private:
 
   void ensureBss();
   void addCommonSymbols(std::vector<DefinedCommon *> &Syms);
-  void addCopyRelSymbols(std::vector<SharedSymbol<ELFT> *> &Syms);
+  void addCopyRelSymbol(SharedSymbol<ELFT> *Sym);
 
   std::unique_ptr<llvm::FileOutputBuffer> Buffer;
 
@@ -385,9 +385,7 @@ void Writer<ELFT>::scanRelocs(InputSecti
       if (B->needsCopy())
         continue;
       if (Target->needsCopyRel<ELFT>(Type, *B)) {
-        B->NeedsCopyOrPltAddr = true;
-        Out<ELFT>::RelaDyn->addReloc(
-            {Target->CopyRel, DynamicReloc<ELFT>::Off_Bss, B});
+        addCopyRelSymbol(B);
         continue;
       }
     }
@@ -741,23 +739,30 @@ template <class ELFT> static uint32_t ge
   return 1 << TrailingZeros;
 }
 
-// Reserve space in .bss for copy relocations.
+// Reserve space in .bss for copy relocation.
 template <class ELFT>
-void Writer<ELFT>::addCopyRelSymbols(std::vector<SharedSymbol<ELFT> *> &Syms) {
-  if (Syms.empty())
-    return;
+void Writer<ELFT>::addCopyRelSymbol(SharedSymbol<ELFT> *SS) {
   ensureBss();
   uintX_t Off = Out<ELFT>::Bss->getSize();
-  uintX_t MaxAlign = Out<ELFT>::Bss->getAlign();
-  for (SharedSymbol<ELFT> *SS : Syms) {
-    uintX_t Align = getAlignment(SS);
-    Off = alignTo(Off, Align);
-    SS->OffsetInBss = Off;
-    Off += SS->template getSize<ELFT>();
-    MaxAlign = std::max(MaxAlign, Align);
+  uintX_t Align = getAlignment(SS);
+  Off = alignTo(Off, Align);
+  Out<ELFT>::Bss->setSize(Off + SS->template getSize<ELFT>());
+  Out<ELFT>::Bss->updateAlign(Align);
+  Out<ELFT>::RelaDyn->addReloc(
+      {Target->CopyRel, DynamicReloc<ELFT>::Off_Bss, SS});
+  uintX_t Shndx = SS->Sym.st_shndx;
+  uintX_t Value = SS->Sym.st_value;
+  // Look through the DSO's dynamic symbol for aliases and create a dynamic
+  // symbol for each one. This causes the copy relocation to correctly interpose
+  // any aliases.
+  for (SharedSymbol<ELFT> &S : SS->File->getSharedSymbols()) {
+    if (S.Sym.st_shndx != Shndx || S.Sym.st_value != Value)
+      continue;
+    S.OffsetInBss = Off;
+    S.NeedsCopyOrPltAddr = true;
+    S.setUsedInRegularObj();
+    S.MustBeInDynSym = true;
   }
-  Out<ELFT>::Bss->setSize(Off);
-  Out<ELFT>::Bss->updateAlign(MaxAlign);
 }
 
 template <class ELFT>
@@ -1080,7 +1085,6 @@ template <class ELFT> void Writer<ELFT>:
   // Now that we have defined all possible symbols including linker-
   // synthesized ones. Visit all symbols to give the finishing touches.
   std::vector<DefinedCommon *> CommonSymbols;
-  std::vector<SharedSymbol<ELFT> *> CopyRelSymbols;
   for (auto &P : Symtab.getSymbols()) {
     SymbolBody *Body = P.second->Body;
     if (auto *U = dyn_cast<Undefined>(Body))
@@ -1089,9 +1093,6 @@ template <class ELFT> void Writer<ELFT>:
 
     if (auto *C = dyn_cast<DefinedCommon>(Body))
       CommonSymbols.push_back(C);
-    if (auto *SC = dyn_cast<SharedSymbol<ELFT>>(Body))
-      if (SC->needsCopy())
-        CopyRelSymbols.push_back(SC);
 
     if (!includeInSymtab<ELFT>(*Body))
       continue;
@@ -1107,7 +1108,6 @@ template <class ELFT> void Writer<ELFT>:
     return;
 
   addCommonSymbols(CommonSymbols);
-  addCopyRelSymbols(CopyRelSymbols);
 
   // So far we have added sections from input object files.
   // This function adds linker-created Out<ELFT>::* sections.

Added: lld/trunk/test/ELF/Inputs/relocation-copy-alias.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/relocation-copy-alias.s?rev=265354&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/relocation-copy-alias.s (added)
+++ lld/trunk/test/ELF/Inputs/relocation-copy-alias.s Mon Apr  4 17:29:24 2016
@@ -0,0 +1,25 @@
+.data
+
+.globl a1
+.type a1, @object
+.size a1, 1
+a1:
+.weak a2
+.type a2, @object
+.size a2, 1
+a2:
+.byte 1
+
+.weak b1
+.type b1, @object
+.size b1, 1
+b1:
+.weak b2
+.type b2, @object
+.size b2, 1
+b2:
+.globl b3
+.type b3, @object
+.size b3, 1
+b3:
+.byte 1

Added: lld/trunk/test/ELF/relocation-copy-alias.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/relocation-copy-alias.s?rev=265354&view=auto
==============================================================================
--- lld/trunk/test/ELF/relocation-copy-alias.s (added)
+++ lld/trunk/test/ELF/relocation-copy-alias.s Mon Apr  4 17:29:24 2016
@@ -0,0 +1,67 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/relocation-copy-alias.s -o %t2.o
+// RUN: ld.lld -shared %t2.o -o %t.so
+// RUN: ld.lld %t.o %t.so -o %t3
+// RUN: llvm-readobj --dyn-symbols -r --expand-relocs %t3 | FileCheck %s
+
+.global _start
+_start:
+movl $5, a1
+movl $5, b1
+movl $5, b2
+
+// CHECK:      .rela.dyn {
+// CHECK-NEXT:   Relocation {
+// CHECK-NEXT:     Offset:
+// CHECK-NEXT:     Type: R_X86_64_COPY
+// CHECK-NEXT:     Symbol: a1
+// CHECK-NEXT:     Addend: 0x0
+// CHECK-NEXT:   }
+// CHECK-NEXT:   Relocation {
+// CHECK-NEXT:     Offset:
+// CHECK-NEXT:     Type: R_X86_64_COPY
+// CHECK-NEXT:     Symbol: b1
+// CHECK-NEXT:     Addend: 0x0
+// CHECK-NEXT:   }
+// CHECK-NEXT: }
+
+// CHECK:      Name: a1
+// CHECK-NEXT: Value: [[A:.*]]
+// CHECK-NEXT: Size: 1
+// CHECK-NEXT: Binding: Global (0x1)
+// CHECK-NEXT: Type: Object (0x1)
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .bss (0x7)
+
+// CHECK:      Name: b1
+// CHECK-NEXT: Value: [[B:.*]]
+// CHECK-NEXT: Size: 1
+// CHECK-NEXT: Binding: Weak (0x2)
+// CHECK-NEXT: Type: Object (0x1)
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .bss
+
+// CHECK:      Name: b2
+// CHECK-NEXT: Value: [[B]]
+// CHECK-NEXT: Size: 1
+// CHECK-NEXT: Binding: Weak (0x2)
+// CHECK-NEXT: Type: Object (0x1)
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .bss
+
+// CHECK:      Name: a2
+// CHECK-NEXT: Value: [[A]]
+// CHECK-NEXT: Size: 1
+// CHECK-NEXT: Binding: Weak (0x2)
+// CHECK-NEXT: Type: Object (0x1)
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .bss
+
+// CHECK:      Name: b3
+// CHECK-NEXT: Value: [[B]]
+// CHECK-NEXT: Size: 1
+// CHECK-NEXT: Binding: Global (0x1)
+// CHECK-NEXT: Type: Object (0x1)
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .bss




More information about the llvm-commits mailing list