Skip to content

Commit 6ea4a7a

Browse files
xguptazwu-2025
authored andcommitted
[AArch64] Support TLS variables in debug info (llvm#146572)
This adds an implementation of getDebugThreadLocalSymbol for AArch64 by using AArch::S_DTPREL. Fixes llvm#83466
1 parent 464ab62 commit 6ea4a7a

4 files changed

Lines changed: 49 additions & 9 deletions

File tree

‎llvm/docs/ReleaseNotes.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ Changes to the AArch64 Backend
128128

129129
* The `sysp`, `mrrs`, and `msrr` instructions are now accepted without
130130
requiring the `+d128` feature gating.
131+
* Added a new internal option `-aarch64-emit-debug-tls-location` to allow the
132+
emission of `DW_AT_location` for thread-local variables. This is currently
133+
disabled by default to maintain compatibility with Binutils and LLVM older
134+
toolchains that do not define the `R_AARCH64_TLS_DTPREL64` static relocation
135+
type for TLS offsets.
131136

132137
Changes to the AMDGPU Backend
133138
-----------------------------

‎llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,17 @@
2222
using namespace llvm;
2323
using namespace dwarf;
2424

25+
static cl::opt<bool> EmitAArch64DebugTLSLocation(
26+
"aarch64-emit-debug-tls-location",
27+
cl::desc("Emit the TLS DWARF location with DTPREL relocation for AArch64"),
28+
cl::Hidden);
29+
2530
void AArch64_ELFTargetObjectFile::Initialize(MCContext &Ctx,
2631
const TargetMachine &TM) {
2732
TargetLoweringObjectFileELF::Initialize(Ctx, TM);
2833
PLTPCRelativeSpecifier = AArch64::S_PLT;
2934
SupportIndirectSymViaGOTPCRel = true;
30-
31-
// AARCH64 ELF ABI does not define static relocation type for TLS offset
32-
// within a module. Do not generate AT_location for TLS variables.
33-
SupportDebugThreadLocalLocation = false;
35+
SupportDebugThreadLocalLocation = EmitAArch64DebugTLSLocation;
3436

3537
// Make sure the implicitly created empty .text section has the
3638
// SHF_AARCH64_PURECODE flag set if the "+execute-only" target feature is
@@ -187,3 +189,8 @@ MCSection *AArch64_ELFTargetObjectFile::SelectSectionForGlobal(
187189

188190
return TargetLoweringObjectFileELF::SelectSectionForGlobal(GO, Kind, TM);
189191
}
192+
193+
const MCExpr *AArch64_ELFTargetObjectFile::getDebugThreadLocalSymbol(
194+
const MCSymbol *Sym) const {
195+
return MCSpecifierExpr::create(Sym, AArch64::S_DTPREL, getContext());
196+
}

‎llvm/lib/Target/AArch64/AArch64TargetObjectFile.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ class AArch64_ELFTargetObjectFile : public TargetLoweringObjectFileELF {
4040

4141
MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
4242
const TargetMachine &TM) const override;
43+
44+
/// Describe a TLS variable address within debug info.
45+
const MCExpr *getDebugThreadLocalSymbol(const MCSymbol *Sym) const override;
4346
};
4447

4548
/// AArch64_MachoTargetObjectFile - This TLOF implementation is used for Darwin.

‎llvm/test/DebugInfo/AArch64/tls-at-location.ll‎

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,33 @@
1-
; RUN: llc -filetype=obj -mtriple=aarch64--linux-gnu -o - %s | llvm-dwarfdump -v - | FileCheck %s
2-
;
3-
; CHECK: .debug_info contents:
4-
; CHECK: DW_TAG_variable
5-
; CHECK-NOT: DW_AT_location
1+
; RUN: llc -O0 -mtriple=aarch64 --aarch64-emit-debug-tls-location -filetype=obj < %s \
2+
; RUN: | llvm-dwarfdump - | FileCheck %s --check-prefix=TLS
3+
4+
; RUN: llc -O0 -mtriple=aarch64 --aarch64-emit-debug-tls-location=false -filetype=obj < %s \
5+
; RUN: | llvm-dwarfdump - | FileCheck %s --check-prefix=NO-TLS
6+
7+
; RUN: llc -O0 -mtriple=aarch64 -filetype=obj < %s \
8+
; RUN: | llvm-dwarfdump - | FileCheck %s --check-prefix=NO-TLS
9+
10+
; RUN: llc -O0 -mtriple=aarch64 --aarch64-emit-debug-tls-location -filetype=obj < %s -o %t
11+
; RUN: llvm-objdump -r %t | FileCheck %s --check-prefix=OBJDUMP
12+
; RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=RELOC
13+
14+
; TLS: .debug_info contents:
15+
; TLS: DW_TAG_variable
16+
; TLS-NEXT: DW_AT_name ("var")
17+
; TLS-NEXT: DW_AT_type (0x{{.*}} "int")
18+
; TLS-NEXT: DW_AT_external (true)
19+
; TLS-NEXT: DW_AT_decl_file ("{{.*}}tls-at-location.c")
20+
; TLS-NEXT: DW_AT_decl_line (1)
21+
; TLS-NEXT: DW_AT_location (DW_OP_const8u 0x0, DW_OP_GNU_push_tls_address)
22+
23+
; NO-TLS: .debug_info contents:
24+
; NO-TLS: DW_TAG_variable
25+
; NO-TLS-NEXT: DW_AT_name ("var")
26+
; NO-TLS-NOT: DW_AT_location
27+
28+
; OBJDUMP: R_AARCH64_TLS_DTPREL64 var
29+
30+
; RELOC: R_AARCH64_TLS_DTPREL64 {{0+}} var + 0
631

732
@var = thread_local global i32 0, align 4, !dbg !0
833

0 commit comments

Comments
 (0)