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
|
language: rust
|
||||||
rust: nightly
|
rust: nightly
|
||||||
|
os:
|
||||||
|
- linux
|
||||||
|
- osx
|
||||||
sudo: false
|
sudo: false
|
||||||
install:
|
install:
|
||||||
- .travis/docs/install
|
- .travis/docs/install
|
||||||
|
|
|
@ -49,6 +49,7 @@ use stack::Stack;
|
||||||
pub struct StackPointer(*mut usize);
|
pub struct StackPointer(*mut usize);
|
||||||
|
|
||||||
pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackPointer {
|
pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackPointer {
|
||||||
|
#[cfg(not(target_vendor = "apple"))]
|
||||||
#[naked]
|
#[naked]
|
||||||
unsafe extern "C" fn trampoline_1() {
|
unsafe extern "C" fn trampoline_1() {
|
||||||
asm!(
|
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")
|
: : "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]
|
#[naked]
|
||||||
unsafe extern "C" fn trampoline_2() {
|
unsafe extern "C" fn trampoline_2() {
|
||||||
asm!(
|
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.
|
# Set up the second part of our DWARF CFI.
|
||||||
# When unwinding the frame corresponding to this function, a DWARF unwinder
|
# 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.
|
# 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 the provided function.
|
||||||
call *8(%rsp)
|
call *8(%rsp)
|
||||||
"#
|
"#
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
// 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
|
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||||
// copied, modified, or distributed except according to those terms.
|
// 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(feature = "alloc", feature(alloc))]
|
||||||
#![cfg_attr(test, feature(test, thread_local, const_fn))]
|
#![cfg_attr(test, feature(test, thread_local, const_fn))]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
|
@ -17,13 +17,13 @@ use self::libc::MAP_FAILED;
|
||||||
const GUARD_PROT: c_int = libc::PROT_NONE;
|
const GUARD_PROT: c_int = libc::PROT_NONE;
|
||||||
const STACK_PROT: c_int = libc::PROT_READ
|
const STACK_PROT: c_int = libc::PROT_READ
|
||||||
| libc::PROT_WRITE;
|
| 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
|
const STACK_FLAGS: c_int = libc::MAP_STACK
|
||||||
| libc::MAP_PRIVATE
|
| libc::MAP_PRIVATE
|
||||||
| libc::MAP_ANON;
|
| libc::MAP_ANON;
|
||||||
// workaround for http://lists.freebsd.org/pipermail/freebsd-bugs/2011-July/044840.html
|
// workaround for http://lists.freebsd.org/pipermail/freebsd-bugs/2011-July/044840.html
|
||||||
// according to libgreen, DragonFlyBSD suffers from this too
|
// 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
|
const STACK_FLAGS: c_int = libc::MAP_PRIVATE
|
||||||
| libc::MAP_ANON;
|
| libc::MAP_ANON;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue