[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