mirror of git://gcc.gnu.org/git/gcc.git
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:
parent
4356b75d98
commit
18b4bd7b6c
|
|
@ -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>
|
2011-10-25 Bernd Schmidt <bernds@codesourcery.com>
|
||||||
|
|
||||||
* config/c6x/pr-support.c (__gnu_unwind_24bit): Correct logic for the
|
* config/c6x/pr-support.c (__gnu_unwind_24bit): Correct logic for the
|
||||||
|
|
|
||||||
|
|
@ -139,44 +139,68 @@ __morestack:
|
||||||
.cfi_lsda 0x1b,.LLSDA1
|
.cfi_lsda 0x1b,.LLSDA1
|
||||||
#endif
|
#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
|
# We return below with a ret $8. We will return to a single
|
||||||
# return instruction, which will return to the caller of our
|
# return instruction, which will return to the caller of our
|
||||||
# caller. We let the unwinder skip that single return
|
# caller. We let the unwinder skip that single return
|
||||||
# instruction, and just return to the real caller.
|
# 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
|
.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
|
# In 32-bit mode the parameters are pushed on the stack. The
|
||||||
# argument size is pushed then the new stack frame size is
|
# argument size is pushed then the new stack frame size is
|
||||||
# pushed.
|
# 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
|
# In 32-bit mode the registers %eax, %edx, and %ecx may be
|
||||||
# used for parameters, depending on the regparm and fastcall
|
# used for parameters, depending on the regparm and fastcall
|
||||||
# attributes.
|
# attributes.
|
||||||
|
|
||||||
pushl %eax
|
movl %eax,-8(%ebp)
|
||||||
pushl %edx
|
movl %edx,-12(%ebp)
|
||||||
pushl %ecx
|
movl %ecx,-16(%ebp)
|
||||||
|
|
||||||
call __morestack_block_signals
|
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.
|
leal 20(%ebp),%eax # Address of caller's parameters.
|
||||||
pushl %eax
|
movl %eax,4(%esp)
|
||||||
addl $BACKOFF,8(%ebp) # Ask for backoff bytes.
|
addl $BACKOFF,8(%ebp) # Ask for backoff bytes.
|
||||||
leal 8(%ebp),%eax # The address of the new frame size.
|
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
|
call __generic_morestack
|
||||||
|
|
||||||
movl %eax,%esp # Switch to the new stack.
|
movl %eax,%esp # Switch to the new stack.
|
||||||
|
|
@ -191,8 +215,8 @@ __morestack:
|
||||||
|
|
||||||
call __morestack_unblock_signals
|
call __morestack_unblock_signals
|
||||||
|
|
||||||
movl -8(%ebp),%edx # Restore registers.
|
movl -12(%ebp),%edx # Restore registers.
|
||||||
movl -12(%ebp),%ecx
|
movl -16(%ebp),%ecx
|
||||||
|
|
||||||
movl 4(%ebp),%eax # Increment the return address
|
movl 4(%ebp),%eax # Increment the return address
|
||||||
cmpb $0xc3,(%eax) # to skip the ret instruction;
|
cmpb $0xc3,(%eax) # to skip the ret instruction;
|
||||||
|
|
@ -200,12 +224,12 @@ __morestack:
|
||||||
addl $2,%eax
|
addl $2,%eax
|
||||||
1: inc %eax
|
1: inc %eax
|
||||||
|
|
||||||
movl %eax,-8(%ebp) # Store return address in an
|
movl %eax,-12(%ebp) # Store return address in an
|
||||||
# unused slot.
|
# 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.
|
# The caller will return here, as predicted.
|
||||||
|
|
||||||
|
|
@ -255,9 +279,13 @@ __morestack:
|
||||||
popl %eax
|
popl %eax
|
||||||
|
|
||||||
.cfi_remember_state
|
.cfi_remember_state
|
||||||
|
|
||||||
|
# We never changed %ebx, so we don't have to actually restore it.
|
||||||
|
.cfi_restore %ebx
|
||||||
|
|
||||||
popl %ebp
|
popl %ebp
|
||||||
.cfi_restore %ebp
|
.cfi_restore %ebp
|
||||||
.cfi_def_cfa %esp, 12
|
.cfi_def_cfa %esp, 4
|
||||||
ret $8 # Return to caller, which will
|
ret $8 # Return to caller, which will
|
||||||
# immediately return. Pop
|
# immediately return. Pop
|
||||||
# arguments as we go.
|
# arguments as we go.
|
||||||
|
|
@ -300,13 +328,6 @@ __morestack:
|
||||||
.cfi_lsda 0x1b,.LLSDA1
|
.cfi_lsda 0x1b,.LLSDA1
|
||||||
#endif
|
#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
|
# We will return a single return instruction, which will
|
||||||
# return to the caller of our caller. Let the unwinder skip
|
# return to the caller of our caller. Let the unwinder skip
|
||||||
# that single return instruction, and just return to the real
|
# that single return instruction, and just return to the real
|
||||||
|
|
@ -314,6 +335,13 @@ __morestack:
|
||||||
.cfi_offset 16, 0
|
.cfi_offset 16, 0
|
||||||
.cfi_escape 0x15, 7, 0x7f # DW_CFA_val_offset_sf, %esp, 8/-8
|
.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
|
# In 64-bit mode the new stack frame size is passed in r10
|
||||||
# and the argument size is passed in r11.
|
# and the argument size is passed in r11.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue