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:
parent
b73caec3ce
commit
7bc34f63d8
@ -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
|
||||
@ -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)
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user