[llvm] f4382be - [ARM] Exclude TLS symbols from the .reloc/R_ARM_REL32 path (#212549)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 28 23:16:42 PDT 2026
Author: dong jianqiang
Date: 2026-07-29T14:16:37+08:00
New Revision: f4382bedc245a22ea7c354d08eb13543166a5f0d
URL: https://github.com/llvm/llvm-project/commit/f4382bedc245a22ea7c354d08eb13543166a5f0d
DIFF: https://github.com/llvm/llvm-project/commit/f4382bedc245a22ea7c354d08eb13543166a5f0d.diff
LOG: [ARM] Exclude TLS symbols from the .reloc/R_ARM_REL32 path (#212549)
The .reloc branch in emitMachineConstantPoolValue fired for any
isWeakForLinker() + isDSOLocal() symbol, including TLS (thread_local)
weak symbols. R_ARM_REL32 is wrong for TLS: TLS symbols need
TLS-specific relocations (R_ARM_TLS_GD32 etc.). Using R_ARM_REL32 for a
TLS symbol produces a wrong address at runtime.
This broke the 2-stage ARM 32-bit buildbots: stage 1 (with the .reloc
branch) miscompiled stage 2's BPF codegen (BTFDebug.cpp references
llvm::sys::sandbox::Enabled, an inline thread_local weak variable),
causing a SIGSEGV in the BPF Assembly Printer.
Add a regression test (tls_weak_var in elf-preemption.ll) verifying that
TLS weak symbols get TLSGD/TPOFF, not R_ARM_REL32.
Fix #212545
Added:
Modified:
llvm/lib/Target/ARM/ARMAsmPrinter.cpp
llvm/test/CodeGen/ARM/elf-preemption.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
index 49c5c983e2934..b067c1e60c4b2 100644
--- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
+++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
@@ -1023,10 +1023,11 @@ void ARMAsmPrinter::emitMachineConstantPoolValue(
// a weak definition with a non-weak definition from another section. Use a
// .reloc directive rather than a fixup to force the generation of a
// relocation (R_ARM_REL32) so the linker can perform the override. This is
- // restricted to dso_local symbols: a preemptible/external weak symbol
- // (e.g. an extern_weak reference) must use the GOT, as R_ARM_REL32 against
- // an external symbol cannot be used when making a shared object.
- if (GV->isWeakForLinker() && GV->isDSOLocal() &&
+ // restricted to dso_local, non-TLS symbols: a preemptible/external weak
+ // symbol (e.g. an extern_weak reference) must use the GOT, as R_ARM_REL32
+ // against an external symbol cannot be used when making a shared object;
+ // and TLS symbols require TLS-specific relocations, not R_ARM_REL32.
+ if (GV->isWeakForLinker() && GV->isDSOLocal() && !GV->isThreadLocal() &&
TM.getTargetTriple().isOSBinFormatELF() && TM.isPositionIndependent() &&
ACPV->getPCAdjustment() != 0) {
MCSymbol *CPILabel = OutContext.createTempSymbol();
diff --git a/llvm/test/CodeGen/ARM/elf-preemption.ll b/llvm/test/CodeGen/ARM/elf-preemption.ll
index 599a59520e5e3..aa8296b0c4902 100644
--- a/llvm/test/CodeGen/ARM/elf-preemption.ll
+++ b/llvm/test/CodeGen/ARM/elf-preemption.ll
@@ -291,3 +291,38 @@ define ptr @get_extern_weak_hidden_func() nounwind {
; PIC-NEXT: .long extern_weak_hidden_func(GOT_PREL)-(.LPC12_0+8-.Ltmp7)
ret ptr @extern_weak_hidden_func
}
+
+;; TLS weak symbols must not use the .reloc/R_ARM_REL32 path; they require
+;; TLS-specific relocations (R_ARM_TLS_GD32 etc.), not R_ARM_REL32. Using
+;; R_ARM_REL32 for a TLS symbol produces a wrong address and crashes at runtime.
+ at tls_weak_var = weak dso_local thread_local global i32 42
+define ptr @get_tls_weak_var() nounwind {
+; STATIC-LABEL: get_tls_weak_var:
+; STATIC: @ %bb.0:
+; STATIC-NEXT: .save {r11, lr}
+; STATIC-NEXT: push {r11, lr}
+; STATIC-NEXT: ldr r1, .LCPI13_0
+; STATIC-NEXT: bl __aeabi_read_tp
+; STATIC-NEXT: add r0, r0, r1
+; STATIC-NEXT: pop {r11, pc}
+; STATIC-NEXT: .p2align 2
+; STATIC-NEXT: @ %bb.1:
+; STATIC-NEXT: .LCPI13_0:
+; STATIC-NEXT: .long tls_weak_var(TPOFF)
+;
+; PIC-LABEL: get_tls_weak_var:
+; PIC: @ %bb.0:
+; PIC-NEXT: .save {r11, lr}
+; PIC-NEXT: push {r11, lr}
+; PIC-NEXT: ldr r0, .LCPI13_0
+; PIC-NEXT: .LPC13_0:
+; PIC-NEXT: add r0, pc, r0
+; PIC-NEXT: bl __tls_get_addr
+; PIC-NEXT: pop {r11, pc}
+; PIC-NEXT: .p2align 2
+; PIC-NEXT: @ %bb.1:
+; PIC-NEXT: .LCPI13_0:
+; PIC-NEXT: .Ltmp8:
+; PIC-NEXT: .long tls_weak_var(TLSGD)-(.LPC13_0+8-.Ltmp8)
+ ret ptr @tls_weak_var
+}
More information about the llvm-commits
mailing list