Bug 1427285
| Summary: | Rust TLS accesses are badly initialized | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Red Hat Enterprise Linux 6 | Reporter: | Josh Stone <jistone> | ||||
| Component: | binutils | Assignee: | 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.10 | CC: | bgollahe, fweimer, mcermak, mnewsome, mprchlik, nickc, vslavik | ||||
| Target Milestone: | rc | Keywords: | 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: |
|
||||||
Created attachment 1258185 [details]
object files and saved "link-command"
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 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! Verified with build binutils-2.20.51.0.2-5.48.el6. 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 |
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