Skip to content

Commit

Permalink
Use .cast_mut and addr_of to avoid as casting raw pointers. (#81)
Browse files Browse the repository at this point in the history
`as` casts can do many different things; use the more specific
`cast`, `cast_mut`, and `addr_of` to be more specific about the
intention of pointer conversions.
  • Loading branch information
sunfishcode committed Oct 17, 2023
1 parent 7a54fb3 commit 242242f
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 9 deletions.
8 changes: 6 additions & 2 deletions src/arch/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use {
alloc::boxed::Box,
core::any::Any,
core::ffi::c_void,
core::ptr::invalid,
core::ptr::invalid_mut,
linux_raw_sys::general::{__NR_clone, __NR_exit, __NR_munmap},
rustix::thread::RawPid,
};
Expand Down Expand Up @@ -207,7 +207,11 @@ pub(super) unsafe fn clone(
"pop esi", // Restore incoming register value.

entry = sym super::thread::entry,
inout("eax") &[newtls as *mut c_void, invalid(__NR_clone as usize), fn_ as *mut c_void] => r0,
inout("eax") &[
newtls.cast::<c_void>().cast_mut(),
invalid_mut(__NR_clone as usize),
fn_.cast::<c_void>()
] => r0,
in("ebx") flags,
in("ecx") child_stack,
in("edx") parent_tid,
Expand Down
10 changes: 5 additions & 5 deletions src/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ pub(super) unsafe extern "C" fn entry(mem: *mut usize) -> ! {
// and envp as extra arguments. In addition to GLIBC ABI compatibility,
// c-scape relies on this.
type InitFn = extern "C" fn(c_int, *mut *mut u8, *mut *mut u8);
let mut init = &__init_array_start as *const _ as *const InitFn;
let init_end = &__init_array_end as *const _ as *const InitFn;
let mut init = addr_of!(__init_array_start).cast::<InitFn>();
let init_end = addr_of!(__init_array_end).cast::<InitFn>();
// Prevent the optimizer from optimizing the `!=` comparison to true;
// `init` and `init_start` may have the same address.
asm!("# {}", inout(reg) init, options(pure, nomem, nostack, preserves_flags));
Expand Down Expand Up @@ -252,7 +252,7 @@ pub fn at_exit(func: Box<dyn FnOnce() + Send>) {

// The function to pass to `__cxa_atexit`.
unsafe extern "C" fn at_exit_func(arg: *mut c_void) {
Box::from_raw(arg as *mut Box<dyn FnOnce() + Send>)();
Box::from_raw(arg.cast::<Box<dyn FnOnce() + Send>>())();
}

let at_exit_arg = Box::into_raw(Box::new(func)).cast::<c_void>();
Expand Down Expand Up @@ -301,8 +301,8 @@ pub fn exit(status: c_int) -> ! {

// Call the `.fini_array` functions.
type FiniFn = extern "C" fn();
let mut fini = &__fini_array_end as *const _ as *const FiniFn;
let fini_start = &__fini_array_start as *const _ as *const FiniFn;
let mut fini = addr_of!(__fini_array_end).cast::<FiniFn>();
let fini_start = addr_off!(__fini_array_start).cast::<FiniFn>();
// Prevent the optimizer from optimizing the `!=` comparison to true;
// `fini` and `fini_start` may have the same address.
asm!("# {}", inout(reg) fini, options(pure, nomem, nostack, preserves_flags));
Expand Down
2 changes: 1 addition & 1 deletion src/thread/libc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,5 +266,5 @@ pub fn yield_current_thread() {
/// Return the address of `__dso_handle`, appropriately casted.
unsafe fn dso_handle() -> *mut c_void {
let dso_handle: *const *const c_void = &__dso_handle;
dso_handle as *mut c_void
dso_handle.cast::<c_void>().cast_mut()
}
4 changes: 3 additions & 1 deletion src/thread/linux_raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,9 @@ pub(super) unsafe fn initialize_main_thread(mem: *mut c_void) {
// See <https://lwn.net/Articles/631631/> for details.
let execfn = linux_execfn().to_bytes_with_nul();
let stack_base = execfn.as_ptr().add(execfn.len());
let stack_base = stack_base.map_addr(|ptr| round_up(ptr, page_size())) as *mut c_void;
let stack_base = stack_base
.map_addr(|ptr| round_up(ptr, page_size()))
.cast_mut();

// We're running before any user code, so the startup soft stack limit is
// the effective stack size. Linux sets up inaccessible memory at the end
Expand Down

0 comments on commit 242242f

Please sign in to comment.