Skip to content

Commit 928bd0a

Browse files
committed
Split out probestack impl for Apple platforms
1 parent 10ffd32 commit 928bd0a

File tree

1 file changed

+92
-2
lines changed

1 file changed

+92
-2
lines changed

src/probestack.rs

+92-2
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,21 @@
4343
4444
#![cfg(not(windows))] // Windows already has builtins to do this
4545

46+
#[cfg(all(
47+
any(target_arch = "x86_64", target_arch = "x86"),
48+
not(target_vendor = "apple")
49+
))]
4650
extern "C" {
4751
pub fn __rust_probestack();
4852
}
4953

5054
#[naked]
5155
#[no_mangle]
52-
#[cfg(all(target_arch = "x86_64", not(feature = "mangled-names")))]
56+
#[cfg(all(
57+
target_arch = "x86_64",
58+
not(target_vendor = "apple"),
59+
not(feature = "mangled-names")
60+
))]
5361
pub unsafe extern "C" fn __rust_probestack_wrapper() {
5462
// Our goal here is to touch each page between %rsp+8 and %rsp+8-%rax,
5563
// ensuring that if any pages are unmapped we'll make a page fault.
@@ -128,7 +136,11 @@ pub unsafe extern "C" fn __rust_probestack_wrapper() {
128136

129137
#[naked]
130138
#[no_mangle]
131-
#[cfg(all(target_arch = "x86", not(feature = "mangled-names")))]
139+
#[cfg(all(
140+
target_arch = "x86",
141+
not(target_vendor = "apple"),
142+
not(feature = "mangled-names")
143+
))]
132144
pub unsafe extern "C" fn __rust_probestack_wrapper() {
133145
// This is the same as x86_64 above, only translated for 32-bit sizes. Note
134146
// that on Unix we're expected to restore everything as it was, this
@@ -179,3 +191,81 @@ pub unsafe extern "C" fn __rust_probestack_wrapper() {
179191
" ::: "memory" : "volatile");
180192
::core::intrinsics::unreachable();
181193
}
194+
195+
#[naked]
196+
#[no_mangle]
197+
#[cfg(all(
198+
target_arch = "x86_64",
199+
target_vendor = "apple",
200+
not(feature = "mangled-names")
201+
))]
202+
pub unsafe extern "C" fn __rust_probestack() {
203+
// Same as above, but without the CFI tricks. The assembler for Apple
204+
// devices doesn't support the directives we were using to define
205+
// __rust_probestack.
206+
asm!("
207+
pushq %rbp
208+
movq %rsp, %rbp
209+
210+
mov %rax,%r11
211+
212+
cmp $$0x1000,%r11
213+
jna 3f
214+
2:
215+
sub $$0x1000,%rsp
216+
test %rsp,8(%rsp)
217+
sub $$0x1000,%r11
218+
cmp $$0x1000,%r11
219+
ja 2b
220+
221+
3:
222+
sub %r11,%rsp
223+
test %rsp,8(%rsp)
224+
225+
add %rax,%rsp
226+
227+
leave
228+
ret
229+
" ::: "memory" : "volatile");
230+
::core::intrinsics::unreachable();
231+
}
232+
233+
#[naked]
234+
#[no_mangle]
235+
#[cfg(all(
236+
target_arch = "x86",
237+
target_vendor = "apple",
238+
not(feature = "mangled-names")
239+
))]
240+
pub unsafe extern "C" fn __rust_probestack() {
241+
// This is the same as x86_64 above, only translated for 32-bit sizes. Note
242+
// that on Unix we're expected to restore everything as it was, this
243+
// function basically can't tamper with anything.
244+
//
245+
// The ABI here is the same as x86_64, except everything is 32-bits large.
246+
asm!("
247+
push %ebp
248+
mov %esp, %ebp
249+
push %ecx
250+
mov %eax,%ecx
251+
252+
cmp $$0x1000,%ecx
253+
jna 3f
254+
2:
255+
sub $$0x1000,%esp
256+
test %esp,8(%esp)
257+
sub $$0x1000,%ecx
258+
cmp $$0x1000,%ecx
259+
ja 2b
260+
261+
3:
262+
sub %ecx,%esp
263+
test %esp,8(%esp)
264+
265+
add %eax,%esp
266+
pop %ecx
267+
leave
268+
ret
269+
" ::: "memory" : "volatile");
270+
::core::intrinsics::unreachable();
271+
}

0 commit comments

Comments
 (0)