Skip to content

[llvm][lld] Support R_AARCH64_GOTPCREL32 #72584

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lld/ELF/Arch/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ RelExpr AArch64::getRelExpr(RelType type, const Symbol &s,
case R_AARCH64_ADR_GOT_PAGE:
case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
return R_AARCH64_GOT_PAGE_PC;
case R_AARCH64_GOTPCREL32:
return R_GOT_PC;
case R_AARCH64_NONE:
return R_NONE;
default:
Expand Down Expand Up @@ -374,6 +376,7 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
write32(loc, val);
break;
case R_AARCH64_PLT32:
case R_AARCH64_GOTPCREL32:
checkInt(loc, val, 32, rel);
write32(loc, val);
break;
Expand Down
27 changes: 27 additions & 0 deletions lld/test/ELF/aarch64-reloc-gotpcrel32.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// REQUIRES: aarch64
// RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
// RUN: ld.lld %t.o -o %t.so -shared --noinhibit-exec 2>&1 | FileCheck %s --check-prefix=WARN
// RUN: llvm-readelf -S %t.so | FileCheck --check-prefix=SEC %s
// RUN: llvm-objdump --no-print-imm-hex -s -d %t.so | FileCheck %s

// SEC: .got PROGBITS 0000000000020390

.section .data
.globl bar
bar:

.globl _start
_start: // PC = 0x303a0
// bar@GOTPCREL = 0x20390 (got entry for `bar`) - 0x303a0 (.) = 0xf0fffeff
// bar@GOTPCREL+4 = 0x20390 (got entry for `bar`) - 0x303a4 (.) + 4 = 0xf0fffeff
// bar@GOTPCREL-4 = 0x20390 (got entry for `bar`) - 0x303a8 (.) - 4 = 0xe4fffeff
// CHECK: Contents of section .data:
// CHECK-NEXT: {{.*}} f0fffeff f0fffeff e4fffeff
.word bar@GOTPCREL
.word bar@GOTPCREL+4
.word bar@GOTPCREL-4

// WARN: relocation R_AARCH64_GOTPCREL32 out of range: {{.*}} is not in [-2147483648, 2147483647]; references 'baz'
// WARN: relocation R_AARCH64_GOTPCREL32 out of range: {{.*}} is not in [-2147483648, 2147483647]; references 'baz'
.word baz@GOTPCREL+0xffffffff
.word baz@GOTPCREL-0xffffffff
1 change: 1 addition & 0 deletions llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ ELF_RELOC(R_AARCH64_ADR_GOT_PAGE, 0x137)
ELF_RELOC(R_AARCH64_LD64_GOT_LO12_NC, 0x138)
ELF_RELOC(R_AARCH64_LD64_GOTPAGE_LO15, 0x139)
ELF_RELOC(R_AARCH64_PLT32, 0x13a)
ELF_RELOC(R_AARCH64_GOTPCREL32, 0x13b)
ELF_RELOC(R_AARCH64_TLSGD_ADR_PREL21, 0x200)
ELF_RELOC(R_AARCH64_TLSGD_ADR_PAGE21, 0x201)
ELF_RELOC(R_AARCH64_TLSGD_ADD_LO12_NC, 0x202)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,

assert((!Target.getSymA() ||
Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None ||
Target.getSymA()->getKind() == MCSymbolRefExpr::VK_PLT) &&
Target.getSymA()->getKind() == MCSymbolRefExpr::VK_PLT ||
Target.getSymA()->getKind() == MCSymbolRefExpr::VK_GOTPCREL) &&
"Should only be expression-level modifiers here");

assert((!Target.getSymB() ||
Expand Down Expand Up @@ -206,7 +207,10 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
case FK_Data_2:
return R_CLS(ABS16);
case FK_Data_4:
return R_CLS(ABS32);
return (!IsILP32 &&
Target.getAccessVariant() == MCSymbolRefExpr::VK_GOTPCREL)
? ELF::R_AARCH64_GOTPCREL32
: R_CLS(ABS32);
case FK_Data_8:
if (IsILP32) {
Ctx.reportError(Fixup.getLoc(),
Expand Down
14 changes: 14 additions & 0 deletions llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// RUN: llvm-mc -triple=aarch64 -filetype=obj %s -o - | \
// RUN: llvm-readobj -r - | FileCheck %s

.section .data
this:
.word this@GOTPCREL
.word extern_sym@GOTPCREL+4
.word negative_offset@GOTPCREL-4

// CHECK: Section ({{.*}}) .rela.data
// CHECK-NEXT: 0x0 R_AARCH64_GOTPCREL32 this 0x0
// CHECK-NEXT: 0x4 R_AARCH64_GOTPCREL32 extern_sym 0x4
// CHECK-NEXT: 0x8 R_AARCH64_GOTPCREL32 negative_offset 0xFFFFFFFFFFFFFFFC
// CHECK-NEXT: }