Bug 17057 - Production of DSOs using TLSDESC is utterly broken on i386
Summary: Production of DSOs using TLSDESC is utterly broken on i386
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.25
: P2 normal
Target Milestone: 2.25
Assignee: H.J. Lu
: 17117 (view as bug list)
Depends on:
Reported: 2014-06-15 03:30 UTC by Rich Felker
Modified: 2014-07-15 20:16 UTC (History)
1 user (show)

See Also:
Last reconfirmed:


Note You need to log in before you can comment on or make changes to this bug.
Description Rich Felker 2014-06-15 03:30:12 UTC
Attempting to compile/link the following program:

__thread int my_tls = 1;
int *my_tls_addr() { return &my_tls; }

with the following gcc command line:

gcc -shared -mtls-dialect=gnu2 -fPIC -o foo.so foo.c

results in the following error message (details vary by version; I also tried two different builds of 2.24, my own and Debian's):

/usr/bin/ld: BFD (GNU Binutils) 2.23.2 assertion fail elf32-i386.c:3922

The problem seems to be a miscomputation of the size of .got.plt needed for the TLSDESC entries. Incidentally, if there are no PLT entries at all (this can be achieved with the above program by -nostartfiles), the error goes away, but the resulting DSO is unusable; it contains no DT_JMPREL in the DYNAMIC, so TLSDESC relocations don't happen and naturally this results in a crash when the program attempts to access the TLS.

Is this code completely untested? I can't seem to figure out how to produce any usable/testable TLSDESC-using DSO.
Comment 1 H.J. Lu 2014-07-15 17:26:58 UTC
*** Bug 17117 has been marked as a duplicate of this bug. ***
Comment 2 H.J. Lu 2014-07-15 17:33:12 UTC
A self-contained testcase:

[hjl@gnu-6 pr17057]$ cat x.c 
__thread int my_tls = 1;
int *my_tls_addr() { return &my_tls; }
[hjl@gnu-6 pr17057]$ cat y.c 
extern void foo (void);

bar (void)
  foo ();
[hjl@gnu-6 pr17057]$ gcc -fPIC -m32 y.c -c -O2 x.c -mtls-dialect=gnu2
[hjl@gnu-6 pr17057]$ ld  -m elf_i386 -shared -o x.so y.o  x.o
ld: BFD (Linux/GNU Binutils) assertion fail /net/gnu-6/export/linux/src/binutils/binutils/bfd/elf32-i386.c:4035
[hjl@gnu-6 pr17057]$
Comment 3 cvs-commit@gcc.gnu.org 2014-07-15 20:16:02 UTC
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "gdb and binutils".

The branch, master has been updated
       via  998d811a23ca3f2c463dfaf40259486ff9958244 (commit)
      from  41e995687391695e16550eb9c18da8e5d0dcffa9 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------

commit 998d811a23ca3f2c463dfaf40259486ff9958244
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Tue Jul 15 13:09:55 2014 -0700

    Update elf_i386_compute_jump_table_size
    Commit e1f987424b7b3f5ac63a2a6ae044a202a44b8ff8 changed how
    next_tls_desc_index was set up.  This patch updates
    elf_i386_compute_jump_table_size to use elf.srelplt->reloc_count
    instead of next_tls_desc_index.
    	PR ld/17057
    	* elf32-i386.c (elf_i386_compute_jump_table_size): Replace
    	next_tls_desc_index with elf.srelplt->reloc_count.
    	PR ld/17057
    	* ld-i386/i386.exp: Run pr17057.
    	* ld-i386/pr17057.d: New file.
    	* ld-i386/pr17057.s: Likewise.


Summary of changes:
 bfd/ChangeLog                  |    6 ++++++
 bfd/elf32-i386.c               |    2 +-
 ld/testsuite/ChangeLog         |    7 +++++++
 ld/testsuite/ld-i386/i386.exp  |    1 +
 ld/testsuite/ld-i386/pr17057.d |    9 +++++++++
 ld/testsuite/ld-i386/pr17057.s |    3 +++
 6 files changed, 27 insertions(+), 1 deletions(-)
 create mode 100644 ld/testsuite/ld-i386/pr17057.d
 create mode 100644 ld/testsuite/ld-i386/pr17057.s
Comment 4 H.J. Lu 2014-07-15 20:16:45 UTC