Index: lld/trunk/ELF/Target.cpp =================================================================== --- lld/trunk/ELF/Target.cpp +++ lld/trunk/ELF/Target.cpp @@ -51,6 +51,7 @@ uint64_t PltEntryAddr) const override; void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, uint64_t PltEntryAddr, int32_t Index) const override; + bool relocNeedsCopy(uint32_t Type, const SymbolBody &S) const override; bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override; bool relocPointsToGot(uint32_t Type) const override; bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override; @@ -177,6 +178,7 @@ void TargetInfo::writeGotPltHeaderEntries(uint8_t *Buf) const {} X86TargetInfo::X86TargetInfo() { + CopyReloc = R_386_COPY; PCRelReloc = R_386_PC32; GotReloc = R_386_GLOB_DAT; GotRefReloc = R_386_GOT32; @@ -196,6 +198,13 @@ write32le(Buf + 2, GotEntryAddr); } +bool X86TargetInfo::relocNeedsCopy(uint32_t Type, const SymbolBody &S) const { + if (Type == R_386_32 || Type == R_386_16 || Type == R_386_8) + if (auto *SS = dyn_cast>(&S)) + return SS->Sym.getType() == STT_OBJECT; + return false; +} + bool X86TargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const { return Type == R_386_GOT32 || relocNeedsPlt(Type, S); } Index: lld/trunk/test/ELF/relocation-copy-i686.s =================================================================== --- lld/trunk/test/ELF/relocation-copy-i686.s +++ lld/trunk/test/ELF/relocation-copy-i686.s @@ -0,0 +1,63 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %p/Inputs/relocation-copy.s -o %t2.o +// RUN: ld.lld -shared %t2.o -o %t.so +// RUN: ld.lld -e main %t.o %t.so -o %t3 +// RUN: llvm-readobj -s -r --expand-relocs %t3 | FileCheck %s +// RUN: llvm-objdump -d %t3 | FileCheck -check-prefix=CODE %s + +.text +.globl main +.align 16, 0x90 +.type main,@function +main: +movl $5, x +movl $7, y +movl $9, z + +// CHECK: Name: .bss +// CHECK-NEXT: Type: SHT_NOBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_WRITE +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x12050 +// CHECK-NEXT: Offset: 0x2050 +// CHECK-NEXT: Size: 24 +// CHECK-NEXT: Link: 0 +// CHECK-NEXT: Info: 0 +// CHECK-NEXT: AddressAlignment: 16 +// CHECK-NEXT: EntrySize: 0 + +// CHECK: Relocations [ +// CHECK-NEXT: Section ({{.*}}) .rel.dyn { +// CHECK-NEXT: Relocation { +// CHECK-NEXT: Offset: +// CHECK-NEXT: Type: R_386_COPY +// CHECK-NEXT: Symbol: x +// CHECK-NEXT: Addend: 0x0 +// CHECK-NEXT: } +// CHECK-NEXT: Relocation { +// CHECK-NEXT: Offset: +// CHECK-NEXT: Type: R_386_COPY +// CHECK-NEXT: Symbol: y +// CHECK-NEXT: Addend: 0x0 +// CHECK-NEXT: } +// CHECK-NEXT: Relocation { +// CHECK-NEXT: Offset: +// CHECK-NEXT: Type: R_386_COPY +// CHECK-NEXT: Symbol: z +// CHECK-NEXT: Addend: 0x0 +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] + +// 73808 = 0x12050 +// 16 is alignment here +// 73824 = 0x12050 + 16 +// 73828 = 0x12050 + 16 + 4 +// CODE: Disassembly of section .text: +// CODE-NEXT: main: +// CODE-NEXT: 11000: c7 05 50 20 01 00 05 00 00 00 movl $5, 73808 +// CODE-NEXT: 1100a: c7 05 60 20 01 00 07 00 00 00 movl $7, 73824 +// CODE-NEXT: 11014: c7 05 64 20 01 00 09 00 00 00 movl $9, 73828