Bug 1427285

Summary: Rust TLS accesses are badly initialized
Product: Red Hat Enterprise Linux 6 Reporter: Josh Stone <jistone>
Component: binutilsAssignee: Nick Clifton <nickc>
Status: CLOSED ERRATA QA Contact: Miloš Prchlík <mprchlik>
Severity: high Docs Contact: Vladimír Slávik <vslavik>
Priority: high    
Version: 6.10CC: bgollahe, fweimer, mcermak, mnewsome, mprchlik, nickc, vslavik
Target Milestone: rcKeywords: ZStream
Target Release: ---   
Hardware: i686   
OS: Unspecified   
Whiteboard:
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.
Story Points: ---
Clone Of:
: 1433075 (view as bug list) Environment:
Last Closed: 2018-06-19 05:08:44 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1433075, 1504312    
Attachments:
Description Flags
object files and saved "link-command" none

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):
binutils-2.20.51.0.2-5.44.el6.i686

How reproducible:
100%

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:

  https://sourceware.org/bugzilla/show_bug.cgi?id=12654

Upstream fix in the Git repository:

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

    Properly handle R_386_TLS_LDO_32 for PIE.

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commitdiff;h=959b0961c9c714aa735ebb59e925fdf6f5117d99

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-2.20.51.0.2-5.48.el6.

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.

https://access.redhat.com/errata/RHBA-2018:1858