]> git.lizzy.rs Git - rust.git/commitdiff
rt: Write CFI instructions that (might) work on mac in __morestack
authorBrian Anderson <banderson@mozilla.com>
Mon, 12 Dec 2011 00:32:36 +0000 (16:32 -0800)
committerBrian Anderson <banderson@mozilla.com>
Mon, 12 Dec 2011 00:32:36 +0000 (16:32 -0800)
The DW_CFA_val_offset_sf instruction doesn't seem to work on mac,
even after implementing it in the llvm-mc assembler, so now
I'm looking for a different way to communicate the stack pointer
adjustment to the unwinder.

src/rt/arch/i386/morestack.S
src/rt/arch/x86_64/morestack.S

index 7d1883833da2572833caf9a4203c9c15afaece5d..23aa36353a195ddb335e5932b05294c047d3b12f 100644 (file)
 MORESTACK:
 #ifdef __linux__
        .cfi_startproc
-
-       // Some magic that explains to the unwinder the unusal nature
-       // of this stack frame. Copied verbatim from libgcc, which
-       // has comments explaining it.
-       .cfi_offset 8, 8
-       .cfi_escape 0x15, 4, 0x7d
 #endif
 
        pushl %ebp
@@ -66,7 +60,7 @@ MORESTACK:
 #ifdef __linux__
        .cfi_def_cfa_register %ebp
 #endif
-       
+
        // FIXME (1226): main is compiled with the split-stack prologue,
        // causing it to call __morestack, so we have to jump back out
        subl $28,%esp
@@ -74,6 +68,21 @@ MORESTACK:
        testl %eax,%eax
        jz .L$bail
 
+       // During unwinding we want to skip our caller.
+#ifdef __linux__
+       // Don't understand this line. I think it means that
+       // the next frame's pc is the return address of our caller.
+       .cfi_offset 8, 8
+       // The next frame's esp is stored at our CFA - 12
+       // (by the code below)
+       .cfi_offset %esp, -12
+#endif
+
+       // Save the the correct %esp value for our grandparent frame,
+       // for the unwinder
+       leal 20(%ebp), %eax
+       movl %eax, -4(%ebp)
+       
        // The arguments to rust_new_stack2
        movl 40(%esp),%eax  // Size of stack arguments
        movl %eax,20(%esp)
index d5212004f100faa66be036e2541d143d467a5654..fafedb54418d47ca6618ba827fea22da827942ec 100644 (file)
@@ -65,6 +65,20 @@ MORESTACK:
        .cfi_def_cfa_register %rbp
 #endif
 
+       // During unwinding we want to skip our caller since it's not
+       // a complete frame and will make the unwinder sad
+#if defined(__linux__)
+       // Don't understand this line
+       .cfi_offset 16, 0
+       // Tell the unwinding where to get the stack pointer for
+       // our grandparent frame
+       .cfi_offset %rsp, -24
+#endif
+
+       // Save the grandparent stack pointer for the unwinder
+       leaq 16(%rbp), %rax
+       pushq %rax
+
        // FIXME: libgcc also saves rax. not sure if we need to
 
        // Save argument registers
@@ -81,8 +95,6 @@ MORESTACK:
        movq %rbp, %rcx
        addq $24, %rcx  // Base pointer, return address x2
 
-       pushq $0 // Alignment
-
        pushq %r11 // Size of stack arguments
        pushq %rcx // Address of stack arguments
        pushq %r10 // The amount of stack needed
@@ -99,7 +111,7 @@ MORESTACK:
 
        // Pop the new_stack_args struct
        popq %rax
-       addq $32, %rsp
+       addq $24, %rsp
 
        // Pop the saved arguments
        popq %r9
@@ -108,7 +120,10 @@ MORESTACK:
        popq %rdx
        popq %rsi
        popq %rdi
-       
+
+       // Pop the unwinding %rsp
+       addq $8, %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.