- .text
+// 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. */
-// __morestack
-//
-// LLVM generates a call to this to allocate more stack space in a functiono
-// prolog when we run out.
+.text
+
+#if defined(__APPLE__)
+#define MORESTACK ___morestack
+#else
+#define MORESTACK __morestack
+#endif
-#if defined(__APPLE__) || defined(_WIN32)
-#define RUST_NEW_STACK _rust_new_stack
-#define RUST_DEL_STACK _rust_del_stack
-#define MORESTACK __morestack
+#if defined(__APPLE__)
+#define EXHAUSTED _rust_stack_exhausted
+#elif defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__)
+#define EXHAUSTED rust_stack_exhausted@PLT
#else
-#define RUST_NEW_STACK rust_new_stack
-#define RUST_DEL_STACK rust_del_stack
-#define MORESTACK __morestack
+#define EXHAUSTED rust_stack_exhausted
#endif
- // Naturally, nobody can agree as to
- // which arguments should go in which
- // registers:
-#if defined(_WIN32)
-# define ARG0 %rcx
-# define ARG1 %rdx
-# define ARG2 %r8
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__)
+ .hidden MORESTACK
#else
-# define ARG0 %rdi
-# define ARG1 %rsi
-# define ARG2 %rdx
+#if defined(__APPLE__)
+ .private_extern MORESTACK
+#endif
#endif
-.globl RUST_NEW_STACK
-.globl RUST_DEL_STACK
+#ifdef __ELF__
+ .type MORESTACK,@function
+#endif
.globl MORESTACK
-
MORESTACK:
- // Hastily and probably incorrectly ported from i386 version.
- // Actually this calling convention doens't make so much sense
- // for x86_64...
- mov %rcx, ARG0 // param 0: amount of space needed
- mov %rdx, ARG2 // param 2: size of arguments
- lea 8(%rsp),ARG1
- call rust_new_stack_sym
-
- mov (%rsp),%rdx // Grab the return pointer.
- inc %rdx // Skip past the `ret`.
- mov %rax,%rsp // Switch to the new stack.
- call *%rdx // Enter the new function.
-
- // Now the function that called us has returned, so we need to delete the
- // old stack space.
- call rust_new_stack_sym
- mov %rax,%rsp // Switch back to the old stack.
- ret
-
-// This is totally broken
-rust_new_stack_sym:
-rust_del_stack_sym:
\ No newline at end of file
+ .cfi_startproc
+
+ pushq %rbp
+ // The CFA is 24 bytes above the register that it will
+ // be associated with for this frame (%rbp). That is 8
+ // 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
+
+ // re-align the stack
+ subq $8, %rsp
+
+ // kill this program
+ call EXHAUSTED
+
+ // the exhaustion function guarantees that it can't return
+
+ .cfi_endproc