Skip to content

Commit

Permalink
Add control flow information to __rust_probestack
Browse files Browse the repository at this point in the history
  • Loading branch information
tmandry committed Dec 5, 2019
1 parent 0df0cf5 commit 10ffd32
Showing 1 changed file with 50 additions and 4 deletions.
54 changes: 50 additions & 4 deletions src/probestack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,36 @@
#![cfg(not(windows))] // Windows already has builtins to do this

extern "C" {
pub fn __rust_probestack();
}

#[naked]
#[no_mangle]
#[cfg(all(target_arch = "x86_64", not(feature = "mangled-names")))]
pub unsafe extern "C" fn __rust_probestack() {
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.
//
// The ABI here is that the stack frame size is located in `%eax`. Upon
// return we're not supposed to modify `%esp` or `%eax`.
// The ABI here is that the stack frame size is located in `%rax`. Upon
// return we're not supposed to modify `%rsp` or `%rax`.
asm!("
// We are about to define a 'function within a function.' Because the
// compiler will have emitted a .cfi_startproc at the beginning of
// __rust_probestack_wrapper, we need .cfi_endproc before we can define
// the contents of __rust_probestack.
.cfi_endproc
.pushsection .text.__rust_probestack
.globl __rust_probestack
.type __rust_probestack, @function
__rust_probestack:
.cfi_startproc
pushq %rbp
.cfi_adjust_cfa_offset 8
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
mov %rax,%r11 // duplicate %rax as we're clobbering %r11
Expand Down Expand Up @@ -93,23 +111,43 @@ pub unsafe extern "C" fn __rust_probestack() {
add %rax,%rsp
leave
.cfi_def_cfa_register %rsp
.cfi_adjust_cfa_offset -8
ret
.cfi_endproc
.size __rust_probestack, . - __rust_probestack
.popsection
// Similar to above, we add .cfi_startproc here to match the
// .cfi_endproc emitted at the end of __rust_probestack_wrapper.
.cfi_startproc
" ::: "memory" : "volatile");
::core::intrinsics::unreachable();
}

#[naked]
#[no_mangle]
#[cfg(all(target_arch = "x86", not(feature = "mangled-names")))]
pub unsafe extern "C" fn __rust_probestack() {
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
// function basically can't tamper with anything.
//
// The ABI here is the same as x86_64, except everything is 32-bits large.
asm!("
.cfi_endproc
.pushsection .text.__rust_probestack
.globl __rust_probestack
.type __rust_probestack, @function
__rust_probestack:
.cfi_startproc
push %ebp
.cfi_adjust_cfa_offset 4
.cfi_offset %ebp, -8
mov %esp, %ebp
.cfi_def_cfa_register %ebp
push %ecx
mov %eax,%ecx
Expand All @@ -129,7 +167,15 @@ pub unsafe extern "C" fn __rust_probestack() {
add %eax,%esp
pop %ecx
leave
.cfi_def_cfa_register %esp
.cfi_adjust_cfa_offset -4
ret
.cfi_endproc
.size __rust_probestack, . - __rust_probestack
.popsection
.cfi_startproc
" ::: "memory" : "volatile");
::core::intrinsics::unreachable();
}

0 comments on commit 10ffd32

Please sign in to comment.