summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/Target.cpp9
-rw-r--r--lld/test/ELF/relocation-copy-i686.s63
2 files changed, 72 insertions, 0 deletions
diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp
index df2e7e6fcea..20ec1f9c644 100644
--- a/lld/ELF/Target.cpp
+++ b/lld/ELF/Target.cpp
@@ -51,6 +51,7 @@ public:
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::writeGotHeaderEntries(uint8_t *Buf) const {}
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 @@ void X86TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
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<SharedSymbol<ELF32LE>>(&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);
}
diff --git a/lld/test/ELF/relocation-copy-i686.s b/lld/test/ELF/relocation-copy-i686.s
new file mode 100644
index 00000000000..b537edf0e6f
--- /dev/null
+++ b/lld/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
OpenPOWER on IntegriCloud