Skip to content

Commit

Permalink
std: Fix thread_local! in non-PIE binaries
Browse files Browse the repository at this point in the history
One of the parameters to the magical "register a thread-local destructor"
function is called `__dso_handle` and largely just passed along (this seems to
be what other implementations do). Currently we pass the *value* of this symbol,
but apparently the correct piece of information to pass is the *address* of the
symbol.

In a PIE binary the symbol actually contains an address to itself which is why
we've gotten away with what we're doing as long as we have. In a non-PIE binary
the symbol contains the address `NULL`, causing a segfault in the runtime
library if it keeps going.

Closes #24445
  • Loading branch information
alexcrichton committed Apr 15, 2015
1 parent 16e1fce commit 3e57c6c
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/libstd/thread/local.rs
Expand Up @@ -373,7 +373,7 @@ mod imp {
arg: *mut u8,
dso_handle: *mut u8) -> libc::c_int;
mem::transmute::<*const (), F>(__cxa_thread_atexit_impl)
(dtor, t, __dso_handle);
(dtor, t, &__dso_handle as *const _ as *mut _);
return
}

Expand Down
12 changes: 12 additions & 0 deletions src/test/run-make/issue-24445/Makefile
@@ -0,0 +1,12 @@
-include ../tools.mk

ifeq ($(UNAME),Linux)
all:
$(RUSTC) foo.rs
$(CC) foo.c -lfoo -L $(TMPDIR) -Wl,--gc-sections -lpthread -o $(TMPDIR)/foo
$(call RUN,foo)
$(CC) foo.c -lfoo -L $(TMPDIR) -Wl,--gc-sections -lpthread -pie -fPIC -o $(TMPDIR)/foo
$(call RUN,foo)
else
all:
endif
16 changes: 16 additions & 0 deletions src/test/run-make/issue-24445/foo.c
@@ -0,0 +1,16 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

void foo();

int main() {
foo();
return 0;
}
25 changes: 25 additions & 0 deletions src/test/run-make/issue-24445/foo.rs
@@ -0,0 +1,25 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![crate_type = "staticlib"]

struct Destroy;
impl Drop for Destroy {
fn drop(&mut self) { println!("drop"); }
}

thread_local! {
static X: Destroy = Destroy
}

#[no_mangle]
pub extern "C" fn foo() {
X.with(|_| ());
}

0 comments on commit 3e57c6c

Please sign in to comment.