Skip to content

Commit 6cf7fbe

Browse files
authored
Couple of refactorings to make adding dynamic linker support easier (#111)
* Move the relocate call from init_runtime to entry Self-relocation is not actually initializing runtime state, but making it possible to safely run any code at all. When using a dynamic linker the dynamic linker needs to be relocated before it can do dynamic linking, but some of the runtime intialization needs to happen after dynamic linking when all static DSO's that use thread local storage are known. * Always write thread_id field after initializing thread metadata Also move writing __stack_chk_guard earlier. This makes future refactorings easier.
1 parent 6484717 commit 6cf7fbe

2 files changed

Lines changed: 22 additions & 37 deletions

File tree

src/program.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,13 @@ pub(super) unsafe extern "C" fn entry(mem: *mut usize) -> ! {
9090
// Compute `argc`, `argv`, and `envp`.
9191
let (argc, argv, envp) = compute_args(mem);
9292

93+
// Before doing anything else, perform dynamic relocations.
94+
#[cfg(all(feature = "experimental-relocate", feature = "origin-start"))]
95+
#[cfg(relocation_model = "pic")]
96+
{
97+
crate::relocate::relocate(envp);
98+
}
99+
93100
// Initialize program state before running any user code.
94101
init_runtime(mem, envp);
95102

@@ -187,8 +194,7 @@ unsafe fn compute_args(mem: *mut usize) -> (i32, *mut *mut u8, *mut *mut u8) {
187194
(argc, argv, envp)
188195
}
189196

190-
/// Perform dynamic relocation (if enabled), and initialize `origin` and
191-
/// `rustix` runtime state.
197+
/// Initialize `origin` and `rustix` runtime state.
192198
///
193199
/// # Safety
194200
///
@@ -197,11 +203,6 @@ unsafe fn compute_args(mem: *mut usize) -> (i32, *mut *mut u8, *mut *mut u8) {
197203
#[cfg(feature = "origin-program")]
198204
#[allow(unused_variables)]
199205
unsafe fn init_runtime(mem: *mut usize, envp: *mut *mut u8) {
200-
// Before doing anything else, perform dynamic relocations.
201-
#[cfg(all(feature = "experimental-relocate", feature = "origin-start"))]
202-
#[cfg(relocation_model = "pic")]
203-
crate::relocate::relocate(envp);
204-
205206
// Explicitly initialize `rustix`. This is needed for things like
206207
// `page_size()` to work.
207208
#[cfg(feature = "param")]

src/thread/linux_raw.rs

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,9 @@ const ABANDONED: u8 = 2;
9999

100100
impl ThreadData {
101101
#[inline]
102-
fn new(
103-
tid: Option<ThreadId>,
104-
stack_addr: *mut c_void,
105-
stack_size: usize,
106-
guard_size: usize,
107-
map_size: usize,
108-
) -> Self {
102+
fn new(stack_addr: *mut c_void, stack_size: usize, guard_size: usize, map_size: usize) -> Self {
109103
Self {
110-
thread_id: AtomicI32::new(ThreadId::as_raw(tid)),
104+
thread_id: AtomicI32::new(0),
111105
#[cfg(feature = "unstable-errno")]
112106
errno_val: Cell::new(0),
113107
detached: AtomicU8::new(INITIAL),
@@ -336,6 +330,12 @@ pub(super) unsafe fn initialize_main(mem: *mut c_void) {
336330
let stack_least = stack_base.cast::<u8>().sub(stack_map_size);
337331
let stack_size = stack_least.offset_from(mem.cast::<u8>()) as usize;
338332
let guard_size = page_size();
333+
334+
// Initialize the canary value from the OS-provided random bytes.
335+
let random_ptr = rustix::runtime::random().cast::<usize>();
336+
let canary = random_ptr.read_unaligned();
337+
__stack_chk_guard = canary;
338+
339339
let map_size = 0;
340340

341341
// Compute relevant alignments.
@@ -390,14 +390,6 @@ pub(super) unsafe fn initialize_main(mem: *mut c_void) {
390390
let metadata: *mut Metadata = new.add(header).cast();
391391
let newtls: *mut c_void = (*metadata).abi.thread_pointee.as_mut_ptr().cast();
392392

393-
let thread_id_ptr = (*metadata).thread.thread_id.as_ptr();
394-
let tid = rustix::runtime::set_tid_address(thread_id_ptr.cast());
395-
396-
// Initialize the canary value from the OS-provided random bytes.
397-
let random_ptr = rustix::runtime::random().cast::<usize>();
398-
let canary = random_ptr.read_unaligned();
399-
__stack_chk_guard = canary;
400-
401393
// Initialize the thread metadata.
402394
metadata.write(Metadata {
403395
abi: Abi {
@@ -408,13 +400,7 @@ pub(super) unsafe fn initialize_main(mem: *mut c_void) {
408400
_pad: Default::default(),
409401
thread_pointee: [],
410402
},
411-
thread: ThreadData::new(
412-
Some(tid),
413-
stack_least.cast(),
414-
stack_size,
415-
guard_size,
416-
map_size,
417-
),
403+
thread: ThreadData::new(stack_least.cast(), stack_size, guard_size, map_size),
418404
});
419405

420406
// Initialize the TLS data with explicit initializer data.
@@ -432,6 +418,10 @@ pub(super) unsafe fn initialize_main(mem: *mut c_void) {
432418
)
433419
.fill(0);
434420

421+
let thread_id_ptr = (*metadata).thread.thread_id.as_ptr();
422+
let tid = rustix::runtime::set_tid_address(thread_id_ptr.cast());
423+
*thread_id_ptr = tid.as_raw_nonzero().get();
424+
435425
// Point the platform thread-pointer register at the new thread metadata.
436426
set_thread_pointer(newtls);
437427
}
@@ -544,13 +534,7 @@ pub unsafe fn create(
544534
_pad: Default::default(),
545535
thread_pointee: [],
546536
},
547-
thread: ThreadData::new(
548-
None, // the real tid will be written by `clone`.
549-
stack_least.cast(),
550-
stack_size,
551-
guard_size,
552-
map_size,
553-
),
537+
thread: ThreadData::new(stack_least.cast(), stack_size, guard_size, map_size),
554538
});
555539

556540
// Initialize the TLS data with explicit initializer data.

0 commit comments

Comments
 (0)