|  | 
| 41 | 41 | //! probes on any other architecture like ARM or PowerPC64. LLVM I'm sure would | 
| 42 | 42 | //! be more than welcome to accept such a change! | 
| 43 | 43 | 
 | 
| 44 |  | -#![cfg(not(windows))] // Windows already has builtins to do this | 
| 45 |  | - | 
| 46 |  | -#[naked] | 
| 47 |  | -#[no_mangle] | 
| 48 |  | -#[cfg(all(target_arch = "x86_64", not(feature = "mangled-names")))] | 
| 49 |  | -pub unsafe extern "C" fn __rust_probestack() { | 
| 50 |  | -    // Our goal here is to touch each page between %rsp+8 and %rsp+8-%rax, | 
| 51 |  | -    // ensuring that if any pages are unmapped we'll make a page fault. | 
| 52 |  | -    // | 
| 53 |  | -    // The ABI here is that the stack frame size is located in `%eax`. Upon | 
| 54 |  | -    // return we're not supposed to modify `%esp` or `%eax`. | 
| 55 |  | -    asm!(" | 
| 56 |  | -        mov    %rax,%r11        // duplicate %rax as we're clobbering %r11 | 
| 57 |  | -
 | 
| 58 |  | -        // Main loop, taken in one page increments. We're decrementing rsp by | 
| 59 |  | -        // a page each time until there's less than a page remaining. We're | 
| 60 |  | -        // guaranteed that this function isn't called unless there's more than a | 
| 61 |  | -        // page needed. | 
| 62 |  | -        // | 
| 63 |  | -        // Note that we're also testing against `8(%rsp)` to account for the 8 | 
| 64 |  | -        // bytes pushed on the stack orginally with our return address. Using | 
| 65 |  | -        // `8(%rsp)` simulates us testing the stack pointer in the caller's | 
| 66 |  | -        // context. | 
| 67 |  | -
 | 
| 68 |  | -        // It's usually called when %rax >= 0x1000, but that's not always true. | 
| 69 |  | -        // Dynamic stack allocation, which is needed to implement unsized | 
| 70 |  | -        // rvalues, triggers stackprobe even if %rax < 0x1000. | 
| 71 |  | -        // Thus we have to check %r11 first to avoid segfault. | 
| 72 |  | -        cmp    $$0x1000,%r11 | 
| 73 |  | -        jna    3f | 
| 74 |  | -    2: | 
| 75 |  | -        sub    $$0x1000,%rsp | 
| 76 |  | -        test   %rsp,8(%rsp) | 
| 77 |  | -        sub    $$0x1000,%r11 | 
| 78 |  | -        cmp    $$0x1000,%r11 | 
| 79 |  | -        ja     2b | 
| 80 |  | -
 | 
| 81 |  | -    3: | 
| 82 |  | -        // Finish up the last remaining stack space requested, getting the last | 
| 83 |  | -        // bits out of r11 | 
| 84 |  | -        sub    %r11,%rsp | 
| 85 |  | -        test   %rsp,8(%rsp) | 
| 86 |  | -
 | 
| 87 |  | -        // Restore the stack pointer to what it previously was when entering | 
| 88 |  | -        // this function. The caller will readjust the stack pointer after we | 
| 89 |  | -        // return. | 
| 90 |  | -        add    %rax,%rsp | 
| 91 |  | -
 | 
| 92 |  | -        ret | 
| 93 |  | -    " ::: "memory" : "volatile"); | 
| 94 |  | -    ::core::intrinsics::unreachable(); | 
| 95 |  | -} | 
| 96 |  | - | 
| 97 |  | -#[naked] | 
| 98 |  | -#[no_mangle] | 
| 99 |  | -#[cfg(all(target_arch = "x86", not(feature = "mangled-names")))] | 
| 100 |  | -pub unsafe extern "C" fn __rust_probestack() { | 
| 101 |  | -    // This is the same as x86_64 above, only translated for 32-bit sizes. Note | 
| 102 |  | -    // that on Unix we're expected to restore everything as it was, this | 
| 103 |  | -    // function basically can't tamper with anything. | 
| 104 |  | -    // | 
| 105 |  | -    // The ABI here is the same as x86_64, except everything is 32-bits large. | 
| 106 |  | -    asm!(" | 
| 107 |  | -        push   %ecx | 
| 108 |  | -        mov    %eax,%ecx | 
| 109 |  | -
 | 
| 110 |  | -        cmp    $$0x1000,%ecx | 
| 111 |  | -        jna    3f | 
| 112 |  | -    2: | 
| 113 |  | -        sub    $$0x1000,%esp | 
| 114 |  | -        test   %esp,8(%esp) | 
| 115 |  | -        sub    $$0x1000,%ecx | 
| 116 |  | -        cmp    $$0x1000,%ecx | 
| 117 |  | -        ja     2b | 
| 118 |  | -
 | 
| 119 |  | -    3: | 
| 120 |  | -        sub    %ecx,%esp | 
| 121 |  | -        test   %esp,8(%esp) | 
| 122 |  | -
 | 
| 123 |  | -        add    %eax,%esp | 
| 124 |  | -        pop    %ecx | 
| 125 |  | -        ret | 
| 126 |  | -    " ::: "memory" : "volatile"); | 
| 127 |  | -    ::core::intrinsics::unreachable(); | 
| 128 |  | -} | 
|  | 44 | +// The code here moved to probestack_*.S, to support debugger frame information. | 
0 commit comments