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__)
57 // Set up a normal backtrace
60 .cfi_def_cfa_offset 16
65 .cfi_def_cfa_register %rbp
68 // During unwinding we want to skip our caller since it's not
69 // a complete frame and will make the unwinder sad
70 #if defined(__linux__)
71 // Don't understand this line
73 // Tell the unwinding where to get the stack pointer for
74 // our grandparent frame
78 // Save the grandparent stack pointer for the unwinder
82 // FIXME: libgcc also saves rax. not sure if we need to
84 // Save argument registers
92 // Calculate the address of the stack arguments.
93 // We have the base pointer, __morestack's return address,
94 // and __morestack's caller's return address to skip
96 addq $24, %rcx // Base pointer, return address x2
98 pushq %r11 // Size of stack arguments
99 pushq %rcx // Address of stack arguments
100 pushq %r10 // The amount of stack needed
101 pushq $0 // Out pointer
103 movq UPCALL_NEW_STACK@GOTPCREL(%rip), %rsi
109 call UPCALL_CALL_C@PLT
112 // Pop the new_stack_args struct
116 // Pop the saved arguments
124 // Pop the unwinding %rsp
127 movq 8(%rbp),%r10 // Grab the return pointer.
128 incq %r10 // Skip past the `ret` in our parent frame
129 movq %rax,%rsp // Switch to the new stack.
131 call *%r10 // Reenter the caller function
133 // Switch back to the rust stack
136 // Align the stack again
139 movq UPCALL_DEL_STACK@GOTPCREL(%rip), %rsi
145 call UPCALL_CALL_C@PLT