Bug 22727 - [2.30, 2.31 regression] Thousands of EH-related execution failures on SPARC
Summary: [2.30, 2.31 regression] Thousands of EH-related execution failures on SPARC
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.31
: P2 normal
Target Milestone: 2.30
Assignee: Eric Botcazou
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-01-18 13:56 UTC by Rainer Orth
Modified: 2018-03-31 12:36 UTC (History)
4 users (show)

See Also:
Host: sparc*-*-*
Target: sparc*-*-*
Build: sparc*-*-*
Last reconfirmed:
Project(s) to access:
ssh public key:


Attachments
Testcase for the incorrect TLS transition in PIE mode (884 bytes, patch)
2018-01-19 11:20 UTC, Eric Botcazou
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Rainer Orth 2018-01-18 13:56:48 UTC
When trying the binutils 2.30 branch on Solaris 11/SPARC with gcc mainline, I found
ca. 8500 testsuite regressions, most/all related to EH failures.  E.g.

FAIL: g++.dg/cpp0x/bad_array_new1.C  -std=c++11 execution test

When I replace the newly-built libstdc++.so.6 with the system one, the test
executes fine.

gdb is lead completely astray for this failure

Thread 2 received signal SIGILL, Illegal instruction.
[Switching to Thread 1 (LWP 1)]
0xff17383c in standard_subs ()
   from ../../../sparc-sun-solaris2.11/libstdc++-v3/src/.libs/libstdc++.so.6
(gdb) where
#0  0xff17383c in standard_subs ()
   from ../../../sparc-sun-solaris2.11/libstdc++-v3/src/.libs/libstdc++.so.6
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) display/i $pc
1: x/i $pc
=> 0xff17383c <standard_subs+4>:        ldq  [ %o5 + -1688 ], %f62

but dbx shows a clearer picture:

signal SEGV (no mapping at the fault address) in (unknown) at 0xff17380c
0xff17380c: npos+0x36110:       ld       [%i3 - 2924], %f31
Current function is __cxa_throw
   80     __cxa_eh_globals *globals = __cxa_get_globals ();
(dbx) where
  [1] 0xff17380c(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xff17380c 
=>[2] __cxa_throw(obj = 0x25888, tinfo = 0x20cd8, dest = 0x20eb8), line 80 in "eh_throw.cc"
  [3] __cxa_throw_bad_array_new_length(), line 42 in "eh_aux_runtime.cc"
  [4] f(0xffffffff, 0x1, 0x0, 0xfeed0200, 0x0, 0x0), at 0x10a48 
  [5] main(0x1, 0xffbfea14, 0xffbfea1c, 0x0, 0x0, 0x107c0), at 0x10a74

Comparing that call to __cxa_get_globals in the new (gld 2.30.0-linked)
libstdc++.so.6

   0xff0722f8 <__cxxabiv1::__cxa_get_globals()>:        save  %sp, -96, %sp
   0xff0722fc <__cxxabiv1::__cxa_get_globals()+4>:      sethi  %hi(0), %g1
   0xff072300 <__cxxabiv1::__cxa_get_globals()+8>:      add  %g1, 4, %g1    ! 0x4
   0xff072304 <__cxxabiv1::__cxa_get_globals()+12>:     sethi  %hi(0x105c00), %l7
   0xff072308 <__cxxabiv1::__cxa_get_globals()+16>:     call  0xff06f4a0 <__sparc_get_pc_thunk.l7>
   0xff07230c <__cxxabiv1::__cxa_get_globals()+20>:     add  %l7, 0xf8, %l7 ! 0x105cf8
   0xff072310 <__cxxabiv1::__cxa_get_globals()+24>:     sethi  %hi(0), %i0
   0xff072314 <__cxxabiv1::__cxa_get_globals()+28>:     add  %l7, %g1, %o0
   0xff072318 <__cxxabiv1::__cxa_get_globals()+32>:     call  0xff17380c
   0xff07231c <__cxxabiv1::__cxa_get_globals()+36>:     xor  %i0, 0, %i0
   0xff072320 <__cxxabiv1::__cxa_get_globals()+40>:     add  %o0, %i0, %i0
   0xff072324 <__cxxabiv1::__cxa_get_globals()+44>:     rett  %i7 + 8
   0xff072328 <__cxxabiv1::__cxa_get_globals()+48>:     nop 

with a gld 2.29-linked libstdc++.so.6:

   0xff072240 <__cxxabiv1::__cxa_get_globals()>:        save  %sp, -96, %sp
   0xff072244 <__cxxabiv1::__cxa_get_globals()+4>:      sethi  %hi(0), %g1
   0xff072248 <__cxxabiv1::__cxa_get_globals()+8>:      add  %g1, 4, %g1    ! 0x4
   0xff07224c <__cxxabiv1::__cxa_get_globals()+12>:     sethi  %hi(0x105c00), %l7
   0xff072250 <__cxxabiv1::__cxa_get_globals()+16>:     call  0xff06f3e8 <__sparc_get_pc_thunk.l7>
   0xff072254 <__cxxabiv1::__cxa_get_globals()+20>:     add  %l7, 0x1b0, %l7        ! 0x105db0
   0xff072258 <__cxxabiv1::__cxa_get_globals()+24>:     sethi  %hi(0), %i0
   0xff07225c <__cxxabiv1::__cxa_get_globals()+28>:     add  %l7, %g1, %o0
   0xff072260 <__cxxabiv1::__cxa_get_globals()+32>:     call  0xff17a1c0 <__tls_get_addr@plt>
   0xff072264 <__cxxabiv1::__cxa_get_globals()+36>:     xor  %i0, 0, %i0
   0xff072268 <__cxxabiv1::__cxa_get_globals()+40>:     add  %o0, %i0, %i0
   0xff07226c <__cxxabiv1::__cxa_get_globals()+44>:     rett  %i7 + 8
   0xff072270 <__cxxabiv1::__cxa_get_globals()+48>:     nop 

shows that what used to be a call to __tls_get_addr is now a call to some
random address, causing the SEGV/ILL.

Disassembling that function gives

Disassembly of section .text.__cxa_get_globals:

00000000 <__cxa_get_globals>:
   0:   9d e3 bf a0     save  %sp, -96, %sp
   4:   03 00 00 00     sethi  %hi(0), %g1
   8:   82 00 60 00     add  %g1, 0, %g1        ! 0 <__cxa_get_globals>
   c:   2f 00 00 00     sethi  %hi(0), %l7
  10:   40 00 00 00     call  10 <__cxa_get_globals+0x10>
  14:   ae 05 e0 00     add  %l7, 0, %l7        ! 0 <__cxa_get_globals>
  18:   31 00 00 00     sethi  %hi(0), %i0
  1c:   90 05 c0 01     add  %l7, %g1, %o0
  20:   40 00 00 00     call  20 <__cxa_get_globals+0x20>
  24:   b0 1e 20 00     xor  %i0, 0, %i0
  28:   b0 02 00 18     add  %o0, %i0, %i0
  2c:   81 cf e0 08     return  %i7 + 8
  30:   01 00 00 00     nop 

with a reloc applied to the __cxa_get_globals call:

Relocation Section:  .rela.text.__cxa_get_globals
  index  type                   offset value     addend  section / symbol
[...]
    [7]  R_SPARC_TLS_LDM_CALL     0x20     0          0  .text.__cxa_get_globals (anonymous namespace)::get_global()::global

A reghunt identified this patch as the culprit:

The first bad revision is:
changeset:   92065:a2a79207e4f5
user:        H.J. Lu <hjl.tools@gmail.com>
date:        Mon Oct 16 03:49:54 2017 -0700
summary:     ELF: Call check_relocs after opening all inputs

  Rainer
Comment 1 H.J. Lu 2018-01-18 14:05:12 UTC
Does Linux/Sparc work?  Are there any regressions in binutils
testsuite on Solaris/Sparc?
Comment 2 Rainer Orth 2018-01-18 14:14:31 UTC
> --- Comment #1 from H.J. Lu <hjl.tools at gmail dot com> ---
> Does Linux/Sparc work?  Are there any regressions in binutils

I've no idea and no way to test.

> testsuite on Solaris/Sparc?

That will take a bit to determine: I'll need to rebuild gcc to use the
freshly-built gas and gld, otherwise testing is meaningless (often the
configured as and ld are used, not the binutils ones).

	Rainer
Comment 3 H.J. Lu 2018-01-18 14:25:38 UTC
This could be a dup of PR 22721.
Comment 4 Eric Botcazou 2018-01-18 14:59:37 UTC
> > Does Linux/Sparc work?  Are there any regressions in binutils
> 
> I've no idea and no way to test.

I'm going to test on SPARC64/Linux.
Comment 5 Eric Botcazou 2018-01-18 15:16:27 UTC
> Does Linux/Sparc work?  Are there any regressions in binutils
> testsuite on Solaris/Sparc?

On SPARC64/Linux: binutils & gas testsuite clean, ld testsuite as follows:

                === ld Summary ===

# of expected passes            1227
# of unexpected failures        7
# of expected failures          26
# of untested testcases         1
# of unsupported tests          21

FAIL: ld-elf/pr22450
FAIL: Build pr22269-1
FAIL: Run pr22393-2
FAIL: Run pr22393-2 (PIE)
FAIL: Build pr22263-1
*** Error in `/home/ebotcazou/binutils-2.30.0/ld/tmpdir/ld/collect-ld': corrupted size vs. prev_size: 0x00000100002b2c30 ***
*** Error in `/home/ebotcazou/binutils-2.30.0/ld/tmpdir/ld/collect-ld': corrupted size vs. prev_size: 0x00000100002b2c30 ***
FAIL: visibility (hidden_normal) (PIC main)
*** Error in `/home/ebotcazou/binutils-2.30.0/ld/tmpdir/ld/collect-ld': corrupted size vs. prev_size: 0x00000100002b2c30 ***
*** Error in `/home/ebotcazou/binutils-2.30.0/ld/tmpdir/ld/collect-ld': corrupted size vs. prev_size: 0x00000100002b2c30 ***
FAIL: visibility (hidden_weak) (PIC main)
Comment 6 Eric Botcazou 2018-01-18 16:40:57 UTC
> Does Linux/Sparc work?  Are there any regressions in binutils
> testsuite on Solaris/Sparc?

The EH failures are also present on SPARC64/Linux with GCC 7.3RC1 and binutils 2.30, whereas they are _not_ present with GCC 7.3RC1 and binutils 2.29.1.
Comment 7 H.J. Lu 2018-01-18 16:44:42 UTC
(In reply to Eric Botcazou from comment #6)
> > Does Linux/Sparc work?  Are there any regressions in binutils
> > testsuite on Solaris/Sparc?
> 
> The EH failures are also present on SPARC64/Linux with GCC 7.3RC1 and
> binutils 2.30, whereas they are _not_ present with GCC 7.3RC1 and binutils
> 2.29.1.

This implies that ld testsuite coverage in binutils for Sparc is very
poor.  Can you extract some ld tesctcases from GCC tests?
Comment 8 Eric Botcazou 2018-01-18 17:14:10 UTC
> This implies that ld testsuite coverage in binutils for Sparc is very
> poor.  Can you extract some ld tesctcases from GCC tests?

Are gcc.dg/torture/tls/run-gd.c or gcc.dg/torture/tls/run-ld.c good enough?

                === gcc tests ===

Schedule of variations:
    unix

Running target unix
Using /usr/share/dejagnu/baseboards/unix.exp as board description file for target.
Using /usr/share/dejagnu/config/unix.exp as generic interface file for target.
Using /home/ebotcazou/src-7.3/gcc/testsuite/config/default.exp as tool-and-target-specific interface file.
Running /home/ebotcazou/src-7.3/gcc/testsuite/gcc.dg/tls/tls.exp ...
Running /home/ebotcazou/src-7.3/gcc/testsuite/gcc.dg/torture/tls/tls.exp ...
FAIL: gcc.dg/torture/tls/run-gd.c   -O0  -pie -fpie  execution test
FAIL: gcc.dg/torture/tls/run-gd.c   -O1  -pie -fpie  execution test
FAIL: gcc.dg/torture/tls/run-gd.c   -O2  -pie -fpie  execution test
FAIL: gcc.dg/torture/tls/run-gd.c   -O3 -g  -pie -fpie  execution test
FAIL: gcc.dg/torture/tls/run-gd.c   -Os  -pie -fpie  execution test
FAIL: gcc.dg/torture/tls/run-gd.c   -O0  -pie -fPIE  execution test
FAIL: gcc.dg/torture/tls/run-gd.c   -O1  -pie -fPIE  execution test
FAIL: gcc.dg/torture/tls/run-gd.c   -O2  -pie -fPIE  execution test
FAIL: gcc.dg/torture/tls/run-gd.c   -O3 -g  -pie -fPIE  execution test
FAIL: gcc.dg/torture/tls/run-gd.c   -Os  -pie -fPIE  execution test
FAIL: gcc.dg/torture/tls/run-ld.c   -O0  -pie -fpie  execution test
FAIL: gcc.dg/torture/tls/run-ld.c   -O1  -pie -fpie   2 blank line(s) in output
FAIL: gcc.dg/torture/tls/run-ld.c   -O1  -pie -fpie  (test for excess errors)
FAIL: gcc.dg/torture/tls/run-ld.c   -O1  -pie -fpie  execution test
FAIL: gcc.dg/torture/tls/run-ld.c   -O2  -pie -fpie   2 blank line(s) in output
FAIL: gcc.dg/torture/tls/run-ld.c   -O2  -pie -fpie  (test for excess errors)
FAIL: gcc.dg/torture/tls/run-ld.c   -O2  -pie -fpie  execution test
FAIL: gcc.dg/torture/tls/run-ld.c   -O3 -g  -pie -fpie   2 blank line(s) in output
FAIL: gcc.dg/torture/tls/run-ld.c   -O3 -g  -pie -fpie  (test for excess errors)
FAIL: gcc.dg/torture/tls/run-ld.c   -O3 -g  -pie -fpie  execution test
FAIL: gcc.dg/torture/tls/run-ld.c   -Os  -pie -fpie   2 blank line(s) in output
FAIL: gcc.dg/torture/tls/run-ld.c   -Os  -pie -fpie  (test for excess errors)
FAIL: gcc.dg/torture/tls/run-ld.c   -Os  -pie -fpie  execution test
FAIL: gcc.dg/torture/tls/run-ld.c   -O0  -pie -fPIE  execution test
FAIL: gcc.dg/torture/tls/run-ld.c   -O1  -pie -fPIE   2 blank line(s) in output
FAIL: gcc.dg/torture/tls/run-ld.c   -O1  -pie -fPIE  (test for excess errors)
FAIL: gcc.dg/torture/tls/run-ld.c   -O1  -pie -fPIE  execution test
FAIL: gcc.dg/torture/tls/run-ld.c   -O2  -pie -fPIE   2 blank line(s) in output
FAIL: gcc.dg/torture/tls/run-ld.c   -O2  -pie -fPIE  (test for excess errors)
FAIL: gcc.dg/torture/tls/run-ld.c   -O2  -pie -fPIE  execution test
FAIL: gcc.dg/torture/tls/run-ld.c   -O3 -g  -pie -fPIE   2 blank line(s) in output
FAIL: gcc.dg/torture/tls/run-ld.c   -O3 -g  -pie -fPIE  (test for excess errors)
FAIL: gcc.dg/torture/tls/run-ld.c   -O3 -g  -pie -fPIE  execution test
FAIL: gcc.dg/torture/tls/run-ld.c   -Os  -pie -fPIE   2 blank line(s) in output
FAIL: gcc.dg/torture/tls/run-ld.c   -Os  -pie -fPIE  (test for excess errors)
FAIL: gcc.dg/torture/tls/run-ld.c   -Os  -pie -fPIE  execution test
Comment 9 H.J. Lu 2018-01-18 17:31:46 UTC
(In reply to Eric Botcazou from comment #8)
> > This implies that ld testsuite coverage in binutils for Sparc is very
> > poor.  Can you extract some ld tesctcases from GCC tests?
> 
> Are gcc.dg/torture/tls/run-gd.c or gcc.dg/torture/tls/run-ld.c good enough?
> 

No.  Someone needs to extract them as assembly tests so that they can
be tested with a cross binutils.  See ld/testsuite/ld-x86-64/*tls*.d
in binutils source as examples.
Comment 10 H.J. Lu 2018-01-18 18:45:00 UTC
This could be a dup of PR 22728.  Please try

https://sourceware.org/ml/binutils/2018-01/msg00278.html
Comment 11 H.J. Lu 2018-01-18 18:47:56 UTC
(In reply to Eric Botcazou from comment #8)
> > This implies that ld testsuite coverage in binutils for Sparc is very
> > poor.  Can you extract some ld tesctcases from GCC tests?
> 
> Are gcc.dg/torture/tls/run-gd.c or gcc.dg/torture/tls/run-ld.c good enough?
> 
>                 === gcc tests ===
> 
> Schedule of variations:
>     unix
> 
> Running target unix
> Using /usr/share/dejagnu/baseboards/unix.exp as board description file for
> target.
> Using /usr/share/dejagnu/config/unix.exp as generic interface file for
> target.
> Using /home/ebotcazou/src-7.3/gcc/testsuite/config/default.exp as
> tool-and-target-specific interface file.
> Running /home/ebotcazou/src-7.3/gcc/testsuite/gcc.dg/tls/tls.exp ...
> Running /home/ebotcazou/src-7.3/gcc/testsuite/gcc.dg/torture/tls/tls.exp ...
> FAIL: gcc.dg/torture/tls/run-gd.c   -O0  -pie -fpie  execution test
> FAIL: gcc.dg/torture/tls/run-gd.c   -O1  -pie -fpie  execution test
> FAIL: gcc.dg/torture/tls/run-gd.c   -O2  -pie -fpie  execution test
> FAIL: gcc.dg/torture/tls/run-gd.c   -O3 -g  -pie -fpie  execution test
> FAIL: gcc.dg/torture/tls/run-gd.c   -Os  -pie -fpie  execution test
> FAIL: gcc.dg/torture/tls/run-gd.c   -O0  -pie -fPIE  execution test
> FAIL: gcc.dg/torture/tls/run-gd.c   -O1  -pie -fPIE  execution test
> FAIL: gcc.dg/torture/tls/run-gd.c   -O2  -pie -fPIE  execution test
> FAIL: gcc.dg/torture/tls/run-gd.c   -O3 -g  -pie -fPIE  execution test
> FAIL: gcc.dg/torture/tls/run-gd.c   -Os  -pie -fPIE  execution test
> FAIL: gcc.dg/torture/tls/run-ld.c   -O0  -pie -fpie  execution test
> FAIL: gcc.dg/torture/tls/run-ld.c   -O1  -pie -fpie   2 blank line(s) in
> output
> FAIL: gcc.dg/torture/tls/run-ld.c   -O1  -pie -fpie  (test for excess errors)
> FAIL: gcc.dg/torture/tls/run-ld.c   -O1  -pie -fpie  execution test
> FAIL: gcc.dg/torture/tls/run-ld.c   -O2  -pie -fpie   2 blank line(s) in
> output
> FAIL: gcc.dg/torture/tls/run-ld.c   -O2  -pie -fpie  (test for excess errors)
> FAIL: gcc.dg/torture/tls/run-ld.c   -O2  -pie -fpie  execution test
> FAIL: gcc.dg/torture/tls/run-ld.c   -O3 -g  -pie -fpie   2 blank line(s) in
> output
> FAIL: gcc.dg/torture/tls/run-ld.c   -O3 -g  -pie -fpie  (test for excess
> errors)
> FAIL: gcc.dg/torture/tls/run-ld.c   -O3 -g  -pie -fpie  execution test
> FAIL: gcc.dg/torture/tls/run-ld.c   -Os  -pie -fpie   2 blank line(s) in
> output
> FAIL: gcc.dg/torture/tls/run-ld.c   -Os  -pie -fpie  (test for excess errors)
> FAIL: gcc.dg/torture/tls/run-ld.c   -Os  -pie -fpie  execution test
> FAIL: gcc.dg/torture/tls/run-ld.c   -O0  -pie -fPIE  execution test
> FAIL: gcc.dg/torture/tls/run-ld.c   -O1  -pie -fPIE   2 blank line(s) in
> output
> FAIL: gcc.dg/torture/tls/run-ld.c   -O1  -pie -fPIE  (test for excess errors)
> FAIL: gcc.dg/torture/tls/run-ld.c   -O1  -pie -fPIE  execution test
> FAIL: gcc.dg/torture/tls/run-ld.c   -O2  -pie -fPIE   2 blank line(s) in
> output
> FAIL: gcc.dg/torture/tls/run-ld.c   -O2  -pie -fPIE  (test for excess errors)
> FAIL: gcc.dg/torture/tls/run-ld.c   -O2  -pie -fPIE  execution test
> FAIL: gcc.dg/torture/tls/run-ld.c   -O3 -g  -pie -fPIE   2 blank line(s) in
> output
> FAIL: gcc.dg/torture/tls/run-ld.c   -O3 -g  -pie -fPIE  (test for excess
> errors)
> FAIL: gcc.dg/torture/tls/run-ld.c   -O3 -g  -pie -fPIE  execution test
> FAIL: gcc.dg/torture/tls/run-ld.c   -Os  -pie -fPIE   2 blank line(s) in
> output
> FAIL: gcc.dg/torture/tls/run-ld.c   -Os  -pie -fPIE  (test for excess errors)
> FAIL: gcc.dg/torture/tls/run-ld.c   -Os  -pie -fPIE  execution test

It looks like that PIE is broken on Sparc.  This could be a dup of PR 22263.
Comment 12 H.J. Lu 2018-01-19 00:39:25 UTC
(In reply to H.J. Lu from comment #10)
> This could be a dup of PR 22728.  Please try
> 
> https://sourceware.org/ml/binutils/2018-01/msg00278.html

I fixed PR 22728.  Please try master branch again.
Comment 13 Eric Botcazou 2018-01-19 07:09:59 UTC
> I fixed PR 22728.  Please try master branch again.

How could a Solaris fix be of any help on Linux exactly?
Comment 14 Eric Botcazou 2018-01-19 11:20:19 UTC
Created attachment 10754 [details]
Testcase for the incorrect TLS transition in PIE mode

To be applied to the source tree, then
  make -k check RUNTESTFLAGS="sparc.exp"
must yield

Running /home/eric/build/binutils-2.30.0/ld/testsuite/ld-sparc/sparc.exp ...
FAIL: 32-bit: TLS -fpie
FAIL: 64-bit: TLS -fpie

                === ld Summary ===

# of expected passes            15
# of unexpected failures        2
Comment 15 H.J. Lu 2018-01-19 11:42:01 UTC
(In reply to Eric Botcazou from comment #14)
> Created attachment 10754 [details]
> Testcase for the incorrect TLS transition in PIE mode
> 
> To be applied to the source tree, then
>   make -k check RUNTESTFLAGS="sparc.exp"
> must yield
> 
> Running /home/eric/build/binutils-2.30.0/ld/testsuite/ld-sparc/sparc.exp ...
> FAIL: 32-bit: TLS -fpie
> FAIL: 64-bit: TLS -fpie
> 
>                 === ld Summary ===
> 
> # of expected passes            15
> # of unexpected failures        2

Yes, TLS in PIE is broken on Linux/Sparc, which is different from
8500 GCC testsuite regressions on Solaris/Sparc.  Please open a new
TLS in PIE bug against Linux/Sparc.
Comment 16 Eric Botcazou 2018-01-19 17:31:21 UTC
> Yes, TLS in PIE is broken on Linux/Sparc, which is different from
> 8500 GCC testsuite regressions on Solaris/Sparc.

Note that I also have 8500 GCC testsuite regressions on SPARC/Linux so I think that we have 2 different breakages in the SPARC BFD back-end.

> Please open a new TLS in PIE bug against Linux/Sparc.

Do you have access to a SPARC/Linux machine?  If no, then I think I'm going to directly post patches to the list.  We first need to revert the PR 22263 patch for the SPARC back-end until we have a comprehensive understanding of which calls to bfd_link_pic need to be turned into !bfd_link_executable.  AFAICS the only one that was explicitly marked:

  /* FIXME: The test here, in check_relocs and in relocate_section
     dealing with TLS optimization, ought to be !bfd_link_executable (info).  */
  if (bfd_link_pic (info))

was not changed, and some that were changed shouldn't have been changed.
Comment 17 Eric Botcazou 2018-01-19 23:58:14 UTC
I think I know what's going on and this looks similar to PR ld/22721.
Comment 18 Sourceware Commits 2018-01-25 11:21:17 UTC
The master branch has been updated by Eric Botcazou <ebotcazou@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=bb363086e7743506d78bc6b1e56face0fb1fc93f

commit bb363086e7743506d78bc6b1e56face0fb1fc93f
Author: Eric Botcazou <ebotcazou@gcc.gnu.org>
Date:   Thu Jan 25 12:16:06 2018 +0100

    Fix PR ld/22727 (TLS breakage in PIC/PIE mode on SPARC).
    
    There are actually 2 different bugs:
     1. TLS transition is broken in PIE mode.
     2. TLS is broken in PIC/PIE mode when the __tls_get_addr symbol
        is versioned  (as is the case on Linux and Solaris at least).
    
    The 1st bug is fixed by reverting the problematic change for now
    (note that the associated test doesn't pass on SPARC because of another
    issue so there is  no formal regression in the testsuite). The 2nd bug
    is fixed by changing the  call to _bfd_generic_link_add_one_symbol
    on __tls_get_addr into a mere lookup in _bfd_sparc_elf_check_relocs.
    
    bfd/
    	* elfxx-sparc.c (_bfd_sparc_elf_check_relocs) <R_SPARC_TLS_GD_CALL>:
    	Do a mere lookup of the __tls_get_addr symbol instead of adding it.
    
    	Revert
    	2017-10-19  H.J. Lu  <hongjiu.lu@intel.com>
    
    	PR ld/22263
    	* elfxx-sparc.c (sparc_elf_tls_transition): Replace
    	bfd_link_pic with !bfd_link_executable, !bfd_link_pic with
    	bfd_link_executable for TLS check.
    	(_bfd_sparc_elf_check_relocs): Likewise.
    	(allocate_dynrelocs): Likewise.
    	(_bfd_sparc_elf_relocate_section): Likewise.
    ld/
    	* testsuite/ld-sparc/sparc.exp (32-bit: Helper shared library):
    	Link with a version script.
    	(32-bit: TLS -fpie): New test.
    	(64-bit: Helper shared library): Link with a version script.
    	(64-bit: TLS -fpie): New test.
    	(64-bit: GOTDATA relocations): Pass -Av9 to the assembler.
    	* testsuite/ld-sparc/tlslib.ver: New file.
    	* testsuite/ld-sparc/tlspie32.dd: Likewise.
    	* testsuite/ld-sparc/tlspie32.s: Likewise.
    	* testsuite/ld-sparc/tlspie64.dd: Likewise.
    	* testsuite/ld-sparc/tlspie64.s: Likewise.
    	* testsuite/ld-sparc/tlssunbin32.dd: Adjust for versioned symbol.
    	* testsuite/ld-sparc/tlssunbin32.rd: Likewise.
    	* testsuite/ld-sparc/tlssunbin32.sd: Likewise.
    	* testsuite/ld-sparc/tlssunbin64.dd: Likewise.
    	* testsuite/ld-sparc/tlssunbin64.rd: Likewise.
    	* testsuite/ld-sparc/tlssunbin64.sd: Likewise.
Comment 19 Sourceware Commits 2018-01-25 11:31:58 UTC
The binutils-2_30-branch branch has been updated by Eric Botcazou <ebotcazou@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=220cf7e75d1e554d0a003e1c505a335ed663725e

commit 220cf7e75d1e554d0a003e1c505a335ed663725e
Author: Eric Botcazou <ebotcazou@gcc.gnu.org>
Date:   Thu Jan 25 12:16:06 2018 +0100

    Fix PR ld/22727 (TLS breakage in PIC/PIE mode on SPARC).
    
    There are actually 2 different bugs:
     1. TLS transition is broken in PIE mode.
     2. TLS is broken in PIC/PIE mode when the __tls_get_addr symbol
        is versioned  (as is the case on Linux and Solaris at least).
    
    The 1st bug is fixed by reverting the problematic change for now
    (note that the associated test doesn't pass on SPARC because of another
    issue so there is  no formal regression in the testsuite). The 2nd bug
    is fixed by changing the  call to _bfd_generic_link_add_one_symbol
    on __tls_get_addr into a mere lookup in _bfd_sparc_elf_check_relocs.
    
    bfd/
    	* elfxx-sparc.c (_bfd_sparc_elf_check_relocs) <R_SPARC_TLS_GD_CALL>:
    	Do a mere lookup of the __tls_get_addr symbol instead of adding it.
    
    	Revert
    	2017-10-19  H.J. Lu  <hongjiu.lu@intel.com>
    
    	PR ld/22263
    	* elfxx-sparc.c (sparc_elf_tls_transition): Replace
    	bfd_link_pic with !bfd_link_executable, !bfd_link_pic with
    	bfd_link_executable for TLS check.
    	(_bfd_sparc_elf_check_relocs): Likewise.
    	(allocate_dynrelocs): Likewise.
    	(_bfd_sparc_elf_relocate_section): Likewise.
    ld/
    	* testsuite/ld-sparc/sparc.exp (32-bit: Helper shared library):
    	Link with a version script.
    	(32-bit: TLS -fpie): New test.
    	(64-bit: Helper shared library): Link with a version script.
    	(64-bit: TLS -fpie): New test.
    	(64-bit: GOTDATA relocations): Pass -Av9 to the assembler.
    	* testsuite/ld-sparc/tlslib.ver: New file.
    	* testsuite/ld-sparc/tlspie32.dd: Likewise.
    	* testsuite/ld-sparc/tlspie32.s: Likewise.
    	* testsuite/ld-sparc/tlspie64.dd: Likewise.
    	* testsuite/ld-sparc/tlspie64.s: Likewise.
    	* testsuite/ld-sparc/tlssunbin32.dd: Adjust for versioned symbol.
    	* testsuite/ld-sparc/tlssunbin32.rd: Likewise.
    	* testsuite/ld-sparc/tlssunbin32.sd: Likewise.
    	* testsuite/ld-sparc/tlssunbin64.dd: Likewise.
    	* testsuite/ld-sparc/tlssunbin64.rd: Likewise.
    	* testsuite/ld-sparc/tlssunbin64.sd: Likewise.
Comment 20 Eric Botcazou 2018-01-25 11:33:54 UTC
Please give it a try on Solaris.
Comment 21 Rainer Orth 2018-01-25 15:38:51 UTC
> --- Comment #20 from Eric Botcazou <ebotcazou at gcc dot gnu.org> ---
> Please give it a try on Solaris.

I just tried gcc mainline with the top of the binutils 2.30 branch on
Solaris 11.4: worked like a charm.

Thanks.
        Rainer
Comment 22 Sourceware Commits 2018-02-15 14:58:43 UTC
The master branch has been updated by Eric Botcazou <ebotcazou@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=e513bd38a6b91401947d90ba5f301f01d3991b8e

commit e513bd38a6b91401947d90ba5f301f01d3991b8e
Author: Eric Botcazou <ebotcazou@gcc.gnu.org>
Date:   Thu Feb 15 15:55:11 2018 +0100

    PR ld/22832 on SPARC.
    
    The fix for PR ld/22727 on SPARC passed TRUE as the 'create' argument
    in the call to bfd_link_hash_lookup.  It turns out this was a bad idea
    because, if the symbol is created at this point, the link will abort
    later in elf_link_output_extsym.  This changes the TRUE into a FALSE
    and puts an assertion on the result of the call, making it easier to
    debug the issue; that's exactly in keeping with what Gold does.
    
    bfd/
    	* elfxx-sparc.c (_bfd_sparc_elf_check_relocs) <R_SPARC_TLS_GD_CALL>:
    	Pass FALSE instead of TRUE as 'create' argument to bfd_link_hash_lookup
    	and assert that the result of the call is not NULL.
Comment 23 Sourceware Commits 2018-02-15 15:04:05 UTC
The binutils-2_30-branch branch has been updated by Eric Botcazou <ebotcazou@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=d31b3bc9174ca62d7527a63e6428718311faff9c

commit d31b3bc9174ca62d7527a63e6428718311faff9c
Author: Eric Botcazou <ebotcazou@gcc.gnu.org>
Date:   Thu Feb 15 15:55:11 2018 +0100

    PR ld/22832 on SPARC.
    
    The fix for PR ld/22727 on SPARC passed TRUE as the 'create' argument
    in the call to bfd_link_hash_lookup.  It turns out this was a bad idea
    because, if the symbol is created at this point, the link will abort
    later in elf_link_output_extsym.  This changes the TRUE into a FALSE
    and puts an assertion on the result of the call, making it easier to
    debug the issue; that's exactly in keeping with what Gold does.
    
    bfd/
    	* elfxx-sparc.c (_bfd_sparc_elf_check_relocs) <R_SPARC_TLS_GD_CALL>:
    	Pass FALSE instead of TRUE as 'create' argument to bfd_link_hash_lookup
    	and assert that the result of the call is not NULL.