[PATCH] D70362: Fix fatal linker error on R_MIPS_JALR against a local TLS symbol

Alexander Richardson via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 17 11:17:32 PST 2019


arichardson created this revision.
arichardson added a reviewer: atanasyan.
Herald added subscribers: llvm-commits, MaskRay, jrtc27, sdardis, emaste.
Herald added a reviewer: espindola.
Herald added a project: LLVM.

In order to determine whether R_MIPS_JALR should use R_PC or R_NONE, the
MIPS code checks whether the target is preemptible and not microMIPS.
To check the later condition we look at the low bit of the virtual address.
However, for TLS symbols calling Symbol::getVA() will report a fatal error
until Out::tlsPhdr has been initialized (which only happens later).

It is unclear whether clang should be emitting these relocations for TLS
symbols in the first place, but we should be able to handle this without
failing in LLD even if clang is later change to not emit the relocation.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D70362

Files:
  lld/ELF/Arch/Mips.cpp
  lld/test/ELF/tls-r-mips-jalr.s


Index: lld/test/ELF/tls-r-mips-jalr.s
===================================================================
--- /dev/null
+++ lld/test/ELF/tls-r-mips-jalr.s
@@ -0,0 +1,47 @@
+# REQUIRES: mips
+# RUN: llvm-mc -filetype=obj -triple=mips64-none-freebsd %s -o %t.o
+# RUN: ld.lld -shared %t.o -o %t.so
+## Minimized test case create from the following C source code
+## typedef int (*callback_f)(void);
+## static __thread callback_f callback;
+## void set_callback(callback_f f) {
+##   callback = f;
+## }
+## int test(void) {
+##   return callback();
+## }
+
+	.set	noat
+	.globl	test                    # -- Begin function test
+	.p2align	3
+	.type	test, at function
+	.ent	test
+test:                                   # @test
+# %bb.0:                                # %entry
+	ld	$t9, %call16(__tls_get_addr)($gp)
+	.reloc .Ltmp1, R_MIPS_JALR, __tls_get_addr
+.Ltmp1:
+	jalr	$t9
+	nop
+	lui	$1, %dtprel_hi(callback)
+	daddu	$1, $1, $2
+	ld	$t9, %dtprel_lo(callback)($1)
+## The following line (creating a R_MIPS_JALR against a TLS symbol)
+## previously caused a linker error:
+## tls-r-mips-jalr.s.tmp.o has an STT_TLS symbol but doesn't have an SHF_TLS section
+	.reloc .Ltmp2, R_MIPS_JALR, callback
+.Ltmp2:
+	jr	$t9
+	nop
+	.end	test
+.Lfunc_end1:
+	.size	test, .Lfunc_end1-test
+
+
+	.type	callback, at object        # @callback
+	.section	.tbss,"awT", at nobits
+	.p2align	3
+callback:
+	.8byte	0
+	.size	callback, 8
+
Index: lld/ELF/Arch/Mips.cpp
===================================================================
--- lld/ELF/Arch/Mips.cpp
+++ lld/ELF/Arch/Mips.cpp
@@ -86,7 +86,10 @@
     // If the target symbol is not preemptible and is not microMIPS,
     // it might be possible to replace jalr/jr instruction by bal/b.
     // It depends on the target symbol's offset.
-    if (!s.isPreemptible && !(s.getVA() & 0x1))
+    // Additionally, we can't optimize references to TLS variables (and
+    // s.getVA() will generate a fatal error for TLS symbols since Out::tlsPhdr
+    // will not have been initialized yet).
+    if (!s.isPreemptible && !s.isTls() && !(s.getVA() & 0x1))
       return R_PC;
     return R_NONE;
   case R_MICROMIPS_JALR:


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D70362.229723.patch
Type: text/x-patch
Size: 2152 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20191117/72fb965c/attachment.bin>


More information about the llvm-commits mailing list