[lld] 63f4d28 - [ELF] Fix data race when handleTlsIe adds a RELATIVE relocation (#208956)

via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 11 14:39:42 PDT 2026


Author: Fangrui Song
Date: 2026-07-11T14:39:37-07:00
New Revision: 63f4d28adf0af9f275f6c09450d5a48d451b59b1

URL: https://github.com/llvm/llvm-project/commit/63f4d28adf0af9f275f6c09450d5a48d451b59b1
DIFF: https://github.com/llvm/llvm-project/commit/63f4d28adf0af9f275f6c09450d5a48d451b59b1.diff

LOG: [ELF] Fix data race when handleTlsIe adds a RELATIVE relocation (#208956)

The ieExpr == R_GOT PIC case (e.g. R_386_TLS_IE in -shared links) calls
the unsynchronized addRelativeReloc from concurrent scanSectionImpl
tasks, racing on relaDyn->relativeRelocs. Use the sharded variant like
processAux. Split i386-tls-ie-shared.s into two input files so that a
ThreadSanitizer build detects the race.

Added: 
    

Modified: 
    lld/ELF/RelocScan.h
    lld/test/ELF/i386-tls-ie-shared.s

Removed: 
    


################################################################################
diff  --git a/lld/ELF/RelocScan.h b/lld/ELF/RelocScan.h
index 526482a156ccc..c0292d35517fa 100644
--- a/lld/ELF/RelocScan.h
+++ b/lld/ELF/RelocScan.h
@@ -113,8 +113,8 @@ class RelocScan {
       // PIC when the relocation uses the full address (not just low page bits).
       if (ieExpr == R_GOT && ctx.arg.isPic &&
           !ctx.target->usesOnlyLowPageBits(type))
-        ctx.in.relaDyn->addRelativeReloc(ctx.target->relativeRel, *sec, offset,
-                                         sym, addend, type, ieExpr);
+        ctx.in.relaDyn->addRelativeReloc<true>(
+            ctx.target->relativeRel, *sec, offset, sym, addend, type, ieExpr);
       else
         sec->addReloc({ieExpr, type, offset, addend, &sym});
     }

diff  --git a/lld/test/ELF/i386-tls-ie-shared.s b/lld/test/ELF/i386-tls-ie-shared.s
index 2e837d068a9e2..f14ce84f4e9e3 100644
--- a/lld/test/ELF/i386-tls-ie-shared.s
+++ b/lld/test/ELF/i386-tls-ie-shared.s
@@ -1,68 +1,58 @@
-// REQUIRES: x86
-// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
-// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %p/Inputs/tls-opt-iele-i686-nopic.s -o %tso.o
-// RUN: ld.lld -shared -soname=t.so %tso.o -o %tso
-// RUN: ld.lld -shared %t.o %tso -o %t1
-// RUN: llvm-readobj -S -r -d %t1 | FileCheck --check-prefix=GOTRELSHARED %s
-// RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn %t1 | FileCheck --check-prefix=DISASMSHARED %s
+# REQUIRES: x86
+## R_386_TLS_IE in a -shared link need R_386_RELATIVE dynamic relocations and GOT slots need R_386_TLS_TPOFF.
+## Two input files test ensure there is no race caught by ThreadSanitizer.
 
-// GOTRELSHARED:     Section {
-// GOTRELSHARED:      Name: .got
-// GOTRELSHARED-NEXT:   Type: SHT_PROGBITS
-// GOTRELSHARED-NEXT:   Flags [
-// GOTRELSHARED-NEXT:     SHF_ALLOC
-// GOTRELSHARED-NEXT:     SHF_WRITE
-// GOTRELSHARED-NEXT:   ]
-// GOTRELSHARED-NEXT:   Address: 0x3388
-// GOTRELSHARED-NEXT:   Offset: 0x388
-// GOTRELSHARED-NEXT:   Size: 16
-// GOTRELSHARED-NEXT:   Link: 0
-// GOTRELSHARED-NEXT:   Info: 0
-// GOTRELSHARED-NEXT:   AddressAlignment: 4
-// GOTRELSHARED-NEXT:   EntrySize: 0
-// GOTRELSHARED-NEXT: }
-// GOTRELSHARED:      0x6FFFFFFA RELCOUNT             8
-// GOTRELSHARED:      Relocations [
-// GOTRELSHARED-NEXT:   Section ({{.*}}) .rel.dyn {
-// GOTRELSHARED-NEXT:     0x22DA R_386_RELATIVE -
-// GOTRELSHARED-NEXT:     0x22E2 R_386_RELATIVE -
-// GOTRELSHARED-NEXT:     0x22EB R_386_RELATIVE -
-// GOTRELSHARED-NEXT:     0x22F4 R_386_RELATIVE -
-// GOTRELSHARED-NEXT:     0x22FC R_386_RELATIVE -
-// GOTRELSHARED-NEXT:     0x2305 R_386_RELATIVE -
-// GOTRELSHARED-NEXT:     0x230E R_386_RELATIVE -
-// GOTRELSHARED-NEXT:     0x2317 R_386_RELATIVE -
-// GOTRELSHARED-NEXT:     0x3390 R_386_TLS_TPOFF tlsshared0
-// GOTRELSHARED-NEXT:     0x3394 R_386_TLS_TPOFF tlsshared1
-// GOTRELSHARED-NEXT:     0x3388 R_386_TLS_TPOFF tlslocal0
-// GOTRELSHARED-NEXT:     0x338C R_386_TLS_TPOFF tlslocal1
-// GOTRELSHARED-NEXT:   }
-// GOTRELSHARED-NEXT: ]
+# RUN: rm -rf %t && split-file %s %t && cd %t
+# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux a.s -o a.o
+# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux b.s -o b.o
+# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %p/Inputs/tls-opt-iele-i686-nopic.s -o so.o
+# RUN: ld.lld -shared -soname=t.so so.o -o t.so
+# RUN: ld.lld -shared a.o b.o t.so -o out
+# RUN: llvm-readelf -S -r -d out | FileCheck %s
+# RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn out | FileCheck --check-prefix=DIS %s
 
-// DISASMSHARED:       Disassembly of section test:
-// DISASMSHARED-EMPTY:
-// DISASMSHARED-NEXT:  <_start>:
-// (.got)[0] = 0x3388 = 13192
-// (.got)[1] = 13196
-// (.got)[2] = 13200
-// (.got)[3] = 13204
-// DISASMSHARED-NEXT:  22d8:       movl  13192, %ecx
-// DISASMSHARED-NEXT:  22de:       movl  %gs:(%ecx), %eax
-// DISASMSHARED-NEXT:  22e1:       movl  13192, %eax
-// DISASMSHARED-NEXT:  22e6:       movl  %gs:(%eax), %eax
-// DISASMSHARED-NEXT:  22e9:       addl  13192, %ecx
-// DISASMSHARED-NEXT:  22ef:       movl  %gs:(%ecx), %eax
-// DISASMSHARED-NEXT:  22f2:       movl  13196, %ecx
-// DISASMSHARED-NEXT:  22f8:       movl  %gs:(%ecx), %eax
-// DISASMSHARED-NEXT:  22fb:       movl  13196, %eax
-// DISASMSHARED-NEXT:  2300:       movl  %gs:(%eax), %eax
-// DISASMSHARED-NEXT:  2303:       addl  13196, %ecx
-// DISASMSHARED-NEXT:  2309:       movl  %gs:(%ecx), %eax
-// DISASMSHARED-NEXT:  230c:       movl  13200, %ecx
-// DISASMSHARED-NEXT:  2312:       movl  %gs:(%ecx), %eax
-// DISASMSHARED-NEXT:  2315:       addl  13204, %ecx
-// DISASMSHARED-NEXT:  231b:       movl  %gs:(%ecx), %eax
+# CHECK:      .got PROGBITS 00003388 000388 000010 00 WA 0 0 4
+# CHECK:      0x6ffffffa (RELCOUNT) 8
+# CHECK:      Relocation section '.rel.dyn' at offset {{.*}} contains 12 entries:
+# CHECK-NEXT:  Offset     Info    Type                Sym. Value  Symbol's Name
+# CHECK-NEXT: 000022da 00000008 R_386_RELATIVE
+# CHECK-NEXT: 000022e2 00000008 R_386_RELATIVE
+# CHECK-NEXT: 000022eb 00000008 R_386_RELATIVE
+# CHECK-NEXT: 000022f4 00000008 R_386_RELATIVE
+# CHECK-NEXT: 000022fc 00000008 R_386_RELATIVE
+# CHECK-NEXT: 00002305 00000008 R_386_RELATIVE
+# CHECK-NEXT: 0000230e 00000008 R_386_RELATIVE
+# CHECK-NEXT: 00002317 00000008 R_386_RELATIVE
+# CHECK-NEXT: 00003390 0000010e R_386_TLS_TPOFF 00000000 tlsshared0
+# CHECK-NEXT: 00003394 0000020e R_386_TLS_TPOFF 00000000 tlsshared1
+# CHECK-NEXT: 00003388 0000030e R_386_TLS_TPOFF 00000000 tlslocal0
+# CHECK-NEXT: 0000338c 0000040e R_386_TLS_TPOFF 00000004 tlslocal1
 
+# DIS:       Disassembly of section test:
+# DIS-EMPTY:
+# DIS-NEXT:  <_start>:
+## (.got)[0] = 0x3388 = 13192
+## (.got)[1] = 13196
+## (.got)[2] = 13200
+## (.got)[3] = 13204
+# DIS-NEXT:              movl  13192, %ecx
+# DIS-NEXT:              movl  %gs:(%ecx), %eax
+# DIS-NEXT:              movl  13192, %eax
+# DIS-NEXT:              movl  %gs:(%eax), %eax
+# DIS-NEXT:              addl  13192, %ecx
+# DIS-NEXT:              movl  %gs:(%ecx), %eax
+# DIS-NEXT:              movl  13196, %ecx
+# DIS-NEXT:              movl  %gs:(%ecx), %eax
+# DIS-NEXT:              movl  13196, %eax
+# DIS-NEXT:              movl  %gs:(%eax), %eax
+# DIS-NEXT:              addl  13196, %ecx
+# DIS-NEXT:              movl  %gs:(%ecx), %eax
+# DIS-NEXT:              movl  13200, %ecx
+# DIS-NEXT:              movl  %gs:(%ecx), %eax
+# DIS-NEXT:              addl  13204, %ecx
+# DIS-NEXT:              movl  %gs:(%ecx), %eax
+
+#--- a.s
 .type tlslocal0, at object
 .section .tbss,"awT", at nobits
 .globl tlslocal0
@@ -99,6 +89,8 @@ movl %gs:(%ecx),%eax
 movl tlslocal1 at indntpoff,%ecx
 movl %gs:(%ecx),%eax
 
+#--- b.s
+.section test, "axw"
 movl tlslocal1 at indntpoff,%eax
 movl %gs:(%eax),%eax
 


        


More information about the llvm-commits mailing list