|
43 | 43 |
|
44 | 44 | #![cfg(not(windows))] // Windows already has builtins to do this
|
45 | 45 |
|
| 46 | +#[cfg(all( |
| 47 | + any(target_arch = "x86_64", target_arch = "x86"), |
| 48 | + not(target_vendor = "apple") |
| 49 | +))] |
46 | 50 | extern "C" {
|
47 | 51 | pub fn __rust_probestack();
|
48 | 52 | }
|
49 | 53 |
|
50 | 54 | #[naked]
|
51 | 55 | #[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 | +))] |
53 | 61 | pub unsafe extern "C" fn __rust_probestack_wrapper() {
|
54 | 62 | // Our goal here is to touch each page between %rsp+8 and %rsp+8-%rax,
|
55 | 63 | // 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() {
|
128 | 136 |
|
129 | 137 | #[naked]
|
130 | 138 | #[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 | +))] |
132 | 144 | pub unsafe extern "C" fn __rust_probestack_wrapper() {
|
133 | 145 | // This is the same as x86_64 above, only translated for 32-bit sizes. Note
|
134 | 146 | // 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() {
|
179 | 191 | " ::: "memory" : "volatile");
|
180 | 192 | ::core::intrinsics::unreachable();
|
181 | 193 | }
|
| 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