unix: split stack_overflow::install_main_guard by os

This commit is contained in:
Jubilee Young 2024-07-16 22:50:25 -07:00
parent 1a6e777c3c
commit 17c70a9aac

View File

@ -325,9 +325,27 @@ mod imp {
}) })
} }
#[forbid(unsafe_op_in_unsafe_fn)]
unsafe fn install_main_guard() -> Option<Range<usize>> { unsafe fn install_main_guard() -> Option<Range<usize>> {
let page_size = PAGE_SIZE.load(Ordering::Relaxed); let page_size = PAGE_SIZE.load(Ordering::Relaxed);
unsafe {
// this way someone on any unix-y OS can check that all these compile
if cfg!(all(target_os = "linux", not(target_env = "musl"))) { if cfg!(all(target_os = "linux", not(target_env = "musl"))) {
install_main_guard_linux(page_size)
} else if cfg!(all(target_os = "linux", target_env = "musl")) {
install_main_guard_linux_musl(page_size)
} else if cfg!(target_os = "freebsd") {
install_main_guard_freebsd(page_size)
} else if cfg!(any(target_os = "netbsd", target_os = "openbsd")) {
install_main_guard_bsds(page_size)
} else {
install_main_guard_default(page_size)
}
}
}
unsafe fn install_main_guard_linux(page_size: usize) -> Option<Range<usize>> {
// Linux doesn't allocate the whole stack right away, and // Linux doesn't allocate the whole stack right away, and
// the kernel has its own stack-guard mechanism to fault // the kernel has its own stack-guard mechanism to fault
// when growing too close to an existing mapping. If we map // when growing too close to an existing mapping. If we map
@ -341,13 +359,17 @@ mod imp {
let stackptr = get_stack_start_aligned()?; let stackptr = get_stack_start_aligned()?;
let stackaddr = stackptr.addr(); let stackaddr = stackptr.addr();
Some(stackaddr - page_size..stackaddr) Some(stackaddr - page_size..stackaddr)
} else if cfg!(all(target_os = "linux", target_env = "musl")) { }
unsafe fn install_main_guard_linux_musl(_page_size: usize) -> Option<Range<usize>> {
// For the main thread, the musl's pthread_attr_getstack // For the main thread, the musl's pthread_attr_getstack
// returns the current stack size, rather than maximum size // returns the current stack size, rather than maximum size
// it can eventually grow to. It cannot be used to determine // it can eventually grow to. It cannot be used to determine
// the position of kernel's stack guard. // the position of kernel's stack guard.
None None
} else if cfg!(target_os = "freebsd") { }
unsafe fn install_main_guard_freebsd(page_size: usize) -> Option<Range<usize>> {
// FreeBSD's stack autogrows, and optionally includes a guard page // FreeBSD's stack autogrows, and optionally includes a guard page
// at the bottom. If we try to remap the bottom of the stack // at the bottom. If we try to remap the bottom of the stack
// ourselves, FreeBSD's guard page moves upwards. So we'll just use // ourselves, FreeBSD's guard page moves upwards. So we'll just use
@ -381,7 +403,9 @@ mod imp {
} }
}); });
Some(guardaddr..guardaddr + pages * page_size) Some(guardaddr..guardaddr + pages * page_size)
} else if cfg!(any(target_os = "openbsd", target_os = "netbsd")) { }
unsafe fn install_main_guard_bsds(page_size: usize) -> Option<Range<usize>> {
// OpenBSD stack already includes a guard page, and stack is // OpenBSD stack already includes a guard page, and stack is
// immutable. // immutable.
// NetBSD stack includes the guard page. // NetBSD stack includes the guard page.
@ -392,7 +416,9 @@ mod imp {
let stackptr = get_stack_start_aligned()?; let stackptr = get_stack_start_aligned()?;
let stackaddr = stackptr.addr(); let stackaddr = stackptr.addr();
Some(stackaddr - page_size..stackaddr) Some(stackaddr - page_size..stackaddr)
} else { }
unsafe fn install_main_guard_default(page_size: usize) -> Option<Range<usize>> {
// Reallocate the last page of the stack. // Reallocate the last page of the stack.
// This ensures SIGBUS will be raised on // This ensures SIGBUS will be raised on
// stack overflow. // stack overflow.
@ -423,7 +449,6 @@ mod imp {
Some(guardaddr..guardaddr + page_size) Some(guardaddr..guardaddr + page_size)
} }
}
#[cfg(any(target_os = "macos", target_os = "openbsd", target_os = "solaris"))] #[cfg(any(target_os = "macos", target_os = "openbsd", target_os = "solaris"))]
unsafe fn current_guard() -> Option<Range<usize>> { unsafe fn current_guard() -> Option<Range<usize>> {