rt: Write CFI instructions that (might) work on mac in __morestack

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.
This commit is contained in:
Brian Anderson 2011-12-11 16:32:36 -08:00
parent b73caec3ce
commit 7bc34f63d8
2 changed files with 35 additions and 11 deletions

View File

@ -49,12 +49,6 @@
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
@ -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)

View 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
@ -109,6 +121,9 @@ MORESTACK:
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.