Skip to content

[PAC][lld][AArch64][ELF] Support signed GOT with tiny code model #113816

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 10 commits into from
Dec 18, 2024
5 changes: 5 additions & 0 deletions lld/ELF/Arch/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,9 @@ RelExpr AArch64::getRelExpr(RelType type, const Symbol &s,
case R_AARCH64_AUTH_LD64_GOT_LO12_NC:
case R_AARCH64_AUTH_GOT_ADD_LO12_NC:
return RE_AARCH64_AUTH_GOT;
case R_AARCH64_AUTH_GOT_LD_PREL19:
case R_AARCH64_AUTH_GOT_ADR_PREL_LO21:
return RE_AARCH64_AUTH_GOT_PC;
case R_AARCH64_LD64_GOTPAGE_LO15:
return RE_AARCH64_GOT_PAGE;
case R_AARCH64_ADR_GOT_PAGE:
Expand Down Expand Up @@ -548,6 +551,7 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
write32AArch64Addr(loc, val >> 12);
break;
case R_AARCH64_ADR_PREL_LO21:
case R_AARCH64_AUTH_GOT_ADR_PREL_LO21:
checkInt(ctx, loc, val, 21, rel);
write32AArch64Addr(loc, val);
break;
Expand All @@ -568,6 +572,7 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
case R_AARCH64_CONDBR19:
case R_AARCH64_LD_PREL_LO19:
case R_AARCH64_GOT_LD_PREL19:
case R_AARCH64_AUTH_GOT_LD_PREL19:
checkAlignment(ctx, loc, val, 4, rel);
checkInt(ctx, loc, val, 21, rel);
writeMaskedBits32le(loc, (val & 0x1FFFFC) << 3, 0x1FFFFC << 3);
Expand Down
1 change: 1 addition & 0 deletions lld/ELF/InputSection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,7 @@ uint64_t InputSectionBase::getRelocTargetVA(Ctx &ctx, const Relocation &r,
case RE_AARCH64_GOT_PAGE:
return r.sym->getGotVA(ctx) + a - getAArch64Page(ctx.in.got->getVA());
case R_GOT_PC:
case RE_AARCH64_AUTH_GOT_PC:
case R_RELAX_TLS_GD_TO_IE:
return r.sym->getGotVA(ctx) + a - p;
case R_GOTPLT_GOTREL:
Expand Down
26 changes: 14 additions & 12 deletions lld/ELF/Relocations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,9 @@ static bool needsPlt(RelExpr expr) {
}

bool lld::elf::needsGot(RelExpr expr) {
return oneof<R_GOT, RE_AARCH64_AUTH_GOT, R_GOT_OFF, RE_MIPS_GOT_LOCAL_PAGE,
RE_MIPS_GOT_OFF, RE_MIPS_GOT_OFF32, RE_AARCH64_GOT_PAGE_PC,
return oneof<R_GOT, RE_AARCH64_AUTH_GOT, RE_AARCH64_AUTH_GOT_PC, R_GOT_OFF,
RE_MIPS_GOT_LOCAL_PAGE, RE_MIPS_GOT_OFF, RE_MIPS_GOT_OFF32,
RE_AARCH64_GOT_PAGE_PC, RE_AARCH64_AUTH_GOT_PAGE_PC,
RE_AARCH64_AUTH_GOT_PAGE_PC, R_GOT_PC, R_GOTPLT,
RE_AARCH64_GOT_PAGE, RE_LOONGARCH_GOT, RE_LOONGARCH_GOT_PAGE_PC>(
expr);
Expand Down Expand Up @@ -974,15 +975,15 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,
const Symbol &sym,
uint64_t relOff) const {
// These expressions always compute a constant
if (oneof<R_GOTPLT, R_GOT_OFF, R_RELAX_HINT, RE_MIPS_GOT_LOCAL_PAGE,
RE_MIPS_GOTREL, RE_MIPS_GOT_OFF, RE_MIPS_GOT_OFF32,
RE_MIPS_GOT_GP_PC, RE_AARCH64_GOT_PAGE_PC,
RE_AARCH64_AUTH_GOT_PAGE_PC, R_GOT_PC, R_GOTONLY_PC,
R_GOTPLTONLY_PC, R_PLT_PC, R_PLT_GOTREL, R_PLT_GOTPLT,
R_GOTPLT_GOTREL, R_GOTPLT_PC, RE_PPC32_PLTREL, RE_PPC64_CALL_PLT,
RE_PPC64_RELAX_TOC, RE_RISCV_ADD, RE_AARCH64_GOT_PAGE,
RE_AARCH64_AUTH_GOT, RE_LOONGARCH_PLT_PAGE_PC, RE_LOONGARCH_GOT,
RE_LOONGARCH_GOT_PAGE_PC>(e))
if (oneof<
R_GOTPLT, R_GOT_OFF, R_RELAX_HINT, RE_MIPS_GOT_LOCAL_PAGE,
RE_MIPS_GOTREL, RE_MIPS_GOT_OFF, RE_MIPS_GOT_OFF32, RE_MIPS_GOT_GP_PC,
RE_AARCH64_GOT_PAGE_PC, RE_AARCH64_AUTH_GOT_PAGE_PC, R_GOT_PC,
R_GOTONLY_PC, R_GOTPLTONLY_PC, R_PLT_PC, R_PLT_GOTREL, R_PLT_GOTPLT,
R_GOTPLT_GOTREL, R_GOTPLT_PC, RE_PPC32_PLTREL, RE_PPC64_CALL_PLT,
RE_PPC64_RELAX_TOC, RE_RISCV_ADD, RE_AARCH64_GOT_PAGE,
RE_AARCH64_AUTH_GOT, RE_AARCH64_AUTH_GOT_PC, RE_LOONGARCH_PLT_PAGE_PC,
RE_LOONGARCH_GOT, RE_LOONGARCH_GOT_PAGE_PC>(e))
return true;

// These never do, except if the entire file is position dependent or if
Expand Down Expand Up @@ -1096,7 +1097,8 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
} else if (!sym.isTls() || ctx.arg.emachine != EM_LOONGARCH) {
// Many LoongArch TLS relocs reuse the RE_LOONGARCH_GOT type, in which
// case the NEEDS_GOT flag shouldn't get set.
if (expr == RE_AARCH64_AUTH_GOT || expr == RE_AARCH64_AUTH_GOT_PAGE_PC)
if (expr == RE_AARCH64_AUTH_GOT || expr == RE_AARCH64_AUTH_GOT_PAGE_PC ||
expr == RE_AARCH64_AUTH_GOT_PC)
sym.setFlags(NEEDS_GOT | NEEDS_GOT_AUTH);
else
sym.setFlags(NEEDS_GOT | NEEDS_GOT_NONAUTH);
Expand Down
1 change: 1 addition & 0 deletions lld/ELF/Relocations.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ enum RelExpr {
RE_AARCH64_AUTH_GOT_PAGE_PC,
RE_AARCH64_GOT_PAGE,
RE_AARCH64_AUTH_GOT,
RE_AARCH64_AUTH_GOT_PC,
RE_AARCH64_PAGE_PC,
RE_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC,
RE_AARCH64_TLSDESC_PAGE,
Expand Down
54 changes: 54 additions & 0 deletions lld/test/ELF/aarch64-got-relocations-pauth.s
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,60 @@ _start:
adrp x1, :got_auth:zed
add x1, x1, :got_auth_lo12:zed

#--- ok-tiny.s
# RUN: llvm-mc -filetype=obj -triple=aarch64 ok-tiny.s -o ok-tiny.o

# RUN: ld.lld ok-tiny.o a.so -pie -o tiny1
# RUN: llvm-readelf -r -S -x .got tiny1 | FileCheck %s --check-prefix=TINY1

# RUN: ld.lld ok-tiny.o a.o -pie -o tiny2
# RUN: llvm-readelf -r -S -x .got -s tiny2 | FileCheck %s --check-prefix=TINY2

# TINY1: Offset Info Type Symbol's Value Symbol's Name + Addend
# TINY1-NEXT: 0000000000020368 0000000100000412 R_AARCH64_AUTH_GLOB_DAT 0000000000000000 bar + 0
# TINY1-NEXT: 0000000000020370 0000000200000412 R_AARCH64_AUTH_GLOB_DAT 0000000000000000 zed + 0

## Symbol's values for bar and zed are equal since they contain no content (see Inputs/shared.s)
# TINY2: Offset Info Type Symbol's Value Symbol's Name + Addend
# TINY2-NEXT: 0000000000020308 0000000000000411 R_AARCH64_AUTH_RELATIVE 10248
# TINY2-NEXT: 0000000000020310 0000000000000411 R_AARCH64_AUTH_RELATIVE 10248

# TINY1: Hex dump of section '.got':
# TINY1-NEXT: 0x00020368 00000000 00000080 00000000 000000a0
## ^^
## 0b10000000 bit 63 address diversity = true, bits 61..60 key = IA
## ^^
## 0b10100000 bit 63 address diversity = true, bits 61..60 key = DA

# TINY2: Symbol table '.symtab' contains {{.*}} entries:
# TINY2: Num: Value Size Type Bind Vis Ndx Name
# TINY2: 0000000000010248 0 FUNC GLOBAL DEFAULT 6 bar
# TINY2: 0000000000010248 0 NOTYPE GLOBAL DEFAULT 6 zed

# TINY2: Hex dump of section '.got':
# TINY2-NEXT: 0x00020308 00000000 00000080 00000000 000000a0
## ^^
## 0b10000000 bit 63 address diversity = true, bits 61..60 key = IA
## ^^
## 0b10100000 bit 63 address diversity = true, bits 61..60 key = DA

# RUN: llvm-objdump -d tiny1 | FileCheck %s --check-prefix=TINY1-ASM

# TINY1-ASM: <_start>:
# TINY1-ASM-NEXT: adr x0, 0x20368
# TINY1-ASM-NEXT: ldr x1, 0x20370

# RUN: llvm-objdump -d tiny2 | FileCheck %s --check-prefix=TINY2-ASM

# TINY2-ASM: <_start>:
# TINY2-ASM-NEXT: adr x0, 0x20308
# TINY2-ASM-NEXT: ldr x1, 0x20310

.globl _start
_start:
adr x0, :got_auth:bar
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for so many instructions.

We want very few instructions that look like simplified real-world codegen. While it's important to test two symbols to add some nuance, we can simplify the code here. Perhaps we just need

adr x0, :got_auth:bar
ldr x1, :got_auth:zed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for suggestion, removed excessive instructions in 3c80d75

ldr x1, :got_auth:zed

#--- err.s
# RUN: llvm-mc -filetype=obj -triple=aarch64 err.s -o err.o
# RUN: not ld.lld err.o a.so -pie 2>&1 | FileCheck %s --check-prefix=ERR --implicit-check-not=error:
Expand Down
Loading