Bug 1427285 - Rust TLS accesses are badly initialized
Summary: Rust TLS accesses are badly initialized
Alias: None
Product: Red Hat Enterprise Linux 6
Classification: Red Hat
Component: binutils
Version: 6.10
Hardware: i686
OS: Unspecified
Target Milestone: rc
: ---
Assignee: Nick Clifton
QA Contact: Miloš Prchlík
Vladimír Slávik
Depends On:
Blocks: 1504312 1433075
TreeView+ depends on / blocked
Reported: 2017-02-27 19:10 UTC by Josh Stone
Modified: 2018-06-19 05:09 UTC (History)
7 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Executable files created using the "-pie" option now start correctly Previously, the linker included in the *binutils* package produced incorrect dynamic relocations for position-independent binaries for the 32-bit Intel architecture. As a consequence, building code with the "-pie" compiler option produced binary files that failed to start. The linker has been fixed and now generates position-independent executable files that run correctly.
Clone Of:
: 1433075 (view as bug list)
Last Closed: 2018-06-19 05:08:44 UTC
Target Upstream Version:

Attachments (Terms of Use)
object files and saved "link-command" (6.63 MB, application/x-xz)
2017-02-27 19:12 UTC, Josh Stone
no flags Details

System ID Priority Status Summary Last Updated
Github rust-lang rust issues 37874 None None None 2017-02-27 19:18:59 UTC
Red Hat Product Errata RHBA-2018:1858 None None None 2018-06-19 05:09:00 UTC
Sourceware 12654 None None None 2017-02-27 19:53:30 UTC

Description Josh Stone 2017-02-27 19:10:44 UTC
Description of problem:
I don't know enough about these details to be sure where the problem lies.  The symptom that I see is that a Rust TLS byte (bool) which should be 0 (false) at the start of the program instead has some other junk.

But I've only seen this on i686 if the program is linked on EL6, and that binary fails to run anywhere.  The same program compiled on EL5, EL7, or F25 runs fine everywhere, even on EL6.  I've even reduced this to the exact same objects and final link command, attached.  I also found that EL6 *does* work if I remove the -pie.

The Rust source is simply 'fn main() {}', so I called it "true".  There's a little bit of runtime initialization before it gets to that no-op main.  In the object, this has a main calling _ZN3std2rt10lang_start17h65647f6e36cffdaeE (std::rt::lang_start::h65647f6e36cffdae), which does initialization and then calls the user's _ZN8rust_out4main17h0c6f2596c7f28a79E (rust_out::main::h0c6f2596c7f28a79)

Version-Release number of selected component (if applicable):

How reproducible:

Steps to Reproduce:
1. extract the attached tarball
2. $ sh link-command
   (my resulting "true" is included, if you want to inspect it first)
3. $ ./true

Actual results:
thread '<unnamed>' panicked at 'cannot access a TLS value during or after it is destroyed', /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libcore/option.rs:715
note: Run with `RUST_BACKTRACE=1` for a backtrace.
Aborted (core dumped)

(This is the result of that bool I mentioned not being initially false.

Expected results:
No output, exit status 0.

Additional info:

_ZN3std10sys_common11thread_info3set17h0d5eb6d5d88442a1E is the problematic function.  In the following sequence, the cmpb should see a 0, but it sees junk (different from run to run), and that jne takes us to the error path.

    7d69:       65 a1 00 00 00 00       mov    %gs:0x0,%eax
    7d6f:       90                      nop
    7d70:       8d 74 26 00             lea    0x0(%esi,%eiz,1),%esi
    7d74:       80 b8 15 00 00 00 00    cmpb   $0x0,0x15(%eax)
    7d7b:       89 c6                   mov    %eax,%esi
    7d7d:       0f 85 88 02 00 00       jne    800b <_ZN3std10sys_common11thread_info3set17h0d5eb6d5d88442a1E+0x2cb>

When I link on EL6 without -pie, which works, it looks like:

 804ea09:       65 a1 00 00 00 00       mov    %gs:0x0,%eax
 804ea0f:       90                      nop
 804ea10:       8d 74 26 00             lea    0x0(%esi,%eiz,1),%esi
 804ea14:       80 b8 a5 ff ff ff 00    cmpb   $0x0,-0x5b(%eax)
 804ea1b:       89 c6                   mov    %eax,%esi
 804ea1d:       0f 85 88 02 00 00       jne    804ecab <_ZN3std10sys_common11thread_info3set17h0d5eb6d5d88442a1E+0x2cb>

The same sequence before linking in libstd-2ddb28df747fcb8c.rlib looks like:

  29:   8d 83 00 00 00 00       lea    0x0(%ebx),%eax
  2f:   e8 fc ff ff ff          call   30 <_ZN3std10sys_common11thread_info3set17h0d5eb6d5d88442a1E+0x30>
  34:   80 b8 15 00 00 00 00    cmpb   $0x0,0x15(%eax)
  3b:   89 c6                   mov    %eax,%esi
  3d:   0f 85 88 02 00 00       jne    2cb <_ZN3std10sys_common11thread_info3set17h0d5eb6d5d88442a1E+0x2cb>

The relocations in this area are:

 Offset     Info    Type            Sym.Value  Sym. Name
00000017  0020cc0a R_386_GOTPC       00000000   _GLOBAL_OFFSET_TABLE_
0000002b  0015e113 R_386_TLS_LDM     00000000   _ZN3std10sys_common11t
00000030  0025b604 R_386_PLT32       00000000   ___tls_get_addr
00000036  0015e120 R_386_TLS_LDO_32  00000000   _ZN3std10sys_common11t

Comment 2 Josh Stone 2017-02-27 19:12:59 UTC
Created attachment 1258185 [details]
object files and saved "link-command"

Comment 3 Florian Weimer 2017-02-27 19:53:30 UTC
I'm sure it's this binutils bug:


Upstream fix in the Git repository:

commit 959b0961c9c714aa735ebb59e925fdf6f5117d99
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Fri Apr 8 16:14:49 2011 +0000

    Properly handle R_386_TLS_LDO_32 for PIE.


Comment 4 Josh Stone 2017-02-27 20:10:32 UTC
Thanks!  The testsuite parts of that patch don't apply cleanly, but I applied just the relevant hunk in bfd/elf32-i386.c, and this works great!

Comment 8 Miloš Prchlík 2018-05-10 06:16:37 UTC
Verified with build binutils-

Comment 13 errata-xmlrpc 2018-06-19 05:08:44 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.


Note You need to log in before you can comment on or make changes to this bug.