]> git.lizzy.rs Git - rust.git/blobdiff - src/rt/arch/x86_64/morestack.S
auto merge of #15999 : Kimundi/rust/fix_folder, r=nikomatsakis
[rust.git] / src / rt / arch / x86_64 / morestack.S
index e7464dfdc0e5b9547ad223f12a2177df74f06e52..c82da57c12847af48603e9bbc1660d0a57a4e36f 100644 (file)
@@ -1,58 +1,69 @@
-    .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