arch/x86_64: hack to work around ld64 shortcomings on OS X.
fix #35, close #36
This commit is contained in:
parent
49d1a24e8f
commit
a1ea208652
@ -1,5 +1,8 @@
|
||||
language: rust
|
||||
rust: nightly
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
sudo: false
|
||||
install:
|
||||
- .travis/docs/install
|
||||
|
@ -49,6 +49,7 @@ use stack::Stack;
|
||||
pub struct StackPointer(*mut usize);
|
||||
|
||||
pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackPointer {
|
||||
#[cfg(not(target_vendor = "apple"))]
|
||||
#[naked]
|
||||
unsafe extern "C" fn trampoline_1() {
|
||||
asm!(
|
||||
@ -77,6 +78,21 @@ pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackP
|
||||
: : "s" (trampoline_2 as usize) : "memory" : "volatile")
|
||||
}
|
||||
|
||||
#[cfg(target_vendor = "apple")]
|
||||
#[naked]
|
||||
unsafe extern "C" fn trampoline_1() {
|
||||
asm!(
|
||||
r#"
|
||||
# Same as above; however, .local and .size are not supported in Mach-O.
|
||||
__morestack:
|
||||
.private_extern __morestack
|
||||
.cfi_def_cfa %rbx, 0
|
||||
.cfi_offset %rbp, -16
|
||||
call ${0:c}
|
||||
"#
|
||||
: : "s" (trampoline_2 as usize) : "memory" : "volatile")
|
||||
}
|
||||
|
||||
#[naked]
|
||||
unsafe extern "C" fn trampoline_2() {
|
||||
asm!(
|
||||
@ -84,7 +100,16 @@ pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackP
|
||||
# Set up the second part of our DWARF CFI.
|
||||
# When unwinding the frame corresponding to this function, a DWARF unwinder
|
||||
# will restore %rbx (and thus CFA of the first trampoline) from the stack slot.
|
||||
.cfi_offset %rbx, 16
|
||||
#
|
||||
# The following is functionally equivalent to:
|
||||
# .cfi_offset %rbx, 16
|
||||
# however positive offsets in .cfi_offset translate to DW_CFA_offset_extended_sf,
|
||||
# and ld64's CFI parser only supports regular DW_CFA_offset (which only supports
|
||||
# negative offsets, with the sign being implicit), so to avoid crashing the linker
|
||||
# on OS X, fold offset into DW_CFA_def_offset.
|
||||
.cfi_def_cfa_offset 24
|
||||
.cfi_offset %rip, -24
|
||||
.cfi_offset %rbx, 0
|
||||
# Call the provided function.
|
||||
call *8(%rsp)
|
||||
"#
|
||||
|
@ -4,7 +4,7 @@
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
#![feature(asm, naked_functions)]
|
||||
#![feature(asm, naked_functions, cfg_target_vendor)]
|
||||
#![cfg_attr(feature = "alloc", feature(alloc))]
|
||||
#![cfg_attr(test, feature(test, thread_local, const_fn))]
|
||||
#![no_std]
|
||||
|
@ -17,13 +17,13 @@ use self::libc::MAP_FAILED;
|
||||
const GUARD_PROT: c_int = libc::PROT_NONE;
|
||||
const STACK_PROT: c_int = libc::PROT_READ
|
||||
| libc::PROT_WRITE;
|
||||
#[cfg(not(any(target_os = "freebsd", target_os = "dragonfly")))]
|
||||
#[cfg(not(any(target_os = "freebsd", target_os = "dragonfly", target_vendor = "apple")))]
|
||||
const STACK_FLAGS: c_int = libc::MAP_STACK
|
||||
| libc::MAP_PRIVATE
|
||||
| libc::MAP_ANON;
|
||||
// workaround for http://lists.freebsd.org/pipermail/freebsd-bugs/2011-July/044840.html
|
||||
// according to libgreen, DragonFlyBSD suffers from this too
|
||||
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
|
||||
#[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_vendor = "apple"))]
|
||||
const STACK_FLAGS: c_int = libc::MAP_PRIVATE
|
||||
| libc::MAP_ANON;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user