Skip to content

Commit 24e2d26

Browse files
committed
Split out probestack impl for Apple platforms
1 parent 10ffd32 commit 24e2d26

File tree

1 file changed

+73
-2
lines changed

1 file changed

+73
-2
lines changed

src/probestack.rs

Lines changed: 73 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,14 @@
4343
4444
#![cfg(not(windows))] // Windows already has builtins to do this
4545

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

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

129130
#[naked]
130131
#[no_mangle]
131-
#[cfg(all(target_arch = "x86", not(feature = "mangled-names")))]
132+
#[cfg(all(target_arch = "x86", not(target_vendor = "apple"), not(feature = "mangled-names")))]
132133
pub unsafe extern "C" fn __rust_probestack_wrapper() {
133134
// This is the same as x86_64 above, only translated for 32-bit sizes. Note
134135
// that on Unix we're expected to restore everything as it was, this
@@ -179,3 +180,73 @@ pub unsafe extern "C" fn __rust_probestack_wrapper() {
179180
" ::: "memory" : "volatile");
180181
::core::intrinsics::unreachable();
181182
}
183+
184+
#[naked]
185+
#[no_mangle]
186+
#[cfg(all(target_arch = "x86_64", target_vendor = "apple", not(feature = "mangled-names")))]
187+
pub unsafe extern "C" fn __rust_probestack() {
188+
// Same as above, but without the CFI tricks. The assembler for Apple
189+
// devices doesn't support the directives we were using to define
190+
// __rust_probestack.
191+
asm!("
192+
pushq %rbp
193+
movq %rsp, %rbp
194+
195+
mov %rax,%r11
196+
197+
cmp $$0x1000,%r11
198+
jna 3f
199+
2:
200+
sub $$0x1000,%rsp
201+
test %rsp,8(%rsp)
202+
sub $$0x1000,%r11
203+
cmp $$0x1000,%r11
204+
ja 2b
205+
206+
3:
207+
sub %r11,%rsp
208+
test %rsp,8(%rsp)
209+
210+
add %rax,%rsp
211+
212+
leave
213+
ret
214+
" ::: "memory" : "volatile");
215+
::core::intrinsics::unreachable();
216+
}
217+
218+
#[naked]
219+
#[no_mangle]
220+
#[cfg(all(target_arch = "x86", target_vendor = "apple", not(feature = "mangled-names")))]
221+
pub unsafe extern "C" fn __rust_probestack() {
222+
// This is the same as x86_64 above, only translated for 32-bit sizes. Note
223+
// that on Unix we're expected to restore everything as it was, this
224+
// function basically can't tamper with anything.
225+
//
226+
// The ABI here is the same as x86_64, except everything is 32-bits large.
227+
asm!("
228+
push %ebp
229+
mov %esp, %ebp
230+
push %ecx
231+
mov %eax,%ecx
232+
233+
cmp $$0x1000,%ecx
234+
jna 3f
235+
2:
236+
sub $$0x1000,%esp
237+
test %esp,8(%esp)
238+
sub $$0x1000,%ecx
239+
cmp $$0x1000,%ecx
240+
ja 2b
241+
242+
3:
243+
sub %ecx,%esp
244+
test %esp,8(%esp)
245+
246+
add %eax,%esp
247+
pop %ecx
248+
leave
249+
ret
250+
" ::: "memory" : "volatile");
251+
::core::intrinsics::unreachable();
252+
}

0 commit comments

Comments
 (0)