[llvm-branch-commits] [lld] fb3c1b3 - [ELF] Reject local-exec TLS relocations for -shared
Fangrui Song via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Dec 21 08:51:17 PST 2020
Author: Fangrui Song
Date: 2020-12-21T08:47:04-08:00
New Revision: fb3c1b3de5ce7342438d7451f01a14f9c52323cd
URL: https://github.com/llvm/llvm-project/commit/fb3c1b3de5ce7342438d7451f01a14f9c52323cd
DIFF: https://github.com/llvm/llvm-project/commit/fb3c1b3de5ce7342438d7451f01a14f9c52323cd.diff
LOG: [ELF] Reject local-exec TLS relocations for -shared
For x86-64, D33100 added a diagnostic for local-exec TLS relocations referencing a preemptible symbol.
This patch generalizes it to non-preemptible symbols (see `-Bsymbolic` in `tls.s`)
on all targets.
Local-exec TLS relocations resolve to offsets relative to a fixed point within
the static TLS block, which are only meaningful for the executable.
With this change, `clang -fpic -shared -fuse-ld=bfd a.c` on the following example will be flagged for AArch64/ARM/i386/x86-64/RISC-V
```
static __attribute__((tls_model("local-exec"))) __thread long TlsVar = 42;
long bump() { return ++TlsVar; }
```
Note, in GNU ld, at least arm, riscv and x86's ports have the similar
diagnostics, but aarch64 and ppc64 do not error.
Differential Revision: https://reviews.llvm.org/D93331
Added:
Modified:
lld/ELF/Relocations.cpp
lld/test/ELF/aarch64-tls-le.s
lld/test/ELF/arm-tls-le32.s
lld/test/ELF/i386-static-tls-model.s
lld/test/ELF/i386-tls-le.s
lld/test/ELF/i386-zrel-zrela.s
lld/test/ELF/mips-tls-hilo.s
lld/test/ELF/ppc64-local-exec-tls.s
lld/test/ELF/riscv-tls-le.s
lld/test/ELF/tls.s
Removed:
lld/test/ELF/Inputs/i386-static-tls-model4.s
lld/test/ELF/x86-64-reloc-tpoff32-fpic.s
################################################################################
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index a9f627a08057..875ecf78ca2c 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1400,10 +1400,17 @@ static void scanReloc(InputSectionBase &sec, OffsetGetter &getOffset, RelTy *&i,
in.got->hasGotOffRel = true;
}
- // Process some TLS relocations, including relaxing TLS relocations.
- // Note that this function does not handle all TLS relocations.
- if (unsigned processed =
- handleTlsRelocation<ELFT>(type, sym, sec, offset, addend, expr)) {
+ // Process TLS relocations, including relaxing TLS relocations. Note that
+ // R_TPREL and R_TPREL_NEG relocations are resolved in processRelocAux.
+ if (expr == R_TPREL || expr == R_TPREL_NEG) {
+ if (config->shared) {
+ errorOrWarn("relocation " + toString(type) + " against " + toString(sym) +
+ " cannot be used with -shared" +
+ getLocation(sec, sym, offset));
+ return;
+ }
+ } else if (unsigned processed = handleTlsRelocation<ELFT>(
+ type, sym, sec, offset, addend, expr)) {
i += (processed - 1);
return;
}
diff --git a/lld/test/ELF/Inputs/i386-static-tls-model4.s b/lld/test/ELF/Inputs/i386-static-tls-model4.s
deleted file mode 100644
index 6006518bfd7c..000000000000
--- a/lld/test/ELF/Inputs/i386-static-tls-model4.s
+++ /dev/null
@@ -1,9 +0,0 @@
-.section ".tdata", "awT", @progbits
-.globl var
-var:
-
-.section .foo, "aw"
-.global _start
-_start:
- movl %gs:0, %eax
- leal var at ntpoff(%eax), %eax # R_386_TLS_LE
diff --git a/lld/test/ELF/aarch64-tls-le.s b/lld/test/ELF/aarch64-tls-le.s
index e63a379fcc45..c43345e8e254 100644
--- a/lld/test/ELF/aarch64-tls-le.s
+++ b/lld/test/ELF/aarch64-tls-le.s
@@ -8,6 +8,14 @@
#RELOC: Relocations [
#RELOC-NEXT: ]
+## Reject local-exec TLS relocations for -shared.
+# RUN: not ld.lld -shared %tmain.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR --implicit-check-not=error:
+
+# ERR: error: relocation R_AARCH64_TLSLE_ADD_TPREL_HI12 against v1 cannot be used with -shared
+# ERR: error: relocation R_AARCH64_TLSLE_ADD_TPREL_LO12_NC against v1 cannot be used with -shared
+# ERR: error: relocation R_AARCH64_TLSLE_ADD_TPREL_HI12 against v2 cannot be used with -shared
+# ERR: error: relocation R_AARCH64_TLSLE_ADD_TPREL_LO12_NC against v2 cannot be used with -shared
+
.globl _start
_start:
mrs x0, TPIDR_EL0
diff --git a/lld/test/ELF/arm-tls-le32.s b/lld/test/ELF/arm-tls-le32.s
index 739752209db4..49469c2b6bfa 100644
--- a/lld/test/ELF/arm-tls-le32.s
+++ b/lld/test/ELF/arm-tls-le32.s
@@ -8,6 +8,13 @@
/// statically for an application. The code sequences assume a thread pointer
/// in r9
+/// Reject local-exec TLS relocations for -shared.
+// RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR --implicit-check-not=error:
+
+// ERR: error: relocation R_ARM_TLS_LE32 against x cannot be used with -shared
+// ERR: error: relocation R_ARM_TLS_LE32 against y cannot be used with -shared
+// ERR: error: relocation R_ARM_TLS_LE32 against z cannot be used with -shared
+
.text
.syntax unified
.globl _start
diff --git a/lld/test/ELF/i386-static-tls-model.s b/lld/test/ELF/i386-static-tls-model.s
index cfd7cf6ba972..dfbbed25ef22 100644
--- a/lld/test/ELF/i386-static-tls-model.s
+++ b/lld/test/ELF/i386-static-tls-model.s
@@ -1,9 +1,5 @@
# REQUIRES: x86
-# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %S/Inputs/i386-static-tls-model1.s -o %t.o
-# RUN: ld.lld %t.o -o %t1 -shared
-# RUN: llvm-readobj --dynamic-table %t1 | FileCheck %s
-
# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %S/Inputs/i386-static-tls-model2.s -o %t.o
# RUN: ld.lld %t.o -o %t2 -shared
# RUN: llvm-readobj --dynamic-table %t2 | FileCheck %s
@@ -12,9 +8,5 @@
# RUN: ld.lld %t.o -o %t3 -shared
# RUN: llvm-readobj --dynamic-table %t3 | FileCheck %s
-# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %S/Inputs/i386-static-tls-model4.s -o %t.o
-# RUN: ld.lld %t.o -o %t4 -shared
-# RUN: llvm-readobj --dynamic-table %t4 | FileCheck %s
-
# CHECK: DynamicSection [
# CHECK: FLAGS STATIC_TLS
diff --git a/lld/test/ELF/i386-tls-le.s b/lld/test/ELF/i386-tls-le.s
index b94ffbb67f07..bcb4a8e21abc 100644
--- a/lld/test/ELF/i386-tls-le.s
+++ b/lld/test/ELF/i386-tls-le.s
@@ -1,11 +1,19 @@
# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=i686 %s -o %t.o
# RUN: ld.lld %t.o -o %t
-# RUN: ld.lld %t.o -shared -o %t.so
+# RUN: ld.lld %t.o -pie -o %t.pie
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s --check-prefix=DIS
# RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=RELOC
-# RUN: llvm-objdump -d --no-show-raw-insn %t.so | FileCheck %s --check-prefix=DISSHARED
-# RUN: llvm-readobj -r %t.so | FileCheck %s --check-prefix=RELOCSHARED
+# RUN: llvm-objdump -d --no-show-raw-insn %t.pie | FileCheck %s --check-prefix=DIS
+# RUN: llvm-readobj -r %t.pie | FileCheck %s --check-prefix=RELOC
+
+## Reject local-exec TLS relocations for -shared.
+# RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR --implicit-check-not=error:
+
+# ERR: error: relocation R_386_TLS_LE_32 against var cannot be used with -shared
+# ERR: error: relocation R_386_TLS_LE_32 against var1 cannot be used with -shared
+# ERR: error: relocation R_386_TLS_LE against var cannot be used with -shared
+# ERR: error: relocation R_386_TLS_LE against var1 cannot be used with -shared
.section ".tdata", "awT", @progbits
.globl var
@@ -33,39 +41,16 @@ _start:
# DIS: Disassembly of section test:
# DIS-EMPTY:
# DIS-NEXT: <_start>:
-# DIS-NEXT: 402134: movl $8, %edx
-# DIS-NEXT: 402139: movl %gs:0, %ecx
-# DIS-NEXT: 402140: subl %edx, %eax
-# DIS-NEXT: 402142: movl $4, %edx
-# DIS-NEXT: 402147: movl %gs:0, %ecx
-# DIS-NEXT: 40214e: subl %edx, %eax
-# DIS-NEXT: 402150: movl %gs:0, %ecx
-# DIS-NEXT: 402157: leal -8(%ecx), %eax
-# DIS-NEXT: 40215d: movl %gs:0, %ecx
-# DIS-NEXT: 402164: leal 119(%ecx), %eax
+# DIS-NEXT: movl $8, %edx
+# DIS-NEXT: movl %gs:0, %ecx
+# DIS-NEXT: subl %edx, %eax
+# DIS-NEXT: movl $4, %edx
+# DIS-NEXT: movl %gs:0, %ecx
+# DIS-NEXT: subl %edx, %eax
+# DIS-NEXT: movl %gs:0, %ecx
+# DIS-NEXT: leal -8(%ecx), %eax
+# DIS-NEXT: movl %gs:0, %ecx
+# DIS-NEXT: leal 119(%ecx), %eax
# RELOC: Relocations [
# RELOC-NEXT: ]
-
-# DISSHARED: Disassembly of section test:
-# DISSHARED-EMPTY:
-# DISSHARED-NEXT: <_start>:
-# DISSHARED-NEXT: 2218: movl $0, %edx
-# DISSHARED-NEXT: 221d: movl %gs:0, %ecx
-# DISSHARED-NEXT: 2224: subl %edx, %eax
-# DISSHARED-NEXT: 2226: movl $0, %edx
-# DISSHARED-NEXT: 222b: movl %gs:0, %ecx
-# DISSHARED-NEXT: 2232: subl %edx, %eax
-# DISSHARED-NEXT: 2234: movl %gs:0, %ecx
-# DISSHARED-NEXT: 223b: leal (%ecx), %eax
-# DISSHARED-NEXT: 2241: movl %gs:0, %ecx
-# DISSHARED-NEXT: 2248: leal 123(%ecx), %eax
-
-# RELOCSHARED: Relocations [
-# RELOCSHARED-NEXT: Section (5) .rel.dyn {
-# RELOCSHARED-NEXT: 0x2219 R_386_TLS_TPOFF32 var
-# RELOCSHARED-NEXT: 0x223D R_386_TLS_TPOFF var
-# RELOCSHARED-NEXT: 0x2227 R_386_TLS_TPOFF32 var1
-# RELOCSHARED-NEXT: 0x224A R_386_TLS_TPOFF var1
-# RELOCSHARED-NEXT: }
-# RELOCSHARED-NEXT: ]
diff --git a/lld/test/ELF/i386-zrel-zrela.s b/lld/test/ELF/i386-zrel-zrela.s
index 27ff3bcab9a5..5e73ca203524 100644
--- a/lld/test/ELF/i386-zrel-zrela.s
+++ b/lld/test/ELF/i386-zrel-zrela.s
@@ -27,7 +27,7 @@
# REL-NEXT: }
# REL: Hex dump of section '.data':
-# REL-NEXT: 0x000042cc cc420000 2a000000
+# REL-NEXT: 0x000042d0 d0420000 2a000000
# RUN: ld.lld -shared -z rel -z rela %t.o -o %t2.so
# RUN: llvm-readobj -d -r %t2.so | FileCheck --check-prefix=RELA %s
@@ -41,9 +41,9 @@
# RELA-NEXT: PLTGOT {{.*}}
# RELA-NEXT: PLTREL RELA
# RELA: .rela.dyn {
-# RELA-NEXT: R_386_RELATIVE - 0x42EC
+# RELA-NEXT: R_386_RELATIVE - 0x42F0
# RELA-NEXT: R_386_GLOB_DAT func 0x0
-# RELA-NEXT: R_386_TLS_TPOFF tls 0x2A
+# RELA-NEXT: R_386_TLS_TPOFF tls 0x0
# RELA-NEXT: R_386_32 _start 0x2A
# RELA-NEXT: }
# RELA-NEXT: .rela.plt {
@@ -56,7 +56,7 @@ _start:
movl func at GOT(%eax), %eax
.section .text1,"awx"
- movl %gs:tls at NTPOFF+42, %eax
+ movl tls at GOTNTPOFF(%eax), %eax
.data
.long .data
diff --git a/lld/test/ELF/mips-tls-hilo.s b/lld/test/ELF/mips-tls-hilo.s
index 4f1417d29525..92cf71be5ecc 100644
--- a/lld/test/ELF/mips-tls-hilo.s
+++ b/lld/test/ELF/mips-tls-hilo.s
@@ -7,8 +7,10 @@
# RUN: llvm-objdump -d -t --no-show-raw-insn %t.exe | FileCheck --check-prefix=DIS %s
# RUN: llvm-readobj -r -A %t.exe | FileCheck %s
-# RUN: ld.lld %t.o -shared -o %t.so
-# RUN: llvm-readobj -r -A %t.so | FileCheck -check-prefix=SO %s
+# RUN: not ld.lld %t.o -shared -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR --implicit-check-not=error:
+
+# ERR: error: relocation R_MIPS_TLS_TPREL_HI16 against loc0 cannot be used with -shared
+# ERR: error: relocation R_MIPS_TLS_TPREL_LO16 against loc0 cannot be used with -shared
# DIS: 00000000 l O .tdata 00000000 loc0
diff --git a/lld/test/ELF/ppc64-local-exec-tls.s b/lld/test/ELF/ppc64-local-exec-tls.s
index f657d96ad1f1..51dcb1a7395a 100644
--- a/lld/test/ELF/ppc64-local-exec-tls.s
+++ b/lld/test/ELF/ppc64-local-exec-tls.s
@@ -4,6 +4,18 @@
// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
+// RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR
+
+/// Reject local-exec TLS relocations for -shared.
+// ERR: error: relocation R_PPC64_TPREL16_HA against a cannot be used with -shared
+// ERR: error: relocation R_PPC64_TPREL16_LO against a cannot be used with -shared
+// ERR: error: relocation R_PPC64_TPREL16 against b cannot be used with -shared
+// ERR: error: relocation R_PPC64_TPREL16_HI against b cannot be used with -shared
+// ERR: error: relocation R_PPC64_TPREL16_DS against b cannot be used with -shared
+// ERR: error: relocation R_PPC64_TPREL16_LO_DS against b cannot be used with -shared
+// ERR: error: relocation R_PPC64_TPREL16_HIGHESTA against b cannot be used with -shared
+// ERR: error: relocation R_PPC64_TPREL16_HIGHERA against b cannot be used with -shared
+
.text
.abiversion 2
.globl test_local_exec # -- Begin function test_local_exec
diff --git a/lld/test/ELF/riscv-tls-le.s b/lld/test/ELF/riscv-tls-le.s
index 860e6884c5da..96a10e940218 100644
--- a/lld/test/ELF/riscv-tls-le.s
+++ b/lld/test/ELF/riscv-tls-le.s
@@ -13,6 +13,13 @@
# RUN: ld.lld -pie %t.64.o -o %t.64
# RUN: llvm-objdump -d --no-show-raw-insn %t.64 | FileCheck --check-prefixes=LE %s
+# RUN: not ld.lld -shared %t.32.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR --implicit-check-not=error:
+
+# ERR: error: relocation R_RISCV_TPREL_HI20 against .LANCHOR0 cannot be used with -shared
+# ERR: error: relocation R_RISCV_TPREL_LO12_I against .LANCHOR0 cannot be used with -shared
+# ERR: error: relocation R_RISCV_TPREL_HI20 against a cannot be used with -shared
+# ERR: error: relocation R_RISCV_TPREL_LO12_S against a cannot be used with -shared
+
# NM: {{0*}}00000008 b .LANCHOR0
# NM: {{0*}}0000000c B a
diff --git a/lld/test/ELF/tls.s b/lld/test/ELF/tls.s
index 353a056ee20d..567e44600ab0 100644
--- a/lld/test/ELF/tls.s
+++ b/lld/test/ELF/tls.s
@@ -4,6 +4,26 @@
// RUN: llvm-readobj -S -l --symbols %tout | FileCheck %s
// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DIS
+/// Reject local-exec TLS relocations for -shared, regardless of the preemptibility.
+// RUN: not ld.lld -shared %t -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR
+// RUN: not ld.lld -shared -Bsymbolic %t -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR
+
+// ERR: error: relocation R_X86_64_TPOFF32 against a cannot be used with -shared
+// ERR-NEXT: defined in {{.*}}
+// ERR-NEXT: referenced by {{.*}}:(.text+0x4)
+// ERR-EMPTY:
+// ERR-NEXT: error: relocation R_X86_64_TPOFF32 against b cannot be used with -shared
+// ERR-NEXT: defined in {{.*}}
+// ERR-NEXT: referenced by {{.*}}:(.text+0xC)
+// ERR-EMPTY:
+// ERR-NEXT: error: relocation R_X86_64_TPOFF32 against c cannot be used with -shared
+// ERR-NEXT: defined in {{.*}}
+// ERR-NEXT: referenced by {{.*}}:(.text+0x14)
+// ERR-EMPTY:
+// ERR-NEXT: error: relocation R_X86_64_TPOFF32 against d cannot be used with -shared
+// ERR-NEXT: defined in {{.*}}
+// ERR-NEXT: referenced by {{.*}}:(.text+0x1C)
+
.global _start
_start:
movl %fs:a at tpoff, %eax
diff --git a/lld/test/ELF/x86-64-reloc-tpoff32-fpic.s b/lld/test/ELF/x86-64-reloc-tpoff32-fpic.s
deleted file mode 100644
index edb04c1d4487..000000000000
--- a/lld/test/ELF/x86-64-reloc-tpoff32-fpic.s
+++ /dev/null
@@ -1,14 +0,0 @@
-# REQUIRES: x86
-# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
-# RUN: not ld.lld %t.o -shared -o /dev/null 2>&1 | FileCheck %s
-
-# CHECK: relocation R_X86_64_TPOFF32 cannot be used against symbol var; recompile with -fPIC
-# CHECK: >>> defined in {{.*}}.o
-# CHECK: >>> referenced by {{.*}}.o:(.tdata+0xC)
-
-.section ".tdata", "awT", @progbits
-.globl var
-var:
-
-movq %fs:0, %rax
-leaq var at TPOFF(%rax),%rax
More information about the llvm-branch-commits
mailing list