[llvm-branch-commits] [llvm] release/23.x: [ARM] Exclude TLS symbols from the .reloc/R_ARM_REL32 path (#212549) (PR #212735)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Jul 29 03:54:05 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-arm
Author: llvmbot
<details>
<summary>Changes</summary>
Backport f4382be
Requested by: @<!-- -->dongjianqiang2
---
Full diff: https://github.com/llvm/llvm-project/pull/212735.diff
2 Files Affected:
- (modified) llvm/lib/Target/ARM/ARMAsmPrinter.cpp (+5-4)
- (modified) llvm/test/CodeGen/ARM/elf-preemption.ll (+35)
``````````diff
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
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/212735
More information about the llvm-branch-commits
mailing list