.cfi_lsda 0x1b,.LLSDA1
#endif
- # Set up a normal backtrace.
- pushl %ebp
- .cfi_def_cfa_offset 8
- .cfi_offset %ebp, -8
- movl %esp, %ebp
- .cfi_def_cfa_register %ebp
-
# We return below with a ret $8. We will return to a single
# return instruction, which will return to the caller of our
# caller. We let the unwinder skip that single return
# instruction, and just return to the real caller.
- .cfi_offset 8, 8
+
+ # Here CFA points just past the return address on the stack,
+ # e.g., on function entry it is %esp + 4. Later we will
+ # change it to %ebp + 8, as set by .cfi_def_cfa_register and
+ # .cfi_def_cfa_offset above. The stack looks like this:
+ # CFA + 12: stack pointer after two returns
+ # CFA + 8: return address of morestack caller's caller
+ # CFA + 4: size of parameters
+ # CFA: new stack frame size
+ # CFA - 4: return address of this function
+ # CFA - 8: previous value of %ebp; %ebp points here
+ # We want to set %esp to the stack pointer after the double
+ # return, which is CFA + 12.
+ .cfi_offset 8, 8 # New PC stored at CFA + 8
.cfi_escape 0x15, 4, 0x7d # DW_CFA_val_offset_sf, %esp, 12/-4
+ # i.e., next %esp is CFA + 12
+
+ # Set up a normal backtrace.
+ pushl %ebp
+ .cfi_def_cfa_offset 8
+ .cfi_offset %ebp, -8
+ movl %esp,%ebp
+ .cfi_def_cfa_register %ebp
# In 32-bit mode the parameters are pushed on the stack. The
# argument size is pushed then the new stack frame size is
# pushed.
+ # Align stack to 16-byte boundary with enough space for saving
+ # registers and passing parameters to functions we call.
+ subl $40,%esp
+
+ # Because our cleanup code may need to clobber %ebx, we need
+ # to save it here so the unwinder can restore the value used
+ # by the caller. Note that we don't have to restore the
+ # register, since we don't change it, we just have to save it
+ # for the unwinder.
+ movl %ebx,-4(%ebp)
+ .cfi_offset %ebx, -12
+
# In 32-bit mode the registers %eax, %edx, and %ecx may be
# used for parameters, depending on the regparm and fastcall
# attributes.
- pushl %eax
- pushl %edx
- pushl %ecx
+ movl %eax,-8(%ebp)
+ movl %edx,-12(%ebp)
+ movl %ecx,-16(%ebp)
call __morestack_block_signals
- pushl 12(%ebp) # The size of the parameters.
+ movl 12(%ebp),%eax # The size of the parameters.
+ movl %eax,8(%esp)
leal 20(%ebp),%eax # Address of caller's parameters.
- pushl %eax
+ movl %eax,4(%esp)
addl $BACKOFF,8(%ebp) # Ask for backoff bytes.
leal 8(%ebp),%eax # The address of the new frame size.
- pushl %eax
+ movl %eax,(%esp)
- # Note that %esp is exactly 32 bytes below the CFA -- perfect for
- # a 16-byte aligned stack. That said, we still ought to compile
- # generic-morestack.c with -mpreferred-stack-boundary=2. FIXME.
call __generic_morestack
movl %eax,%esp # Switch to the new stack.
call __morestack_unblock_signals
- movl -8(%ebp),%edx # Restore registers.
- movl -12(%ebp),%ecx
+ movl -12(%ebp),%edx # Restore registers.
+ movl -16(%ebp),%ecx
movl 4(%ebp),%eax # Increment the return address
cmpb $0xc3,(%eax) # to skip the ret instruction;
addl $2,%eax
1: inc %eax
- movl %eax,-8(%ebp) # Store return address in an
+ movl %eax,-12(%ebp) # Store return address in an
# unused slot.
- movl -4(%ebp),%eax # Restore the last register.
+ movl -8(%ebp),%eax # Restore the last register.
- call *-8(%ebp) # Call our caller!
+ call *-12(%ebp) # Call our caller!
# The caller will return here, as predicted.
popl %eax
.cfi_remember_state
+
+ # We never changed %ebx, so we don't have to actually restore it.
+ .cfi_restore %ebx
+
popl %ebp
.cfi_restore %ebp
- .cfi_def_cfa %esp, 12
+ .cfi_def_cfa %esp, 4
ret $8 # Return to caller, which will
# immediately return. Pop
# arguments as we go.
.cfi_lsda 0x1b,.LLSDA1
#endif
- # Set up a normal backtrace.
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
-
# We will return a single return instruction, which will
# return to the caller of our caller. Let the unwinder skip
# that single return instruction, and just return to the real
.cfi_offset 16, 0
.cfi_escape 0x15, 7, 0x7f # DW_CFA_val_offset_sf, %esp, 8/-8
+ # Set up a normal backtrace.
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+
# In 64-bit mode the new stack frame size is passed in r10
# and the argument size is passed in r11.