Skip to content

[PAC][ELF] Support R_AARCH64_AUTH_TLSDESC_CALL relocation#198327

Open
kovdan01 wants to merge 2 commits into
users/kovdan01/pauth-tlsdesc-call-relocfrom
users/kovdan01/llvm-support-auth-tlsdesc-call-rel
Open

[PAC][ELF] Support R_AARCH64_AUTH_TLSDESC_CALL relocation#198327
kovdan01 wants to merge 2 commits into
users/kovdan01/pauth-tlsdesc-call-relocfrom
users/kovdan01/llvm-support-auth-tlsdesc-call-rel

Conversation

@kovdan01
Copy link
Copy Markdown
Contributor

The R_AARCH64_AUTH_TLSDESC_CALL is introduced to allow linker relaxation of AUTH TLSDESC call sequences for non-preemptible undefined weak symbols.

The lld patch introducing the relaxation: #194636

Corresponding ARM docs PR: ARM-software/abi-aa#395

@MaskRay
Copy link
Copy Markdown
Member

MaskRay commented May 18, 2026

We need MC layer tests to show how .tlsdescauthcall directives generate relocations at specific offsets referencing specific symbols. The existing PAUTH tests don't seem to cover offsets or symbols.

@kovdan01
Copy link
Copy Markdown
Contributor Author

We need MC layer tests to show how .tlsdescauthcall directives generate relocations at specific offsets referencing specific symbols. The existing PAUTH tests don't seem to cover offsets or symbols.

@MaskRay Just to ensure that we are talking about the same thing - do you mean tests like the following? For non-auth tlsdesc, we have no other MC-level tests except this and directives-case_insensitive.s (which is already covered by this PR)

// TLS descriptor forms
adrp x8, :tlsdesc:var
ldr x7, [x6, :tlsdesc_lo12:var]
add x5, x4, #:tlsdesc_lo12:var
.tlsdesccall var
blr x3
// CHECK: adrp x8, :tlsdesc:var // encoding: [0x08'A',A,A,0x90'A']
// CHECK: // fixup A - offset: 0, value: :tlsdesc:var, kind: fixup_aarch64_pcrel_adrp_imm21
// CHECK: ldr x7, [x6, :tlsdesc_lo12:var] // encoding: [0xc7,0bAAAAAA00,0b01AAAAAA,0xf9]
// CHECK: // fixup A - offset: 0, value: :tlsdesc_lo12:var, kind: fixup_aarch64_ldst_imm12_scale8
// CHECK: add x5, x4, :tlsdesc_lo12:var // encoding: [0x85,0bAAAAAA00,0b00AAAAAA,0x91]
// CHECK: // fixup A - offset: 0, value: :tlsdesc_lo12:var, kind: fixup_aarch64_add_imm12
// CHECK: .tlsdesccall var // encoding: []
// CHECK-NEXT: // fixup A - offset: 0, value: var, relocation type: 569
// CHECK: blr x3 // encoding: [0x60,0x00,0x3f,0xd6]
// CHECK-ELF-NEXT: 0x104 R_AARCH64_TLSDESC_ADR_PAGE21 [[VARSYM]]
// CHECK-ELF-NEXT: 0x108 R_AARCH64_TLSDESC_LD64_LO12 [[VARSYM]]
// CHECK-ELF-NEXT: 0x10C R_AARCH64_TLSDESC_ADD_LO12 [[VARSYM]]
// CHECK-ELF-NEXT: 0x110 R_AARCH64_TLSDESC_CALL [[VARSYM]]

@kovdan01
Copy link
Copy Markdown
Contributor Author

We need MC layer tests to show how .tlsdescauthcall directives generate relocations at specific offsets referencing specific symbols. The existing PAUTH tests don't seem to cover offsets or symbols.

@MaskRay Please let me know if a7f0877 addresses your concern and if you have any other comments regarding this PR

@llvmorg-github-actions
Copy link
Copy Markdown

llvmorg-github-actions Bot commented May 21, 2026

@llvm/pr-subscribers-llvm-binary-utilities

@llvm/pr-subscribers-backend-aarch64

Author: Daniil Kovalev (kovdan01)

Changes

The R_AARCH64_AUTH_TLSDESC_CALL is introduced to allow linker relaxation of AUTH TLSDESC call sequences for non-preemptible undefined weak symbols.

The lld patch introducing the relaxation: #194636

Corresponding ARM docs PR: ARM-software/abi-aa#395


Full diff: https://github.com/llvm/llvm-project/pull/198327.diff

8 Files Affected:

  • (modified) llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def (+1)
  • (modified) llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp (+12-3)
  • (modified) llvm/lib/Target/AArch64/AArch64InstrInfo.td (+8)
  • (modified) llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp (+11-6)
  • (modified) llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp (+9)
  • (modified) llvm/test/CodeGen/AArch64/ptrauth-arm64-tls-dynamics.ll (+10-5)
  • (modified) llvm/test/MC/AArch64/directives-case_insensitive.s (+3)
  • (added) llvm/test/MC/AArch64/tls-auth-relocs.s (+36)
diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
index 1cfcdbf67dac5..c8e9e1cd4f644 100644
--- a/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
+++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
@@ -162,6 +162,7 @@ ELF_RELOC(R_AARCH64_AUTH_GOT_ADR_PREL_LO21,          0x252)
 ELF_RELOC(R_AARCH64_AUTH_TLSDESC_ADR_PAGE21,         0x253)
 ELF_RELOC(R_AARCH64_AUTH_TLSDESC_LD64_LO12,          0x254)
 ELF_RELOC(R_AARCH64_AUTH_TLSDESC_ADD_LO12,           0x255)
+ELF_RELOC(R_AARCH64_AUTH_TLSDESC_CALL,               0x256)
 ELF_RELOC(R_AARCH64_AUTH_RELATIVE,                   0x411)
 ELF_RELOC(R_AARCH64_AUTH_GLOB_DAT,                   0x412)
 ELF_RELOC(R_AARCH64_AUTH_TLSDESC,                    0x413)
diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index 4eb475ef606de..35eac377779f7 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -3438,13 +3438,15 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
     ///    adrp  x0, :tlsdesc_auth:var
     ///    ldr   x16, [x0, #:tlsdesc_auth_lo12:var]
     ///    add   x0, x0, #:tlsdesc_auth_lo12:var
+    ///    .tlsdescauthcall var
     ///    blraa x16, x0
     ///    (TPIDR_EL0 offset now in x0)
     const MachineOperand &MO_Sym = MI->getOperand(0);
     MachineOperand MO_TLSDESC_LO12(MO_Sym), MO_TLSDESC(MO_Sym);
-    MCOperand SymTLSDescLo12, SymTLSDesc;
+    MCOperand Sym, SymTLSDescLo12, SymTLSDesc;
     MO_TLSDESC_LO12.setTargetFlags(AArch64II::MO_TLS | AArch64II::MO_PAGEOFF);
     MO_TLSDESC.setTargetFlags(AArch64II::MO_TLS | AArch64II::MO_PAGE);
+    MCInstLowering.lowerOperand(MO_Sym, Sym);
     MCInstLowering.lowerOperand(MO_TLSDESC_LO12, SymTLSDescLo12);
     MCInstLowering.lowerOperand(MO_TLSDESC, SymTLSDesc);
 
@@ -3470,8 +3472,15 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
     Add.addOperand(MCOperand::createImm(AArch64_AM::getShiftValue(0)));
     EmitToStreamer(*OutStreamer, Add);
 
-    // Authenticated TLSDESC accesses are not relaxed.
-    // Thus, do not emit .tlsdesccall for AUTH TLSDESC.
+    // Emit a relocation-annotation. This expands to no code, but requests
+    // the following instruction gets an R_AARCH64_AUTH_TLSDESC_CALL.
+    MCInst TLSDescAuthCall;
+    TLSDescAuthCall.setOpcode(AArch64::TLSDESCAUTHCALL);
+    TLSDescAuthCall.addOperand(Sym);
+    EmitToStreamer(*OutStreamer, TLSDescAuthCall);
+#ifndef NDEBUG
+    --InstsEmitted; // no code emitted
+#endif
 
     MCInst Blraa;
     Blraa.setOpcode(AArch64::BLRAA);
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index a8ca9f0f39a53..72ca351f6a602 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -3683,6 +3683,14 @@ def TLSDESCCALL : Pseudo<(outs), (ins i64imm:$sym), []>, Sched<[]> {
   let AsmString = ".tlsdesccall $sym";
 }
 
+// This is a directive-like pseudo-instruction. The purpose is to insert an
+// R_AARCH64_AUTH_TLSDESC_CALL relocation at the offset of the following instruction
+// (which in the usual case is a BLRAA).
+let hasSideEffects = 1 in
+def TLSDESCAUTHCALL : Pseudo<(outs), (ins i64imm:$sym), []>, Sched<[]> {
+  let AsmString = ".tlsdescauthcall $sym";
+}
+
 // Pseudo instruction to tell the streamer to emit a 'B' character into the
 // augmentation string.
 def EMITBKEY : Pseudo<(outs), (ins), []>, Sched<[]> {}
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 6a6b73b8a4c88..f33d84db7ccec 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -191,7 +191,7 @@ class AArch64AsmParser : public MCTargetAsmParser {
   bool parseDirectiveCPU(SMLoc L);
   bool parseDirectiveInst(SMLoc L);
 
-  bool parseDirectiveTLSDescCall(SMLoc L);
+  bool parseDirectiveTLSDescCall(SMLoc L, bool IsAuth);
 
   bool parseDirectiveLOH(StringRef LOH, SMLoc L);
   bool parseDirectiveLtorg(SMLoc L);
@@ -7271,7 +7271,9 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
   else if (IDVal == ".cpu")
     parseDirectiveCPU(Loc);
   else if (IDVal == ".tlsdesccall")
-    parseDirectiveTLSDescCall(Loc);
+    parseDirectiveTLSDescCall(Loc, /*IsAuth=*/false);
+  else if (IDVal == ".tlsdescauthcall")
+    parseDirectiveTLSDescCall(Loc, /*IsAuth=*/true);
   else if (IDVal == ".ltorg" || IDVal == ".pool")
     parseDirectiveLtorg(Loc);
   else if (IDVal == ".unreq")
@@ -7594,8 +7596,9 @@ bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
 }
 
 // parseDirectiveTLSDescCall:
-//   ::= .tlsdesccall symbol
-bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
+//   ::= .tlsdesccall symbol (if IsAuth is false)
+//   ::= .tlsdescauthcall symbol (if IsAuth is true)
+bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L, bool IsAuth) {
   StringRef Name;
   if (check(getParser().parseIdentifier(Name), L, "expected symbol") ||
       parseToken(AsmToken::EndOfStatement))
@@ -7603,10 +7606,12 @@ bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
 
   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
   const MCExpr *Expr = MCSymbolRefExpr::create(Sym, getContext());
-  Expr = MCSpecifierExpr::create(Expr, AArch64::S_TLSDESC, getContext());
+  Expr = MCSpecifierExpr::create(
+      Expr, IsAuth ? AArch64::S_TLSDESC_AUTH : AArch64::S_TLSDESC,
+      getContext());
 
   MCInst Inst;
-  Inst.setOpcode(AArch64::TLSDESCCALL);
+  Inst.setOpcode(IsAuth ? AArch64::TLSDESCAUTHCALL : AArch64::TLSDESCCALL);
   Inst.addOperand(MCOperand::createExpr(Expr));
 
   getParser().getStreamer().emitInstruction(Inst, getSTI());
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
index 21ff55e9d9a7f..0183b826c1cb0 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
@@ -738,6 +738,15 @@ void AArch64MCCodeEmitter::encodeInstruction(const MCInst &MI,
     return;
   }
 
+  if (MI.getOpcode() == AArch64::TLSDESCAUTHCALL) {
+    // This is a directive which applies an R_AARCH64_AUTH_TLSDESC_CALL to the
+    // following (BLRAA) instruction. It doesn't emit any code itself so it
+    // doesn't go through the normal TableGenerated channels.
+    addFixup(Fixups, 0, MI.getOperand(0).getExpr(),
+             ELF::R_AARCH64_AUTH_TLSDESC_CALL);
+    return;
+  }
+
   if (MI.getOpcode() == AArch64::SPACE) {
     // SPACE just increases basic block size, in both cases no actual code.
     return;
diff --git a/llvm/test/CodeGen/AArch64/ptrauth-arm64-tls-dynamics.ll b/llvm/test/CodeGen/AArch64/ptrauth-arm64-tls-dynamics.ll
index 2d8085cf489b9..d6cbe9d50c2ba 100644
--- a/llvm/test/CodeGen/AArch64/ptrauth-arm64-tls-dynamics.ll
+++ b/llvm/test/CodeGen/AArch64/ptrauth-arm64-tls-dynamics.ll
@@ -16,6 +16,7 @@ define i32 @test_generaldynamic() {
 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc_auth:general_dynamic_var
 ; CHECK-NEXT: ldr x16, [x[[TLSDESC_HI]], :tlsdesc_auth_lo12:general_dynamic_var]
 ; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_auth_lo12:general_dynamic_var
+; CHECK-NEXT: .tlsdescauthcall general_dynamic_var
 ; CHECK-NEXT: blraa x16, x0
 ; CHECK-NEXT: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0
 ; CHECK-NEXT: ldr w0, [x[[TPIDR]], x0]
@@ -23,7 +24,7 @@ define i32 @test_generaldynamic() {
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_ADR_PAGE21
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_LD64_LO12
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_ADD_LO12
-; CHECK-OBJ-NOT: R_AARCH64_TLSDESC_CALL
+; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_CALL
 
 ; CHECK-ERR: LLVM ERROR: cannot select: %1:gpr64sp(p0) = G_GLOBAL_VALUE @general_dynamic_var (in function: test_generaldynamic)
 }
@@ -36,6 +37,7 @@ define ptr @test_generaldynamic_addr() {
 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc_auth:general_dynamic_var
 ; CHECK-NEXT: ldr x16, [x[[TLSDESC_HI]], :tlsdesc_auth_lo12:general_dynamic_var]
 ; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_auth_lo12:general_dynamic_var
+; CHECK-NEXT: .tlsdescauthcall general_dynamic_var
 ; CHECK-NEXT: blraa x16, x0
 ; CHECK-NEXT: mrs [[TP:x[0-9]+]], TPIDR_EL0
 ; CHECK-NEXT: add x0, [[TP]], x0
@@ -43,7 +45,7 @@ define ptr @test_generaldynamic_addr() {
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_ADR_PAGE21
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_LD64_LO12
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_ADD_LO12
-; CHECK-OBJ-NOT: R_AARCH64_TLSDESC_CALL
+; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_CALL
 }
 
 ;; Note: with signed TLSDESC, general dynamic model is always used,
@@ -60,6 +62,7 @@ define i32 @test_localdynamic() {
 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc_auth:local_dynamic_var
 ; CHECK-NEXT: ldr x16, [x[[TLSDESC_HI]], :tlsdesc_auth_lo12:local_dynamic_var]
 ; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_auth_lo12:local_dynamic_var
+; CHECK-NEXT: .tlsdescauthcall local_dynamic_var
 ; CHECK-NEXT: blraa x16, x0
 ; CHECK-NEXT: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0
 ; CHECK-NEXT: ldr w0, [x[[TPIDR]], x0]
@@ -67,7 +70,7 @@ define i32 @test_localdynamic() {
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_ADR_PAGE21
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_LD64_LO12
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_ADD_LO12
-; CHECK-OBJ-NOT: R_AARCH64_TLSDESC_CALL
+; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_CALL
 }
 
 define ptr @test_localdynamic_addr() {
@@ -78,6 +81,7 @@ define ptr @test_localdynamic_addr() {
 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc_auth:local_dynamic_var
 ; CHECK-NEXT: ldr x16, [x[[TLSDESC_HI]], :tlsdesc_auth_lo12:local_dynamic_var]
 ; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_auth_lo12:local_dynamic_var
+; CHECK-NEXT: .tlsdescauthcall local_dynamic_var
 ; CHECK-NEXT: blraa x16, x0
 ; CHECK-NEXT: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0
 ; CHECK-NEXT: add x0, x[[TPIDR]], x0
@@ -85,7 +89,7 @@ define ptr @test_localdynamic_addr() {
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_ADR_PAGE21
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_LD64_LO12
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_ADD_LO12
-; CHECK-OBJ-NOT: R_AARCH64_TLSDESC_CALL
+; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_CALL
 }
 
 @extern_weak_var = extern_weak thread_local global i32
@@ -99,6 +103,7 @@ define i32 @test_extern_weak() {
 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc_auth:extern_weak_var
 ; CHECK-NEXT: ldr x16, [x[[TLSDESC_HI]], :tlsdesc_auth_lo12:extern_weak_var]
 ; CHECK-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_auth_lo12:extern_weak_var
+; CHECK-NEXT: .tlsdescauthcall extern_weak_var
 ; CHECK-NEXT: blraa x16, x0
 ; CHECK-NEXT: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0
 ; CHECK-NEXT: ldr w0, [x[[TPIDR]], x0]
@@ -106,7 +111,7 @@ define i32 @test_extern_weak() {
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_ADR_PAGE21
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_LD64_LO12
 ; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_ADD_LO12
-; CHECK-OBJ-NOT: R_AARCH64_TLSDESC_CALL
+; CHECK-OBJ: R_AARCH64_AUTH_TLSDESC_CALL
 ; CHECK-OBJ: 0000000000000000     0 TLS     WEAK   DEFAULT   UND extern_weak_var
 }
 
diff --git a/llvm/test/MC/AArch64/directives-case_insensitive.s b/llvm/test/MC/AArch64/directives-case_insensitive.s
index c2bdec73e349e..d653d35858d17 100644
--- a/llvm/test/MC/AArch64/directives-case_insensitive.s
+++ b/llvm/test/MC/AArch64/directives-case_insensitive.s
@@ -44,5 +44,8 @@ fred .REQ x5
 .TLSDESCCALL var
 // CHECK: .tlsdesccall var
 
+.TLSDESCAUTHCALL var
+// CHECK: .tlsdescauthcall var
+
 .LTORG
 .POOL
diff --git a/llvm/test/MC/AArch64/tls-auth-relocs.s b/llvm/test/MC/AArch64/tls-auth-relocs.s
new file mode 100644
index 0000000000000..500564661ddef
--- /dev/null
+++ b/llvm/test/MC/AArch64/tls-auth-relocs.s
@@ -0,0 +1,36 @@
+// RUN: llvm-mc -triple=aarch64-none-linux-gnu -mattr=+pauth -show-encoding < %s | FileCheck %s
+// RUN: llvm-mc -triple=aarch64-none-linux-gnu -mattr=+pauth -filetype=obj < %s -o - | \
+// RUN:   llvm-readobj -r --symbols - | FileCheck --check-prefix=CHECK-ELF %s
+
+        adrp x8, :tlsdesc_auth:var
+        ldr x7, [x6, :tlsdesc_auth_lo12:var]
+        add x5, x4, #:tlsdesc_auth_lo12:var
+        .tlsdescauthcall var
+        blraa x3, x2
+
+// CHECK:      adrp   x8, :tlsdesc_auth:var            // encoding: [0x08'A',A,A,0x90'A']
+// CHECK-NEXT:                                         // fixup A - offset: 0, value: :tlsdesc_auth:var, kind: fixup_aarch64_pcrel_adrp_imm21
+// CHECK:      ldr    x7, [x6, :tlsdesc_auth_lo12:var] // encoding: [0xc7,0bAAAAAA00,0b01AAAAAA,0xf9]
+// CHECK-NEXT:                                         // fixup A - offset: 0, value: :tlsdesc_auth_lo12:var, kind: fixup_aarch64_ldst_imm12_scale8
+// CHECK:      add    x5, x4, :tlsdesc_auth_lo12:var   // encoding: [0x85,0bAAAAAA00,0b00AAAAAA,0x91]
+// CHECK-NEXT:                                         // fixup A - offset: 0, value: :tlsdesc_auth_lo12:var, kind: fixup_aarch64_add_imm12
+// CHECK:      .tlsdescauthcall var                    // encoding: []
+// CHECK-NEXT:                                         // fixup A - offset: 0, value: var, relocation type: 598
+// CHECK:      blraa  x3, x2                           // encoding: [0x62,0x08,0x3f,0xd7]
+
+// CHECK-ELF:      Relocations [
+// CHECK-ELF-NEXT:   Section {{.*}} .rela.text {
+// CHECK-ELF-NEXT:     0x0 R_AARCH64_AUTH_TLSDESC_ADR_PAGE21 [[VARSYM:[^ ]+]]
+// CHECK-ELF-NEXT:     0x4 R_AARCH64_AUTH_TLSDESC_LD64_LO12 [[VARSYM]]
+// CHECK-ELF-NEXT:     0x8 R_AARCH64_AUTH_TLSDESC_ADD_LO12 [[VARSYM]]
+// CHECK-ELF-NEXT:     0xC R_AARCH64_AUTH_TLSDESC_CALL [[VARSYM]]
+
+// Make sure symbol has type STT_TLS:
+
+// CHECK-ELF:      Symbols [
+// CHECK-ELF:        Symbol {
+// CHECK-ELF:          Name: var
+// CHECK-ELF-NEXT:     Value:
+// CHECK-ELF-NEXT:     Size:
+// CHECK-ELF-NEXT:     Binding: Global
+// CHECK-ELF-NEXT:     Type: TLS

@kovdan01 kovdan01 marked this pull request as draft May 25, 2026 09:33
@kovdan01 kovdan01 changed the base branch from main to users/kovdan01/lld-pauth-undef-weak May 25, 2026 09:37
@kovdan01 kovdan01 force-pushed the users/kovdan01/llvm-support-auth-tlsdesc-call-rel branch from a7f0877 to 9f74ecb Compare May 25, 2026 09:37
@kovdan01 kovdan01 changed the base branch from users/kovdan01/lld-pauth-undef-weak to users/kovdan01/pauth-tlsdesc-call-reloc May 25, 2026 10:42
kovdan01 added 2 commits May 25, 2026 13:43
The R_AARCH64_AUTH_TLSDESC_CALL is introduced to allow linker relaxation of
AUTH TLSDESC call sequences for non-preemptible undefined weak symbols.

The lld patch introducing the relaxation: #194636

Corresponding ARM docs PR: ARM-software/abi-aa#395
@kovdan01 kovdan01 force-pushed the users/kovdan01/llvm-support-auth-tlsdesc-call-rel branch from 9f74ecb to 728f4a1 Compare May 25, 2026 10:44
@kovdan01 kovdan01 marked this pull request as ready for review June 2, 2026 08:42
@kovdan01
Copy link
Copy Markdown
Contributor Author

kovdan01 commented Jun 2, 2026

@MaskRay @smithp35 @jrtc27 I would appreciate your feedback on this

@jrtc27
Copy link
Copy Markdown
Contributor

jrtc27 commented Jun 2, 2026

I thought we were still discussing things on the spec side?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

3 participants