diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -1400,10 +1400,17 @@ 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(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( + 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 --- 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@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 --- 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 --- 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 --- 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 --- 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 @@ # 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 --- 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 @@ movl func@GOT(%eax), %eax .section .text1,"awx" - movl %gs:tls@NTPOFF+42, %eax + movl tls@GOTNTPOFF(%eax), %eax .data .long .data diff --git a/lld/test/ELF/mips-tls-hilo.s b/lld/test/ELF/mips-tls-hilo.s --- 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 --- 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 --- 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 --- 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@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 --- 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@TPOFF(%rax),%rax