Skip to content

Commit 1ef5b98

Browse files
authored
[PAC][lld][AArch64][ELF] Support signed GOT with tiny code model (#113816)
Depends on #114525 Support `R_AARCH64_AUTH_GOT_ADR_PREL_LO21` and `R_AARCH64_AUTH_GOT_LD_PREL19` GOT-generating relocations. A corresponding `RE_AARCH64_AUTH_GOT_PC` member of `RelExpr` is added, which is an AUTH-specific variant of `R_GOT_PC`.
1 parent 67c55b1 commit 1ef5b98

File tree

5 files changed

+75
-12
lines changed

5 files changed

+75
-12
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 RE_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: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,9 @@ static bool needsPlt(RelExpr expr) {
197197
}
198198

199199
bool lld::elf::needsGot(RelExpr expr) {
200-
return oneof<R_GOT, RE_AARCH64_AUTH_GOT, R_GOT_OFF, RE_MIPS_GOT_LOCAL_PAGE,
201-
RE_MIPS_GOT_OFF, RE_MIPS_GOT_OFF32, RE_AARCH64_GOT_PAGE_PC,
200+
return oneof<R_GOT, RE_AARCH64_AUTH_GOT, RE_AARCH64_AUTH_GOT_PC, R_GOT_OFF,
201+
RE_MIPS_GOT_LOCAL_PAGE, RE_MIPS_GOT_OFF, RE_MIPS_GOT_OFF32,
202+
RE_AARCH64_GOT_PAGE_PC, RE_AARCH64_AUTH_GOT_PAGE_PC,
202203
RE_AARCH64_AUTH_GOT_PAGE_PC, R_GOT_PC, R_GOTPLT,
203204
RE_AARCH64_GOT_PAGE, RE_LOONGARCH_GOT, RE_LOONGARCH_GOT_PAGE_PC>(
204205
expr);
@@ -974,15 +975,15 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,
974975
const Symbol &sym,
975976
uint64_t relOff) const {
976977
// These expressions always compute a constant
977-
if (oneof<R_GOTPLT, R_GOT_OFF, R_RELAX_HINT, RE_MIPS_GOT_LOCAL_PAGE,
978-
RE_MIPS_GOTREL, RE_MIPS_GOT_OFF, RE_MIPS_GOT_OFF32,
979-
RE_MIPS_GOT_GP_PC, RE_AARCH64_GOT_PAGE_PC,
980-
RE_AARCH64_AUTH_GOT_PAGE_PC, R_GOT_PC, R_GOTONLY_PC,
981-
R_GOTPLTONLY_PC, R_PLT_PC, R_PLT_GOTREL, R_PLT_GOTPLT,
982-
R_GOTPLT_GOTREL, R_GOTPLT_PC, RE_PPC32_PLTREL, RE_PPC64_CALL_PLT,
983-
RE_PPC64_RELAX_TOC, RE_RISCV_ADD, RE_AARCH64_GOT_PAGE,
984-
RE_AARCH64_AUTH_GOT, RE_LOONGARCH_PLT_PAGE_PC, RE_LOONGARCH_GOT,
985-
RE_LOONGARCH_GOT_PAGE_PC>(e))
978+
if (oneof<
979+
R_GOTPLT, R_GOT_OFF, R_RELAX_HINT, RE_MIPS_GOT_LOCAL_PAGE,
980+
RE_MIPS_GOTREL, RE_MIPS_GOT_OFF, RE_MIPS_GOT_OFF32, RE_MIPS_GOT_GP_PC,
981+
RE_AARCH64_GOT_PAGE_PC, RE_AARCH64_AUTH_GOT_PAGE_PC, R_GOT_PC,
982+
R_GOTONLY_PC, R_GOTPLTONLY_PC, R_PLT_PC, R_PLT_GOTREL, R_PLT_GOTPLT,
983+
R_GOTPLT_GOTREL, R_GOTPLT_PC, RE_PPC32_PLTREL, RE_PPC64_CALL_PLT,
984+
RE_PPC64_RELAX_TOC, RE_RISCV_ADD, RE_AARCH64_GOT_PAGE,
985+
RE_AARCH64_AUTH_GOT, RE_AARCH64_AUTH_GOT_PC, RE_LOONGARCH_PLT_PAGE_PC,
986+
RE_LOONGARCH_GOT, RE_LOONGARCH_GOT_PAGE_PC>(e))
986987
return true;
987988

988989
// These never do, except if the entire file is position dependent or if
@@ -1096,7 +1097,8 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
10961097
} else if (!sym.isTls() || ctx.arg.emachine != EM_LOONGARCH) {
10971098
// Many LoongArch TLS relocs reuse the RE_LOONGARCH_GOT type, in which
10981099
// case the NEEDS_GOT flag shouldn't get set.
1099-
if (expr == RE_AARCH64_AUTH_GOT || expr == RE_AARCH64_AUTH_GOT_PAGE_PC)
1100+
if (expr == RE_AARCH64_AUTH_GOT || expr == RE_AARCH64_AUTH_GOT_PAGE_PC ||
1101+
expr == RE_AARCH64_AUTH_GOT_PC)
11001102
sym.setFlags(NEEDS_GOT | NEEDS_GOT_AUTH);
11011103
else
11021104
sym.setFlags(NEEDS_GOT | NEEDS_GOT_NONAUTH);

lld/ELF/Relocations.h

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

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

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

80+
#--- ok-tiny.s
81+
# RUN: llvm-mc -filetype=obj -triple=aarch64 ok-tiny.s -o ok-tiny.o
82+
83+
# RUN: ld.lld ok-tiny.o a.so -pie -o tiny1
84+
# RUN: llvm-readelf -r -S -x .got tiny1 | FileCheck %s --check-prefix=TINY1
85+
86+
# RUN: ld.lld ok-tiny.o a.o -pie -o tiny2
87+
# RUN: llvm-readelf -r -S -x .got -s tiny2 | FileCheck %s --check-prefix=TINY2
88+
89+
# TINY1: Offset Info Type Symbol's Value Symbol's Name + Addend
90+
# TINY1-NEXT: 0000000000020368 0000000100000412 R_AARCH64_AUTH_GLOB_DAT 0000000000000000 bar + 0
91+
# TINY1-NEXT: 0000000000020370 0000000200000412 R_AARCH64_AUTH_GLOB_DAT 0000000000000000 zed + 0
92+
93+
## Symbol's values for bar and zed are equal since they contain no content (see Inputs/shared.s)
94+
# TINY2: Offset Info Type Symbol's Value Symbol's Name + Addend
95+
# TINY2-NEXT: 0000000000020308 0000000000000411 R_AARCH64_AUTH_RELATIVE 10248
96+
# TINY2-NEXT: 0000000000020310 0000000000000411 R_AARCH64_AUTH_RELATIVE 10248
97+
98+
# TINY1: Hex dump of section '.got':
99+
# TINY1-NEXT: 0x00020368 00000000 00000080 00000000 000000a0
100+
## ^^
101+
## 0b10000000 bit 63 address diversity = true, bits 61..60 key = IA
102+
## ^^
103+
## 0b10100000 bit 63 address diversity = true, bits 61..60 key = DA
104+
105+
# TINY2: Symbol table '.symtab' contains {{.*}} entries:
106+
# TINY2: Num: Value Size Type Bind Vis Ndx Name
107+
# TINY2: 0000000000010248 0 FUNC GLOBAL DEFAULT 6 bar
108+
# TINY2: 0000000000010248 0 NOTYPE GLOBAL DEFAULT 6 zed
109+
110+
# TINY2: Hex dump of section '.got':
111+
# TINY2-NEXT: 0x00020308 00000000 00000080 00000000 000000a0
112+
## ^^
113+
## 0b10000000 bit 63 address diversity = true, bits 61..60 key = IA
114+
## ^^
115+
## 0b10100000 bit 63 address diversity = true, bits 61..60 key = DA
116+
117+
# RUN: llvm-objdump -d tiny1 | FileCheck %s --check-prefix=TINY1-ASM
118+
119+
# TINY1-ASM: <_start>:
120+
# TINY1-ASM-NEXT: adr x0, 0x20368
121+
# TINY1-ASM-NEXT: ldr x1, 0x20370
122+
123+
# RUN: llvm-objdump -d tiny2 | FileCheck %s --check-prefix=TINY2-ASM
124+
125+
# TINY2-ASM: <_start>:
126+
# TINY2-ASM-NEXT: adr x0, 0x20308
127+
# TINY2-ASM-NEXT: ldr x1, 0x20310
128+
129+
.globl _start
130+
_start:
131+
adr x0, :got_auth:bar
132+
ldr x1, :got_auth:zed
133+
80134
#--- err.s
81135
# RUN: llvm-mc -filetype=obj -triple=aarch64 err.s -o err.o
82136
# RUN: not ld.lld err.o a.so -pie 2>&1 | FileCheck %s --check-prefix=ERR --implicit-check-not=error:

0 commit comments

Comments
 (0)