Skip to content

Commit 7eddd30

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 1621897 commit 7eddd30

File tree

5 files changed

+89
-8
lines changed

5 files changed

+89
-8
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 R_AARCH64_AUTH_GOT;
208+
case R_AARCH64_AUTH_GOT_LD_PREL19:
209+
case R_AARCH64_AUTH_GOT_ADR_PREL_LO21:
210+
return R_AARCH64_AUTH_GOT_PC;
208211
case R_AARCH64_LD64_GOTPAGE_LO15:
209212
return R_AARCH64_GOT_PAGE;
210213
case R_AARCH64_ADR_GOT_PAGE:
@@ -549,6 +552,7 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
549552
write32AArch64Addr(loc, val >> 12);
550553
break;
551554
case R_AARCH64_ADR_PREL_LO21:
555+
case R_AARCH64_AUTH_GOT_ADR_PREL_LO21:
552556
checkInt(ctx, loc, val, 21, rel);
553557
write32AArch64Addr(loc, val);
554558
break;
@@ -569,6 +573,7 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
569573
case R_AARCH64_CONDBR19:
570574
case R_AARCH64_LD_PREL_LO19:
571575
case R_AARCH64_GOT_LD_PREL19:
576+
case R_AARCH64_AUTH_GOT_LD_PREL19:
572577
checkAlignment(ctx, loc, val, 4, rel);
573578
checkInt(ctx, loc, val, 21, rel);
574579
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
@@ -795,6 +795,7 @@ uint64_t InputSectionBase::getRelocTargetVA(Ctx &ctx, const Relocation &r,
795795
case R_AARCH64_GOT_PAGE:
796796
return r.sym->getGotVA(ctx) + a - getAArch64Page(ctx.in.got->getVA());
797797
case R_GOT_PC:
798+
case R_AARCH64_AUTH_GOT_PC:
798799
case R_RELAX_TLS_GD_TO_IE:
799800
return r.sym->getGotVA(ctx) + a - p;
800801
case R_GOTPLT_GOTREL:

lld/ELF/Relocations.cpp

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

212212
bool lld::elf::needsGot(RelExpr expr) {
213-
return oneof<R_GOT, R_AARCH64_AUTH_GOT, R_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE,
214-
R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_AARCH64_GOT_PAGE_PC,
215-
R_AARCH64_AUTH_GOT_PAGE_PC, R_GOT_PC, R_GOTPLT,
216-
R_AARCH64_GOT_PAGE, R_LOONGARCH_GOT, R_LOONGARCH_GOT_PAGE_PC>(
217-
expr);
213+
return oneof<R_GOT, R_AARCH64_AUTH_GOT, R_AARCH64_AUTH_GOT_PC, R_GOT_OFF,
214+
R_MIPS_GOT_LOCAL_PAGE, R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32,
215+
R_AARCH64_GOT_PAGE_PC, R_AARCH64_AUTH_GOT_PAGE_PC, R_GOT_PC,
216+
R_GOTPLT, R_AARCH64_GOT_PAGE, R_LOONGARCH_GOT,
217+
R_LOONGARCH_GOT_PAGE_PC>(expr);
218218
}
219219

220220
// True if this expression is of the form Sym - X, where X is a position in the
@@ -1010,8 +1010,8 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,
10101010
R_GOTONLY_PC, R_GOTPLTONLY_PC, R_PLT_PC, R_PLT_GOTREL, R_PLT_GOTPLT,
10111011
R_GOTPLT_GOTREL, R_GOTPLT_PC, R_PPC32_PLTREL, R_PPC64_CALL_PLT,
10121012
R_PPC64_RELAX_TOC, R_RISCV_ADD, R_AARCH64_GOT_PAGE,
1013-
R_AARCH64_AUTH_GOT, R_LOONGARCH_PLT_PAGE_PC, R_LOONGARCH_GOT,
1014-
R_LOONGARCH_GOT_PAGE_PC>(e))
1013+
R_AARCH64_AUTH_GOT, R_AARCH64_AUTH_GOT_PC, R_LOONGARCH_PLT_PAGE_PC,
1014+
R_LOONGARCH_GOT, R_LOONGARCH_GOT_PAGE_PC>(e))
10151015
return true;
10161016

10171017
// These never do, except if the entire file is position dependent or if
@@ -1126,7 +1126,8 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
11261126
// Many LoongArch TLS relocs reuse the R_LOONGARCH_GOT type, in which
11271127
// case the NEEDS_GOT flag shouldn't get set.
11281128
bool needsGotAuth =
1129-
(expr == R_AARCH64_AUTH_GOT || expr == R_AARCH64_AUTH_GOT_PAGE_PC);
1129+
(expr == R_AARCH64_AUTH_GOT || expr == R_AARCH64_AUTH_GOT_PC ||
1130+
expr == R_AARCH64_AUTH_GOT_PAGE_PC);
11301131
uint16_t flags = sym.flags.load(std::memory_order_relaxed);
11311132
if (!(flags & NEEDS_GOT)) {
11321133
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
@@ -89,6 +89,7 @@ enum RelExpr {
8989
R_AARCH64_AUTH_GOT_PAGE_PC,
9090
R_AARCH64_GOT_PAGE,
9191
R_AARCH64_AUTH_GOT,
92+
R_AARCH64_AUTH_GOT_PC,
9293
R_AARCH64_PAGE_PC,
9394
R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC,
9495
R_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
@@ -78,6 +78,79 @@ _start:
7878
adrp x1, :got_auth:zed
7979
add x1, x1, :got_auth_lo12:zed
8080

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

83156
# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux err.s -o err.o

0 commit comments

Comments
 (0)