[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