5 // LLVM generates a call to this to allocate more stack space in a functiono
6 // prolog when we run out.
8 #if defined(__APPLE__) || defined(_WIN32)
9 #define UPCALL_NEW_STACK _upcall_new_stack
10 #define UPCALL_DEL_STACK _upcall_del_stack
11 #define UPCALL_CALL_C _upcall_call_shim_on_c_stack
12 #define MORESTACK ___morestack
14 #define UPCALL_NEW_STACK upcall_new_stack
15 #define UPCALL_DEL_STACK upcall_del_stack
16 #define UPCALL_CALL_C upcall_call_shim_on_c_stack
17 #define MORESTACK __morestack
20 // Naturally, nobody can agree as to
21 // which arguments should go in which
33 .globl UPCALL_NEW_STACK
34 .globl UPCALL_DEL_STACK
38 // FIXME: What about _WIN32?
39 #if defined(__linux__)
42 #if defined(__APPLE__)
43 .private_extern MORESTACK
48 .type MORESTACK,@function
51 #if defined(__linux__) || defined(__APPLE__)
55 // Set up a normal backtrace
57 .cfi_def_cfa_offset 24
60 .cfi_def_cfa_register %rbp
62 // Save the grandparent stack pointer for the unwinder
66 // FIXME: libgcc also saves rax. not sure if we need to
68 // Save argument registers
76 // Calculate the address of the stack arguments.
77 // We have the base pointer, __morestack's return address,
78 // and __morestack's caller's return address to skip
80 addq $24, %rcx // Base pointer, return address x2
82 pushq %r11 // Size of stack arguments
83 pushq %rcx // Address of stack arguments
84 pushq %r10 // The amount of stack needed
85 pushq $0 // Out pointer
87 movq UPCALL_NEW_STACK@GOTPCREL(%rip), %rsi
93 call UPCALL_CALL_C@PLT
96 // Pop the new_stack_args struct
100 // Pop the saved arguments
108 // Pop the unwinding %rsp
111 movq 8(%rbp),%r10 // Grab the return pointer.
112 incq %r10 // Skip past the `ret` in our parent frame
113 movq %rax,%rsp // Switch to the new stack.
115 call *%r10 // Reenter the caller function
117 // Switch back to the rust stack
120 // Align the stack again
123 movq UPCALL_DEL_STACK@GOTPCREL(%rip), %rsi
129 call UPCALL_CALL_C@PLT
135 .cfi_def_cfa %rsp, 16