1 // Mark stack as non-executable
2 #if defined(__linux__) && defined(__ELF__)
3 .section .note.GNU-stack, "", @progbits
9 See i386/morestack.S for the lengthy, general explanation.
14 #if defined(__APPLE__) || defined(_WIN32)
15 #define UPCALL_NEW_STACK _upcall_new_stack
16 #define UPCALL_DEL_STACK _upcall_del_stack
17 #define MORESTACK ___morestack
19 #define UPCALL_NEW_STACK upcall_new_stack
20 #define UPCALL_DEL_STACK upcall_del_stack
21 #define MORESTACK __morestack
24 .globl UPCALL_NEW_STACK
25 .globl UPCALL_DEL_STACK
28 #if defined(__linux__) || defined(__FreeBSD__)
31 #if defined(__APPLE__)
32 .private_extern MORESTACK
37 .type MORESTACK,@function
41 #if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)
46 // The CFA is 24 bytes above the register that it will
47 // be associated with for this frame (%rbp). That is 8
48 // bytes greater than a normal frame, to allow the unwinder
49 // to skip the partial frame of the original function.
50 .cfi_def_cfa_offset 24
51 // %rbp is -24 bytes from the CFA
54 // Calculate the CFA as on offset from %ebp
55 .cfi_def_cfa_register %rbp
59 // Save argument registers of the original function
66 movdqa %xmm0, 48(%rsp)
67 movdqa %xmm1, 64(%rsp)
68 movdqa %xmm2, 80(%rsp)
69 movdqa %xmm3, 96(%rsp)
70 movdqa %xmm4, 112(%rsp)
71 movdqa %xmm5, 128(%rsp)
72 movdqa %xmm6, 144(%rsp)
73 movdqa %xmm7, 160(%rsp)
75 // Calculate the address of the stack arguments.
76 // We have the base pointer, __morestack's return address,
77 // and __morestack's caller's return address to skip
79 addq $24, %rax // Base pointer, return address x2
81 // The arguments to __morestack are passed in %r10 & %r11
83 movq %r11, %rdx // Size of stack arguments
84 movq %rax, %rsi // Address of stack arguments
85 movq %r10, %rdi // The amount of stack needed
91 call UPCALL_NEW_STACK@PLT
94 call UPCALL_NEW_STACK@PLT
97 // Pop the saved arguments
104 movdqa 48(%rsp), %xmm0
105 movdqa 64(%rsp), %xmm1
106 movdqa 80(%rsp), %xmm2
107 movdqa 96(%rsp), %xmm3
108 movdqa 112(%rsp), %xmm4
109 movdqa 128(%rsp), %xmm5
110 movdqa 144(%rsp), %xmm6
111 movdqa 160(%rsp), %xmm7
115 movq 8(%rbp),%r10 // Grab the return pointer.
116 incq %r10 // Skip past the `ret` in our parent frame
117 movq %rax,%rsp // Switch to the new stack.
119 call *%r10 // Reenter the caller function
121 // Switch back to the rust stack
124 // Save the return value
128 call UPCALL_DEL_STACK
131 call UPCALL_DEL_STACK@PLT
134 call UPCALL_DEL_STACK@PLT
137 popq %rax // Restore the return value