morestack.S: Correct CFI information to do proper returns throughout function.

* config/i386/morestack.S: Correct CFI information to do proper
	returns throughout function.  In 32-bit mode, save %ebx so that it
	is restored on unwind.

From-SVN: r180633
This commit is contained in:
Ian Lance Taylor 2011-10-28 22:03:56 +00:00 committed by Ian Lance Taylor
parent 4356b75d98
commit 18b4bd7b6c
2 changed files with 64 additions and 30 deletions

View File

@ -1,3 +1,9 @@
2011-10-28 Ian Lance Taylor <iant@google.com>
* config/i386/morestack.S: Correct CFI information to do proper
returns throughout function. In 32-bit mode, save %ebx so that it
is restored on unwind.
2011-10-25 Bernd Schmidt <bernds@codesourcery.com>
* config/c6x/pr-support.c (__gnu_unwind_24bit): Correct logic for the

View File

@ -139,44 +139,68 @@ __morestack:
.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.
@ -191,8 +215,8 @@ __morestack:
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;
@ -200,12 +224,12 @@ __morestack:
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.
@ -255,9 +279,13 @@ __morestack:
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.
@ -300,13 +328,6 @@ __morestack:
.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
@ -314,6 +335,13 @@ __morestack:
.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.