Patchwork [build] Fix Solaris 2/x86 GD/LD TLS code sequences with Sun ld

login
register
mail settings
Submitter Uros Bizjak
Date May 23, 2011, 6:39 p.m.
Message ID <BANLkTinC3i=r5_voonZX9v-+zEuZ5DUo1Q@mail.gmail.com>
Download mbox | patch
Permalink /patch/97027/
State New
Headers show

Comments

Uros Bizjak - May 23, 2011, 6:39 p.m.
On Mon, May 23, 2011 at 7:22 PM, Rainer Orth
<ro@cebitec.uni-bielefeld.de> wrote:
> As described in
>
>        [testsuite] Provide TLS access model testcases
>        http://gcc.gnu.org/ml/gcc-patches/2011-05/msg01601.html
>
> both the 32 and 64-bit TLS GD and LD execution tests fail on Solaris 2
> with Sun ld unless you have a very recent Solaris 11 version (snv_164).
>
> This happens because the code sequences emitted by GCC don't match those
> expected by Sun ld:
>
>        32-bit x86: Thread-Local Variable Access
>        http://download.oracle.com/docs/cd/E19963-01/html/819-0690/chapter8-20.html#gentextid-20367
>
> For GD, one needs to use call x@tlsgdplt here, but call ___tls_get_addr@plt
> works, too.
>
> For LD, one really needs call x@tlsldmplt.
>
> The corresponding R_386_TLS_GD_PLT and R_386_TLS_LDM_PLT relocations are
> not yet handled by binutils.
>
>        x64: Thread-Local Variable Access
>        http://download.oracle.com/docs/cd/E19963-01/html/819-0690/chapter8-20.html#chapter8-60
>
> For both GD and LD, one needs to use call __tls_get_addr@plt.
>
> The following patch handles this:
>
> * It autoconfigures support for the @tlsgdplt and @tlsldmplt
>  relocations: Sun as supports them, while gas doesn't yet.  I've got a
>  patch in the works to fix this: while the gas part is easy, I have
>  serious problems getting the ld side to work properly.  Unfortunately,
>  I doubt the binutils maintainers will accept such partial support for
>  the relocs.
>
> * I'm using a new 'p' code to control the printing of @plt.  'P' doesn't
>  work since this is needed in both PIC and non-PIC code.

Since handling of "p" is not conditional (that is, controlled by some
compile flag), it is IMO better to just output correct assembly from
the insn pattern itself.  You will also output lower-case "@plt" which
is IIRC preferred by Sun assebler.

Something like attached (untested) patch.

Uros.
Rainer Orth - May 24, 2011, 3:09 p.m.
Uros,

> Since handling of "p" is not conditional (that is, controlled by some
> compile flag), it is IMO better to just output correct assembly from
> the insn pattern itself.  You will also output lower-case "@plt" which

I think I tried something along these lines, but failed with duplicate
@plt@plt for PIC code.

> is IIRC preferred by Sun assebler.

I've never seen such an issue.

> Something like attached (untested) patch.

Unfortunately, the Solaris 10/x86 bootstrap fails in the stage1 libgomp:

/vol/gcc/src/hg/trunk/solaris/libgomp/single.c: In function 'GOMP_single_start':
/vol/gcc/src/hg/trunk/solaris/libgomp/single.c:55:1: internal compiler error: ou
tput_operand: '%&' used without any local dynamic TLS references

	Rainer

Patch

Index: i386.md
===================================================================
--- i386.md	(revision 174076)
+++ i386.md	(working copy)
@@ -12367,6 +12367,12 @@ 
 {
   output_asm_insn
     ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
+  if (TARGET_SUN_TLS)
+#ifdef HAVE_AS_IX86_TLSGDPLT
+    return "call\t%&@tlslgdplt";
+#else
+    return "call\t%a3@plt";
+#endif
   return "call\t%P3";
 }
   [(set_attr "type" "multi")
@@ -12397,6 +12403,8 @@ 
     ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
   fputs (ASM_SHORT "0x6666\n", asm_out_file);
   fputs ("\trex64\n", asm_out_file);
+  if (TARGET_SUN_TLS)
+    return "call\t%a2@plt";
   return "call\t%P2";
 }
   [(set_attr "type" "multi")
@@ -12424,6 +12432,12 @@ 
 {
   output_asm_insn
     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
+  if (TARGET_SUN_TLS)
+#ifdef HAVE_AS_IX86_TLSLDMPLT
+    return "call\t%&@tlsldmplt";
+#else
+    return "call\t%a2@plt";
+#endif
   return "call\t%P2";
 }
   [(set_attr "type" "multi")
@@ -12450,6 +12464,8 @@ 
 {
   output_asm_insn
     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
+  if (TARGET_SUN_TLS)
+    return "call\t%a1@plt";
   return "call\t%P1";
 }
   [(set_attr "type" "multi")