Index: ELF/Target.cpp =================================================================== --- ELF/Target.cpp +++ ELF/Target.cpp @@ -148,6 +148,7 @@ void writePltEntry(uint8_t *Buf, uint64_t GotAddr, uint64_t GotEntryAddr, uint64_t PltEntryAddr, int32_t Index, unsigned RelOff) const override; + bool relocNeedsCopy(uint32_t Type, const SymbolBody &S) const override; bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override; bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override; void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, @@ -847,6 +848,7 @@ } AArch64TargetInfo::AArch64TargetInfo() { + CopyReloc = R_AARCH64_COPY; GotReloc = R_AARCH64_GLOB_DAT; PltReloc = R_AARCH64_JUMP_SLOT; LazyRelocations = true; @@ -904,6 +906,29 @@ GotEntryAddr); } +bool AArch64TargetInfo::relocNeedsCopy(uint32_t Type, + const SymbolBody &S) const { + switch (Type) { + default: + return false; + case R_AARCH64_ABS16: + case R_AARCH64_ABS32: + case R_AARCH64_ABS64: + case R_AARCH64_PREL16: + case R_AARCH64_PREL32: + case R_AARCH64_PREL64: + case R_AARCH64_ADR_PREL_LO21: + case R_AARCH64_ADR_PREL_PG_HI21: + case R_AARCH64_ADD_ABS_LO12_NC: + case R_AARCH64_LDST8_ABS_LO12_NC: + case R_AARCH64_LDST32_ABS_LO12_NC: + case R_AARCH64_LDST64_ABS_LO12_NC: + if (auto *SS = dyn_cast>(&S)) + return SS->Sym.getType() == STT_OBJECT; + return false; + } +} + bool AArch64TargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const { return Type == R_AARCH64_ADR_GOT_PAGE || Type == R_AARCH64_LD64_GOT_LO12_NC || Index: test/ELF/Inputs/relocation-copy.s =================================================================== --- test/ELF/Inputs/relocation-copy.s +++ test/ELF/Inputs/relocation-copy.s @@ -2,21 +2,21 @@ .type x,@object .globl x -.align 16 +.balign 16 x: .long 0 .size x, 4 .type y,@object .globl y -.align 16 +.balign 16 y: .long 0 .size y, 4 .type z,@object .globl z -.align 4 +.balign 4 z: .long 0 .size z, 4 Index: test/ELF/aarch64-copy.s =================================================================== --- /dev/null +++ test/ELF/aarch64-copy.s @@ -0,0 +1,93 @@ +// REQUIRES: aarch64 +// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %p/Inputs/relocation-copy.s -o %t2.o +// RUN: ld.lld -shared %t2.o -o %t2.so +// RUN: ld.lld %t.o %t2.so -o %t3 +// RUN: llvm-readobj -s -r --expand-relocs -symbols %t3 | FileCheck %s +// RUN: llvm-objdump -d %t3 | FileCheck -check-prefix=CODE %s +// RUN: llvm-objdump -s -section=.data %t3 | FileCheck -check-prefix=DATA %s + +.text +.globl _start +_start: + adr x1, x + adrp x2, y + add x2, x2, :lo12:y +.data + .word 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: 0x120B0 +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: 24 +// CHECK-NEXT: Link: +// CHECK-NEXT: Info: +// CHECK-NEXT: AddressAlignment: 16 + +// CHECK: Relocations [ +// CHECK-NEXT: Section ({{.*}}) .rela.dyn { +// CHECK-NEXT: Relocation { +// CHECK-NEXT: Offset: 0x120B0 +// CHECK-NEXT: Type: R_AARCH64_COPY +// CHECK-NEXT: Symbol: x +// CHECK-NEXT: Addend: 0x0 +// CHECK-NEXT: } +// CHECK-NEXT: Relocation { +// CHECK-NEXT: Offset: 0x120C0 +// CHECK-NEXT: Type: R_AARCH64_COPY +// CHECK-NEXT: Symbol: y +// CHECK-NEXT: Addend: 0x0 +// CHECK-NEXT: } +// CHECK-NEXT: Relocation { +// CHECK-NEXT: Offset: 0x120C4 +// CHECK-NEXT: Type: R_AARCH64_COPY +// CHECK-NEXT: Symbol: z +// CHECK-NEXT: Addend: 0x0 +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] + +// CHECK: Symbols [ +// CHECK: Name: x +// CHECK-NEXT: Value: 0x120B0 +// CHECK-NEXT: Size: 4 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: Object +// CHECK-NEXT: Other: +// CHECK-NEXT: Section: .bss +// CHECK: Name: y +// CHECK-NEXT: Value: 0x120C0 +// CHECK-NEXT: Size: 4 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: Object +// CHECK-NEXT: Other: +// CHECK-NEXT: Section: .bss +// CHECK: Name: z +// CHECK-NEXT: Value: 0x120C4 +// CHECK-NEXT: Size: 4 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: Object +// CHECK-NEXT: Other: +// CHECK-NEXT: Section: .bss +// CHECK: ] + +// CODE: Disassembly of section .text: +// CODE-NEXT: _start: +// S(x) = 0x120B0, A = 0, P = 0x11000 +// S + A - P = 0x10B0 = 4272 +// CODE-NEXT: 11000: {{.*}} adr x1, #4272 +// S(y) = 0x120C0, A = 0, P = 0x11004 +// Page(S + A) - Page(P) = 0x12000 - 0x11000 = 0x1000 - 4096 +// CODE-NEXT: 11004: {{.*}} adrp x2, #4096 +// S(y) = 0x120C0, A = 0 +// (S + A) & 0xFFF = 0xC0 = 192 +// CODE-NEXT: 11008: {{.*}} add x2, x2, #192 + +// DATA: Contents of section .data: +// S(z) = 0x120c4 +// DATA-NEXT: 120a0 c4200100