Skip to content

Commit

Permalink
Split out probestack impl for Apple platforms
Browse files Browse the repository at this point in the history
  • Loading branch information
tmandry committed Dec 5, 2019
1 parent 10ffd32 commit 928bd0a
Showing 1 changed file with 92 additions and 2 deletions.
94 changes: 92 additions & 2 deletions src/probestack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,21 @@
#![cfg(not(windows))] // Windows already has builtins to do this

#[cfg(all(
any(target_arch = "x86_64", target_arch = "x86"),
not(target_vendor = "apple")
))]
extern "C" {
pub fn __rust_probestack();
}

#[naked]
#[no_mangle]
#[cfg(all(target_arch = "x86_64", not(feature = "mangled-names")))]
#[cfg(all(
target_arch = "x86_64",
not(target_vendor = "apple"),
not(feature = "mangled-names")
))]
pub unsafe extern "C" fn __rust_probestack_wrapper() {
// Our goal here is to touch each page between %rsp+8 and %rsp+8-%rax,
// ensuring that if any pages are unmapped we'll make a page fault.
Expand Down Expand Up @@ -128,7 +136,11 @@ pub unsafe extern "C" fn __rust_probestack_wrapper() {

#[naked]
#[no_mangle]
#[cfg(all(target_arch = "x86", not(feature = "mangled-names")))]
#[cfg(all(
target_arch = "x86",
not(target_vendor = "apple"),
not(feature = "mangled-names")
))]
pub unsafe extern "C" fn __rust_probestack_wrapper() {
// This is the same as x86_64 above, only translated for 32-bit sizes. Note
// that on Unix we're expected to restore everything as it was, this
Expand Down Expand Up @@ -179,3 +191,81 @@ pub unsafe extern "C" fn __rust_probestack_wrapper() {
" ::: "memory" : "volatile");
::core::intrinsics::unreachable();
}

#[naked]
#[no_mangle]
#[cfg(all(
target_arch = "x86_64",
target_vendor = "apple",
not(feature = "mangled-names")
))]
pub unsafe extern "C" fn __rust_probestack() {
// Same as above, but without the CFI tricks. The assembler for Apple
// devices doesn't support the directives we were using to define
// __rust_probestack.
asm!("
pushq %rbp
movq %rsp, %rbp
mov %rax,%r11
cmp $$0x1000,%r11
jna 3f
2:
sub $$0x1000,%rsp
test %rsp,8(%rsp)
sub $$0x1000,%r11
cmp $$0x1000,%r11
ja 2b
3:
sub %r11,%rsp
test %rsp,8(%rsp)
add %rax,%rsp
leave
ret
" ::: "memory" : "volatile");
::core::intrinsics::unreachable();
}

#[naked]
#[no_mangle]
#[cfg(all(
target_arch = "x86",
target_vendor = "apple",
not(feature = "mangled-names")
))]
pub unsafe extern "C" fn __rust_probestack() {
// This is the same as x86_64 above, only translated for 32-bit sizes. Note
// that on Unix we're expected to restore everything as it was, this
// function basically can't tamper with anything.
//
// The ABI here is the same as x86_64, except everything is 32-bits large.
asm!("
push %ebp
mov %esp, %ebp
push %ecx
mov %eax,%ecx
cmp $$0x1000,%ecx
jna 3f
2:
sub $$0x1000,%esp
test %esp,8(%esp)
sub $$0x1000,%ecx
cmp $$0x1000,%ecx
ja 2b
3:
sub %ecx,%esp
test %esp,8(%esp)
add %eax,%esp
pop %ecx
leave
ret
" ::: "memory" : "volatile");
::core::intrinsics::unreachable();
}

0 comments on commit 928bd0a

Please sign in to comment.