Index: lld/trunk/ELF/OutputSections.cpp =================================================================== --- lld/trunk/ELF/OutputSections.cpp +++ lld/trunk/ELF/OutputSections.cpp @@ -839,7 +839,7 @@ // This function is called after we sort input sections // and scan relocations to setup sections' offsets. template void OutputSection::assignOffsets() { - uintX_t Off = 0; + uintX_t Off = this->Header.sh_size; for (InputSection *S : Sections) { Off = alignTo(Off, S->Align); S->OutSecOff = Off; Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -96,7 +96,7 @@ void ensureBss(); void addCommonSymbols(std::vector &Syms); - void addCopyRelSymbols(std::vector *> &Syms); + void addCopyRelSymbol(SharedSymbol *Sym); std::unique_ptr Buffer; @@ -385,9 +385,7 @@ if (B->needsCopy()) continue; if (Target->needsCopyRel(Type, *B)) { - B->NeedsCopyOrPltAddr = true; - Out::RelaDyn->addReloc( - {Target->CopyRel, DynamicReloc::Off_Bss, B}); + addCopyRelSymbol(B); continue; } } @@ -741,23 +739,30 @@ return 1 << TrailingZeros; } -// Reserve space in .bss for copy relocations. +// Reserve space in .bss for copy relocation. template -void Writer::addCopyRelSymbols(std::vector *> &Syms) { - if (Syms.empty()) - return; +void Writer::addCopyRelSymbol(SharedSymbol *SS) { ensureBss(); uintX_t Off = Out::Bss->getSize(); - uintX_t MaxAlign = Out::Bss->getAlign(); - for (SharedSymbol *SS : Syms) { - uintX_t Align = getAlignment(SS); - Off = alignTo(Off, Align); - SS->OffsetInBss = Off; - Off += SS->template getSize(); - MaxAlign = std::max(MaxAlign, Align); + uintX_t Align = getAlignment(SS); + Off = alignTo(Off, Align); + Out::Bss->setSize(Off + SS->template getSize()); + Out::Bss->updateAlign(Align); + Out::RelaDyn->addReloc( + {Target->CopyRel, DynamicReloc::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 &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::Bss->setSize(Off); - Out::Bss->updateAlign(MaxAlign); } template @@ -1080,7 +1085,6 @@ // Now that we have defined all possible symbols including linker- // synthesized ones. Visit all symbols to give the finishing touches. std::vector CommonSymbols; - std::vector *> CopyRelSymbols; for (auto &P : Symtab.getSymbols()) { SymbolBody *Body = P.second->Body; if (auto *U = dyn_cast(Body)) @@ -1089,9 +1093,6 @@ if (auto *C = dyn_cast(Body)) CommonSymbols.push_back(C); - if (auto *SC = dyn_cast>(Body)) - if (SC->needsCopy()) - CopyRelSymbols.push_back(SC); if (!includeInSymtab(*Body)) continue; @@ -1107,7 +1108,6 @@ return; addCommonSymbols(CommonSymbols); - addCopyRelSymbols(CopyRelSymbols); // So far we have added sections from input object files. // This function adds linker-created Out::* sections. Index: lld/trunk/test/ELF/Inputs/relocation-copy-alias.s =================================================================== --- lld/trunk/test/ELF/Inputs/relocation-copy-alias.s +++ lld/trunk/test/ELF/Inputs/relocation-copy-alias.s @@ -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 Index: lld/trunk/test/ELF/relocation-copy-alias.s =================================================================== --- lld/trunk/test/ELF/relocation-copy-alias.s +++ lld/trunk/test/ELF/relocation-copy-alias.s @@ -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