Skip to content

Commit 8f3005f

Browse files
committed
[PAC][lld][AArch64][ELF] Support signed GOT with tiny code model
Support `R_AARCH64_AUTH_GOT_ADR_PREL_LO21` and `R_AARCH64_AUTH_GOT_LD_PREL19` GOT-generating relocations.
1 parent d7336f6 commit 8f3005f

File tree

5 files changed

+87
-4
lines changed

5 files changed

+87
-4
lines changed

lld/ELF/Arch/AArch64.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,9 @@ RelExpr AArch64::getRelExpr(RelType type, const Symbol &s,
205205
case R_AARCH64_AUTH_LD64_GOT_LO12_NC:
206206
case R_AARCH64_AUTH_GOT_ADD_LO12_NC:
207207
return RE_AARCH64_AUTH_GOT;
208+
case R_AARCH64_AUTH_GOT_LD_PREL19:
209+
case R_AARCH64_AUTH_GOT_ADR_PREL_LO21:
210+
return RE_AARCH64_AUTH_GOT_PC;
208211
case R_AARCH64_LD64_GOTPAGE_LO15:
209212
return RE_AARCH64_GOT_PAGE;
210213
case R_AARCH64_ADR_GOT_PAGE:
@@ -548,6 +551,7 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
548551
write32AArch64Addr(loc, val >> 12);
549552
break;
550553
case R_AARCH64_ADR_PREL_LO21:
554+
case R_AARCH64_AUTH_GOT_ADR_PREL_LO21:
551555
checkInt(ctx, loc, val, 21, rel);
552556
write32AArch64Addr(loc, val);
553557
break;
@@ -568,6 +572,7 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
568572
case R_AARCH64_CONDBR19:
569573
case R_AARCH64_LD_PREL_LO19:
570574
case R_AARCH64_GOT_LD_PREL19:
575+
case R_AARCH64_AUTH_GOT_LD_PREL19:
571576
checkAlignment(ctx, loc, val, 4, rel);
572577
checkInt(ctx, loc, val, 21, rel);
573578
writeMaskedBits32le(loc, (val & 0x1FFFFC) << 3, 0x1FFFFC << 3);

lld/ELF/InputSection.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,7 @@ uint64_t InputSectionBase::getRelocTargetVA(Ctx &ctx, const Relocation &r,
817817
case RE_AARCH64_GOT_PAGE:
818818
return r.sym->getGotVA(ctx) + a - getAArch64Page(ctx.in.got->getVA());
819819
case R_GOT_PC:
820+
case R_AARCH64_AUTH_GOT_PC:
820821
case R_RELAX_TLS_GD_TO_IE:
821822
return r.sym->getGotVA(ctx) + a - p;
822823
case R_GOTPLT_GOTREL:

lld/ELF/Relocations.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,9 @@ static bool needsPlt(RelExpr expr) {
210210
}
211211

212212
bool lld::elf::needsGot(RelExpr expr) {
213-
return oneof<R_GOT, RE_AARCH64_AUTH_GOT, R_GOT_OFF, RE_MIPS_GOT_LOCAL_PAGE,
214-
RE_MIPS_GOT_OFF, RE_MIPS_GOT_OFF32, RE_AARCH64_GOT_PAGE_PC,
213+
return oneof<R_GOT, RE_AARCH64_AUTH_GOT, RE_AARCH64_AUTH_GOT_PC, R_GOT_OFF,
214+
RE_MIPS_GOT_LOCAL_PAGE, RE_MIPS_GOT_OFF, RE_MIPS_GOT_OFF32,
215+
RE_AARCH64_GOT_PAGE_PC, RE_AARCH64_AUTH_GOT_PAGE_PC,
215216
RE_AARCH64_AUTH_GOT_PAGE_PC, R_GOT_PC, R_GOTPLT,
216217
RE_AARCH64_GOT_PAGE, RE_LOONGARCH_GOT, RE_LOONGARCH_GOT_PAGE_PC>(
217218
expr);
@@ -995,7 +996,8 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,
995996
R_GOTPLTONLY_PC, R_PLT_PC, R_PLT_GOTREL, R_PLT_GOTPLT,
996997
R_GOTPLT_GOTREL, R_GOTPLT_PC, RE_PPC32_PLTREL, RE_PPC64_CALL_PLT,
997998
RE_PPC64_RELAX_TOC, RE_RISCV_ADD, RE_AARCH64_GOT_PAGE,
998-
RE_AARCH64_AUTH_GOT, RE_LOONGARCH_PLT_PAGE_PC, RE_LOONGARCH_GOT,
999+
RE_AARCH64_AUTH_GOT, RE_AARCH64_AUTH_GOT_PC,
1000+
RE_LOONGARCH_PLT_PAGE_PC, RE_LOONGARCH_GOT,
9991001
RE_LOONGARCH_GOT_PAGE_PC>(e))
10001002
return true;
10011003

@@ -1111,7 +1113,8 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
11111113
// Many LoongArch TLS relocs reuse the RE_LOONGARCH_GOT type, in which
11121114
// case the NEEDS_GOT flag shouldn't get set.
11131115
bool needsGotAuth =
1114-
(expr == RE_AARCH64_AUTH_GOT || expr == RE_AARCH64_AUTH_GOT_PAGE_PC);
1116+
(expr == RE_AARCH64_AUTH_GOT || expr == RE_AARCH64_AUTH_GOT_PC ||
1117+
expr == RE_AARCH64_AUTH_GOT_PAGE_PC);
11151118
uint16_t flags = sym.flags.load(std::memory_order_relaxed);
11161119
if (!(flags & NEEDS_GOT)) {
11171120
sym.setFlags(needsGotAuth ? (NEEDS_GOT | NEEDS_GOT_AUTH) : NEEDS_GOT);

lld/ELF/Relocations.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ enum RelExpr {
9494
RE_AARCH64_AUTH_GOT_PAGE_PC,
9595
RE_AARCH64_GOT_PAGE,
9696
RE_AARCH64_AUTH_GOT,
97+
RE_AARCH64_AUTH_GOT_PC,
9798
RE_AARCH64_PAGE_PC,
9899
RE_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC,
99100
RE_AARCH64_TLSDESC_PAGE,

lld/test/ELF/aarch64-got-relocations-pauth.s

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,79 @@ _start:
7777
adrp x1, :got_auth:zed
7878
add x1, x1, :got_auth_lo12:zed
7979

80+
#--- ok-tiny.s
81+
82+
# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux ok-tiny.s -o ok-tiny.o
83+
84+
# RUN: ld.lld ok-tiny.o a.so -pie -o external-tiny
85+
# RUN: llvm-readelf -r -S -x .got external-tiny | FileCheck %s --check-prefix=EXTERNAL-TINY
86+
87+
# RUN: ld.lld ok-tiny.o a.o -pie -o local-tiny
88+
# RUN: llvm-readelf -r -S -x .got -s local-tiny | FileCheck %s --check-prefix=LOCAL-TINY
89+
90+
# EXTERNAL-TINY: Offset Info Type Symbol's Value Symbol's Name + Addend
91+
# EXTERNAL-TINY-NEXT: 0000000000020380 000000010000e201 R_AARCH64_AUTH_GLOB_DAT 0000000000000000 bar + 0
92+
# EXTERNAL-TINY-NEXT: 0000000000020388 000000020000e201 R_AARCH64_AUTH_GLOB_DAT 0000000000000000 zed + 0
93+
94+
## Symbol's values for bar and zed are equal since they contain no content (see Inputs/shared.s)
95+
# LOCAL-TINY: Offset Info Type Symbol's Value Symbol's Name + Addend
96+
# LOCAL-TINY-NEXT: 0000000000020320 0000000000000411 R_AARCH64_AUTH_RELATIVE 10260
97+
# LOCAL-TINY-NEXT: 0000000000020328 0000000000000411 R_AARCH64_AUTH_RELATIVE 10260
98+
99+
# EXTERNAL-TINY: Hex dump of section '.got':
100+
# EXTERNAL-TINY-NEXT: 0x00020380 00000000 00000080 00000000 000000a0
101+
# ^^
102+
# 0b10000000 bit 63 address diversity = true, bits 61..60 key = IA
103+
# ^^
104+
# 0b10100000 bit 63 address diversity = true, bits 61..60 key = DA
105+
106+
# LOCAL-TINY: Symbol table '.symtab' contains {{.*}} entries:
107+
# LOCAL-TINY: Num: Value Size Type Bind Vis Ndx Name
108+
# LOCAL-TINY: 0000000000010260 0 FUNC GLOBAL DEFAULT 6 bar
109+
# LOCAL-TINY: 0000000000010260 0 NOTYPE GLOBAL DEFAULT 6 zed
110+
111+
# LOCAL-TINY: Hex dump of section '.got':
112+
# LOCAL-TINY-NEXT: 0x00020320 00000000 00000080 00000000 000000a0
113+
# ^^
114+
# 0b10000000 bit 63 address diversity = true, bits 61..60 key = IA
115+
# ^^
116+
# 0b10100000 bit 63 address diversity = true, bits 61..60 key = DA
117+
118+
# RUN: llvm-objdump -d external-tiny | FileCheck %s --check-prefix=EXTERNAL-TINY-ASM
119+
120+
# EXTERNAL-TINY-ASM: <_start>:
121+
# EXTERNAL-TINY-ASM-NEXT: adr x0, 0x20380
122+
# EXTERNAL-TINY-ASM-NEXT: ldr x1, [x0]
123+
# EXTERNAL-TINY-ASM-NEXT: adr x0, 0x20380
124+
# EXTERNAL-TINY-ASM-NEXT: ldr x1, 0x20380
125+
# EXTERNAL-TINY-ASM-NEXT: adr x0, 0x20388
126+
# EXTERNAL-TINY-ASM-NEXT: ldr x1, [x0]
127+
# EXTERNAL-TINY-ASM-NEXT: adr x0, 0x20388
128+
# EXTERNAL-TINY-ASM-NEXT: ldr x1, 0x20388
129+
130+
# RUN: llvm-objdump -d local-tiny | FileCheck %s --check-prefix=LOCAL-TINY-ASM
131+
132+
# LOCAL-TINY-ASM: <_start>:
133+
# LOCAL-TINY-ASM-NEXT: adr x0, 0x20320
134+
# LOCAL-TINY-ASM-NEXT: ldr x1, [x0]
135+
# LOCAL-TINY-ASM-NEXT: adr x0, 0x20320
136+
# LOCAL-TINY-ASM-NEXT: ldr x1, 0x20320
137+
# LOCAL-TINY-ASM-NEXT: adr x0, 0x20328
138+
# LOCAL-TINY-ASM-NEXT: ldr x1, [x0]
139+
# LOCAL-TINY-ASM-NEXT: adr x0, 0x20328
140+
# LOCAL-TINY-ASM-NEXT: ldr x1, 0x20328
141+
142+
.globl _start
143+
_start:
144+
adr x0, :got_auth:bar
145+
ldr x1, [x0]
146+
adr x0, :got_auth:bar
147+
ldr x1, :got_auth:bar
148+
adr x0, :got_auth:zed
149+
ldr x1, [x0]
150+
adr x0, :got_auth:zed
151+
ldr x1, :got_auth:zed
152+
80153
#--- err.s
81154
# RUN: llvm-mc -filetype=obj -triple=aarch64 err.s -o err.o
82155

0 commit comments

Comments
 (0)