https://github.com/kovdan01 updated https://github.com/llvm/llvm-project/pull/194636
>From b48bca9225adb58e865c661a43fb1165b419f30e Mon Sep 17 00:00:00 2001 From: Daniil Kovalev <[email protected]> Date: Mon, 3 Aug 2026 13:40:39 +0300 Subject: [PATCH 1/3] [PAC][lld] Do not emit AUTH relocs against undef weak non-preemptible symbols Undefined weak non-preemptible symbols should be statically resolved and not signed. See the corresponding relaxation described in docs: https://github.com/ARM-software/abi-aa/blob/6e0d6611ac977628af7b2444ff841e76931a3557/design-documents/pauthabi-tls.rst Previously, a dynamic relocation against such symbols was emitted, which is not a correct behavior. See also: https://github.com/ARM-software/abi-aa/pull/391 Depends on: #198327 Resolves #173296 --- lld/ELF/Arch/AArch64.cpp | 88 +++++++++++++++++-- lld/ELF/Relocations.cpp | 19 ++-- lld/ELF/SyntheticSections.cpp | 20 +++-- lld/ELF/SyntheticSections.h | 3 +- .../ELF/aarch64-reloc-pauth-undef-weak-dso.s | 48 ++++++++++ .../ELF/aarch64-reloc-pauth-undef-weak-pie.s | 47 ++++++++++ lld/test/ELF/aarch64-reloc-pauth-undef-weak.s | 48 ++++++++++ lld/test/ELF/aarch64-tlsdesc-pauth.s | 7 ++ 8 files changed, 259 insertions(+), 21 deletions(-) create mode 100644 lld/test/ELF/aarch64-reloc-pauth-undef-weak-dso.s create mode 100644 lld/test/ELF/aarch64-reloc-pauth-undef-weak-pie.s create mode 100644 lld/test/ELF/aarch64-reloc-pauth-undef-weak.s diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp index 4d24c49382559..90d05fda47b32 100644 --- a/lld/ELF/Arch/AArch64.cpp +++ b/lld/ELF/Arch/AArch64.cpp @@ -103,6 +103,8 @@ class AArch64 : public TargetInfo { void relaxTlsGdToLe(uint8_t *loc, const Relocation &rel, uint64_t val) const; void relaxTlsGdToIe(uint8_t *loc, const Relocation &rel, uint64_t val) const; void relaxTlsIeToLe(uint8_t *loc, const Relocation &rel, uint64_t val) const; + void relaxAuthTlsDescForNonPreemptibleUndefWeak(uint8_t *loc, + const Relocation &rel) const; }; struct AArch64Relaxer { @@ -212,6 +214,20 @@ void AArch64::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels, // Relocation types that only need a RelExpr set `expr` and break out of // the switch to reach rs.process(). Types that need special handling // (fast-path helpers, TLS) call a handler and use `continue`. + + auto handleTlsDescAuth = [&sym, &sec, type, offset, + addend](RelExpr tlsdescExpr) { + sym.setFlags(NEEDS_TLSDESC_AUTH); + if (sym.isUndefWeak() && !sym.isPreemptible) { + // Resolves statically to null. Handle in + // relaxAuthTlsDescForNonPreemptibleUndefWeak + sec.addReloc({R_TPREL, type, offset, addend, &sym}); + } else { + sym.setFlags(NEEDS_TLSDESC); + sec.addReloc({tlsdescExpr, type, offset, addend, &sym}); + } + }; + switch (type) { case R_AARCH64_NONE: continue; @@ -363,13 +379,16 @@ void AArch64::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels, // only supports the descriptor based TLS (TLSDESC). // https://github.com/ARM-software/abi-aa/blob/main/pauthabielf64/pauthabielf64.rst#general-restrictions case R_AARCH64_AUTH_TLSDESC_ADR_PAGE21: - sym.setFlags(NEEDS_TLSDESC | NEEDS_TLSDESC_AUTH); - sec.addReloc({RE_AARCH64_TLSDESC_PAGE, type, offset, addend, &sym}); + handleTlsDescAuth(RE_AARCH64_TLSDESC_PAGE); continue; case R_AARCH64_AUTH_TLSDESC_LD64_LO12: case R_AARCH64_AUTH_TLSDESC_ADD_LO12: - sym.setFlags(NEEDS_TLSDESC | NEEDS_TLSDESC_AUTH); - sec.addReloc({R_TLSDESC, type, offset, addend, &sym}); + handleTlsDescAuth(R_TLSDESC); + continue; + case R_AARCH64_AUTH_TLSDESC_CALL: + sym.setFlags(NEEDS_TLSDESC_AUTH); + if (sym.isUndefWeak() && !sym.isPreemptible) + sec.addReloc({R_TPREL, type, offset, addend, &sym}); continue; default: @@ -654,11 +673,22 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel, write64(ctx, loc, val); break; case R_AARCH64_AUTH_ABS64: - // This is used for the addend of a .relr.auth.dyn entry, - // which is a 32-bit value; the upper 32 bits are used to - // encode the schema. - checkInt(ctx, loc, val, 32, rel); - write32(ctx, loc, val); + if (rel.sym->isUndefined() && !rel.sym->isPreemptible) { + // Undefined weak non-preemptible symbols are statically resolved to the + // addend. No dynamic relocation and corresponding signing schema encoding + // is needed. + // + // Note: at this point, binding of undefined weak non-preemptible symbols + // has already been changed from weak to local by computeBinding call, so + // just check against isUndefined(). + write64(ctx, loc, val); + } else { + // This is used for the addend of a .relr.auth.dyn entry, + // which is a 32-bit value; the upper 32 bits are used to + // encode the schema. + checkInt(ctx, loc, val, 32, rel); + write32(ctx, loc, val); + } break; case R_AARCH64_TLS_DTPREL64: write64(ctx, loc, val); @@ -820,6 +850,37 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel, } } +void AArch64::relaxAuthTlsDescForNonPreemptibleUndefWeak( + uint8_t *loc, const Relocation &rel) const { + // AUTH TLSDESC relocations are in the form: + // adrp x0, :tlsdesc_auth:v [R_AARCH64_AUTH_TLSDESC_ADR_PAGE21] + // ldr x16, [x0, :tlsdesc_auth_lo12:v] [R_AARCH64_AUTH_TLSDESC_LD64_LO12] + // add x0, x0, :tlsdesc_auth_lo12:v [R_AARCH64_AUTH_TLSDESC_ADD_LO12] + // .tlsdescauthcall v [R_AARCH64_AUTH_TLSDESC_CALL] + // blraa x16, x0 + // And it can optimized to: + // mrs x0, tpidr_el0 + // neg x0, x0 + // nop + // nop + + switch (rel.type) { + case R_AARCH64_AUTH_TLSDESC_ADR_PAGE21: + write32le(loc, 0xd53bd040); // mrs x0, tpidr_el0 + return; + case R_AARCH64_AUTH_TLSDESC_LD64_LO12: + write32le(loc, 0xcb0003e0); // neg x0, x0 + return; + case R_AARCH64_AUTH_TLSDESC_ADD_LO12: + case R_AARCH64_AUTH_TLSDESC_CALL: + write32le(loc, 0xd503201f); // nop + return; + default: + llvm_unreachable("unsupported relocation for non-preemptible undefined " + "weak AUTH TLSDESC relaxation"); + } +} + void AArch64::relaxTlsGdToLe(uint8_t *loc, const Relocation &rel, uint64_t val) const { // TLSDESC Global-Dynamic relocation are in the form: @@ -1115,6 +1176,15 @@ void AArch64::relocateAlloc(InputSection &sec, uint8_t *buf) const { else relocate(loc, rel, val); continue; + case R_AARCH64_AUTH_TLSDESC_ADR_PAGE21: + case R_AARCH64_AUTH_TLSDESC_LD64_LO12: + case R_AARCH64_AUTH_TLSDESC_ADD_LO12: + case R_AARCH64_AUTH_TLSDESC_CALL: + if (rel.expr == R_TPREL) + relaxAuthTlsDescForNonPreemptibleUndefWeak(loc, rel); + else + relocate(loc, rel, val); + continue; case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: if (rel.expr == R_TPREL) diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index d335da63ebf84..7cd908fe71ad7 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -793,9 +793,12 @@ static void addGotAuthEntry(Ctx &ctx, Symbol &sym) { return; } - // Signed GOT requires dynamic relocation. - ctx.in.relaDyn->addReloc( - {R_AARCH64_AUTH_RELATIVE, ctx.in.got.get(), off, false, sym, 0, R_ABS}); + // Signed GOT requires dynamic relocation unless the symbol is + // non-preemptible and undefined weak. + if (!sym.isUndefWeak()) { + ctx.in.relaDyn->addReloc( + {R_AARCH64_AUTH_RELATIVE, ctx.in.got.get(), off, false, sym, 0, R_ABS}); + } } static void addTpOffsetGotEntry(Ctx &ctx, Symbol &sym) { @@ -855,8 +858,12 @@ bool RelocScan::isStaticLinkTimeConstant(RelExpr e, RelType type, // only the low bits are used. if (e == R_GOT || e == R_PLT) return ctx.target->usesOnlyLowPageBits(type) || !ctx.arg.isPic; - // R_AARCH64_AUTH_ABS64 and iRelSymbolicRel require a dynamic relocation. - if (e == RE_AARCH64_AUTH || type == ctx.target->iRelSymbolicRel) + // R_AARCH64_AUTH_ABS64 requires a dynamic relocation unless the symbol is + // non-preemptible and undefined weak. + if (e == RE_AARCH64_AUTH && (!sym.isUndefWeak() || sym.isPreemptible)) + return false; + // iRelSymbolicRel requires a dynamic relocation. + if (type == ctx.target->iRelSymbolicRel) return false; // The behavior of an undefined weak reference is implementation defined. @@ -1348,7 +1355,7 @@ void elf::postScanRelocations(Ctx &ctx) { got->addTlsDescEntry(sym); RelType tlsDescRel = ctx.target->tlsDescRel; if (flags & NEEDS_TLSDESC_AUTH) { - got->addTlsDescAuthEntry(); + got->addTlsDescAuthEntry(sym); tlsDescRel = ELF::R_AARCH64_AUTH_TLSDESC; } ctx.in.relaDyn->addAddendOnlyRelocIfNonPreemptible( diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 6bac881446fd0..ecd86fa2ab622 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -507,7 +507,9 @@ void GotSection::addEntry(const Symbol &sym) { void GotSection::addAuthEntry(const Symbol &sym) { authEntries.push_back( - {(numEntries - 1) * ctx.target->gotEntrySize, sym.isFunc()}); + {/*offset=*/(numEntries - 1) * ctx.target->gotEntrySize, + /*isSymbolFunc=*/sym.isFunc(), + /*isUndefWeakNonPreemptible=*/sym.isUndefWeak() && !sym.isPreemptible}); } bool GotSection::addTlsDescEntry(const Symbol &sym) { @@ -517,9 +519,12 @@ bool GotSection::addTlsDescEntry(const Symbol &sym) { return true; } -void GotSection::addTlsDescAuthEntry() { - authEntries.push_back({(numEntries - 2) * ctx.target->gotEntrySize, true}); - authEntries.push_back({(numEntries - 1) * ctx.target->gotEntrySize, false}); +void GotSection::addTlsDescAuthEntry(const Symbol &sym) { + authEntries.push_back({/*offset=*/(numEntries - 2) * ctx.target->gotEntrySize, + /*isSymbolFunc=*/true, + /*isUndefWeakNonPreemptible=*/false}); + assert(!sym.isFunc()); + addAuthEntry(sym); } bool GotSection::addDynTlsEntry(const Symbol &sym) { @@ -578,6 +583,12 @@ void GotSection::writeTo(uint8_t *buf) { ctx.target->writeGotHeader(buf); ctx.target->relocateAlloc(*this, buf); for (const AuthEntryInfo &authEntry : authEntries) { + uint8_t *dest = buf + authEntry.offset; + + if (authEntry.isUndefWeakNonPreemptible) { + write64(ctx, dest, 0); + continue; + } // https://github.com/ARM-software/abi-aa/blob/2024Q3/pauthabielf64/pauthabielf64.rst#default-signing-schema // Signed GOT entries use the IA key for symbols of type STT_FUNC and the // DA key for all other symbol types, with the address of the GOT entry as @@ -587,7 +598,6 @@ void GotSection::writeTo(uint8_t *buf) { // https://github.com/ARM-software/abi-aa/blob/2024Q3/pauthabielf64/pauthabielf64.rst#encoding-the-signing-schema // If address diversity is set and the discriminator // is 0 then modifier = Place - uint8_t *dest = buf + authEntry.offset; uint64_t key = authEntry.isSymbolFunc ? /*IA=*/0b00 : /*DA=*/0b10; uint64_t addrDiversity = 1; write64(ctx, dest, (addrDiversity << 63) | (key << 60)); diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 19d4461348f3f..c45734612ac97 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -122,7 +122,7 @@ class GotSection final : public SyntheticSection { void addEntry(const Symbol &sym); void addAuthEntry(const Symbol &sym); bool addTlsDescEntry(const Symbol &sym); - void addTlsDescAuthEntry(); + void addTlsDescAuthEntry(const Symbol &sym); bool addDynTlsEntry(const Symbol &sym); bool addTlsIndex(); uint32_t getTlsDescOffset(const Symbol &sym) const; @@ -143,6 +143,7 @@ class GotSection final : public SyntheticSection { struct AuthEntryInfo { size_t offset; bool isSymbolFunc; + bool isUndefWeakNonPreemptible; }; SmallVector<AuthEntryInfo, 0> authEntries; }; diff --git a/lld/test/ELF/aarch64-reloc-pauth-undef-weak-dso.s b/lld/test/ELF/aarch64-reloc-pauth-undef-weak-dso.s new file mode 100644 index 0000000000000..826276c7bf819 --- /dev/null +++ b/lld/test/ELF/aarch64-reloc-pauth-undef-weak-dso.s @@ -0,0 +1,48 @@ +# REQUIRES: aarch64 +# RUN: llvm-mc -filetype=obj -triple=aarch64 -mattr=+pauth %s -o %t.o +# RUN: ld.lld -shared %t.o -o %t +# RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=RELA +# RUN: llvm-readelf -x.data %t | FileCheck %s --check-prefix=DATA +# RUN: llvm-readelf -x.got %t | FileCheck %s --check-prefix=GOT +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s --check-prefix=DIS + +## Verify that R_AARCH64_AUTH_ABS64 against a weak undefined symbol is resolved +## to NULL (plus addend). + +# RELA-LABEL: Relocations [ +# RELA-NEXT: ] + +# DATA-LABEL: Hex dump of section '.data': +# DATA-NEXT: 0x00030300 00000000 00000000 25000000 00000000 +# DATA-NEXT: 0x00030310 00000000 00000000 25000000 00000000 + +# GOT-LABEL: Hex dump of section '.got': +# GOT-NEXT: 0x000202f8 00000000 00000000 + +# DIS-LABEL: <_start>: +# DIS-NEXT: adrp x0, 0x20000 +# DIS-NEXT: ldr x0, [x0, #0x2f8] +# DIS-NEXT: mrs x0, TPIDR_EL0 +# DIS-NEXT: neg x0, x0 +# DIS-NEXT: nop +# DIS-NEXT: nop + +.weak undef +.hidden undef + +.globl _start +_start: + adrp x0, :got_auth:undef + ldr x0, [x0, :got_auth_lo12:undef] + adrp x0, :tlsdesc_auth:undef + ldr x16, [x0, :tlsdesc_auth_lo12:undef] + add x0, x0, :tlsdesc_auth_lo12:undef + .tlsdescauthcall undef + blraa x16, x0 + +.data +foo: +.quad undef@AUTH(da,42) +.quad (undef + 37)@AUTH(da,42) +.quad undef +.quad (undef + 37) diff --git a/lld/test/ELF/aarch64-reloc-pauth-undef-weak-pie.s b/lld/test/ELF/aarch64-reloc-pauth-undef-weak-pie.s new file mode 100644 index 0000000000000..dba8d3d830b42 --- /dev/null +++ b/lld/test/ELF/aarch64-reloc-pauth-undef-weak-pie.s @@ -0,0 +1,47 @@ +# REQUIRES: aarch64 +# RUN: llvm-mc -filetype=obj -triple=aarch64 -mattr=+pauth %s -o %t.o +# RUN: ld.lld -pie %t.o -o %t +# RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=RELA +# RUN: llvm-readelf -x.data %t | FileCheck %s --check-prefix=DATA +# RUN: llvm-readelf -x.got %t | FileCheck %s --check-prefix=GOT +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s --check-prefix=DIS + +## Verify that R_AARCH64_AUTH_ABS64 against a weak undefined symbol is resolved +## to NULL (plus addend). + +# RELA-LABEL: Relocations [ +# RELA-NEXT: ] + +# DATA-LABEL: Hex dump of section '.data': +# DATA-NEXT: 0x000302f8 00000000 00000000 25000000 00000000 +# DATA-NEXT: 0x00030308 00000000 00000000 25000000 00000000 + +# GOT-LABEL: Hex dump of section '.got': +# GOT-NEXT: 0x000202f0 00000000 00000000 + +# DIS-LABEL: <_start>: +# DIS-NEXT: adrp x0, 0x20000 +# DIS-NEXT: ldr x0, [x0, #0x2f0] +# DIS-NEXT: mrs x0, TPIDR_EL0 +# DIS-NEXT: neg x0, x0 +# DIS-NEXT: nop +# DIS-NEXT: nop + +.weak undef + +.globl _start +_start: + adrp x0, :got_auth:undef + ldr x0, [x0, :got_auth_lo12:undef] + adrp x0, :tlsdesc_auth:undef + ldr x16, [x0, :tlsdesc_auth_lo12:undef] + add x0, x0, :tlsdesc_auth_lo12:undef + .tlsdescauthcall undef + blraa x16, x0 + +.data +foo: +.quad undef@AUTH(da,42) +.quad (undef + 37)@AUTH(da,42) +.quad undef +.quad (undef + 37) diff --git a/lld/test/ELF/aarch64-reloc-pauth-undef-weak.s b/lld/test/ELF/aarch64-reloc-pauth-undef-weak.s new file mode 100644 index 0000000000000..276a04957f730 --- /dev/null +++ b/lld/test/ELF/aarch64-reloc-pauth-undef-weak.s @@ -0,0 +1,48 @@ +# REQUIRES: aarch64 +# RUN: llvm-mc -filetype=obj -triple=aarch64 -mattr=+pauth %s -o %t.o +# RUN: ld.lld --static %t.o -o %t +# RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=RELA +# RUN: llvm-readelf -x.data %t | FileCheck %s --check-prefix=DATA +# RUN: llvm-readelf -x.got %t | FileCheck %s --check-prefix=GOT +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s --check-prefix=DIS + +## Verify that R_AARCH64_AUTH_ABS64 against a weak undefined symbol is resolved +## to NULL (plus addend). + +# RELA-LABEL: Relocations [ +# RELA-NEXT: ] + +# DATA-LABEL: Hex dump of section '.data': +# DATA-NEXT: 0x002301e8 00000000 00000000 25000000 00000000 +# DATA-NEXT: 0x002301f8 00000000 00000000 25000000 00000000 + +# GOT-LABEL: Hex dump of section '.got': +# GOT-NEXT: 0x002201e0 00000000 00000000 + +# DIS-LABEL: <_start>: + +# DIS-NEXT: adrp x0, 0x220000 +# DIS-NEXT: ldr x0, [x0, #0x1e0] +# DIS-NEXT: mrs x0, TPIDR_EL0 +# DIS-NEXT: neg x0, x0 +# DIS-NEXT: nop +# DIS-NEXT: nop + +.weak undef + +.globl _start +_start: + adrp x0, :got_auth:undef + ldr x0, [x0, :got_auth_lo12:undef] + adrp x0, :tlsdesc_auth:undef + ldr x16, [x0, :tlsdesc_auth_lo12:undef] + add x0, x0, :tlsdesc_auth_lo12:undef + .tlsdescauthcall undef + blraa x16, x0 + +.data +foo: +.quad undef@AUTH(da,42) +.quad (undef + 37)@AUTH(da,42) +.quad undef +.quad undef + 37 diff --git a/lld/test/ELF/aarch64-tlsdesc-pauth.s b/lld/test/ELF/aarch64-tlsdesc-pauth.s index bf0ae4a87f322..41c7b31b5a7e6 100644 --- a/lld/test/ELF/aarch64-tlsdesc-pauth.s +++ b/lld/test/ELF/aarch64-tlsdesc-pauth.s @@ -27,6 +27,7 @@ a: adrp x0, :tlsdesc_auth:a ldr x16, [x0, :tlsdesc_auth_lo12:a] add x0, x0, :tlsdesc_auth_lo12:a + .tlsdescauthcall a blraa x16, x0 // CHECK: adrp x0, 0x[[P]]000 @@ -41,6 +42,7 @@ a: adrp x0, :tlsdesc_auth:local1 ldr x16, [x0, :tlsdesc_auth_lo12:local1] add x0, x0, :tlsdesc_auth_lo12:local1 + .tlsdescauthcall local1 blraa x16, x0 // CHECK: adrp x0, 0x[[P]]000 @@ -51,6 +53,7 @@ a: adrp x0, :tlsdesc_auth:local2 ldr x16, [x0, :tlsdesc_auth_lo12:local2] add x0, x0, :tlsdesc_auth_lo12:local2 + .tlsdescauthcall local2 blraa x16, x0 // CHECK: adrp x0, 0x[[P]]000 @@ -100,11 +103,13 @@ local2: adrp x0, :tlsdesc_auth:a ldr x16, [x0, :tlsdesc_auth_lo12:a] add x0, x0, :tlsdesc_auth_lo12:a + .tlsdesccall a blraa x16, x0 adrp x0, :tlsdesc:a ldr x1, [x0, :tlsdesc_lo12:a] add x0, x0, :tlsdesc_lo12:a + .tlsdescauthcall a blr x1 //--- err2.s @@ -115,11 +120,13 @@ local2: adrp x0, :tlsdesc:a ldr x1, [x0, :tlsdesc_lo12:a] add x0, x0, :tlsdesc_lo12:a + .tlsdesccall a blr x1 adrp x0, :tlsdesc_auth:a ldr x16, [x0, :tlsdesc_auth_lo12:a] add x0, x0, :tlsdesc_auth_lo12:a + .tlsdescauthcall a blraa x16, x0 //--- err3.s >From 3b4fb49bcfbe196cf4266f4f69ee3aea7d876545 Mon Sep 17 00:00:00 2001 From: Daniil Kovalev <[email protected]> Date: Mon, 3 Aug 2026 17:17:08 +0300 Subject: [PATCH 2/3] `.tlsdescauthcall` -> `.tlsauthdesccall` (per documentation) --- lld/ELF/Arch/AArch64.cpp | 2 +- lld/test/ELF/aarch64-reloc-pauth-undef-weak-dso.s | 2 +- lld/test/ELF/aarch64-reloc-pauth-undef-weak-pie.s | 2 +- lld/test/ELF/aarch64-reloc-pauth-undef-weak.s | 2 +- lld/test/ELF/aarch64-tlsdesc-pauth.s | 10 +++++----- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp index 90d05fda47b32..e11ff626eb21c 100644 --- a/lld/ELF/Arch/AArch64.cpp +++ b/lld/ELF/Arch/AArch64.cpp @@ -856,7 +856,7 @@ void AArch64::relaxAuthTlsDescForNonPreemptibleUndefWeak( // adrp x0, :tlsdesc_auth:v [R_AARCH64_AUTH_TLSDESC_ADR_PAGE21] // ldr x16, [x0, :tlsdesc_auth_lo12:v] [R_AARCH64_AUTH_TLSDESC_LD64_LO12] // add x0, x0, :tlsdesc_auth_lo12:v [R_AARCH64_AUTH_TLSDESC_ADD_LO12] - // .tlsdescauthcall v [R_AARCH64_AUTH_TLSDESC_CALL] + // .tlsauthdesccall v [R_AARCH64_AUTH_TLSDESC_CALL] // blraa x16, x0 // And it can optimized to: // mrs x0, tpidr_el0 diff --git a/lld/test/ELF/aarch64-reloc-pauth-undef-weak-dso.s b/lld/test/ELF/aarch64-reloc-pauth-undef-weak-dso.s index 826276c7bf819..5e771baf947f3 100644 --- a/lld/test/ELF/aarch64-reloc-pauth-undef-weak-dso.s +++ b/lld/test/ELF/aarch64-reloc-pauth-undef-weak-dso.s @@ -37,7 +37,7 @@ _start: adrp x0, :tlsdesc_auth:undef ldr x16, [x0, :tlsdesc_auth_lo12:undef] add x0, x0, :tlsdesc_auth_lo12:undef - .tlsdescauthcall undef + .tlsauthdesccall undef blraa x16, x0 .data diff --git a/lld/test/ELF/aarch64-reloc-pauth-undef-weak-pie.s b/lld/test/ELF/aarch64-reloc-pauth-undef-weak-pie.s index dba8d3d830b42..e612e9ec68ecb 100644 --- a/lld/test/ELF/aarch64-reloc-pauth-undef-weak-pie.s +++ b/lld/test/ELF/aarch64-reloc-pauth-undef-weak-pie.s @@ -36,7 +36,7 @@ _start: adrp x0, :tlsdesc_auth:undef ldr x16, [x0, :tlsdesc_auth_lo12:undef] add x0, x0, :tlsdesc_auth_lo12:undef - .tlsdescauthcall undef + .tlsauthdesccall undef blraa x16, x0 .data diff --git a/lld/test/ELF/aarch64-reloc-pauth-undef-weak.s b/lld/test/ELF/aarch64-reloc-pauth-undef-weak.s index 276a04957f730..3dce1ee1bca6c 100644 --- a/lld/test/ELF/aarch64-reloc-pauth-undef-weak.s +++ b/lld/test/ELF/aarch64-reloc-pauth-undef-weak.s @@ -37,7 +37,7 @@ _start: adrp x0, :tlsdesc_auth:undef ldr x16, [x0, :tlsdesc_auth_lo12:undef] add x0, x0, :tlsdesc_auth_lo12:undef - .tlsdescauthcall undef + .tlsauthdesccall undef blraa x16, x0 .data diff --git a/lld/test/ELF/aarch64-tlsdesc-pauth.s b/lld/test/ELF/aarch64-tlsdesc-pauth.s index 41c7b31b5a7e6..ecfba88977987 100644 --- a/lld/test/ELF/aarch64-tlsdesc-pauth.s +++ b/lld/test/ELF/aarch64-tlsdesc-pauth.s @@ -27,7 +27,7 @@ a: adrp x0, :tlsdesc_auth:a ldr x16, [x0, :tlsdesc_auth_lo12:a] add x0, x0, :tlsdesc_auth_lo12:a - .tlsdescauthcall a + .tlsauthdesccall a blraa x16, x0 // CHECK: adrp x0, 0x[[P]]000 @@ -42,7 +42,7 @@ a: adrp x0, :tlsdesc_auth:local1 ldr x16, [x0, :tlsdesc_auth_lo12:local1] add x0, x0, :tlsdesc_auth_lo12:local1 - .tlsdescauthcall local1 + .tlsauthdesccall local1 blraa x16, x0 // CHECK: adrp x0, 0x[[P]]000 @@ -53,7 +53,7 @@ a: adrp x0, :tlsdesc_auth:local2 ldr x16, [x0, :tlsdesc_auth_lo12:local2] add x0, x0, :tlsdesc_auth_lo12:local2 - .tlsdescauthcall local2 + .tlsauthdesccall local2 blraa x16, x0 // CHECK: adrp x0, 0x[[P]]000 @@ -109,7 +109,7 @@ local2: adrp x0, :tlsdesc:a ldr x1, [x0, :tlsdesc_lo12:a] add x0, x0, :tlsdesc_lo12:a - .tlsdescauthcall a + .tlsauthdesccall a blr x1 //--- err2.s @@ -126,7 +126,7 @@ local2: adrp x0, :tlsdesc_auth:a ldr x16, [x0, :tlsdesc_auth_lo12:a] add x0, x0, :tlsdesc_auth_lo12:a - .tlsdescauthcall a + .tlsauthdesccall a blraa x16, x0 //--- err3.s >From 957c1f69096fd3c47328ab505d22ac22bf73c79a Mon Sep 17 00:00:00 2001 From: Daniil Kovalev <[email protected]> Date: Mon, 10 Aug 2026 18:44:09 +0300 Subject: [PATCH 3/3] Address review comments --- lld/ELF/Relocations.cpp | 3 +- .../ELF/aarch64-reloc-pauth-undef-weak-dso.s | 70 +++++++++++++------ .../ELF/aarch64-reloc-pauth-undef-weak-pie.s | 4 +- lld/test/ELF/aarch64-reloc-pauth-undef-weak.s | 4 +- 4 files changed, 55 insertions(+), 26 deletions(-) diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 7cd908fe71ad7..fb406bd05d7ac 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -795,10 +795,9 @@ static void addGotAuthEntry(Ctx &ctx, Symbol &sym) { // Signed GOT requires dynamic relocation unless the symbol is // non-preemptible and undefined weak. - if (!sym.isUndefWeak()) { + if (!sym.isUndefWeak()) ctx.in.relaDyn->addReloc( {R_AARCH64_AUTH_RELATIVE, ctx.in.got.get(), off, false, sym, 0, R_ABS}); - } } static void addTpOffsetGotEntry(Ctx &ctx, Symbol &sym) { diff --git a/lld/test/ELF/aarch64-reloc-pauth-undef-weak-dso.s b/lld/test/ELF/aarch64-reloc-pauth-undef-weak-dso.s index 5e771baf947f3..553d4aff589b8 100644 --- a/lld/test/ELF/aarch64-reloc-pauth-undef-weak-dso.s +++ b/lld/test/ELF/aarch64-reloc-pauth-undef-weak-dso.s @@ -6,43 +6,73 @@ # RUN: llvm-readelf -x.got %t | FileCheck %s --check-prefix=GOT # RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s --check-prefix=DIS -## Verify that R_AARCH64_AUTH_ABS64 against a weak undefined symbol is resolved -## to NULL (plus addend). +## Verify that R_AARCH64_AUTH_ABS64 against a weak non-preemptible +## undefined symbol is resolved to NULL (plus addend). # RELA-LABEL: Relocations [ +# RELA-NEXT: Section (5) .rela.dyn { +# RELA-NEXT: 0x20400 R_AARCH64_AUTH_GLOB_DAT preempt 0x0 +# RELA-NEXT: 0x20408 R_AARCH64_AUTH_TLSDESC preempt 0x0 +# RELA-NEXT: 0x30438 R_AARCH64_AUTH_ABS64 preempt 0x0 +# RELA-NEXT: 0x30440 R_AARCH64_AUTH_ABS64 preempt 0x25 +# RELA-NEXT: 0x30448 R_AARCH64_ABS64 preempt 0x0 +# RELA-NEXT: 0x30450 R_AARCH64_ABS64 preempt 0x25 +# RELA-NEXT: } # RELA-NEXT: ] # DATA-LABEL: Hex dump of section '.data': -# DATA-NEXT: 0x00030300 00000000 00000000 25000000 00000000 -# DATA-NEXT: 0x00030310 00000000 00000000 25000000 00000000 +# DATA-NEXT: 0x00030418 00000000 00000000 25000000 00000000 +# DATA-NEXT: 0x00030428 00000000 00000000 25000000 00000000 +# DATA-NEXT: 0x00030438 00000000 2a000020 00000000 2a000020 +# DATA-NEXT: 0x00030448 00000000 00000000 00000000 00000000 # GOT-LABEL: Hex dump of section '.got': -# GOT-NEXT: 0x000202f8 00000000 00000000 +# GOT-NEXT: 0x000203f8 00000000 00000000 00000000 000000a0 +# GOT-NEXT: 0x00020408 00000000 00000080 00000000 000000a0 # DIS-LABEL: <_start>: # DIS-NEXT: adrp x0, 0x20000 -# DIS-NEXT: ldr x0, [x0, #0x2f8] -# DIS-NEXT: mrs x0, TPIDR_EL0 -# DIS-NEXT: neg x0, x0 +# DIS-NEXT: ldr x0, [x0, #0x3f8] +# DIS-NEXT: mrs x0, TPIDR_EL0 +# DIS-NEXT: neg x0, x0 # DIS-NEXT: nop # DIS-NEXT: nop +# DIS-NEXT: adrp x0, 0x20000 +# DIS-NEXT: ldr x0, [x0, #0x400] +# DIS-NEXT: adrp x0, 0x20000 +# DIS-NEXT: ldr x16, [x0, #0x408] +# DIS-NEXT: add x0, x0, #0x408 +# DIS-NEXT: blraa x16, x0 -.weak undef -.hidden undef +.weak nonpreempt +.hidden nonpreempt + +.weak preempt .globl _start _start: - adrp x0, :got_auth:undef - ldr x0, [x0, :got_auth_lo12:undef] - adrp x0, :tlsdesc_auth:undef - ldr x16, [x0, :tlsdesc_auth_lo12:undef] - add x0, x0, :tlsdesc_auth_lo12:undef - .tlsauthdesccall undef + adrp x0, :got_auth:nonpreempt + ldr x0, [x0, :got_auth_lo12:nonpreempt] + adrp x0, :tlsdesc_auth:nonpreempt + ldr x16, [x0, :tlsdesc_auth_lo12:nonpreempt] + add x0, x0, :tlsdesc_auth_lo12:nonpreempt + .tlsauthdesccall nonpreempt + blraa x16, x0 + adrp x0, :got_auth:preempt + ldr x0, [x0, :got_auth_lo12:preempt] + adrp x0, :tlsdesc_auth:preempt + ldr x16, [x0, :tlsdesc_auth_lo12:preempt] + add x0, x0, :tlsdesc_auth_lo12:preempt + .tlsauthdesccall preempt blraa x16, x0 .data foo: -.quad undef@AUTH(da,42) -.quad (undef + 37)@AUTH(da,42) -.quad undef -.quad (undef + 37) +.quad nonpreempt@AUTH(da,42) +.quad (nonpreempt + 37)@AUTH(da,42) +.quad nonpreempt +.quad (nonpreempt + 37) +.quad preempt@AUTH(da,42) +.quad (preempt + 37)@AUTH(da,42) +.quad preempt +.quad (preempt + 37) diff --git a/lld/test/ELF/aarch64-reloc-pauth-undef-weak-pie.s b/lld/test/ELF/aarch64-reloc-pauth-undef-weak-pie.s index e612e9ec68ecb..c698aa30c70ad 100644 --- a/lld/test/ELF/aarch64-reloc-pauth-undef-weak-pie.s +++ b/lld/test/ELF/aarch64-reloc-pauth-undef-weak-pie.s @@ -6,8 +6,8 @@ # RUN: llvm-readelf -x.got %t | FileCheck %s --check-prefix=GOT # RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s --check-prefix=DIS -## Verify that R_AARCH64_AUTH_ABS64 against a weak undefined symbol is resolved -## to NULL (plus addend). +## Verify that R_AARCH64_AUTH_ABS64 against a weak non-preemptible +## undefined symbol is resolved to NULL (plus addend). # RELA-LABEL: Relocations [ # RELA-NEXT: ] diff --git a/lld/test/ELF/aarch64-reloc-pauth-undef-weak.s b/lld/test/ELF/aarch64-reloc-pauth-undef-weak.s index 3dce1ee1bca6c..350da8df6bd92 100644 --- a/lld/test/ELF/aarch64-reloc-pauth-undef-weak.s +++ b/lld/test/ELF/aarch64-reloc-pauth-undef-weak.s @@ -6,8 +6,8 @@ # RUN: llvm-readelf -x.got %t | FileCheck %s --check-prefix=GOT # RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s --check-prefix=DIS -## Verify that R_AARCH64_AUTH_ABS64 against a weak undefined symbol is resolved -## to NULL (plus addend). +## Verify that R_AARCH64_AUTH_ABS64 against a weak non-preemptible +## undefined symbol is resolved to NULL (plus addend). # RELA-LABEL: Relocations [ # RELA-NEXT: ] _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
