Skip to content

Commit

Permalink
Split out define_rust_probestack!, specialize for apple
Browse files Browse the repository at this point in the history
  • Loading branch information
tmandry committed Dec 5, 2019
1 parent 10ffd32 commit 66b1486
Showing 1 changed file with 71 additions and 36 deletions.
107 changes: 71 additions & 36 deletions src/probestack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,73 @@ extern "C" {
pub fn __rust_probestack();
}

// A wrapper for our implementation of __rust_probestack, which allows us to
// keep the assembly inline while controlling all CFI directives in the assembly
// emitted for the function.
//
// This is the ELF version.
#[cfg(all(
any(target_arch = "x86_64", target_arch = "x86"),
not(target_vendor = "apple")
))]
macro_rules! define_rust_probestack {
($body: expr) => {
concat!(
"
// 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
",
$body,
"
.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
"
)
};
}

// Same as above, but for Mach-O.
#[cfg(all(
any(target_arch = "x86_64", target_arch = "x86"),
target_vendor = "apple"
))]
macro_rules! define_rust_probestack {
($body: expr) => {
concat!(
"
.cfi_endproc
.globl __rust_probestack
__rust_probestack:
.cfi_startproc
",
$body,
"
.cfi_endproc
.cfi_startproc
"
)
};
}

#[naked]
#[no_mangle]
#[cfg(all(target_arch = "x86_64", not(feature = "mangled-names")))]
Expand All @@ -56,18 +123,7 @@ pub unsafe extern "C" fn __rust_probestack_wrapper() {
//
// 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
asm!(define_rust_probestack!("
pushq %rbp
.cfi_adjust_cfa_offset 8
.cfi_offset %rbp, -16
Expand Down Expand Up @@ -114,15 +170,7 @@ pub unsafe extern "C" fn __rust_probestack_wrapper() {
.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");
") ::: "memory" : "volatile");
::core::intrinsics::unreachable();
}

Expand All @@ -135,14 +183,7 @@ pub unsafe extern "C" fn __rust_probestack_wrapper() {
// 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
asm!(define_rust_probestack!("
push %ebp
.cfi_adjust_cfa_offset 4
.cfi_offset %ebp, -8
Expand Down Expand Up @@ -170,12 +211,6 @@ pub unsafe extern "C" fn __rust_probestack_wrapper() {
.cfi_def_cfa_register %esp
.cfi_adjust_cfa_offset -4
ret
.cfi_endproc
.size __rust_probestack, . - __rust_probestack
.popsection
.cfi_startproc
" ::: "memory" : "volatile");
") ::: "memory" : "volatile");
::core::intrinsics::unreachable();
}

0 comments on commit 66b1486

Please sign in to comment.