-/*
- __morestack
+// Mark stack as non-executable
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack, "", @progbits
+#endif
- See i386/morestack.S for the lengthy, general explanation.
-*/
+/* See i386/morestack.S for the lengthy, general explanation. */
.text
-#if defined(__APPLE__) || defined(_WIN32)
-#define UPCALL_NEW_STACK _upcall_new_stack
-#define UPCALL_DEL_STACK _upcall_del_stack
+#if defined(__APPLE__)
#define MORESTACK ___morestack
#else
-#define UPCALL_NEW_STACK upcall_new_stack
-#define UPCALL_DEL_STACK upcall_del_stack
#define MORESTACK __morestack
#endif
-.globl UPCALL_NEW_STACK
-.globl UPCALL_DEL_STACK
-.globl MORESTACK
+#if defined(__APPLE__)
+#define EXHAUSTED _rust_stack_exhausted
+#elif defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__)
+#define EXHAUSTED rust_stack_exhausted@PLT
+#else
+#define EXHAUSTED rust_stack_exhausted
+#endif
-#if defined(__linux__) || defined(__FreeBSD__)
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__)
.hidden MORESTACK
#else
#if defined(__APPLE__)
.type MORESTACK,@function
#endif
-
-#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)
+.globl MORESTACK
MORESTACK:
.cfi_startproc
// bytes greater than a normal frame, to allow the unwinder
// to skip the partial frame of the original function.
.cfi_def_cfa_offset 24
+
+#if defined(__APPLE__)
+ // The pattern of the return address being saved twice to the same location
+ // tells the OS X linker that it should not attempt to convert the DWARF
+ // unwind information to the compact format.
+ .cfi_offset %rip, -8
+ .cfi_offset %rip, -8
+#endif
+
// %rbp is -24 bytes from the CFA
.cfi_offset %rbp, -24
movq %rsp, %rbp
// Calculate the CFA as on offset from %ebp
.cfi_def_cfa_register %rbp
- subq $200, %rsp
-
- // FIXME: libgcc also saves rax. not sure if we need to
-
- // Save argument registers of the original function
- movq %rdi, (%rsp)
- movq %rsi, 8(%rsp)
- movq %rdx, 16(%rsp)
- movq %rcx, 24(%rsp)
- movq %r8, 32(%rsp)
- movq %r9, 40(%rsp)
- movdqa %xmm0, 48(%rsp)
- movdqa %xmm1, 64(%rsp)
- movdqa %xmm2, 80(%rsp)
- movdqa %xmm3, 96(%rsp)
- movdqa %xmm4, 112(%rsp)
- movdqa %xmm5, 128(%rsp)
- movdqa %xmm6, 144(%rsp)
- movdqa %xmm7, 160(%rsp)
-
- // Calculate the address of the stack arguments.
- // We have the base pointer, __morestack's return address,
- // and __morestack's caller's return address to skip
- movq %rbp, %rax
- addq $24, %rax // Base pointer, return address x2
-
- // The arguments to __morestack are passed in %r10 & %r11
+ // re-align the stack
+ subq $8, %rsp
- movq %r11, %rdx // Size of stack arguments
- movq %rax, %rsi // Address of stack arguments
- movq %r10, %rdi // The amount of stack needed
-
-#ifdef __APPLE__
- call UPCALL_NEW_STACK
-#endif
-#ifdef __linux__
- call UPCALL_NEW_STACK@PLT
-#endif
-#ifdef __FreeBSD__
- call UPCALL_NEW_STACK@PLT
-#endif
-
- // Pop the saved arguments
- movq (%rsp), %rdi
- movq 8(%rsp), %rsi
- movq 16(%rsp), %rdx
- movq 24(%rsp), %rcx
- movq 32(%rsp), %r8
- movq 40(%rsp), %r9
- movdqa 48(%rsp), %xmm0
- movdqa 64(%rsp), %xmm1
- movdqa 80(%rsp), %xmm2
- movdqa 96(%rsp), %xmm3
- movdqa 112(%rsp), %xmm4
- movdqa 128(%rsp), %xmm5
- movdqa 144(%rsp), %xmm6
- movdqa 160(%rsp), %xmm7
-
- addq $200, %rsp
-
- movq 8(%rbp),%r10 // Grab the return pointer.
- incq %r10 // Skip past the `ret` in our parent frame
- movq %rax,%rsp // Switch to the new stack.
-
- call *%r10 // Reenter the caller function
-
- // Switch back to the rust stack
- movq %rbp, %rsp
+ // kill this program
+ call EXHAUSTED
- // Save the return value
- pushq %rax
+ // the exhaustion function guarantees that it can't return
-#ifdef __APPLE__
- call UPCALL_DEL_STACK
-#endif
-#ifdef __linux__
- call UPCALL_DEL_STACK@PLT
-#endif
-#ifdef __FreeBSD__
- call UPCALL_DEL_STACK@PLT
-#endif
-
- popq %rax // Restore the return value
- popq %rbp
- // FIXME: I don't think these rules are necessary
- // since the unwinder should never encounter an instruction
- // pointer pointing here.
- .cfi_restore %rbp
- .cfi_def_cfa %rsp, 16
- ret
-
.cfi_endproc
-
-#else
-MORESTACK:
- ret
-#endif