[llvm] 8e20a6d - [AArch64] Support TLS variables in debug info (#146572)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 30 20:20:48 PDT 2026
Author: Shivam Gupta
Date: 2026-03-31T08:50:43+05:30
New Revision: 8e20a6dc866c54683f801d1ca041c6b3ba302485
URL: https://github.com/llvm/llvm-project/commit/8e20a6dc866c54683f801d1ca041c6b3ba302485
DIFF: https://github.com/llvm/llvm-project/commit/8e20a6dc866c54683f801d1ca041c6b3ba302485.diff
LOG: [AArch64] Support TLS variables in debug info (#146572)
This adds an implementation of getDebugThreadLocalSymbol for AArch64 by
using AArch::S_DTPREL.
Fixes #83466
Added:
Modified:
llvm/docs/ReleaseNotes.md
llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
llvm/lib/Target/AArch64/AArch64TargetObjectFile.h
llvm/test/DebugInfo/AArch64/tls-at-location.ll
Removed:
################################################################################
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index fbf47b9789b09..9462510fc8d9e 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -128,6 +128,11 @@ Changes to the AArch64 Backend
* The `sysp`, `mrrs`, and `msrr` instructions are now accepted without
requiring the `+d128` feature gating.
+* Added a new internal option `-aarch64-emit-debug-tls-location` to allow the
+ emission of `DW_AT_location` for thread-local variables. This is currently
+ disabled by default to maintain compatibility with Binutils and LLVM older
+ toolchains that do not define the `R_AARCH64_TLS_DTPREL64` static relocation
+ type for TLS offsets.
Changes to the AMDGPU Backend
-----------------------------
diff --git a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
index 886f41975e199..9debe57634ff3 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
@@ -22,15 +22,17 @@
using namespace llvm;
using namespace dwarf;
+static cl::opt<bool> EmitAArch64DebugTLSLocation(
+ "aarch64-emit-debug-tls-location",
+ cl::desc("Emit the TLS DWARF location with DTPREL relocation for AArch64"),
+ cl::Hidden);
+
void AArch64_ELFTargetObjectFile::Initialize(MCContext &Ctx,
const TargetMachine &TM) {
TargetLoweringObjectFileELF::Initialize(Ctx, TM);
PLTPCRelativeSpecifier = AArch64::S_PLT;
SupportIndirectSymViaGOTPCRel = true;
-
- // AARCH64 ELF ABI does not define static relocation type for TLS offset
- // within a module. Do not generate AT_location for TLS variables.
- SupportDebugThreadLocalLocation = false;
+ SupportDebugThreadLocalLocation = EmitAArch64DebugTLSLocation;
// Make sure the implicitly created empty .text section has the
// SHF_AARCH64_PURECODE flag set if the "+execute-only" target feature is
@@ -187,3 +189,8 @@ MCSection *AArch64_ELFTargetObjectFile::SelectSectionForGlobal(
return TargetLoweringObjectFileELF::SelectSectionForGlobal(GO, Kind, TM);
}
+
+const MCExpr *AArch64_ELFTargetObjectFile::getDebugThreadLocalSymbol(
+ const MCSymbol *Sym) const {
+ return MCSpecifierExpr::create(Sym, AArch64::S_DTPREL, getContext());
+}
diff --git a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h
index 6b3381452c70b..78c0c22da8d1b 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h
+++ b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h
@@ -40,6 +40,9 @@ class AArch64_ELFTargetObjectFile : public TargetLoweringObjectFileELF {
MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
const TargetMachine &TM) const override;
+
+ /// Describe a TLS variable address within debug info.
+ const MCExpr *getDebugThreadLocalSymbol(const MCSymbol *Sym) const override;
};
/// AArch64_MachoTargetObjectFile - This TLOF implementation is used for Darwin.
diff --git a/llvm/test/DebugInfo/AArch64/tls-at-location.ll b/llvm/test/DebugInfo/AArch64/tls-at-location.ll
index 20a0afb789771..97c69996945b1 100644
--- a/llvm/test/DebugInfo/AArch64/tls-at-location.ll
+++ b/llvm/test/DebugInfo/AArch64/tls-at-location.ll
@@ -1,8 +1,33 @@
-; RUN: llc -filetype=obj -mtriple=aarch64--linux-gnu -o - %s | llvm-dwarfdump -v - | FileCheck %s
-;
-; CHECK: .debug_info contents:
-; CHECK: DW_TAG_variable
-; CHECK-NOT: DW_AT_location
+; RUN: llc -O0 -mtriple=aarch64 --aarch64-emit-debug-tls-location -filetype=obj < %s \
+; RUN: | llvm-dwarfdump - | FileCheck %s --check-prefix=TLS
+
+; RUN: llc -O0 -mtriple=aarch64 --aarch64-emit-debug-tls-location=false -filetype=obj < %s \
+; RUN: | llvm-dwarfdump - | FileCheck %s --check-prefix=NO-TLS
+
+; RUN: llc -O0 -mtriple=aarch64 -filetype=obj < %s \
+; RUN: | llvm-dwarfdump - | FileCheck %s --check-prefix=NO-TLS
+
+; RUN: llc -O0 -mtriple=aarch64 --aarch64-emit-debug-tls-location -filetype=obj < %s -o %t
+; RUN: llvm-objdump -r %t | FileCheck %s --check-prefix=OBJDUMP
+; RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=RELOC
+
+; TLS: .debug_info contents:
+; TLS: DW_TAG_variable
+; TLS-NEXT: DW_AT_name ("var")
+; TLS-NEXT: DW_AT_type (0x{{.*}} "int")
+; TLS-NEXT: DW_AT_external (true)
+; TLS-NEXT: DW_AT_decl_file ("{{.*}}tls-at-location.c")
+; TLS-NEXT: DW_AT_decl_line (1)
+; TLS-NEXT: DW_AT_location (DW_OP_const8u 0x0, DW_OP_GNU_push_tls_address)
+
+; NO-TLS: .debug_info contents:
+; NO-TLS: DW_TAG_variable
+; NO-TLS-NEXT: DW_AT_name ("var")
+; NO-TLS-NOT: DW_AT_location
+
+; OBJDUMP: R_AARCH64_TLS_DTPREL64 var
+
+; RELOC: R_AARCH64_TLS_DTPREL64 {{0+}} var + 0
@var = thread_local global i32 0, align 4, !dbg !0
More information about the llvm-commits
mailing list