mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-14 04:20:25 +08:00
generic-morestack.c (__generic_morestack): Align the returned stack pointer to a 32 byte boundary.
* generic-morestack.c (__generic_morestack): Align the returned stack pointer to a 32 byte boundary. * config/i386/morestack.S (__morestack_non_split) [32-bit]: Don't increment the return address until we have decided that we don't have a varargs function. (__morestack) [32-bit]: Align stack correctly when calling C functions. (__morestack) [64-bit]: Likewise. From-SVN: r193264
This commit is contained in:
parent
b142d8a2b5
commit
e808687a8c
@ -1,3 +1,14 @@
|
||||
2012-11-06 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* generic-morestack.c (__generic_morestack): Align the returned
|
||||
stack pointer to a 32 byte boundary.
|
||||
* config/i386/morestack.S (__morestack_non_split) [32-bit]: Don't
|
||||
increment the return address until we have decided that we don't
|
||||
have a varargs function.
|
||||
(__morestack) [32-bit]: Align stack correctly when calling C
|
||||
functions.
|
||||
(__morestack) [64-bit]: Likewise.
|
||||
|
||||
2012-11-04 Thomas Schwinge <thomas@codesourcery.com>
|
||||
|
||||
* configure: Regenerate.
|
||||
|
@ -200,18 +200,19 @@ __morestack_non_split:
|
||||
|
||||
jb 2f # Get more space if we need it.
|
||||
|
||||
# This breaks call/return prediction, as described above.
|
||||
incq 8(%rsp) # Increment the return address.
|
||||
|
||||
# If the instruction that we return to is
|
||||
# leaq 24(%rbp), %r11n
|
||||
# then we have been called by a varargs function that expects
|
||||
# %ebp to hold a real value. That can only work if we do the
|
||||
# full stack split routine. FIXME: This is fragile.
|
||||
movq 8(%rsp),%rax
|
||||
incq %rax # Skip ret instruction in caller.
|
||||
cmpl $0x185d8d4c,(%rax)
|
||||
je 2f
|
||||
|
||||
# This breaks call/return prediction, as described above.
|
||||
incq 8(%rsp) # Increment the return address.
|
||||
|
||||
popq %rax # Restore register.
|
||||
|
||||
.cfi_adjust_cfa_offset -8 # Adjust for popped register.
|
||||
@ -296,9 +297,13 @@ __morestack:
|
||||
# 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
|
||||
# In the body of a non-leaf function, the stack pointer will
|
||||
# be aligned to a 16-byte boundary. That is CFA + 12 in the
|
||||
# stack picture above: (CFA + 12) % 16 == 0. At this point we
|
||||
# have %esp == CFA - 8, so %esp % 16 == 12. We need some
|
||||
# space for saving registers and passing parameters, and we
|
||||
# need to wind up with %esp % 16 == 0.
|
||||
subl $44,%esp
|
||||
|
||||
# Because our cleanup code may need to clobber %ebx, we need
|
||||
# to save it here so the unwinder can restore the value used
|
||||
@ -393,13 +398,15 @@ __morestack:
|
||||
|
||||
movl %ebp,%esp # Restore stack pointer.
|
||||
|
||||
# As before, we now have %esp % 16 == 12.
|
||||
|
||||
pushl %eax # Push return value on old stack.
|
||||
pushl %edx
|
||||
subl $8,%esp # Align stack to 16-byte boundary.
|
||||
subl $4,%esp # Align stack to 16-byte boundary.
|
||||
|
||||
call __morestack_unblock_signals
|
||||
|
||||
addl $8,%esp
|
||||
addl $4,%esp
|
||||
popl %edx # Restore return value.
|
||||
popl %eax
|
||||
|
||||
@ -485,15 +492,21 @@ __morestack:
|
||||
pushq %r9
|
||||
|
||||
pushq %r11
|
||||
pushq $0 # For alignment.
|
||||
|
||||
# We entered morestack with the stack pointer aligned to a
|
||||
# 16-byte boundary (the call to morestack's caller used 8
|
||||
# bytes, and the call to morestack used 8 bytes). We have now
|
||||
# pushed 10 registers, so we are still aligned to a 16-byte
|
||||
# boundary.
|
||||
|
||||
call __morestack_block_signals
|
||||
|
||||
leaq -8(%rbp),%rdi # Address of new frame size.
|
||||
leaq 24(%rbp),%rsi # The caller's parameters.
|
||||
addq $8,%rsp
|
||||
popq %rdx # The size of the parameters.
|
||||
|
||||
subq $8,%rsp # Align stack.
|
||||
|
||||
call __generic_morestack
|
||||
|
||||
movq -8(%rbp),%r10 # Reload modified frame size
|
||||
@ -564,6 +577,9 @@ __morestack:
|
||||
|
||||
movq %rbp,%rsp # Restore stack pointer.
|
||||
|
||||
# Now (%rsp & 16) == 8.
|
||||
|
||||
subq $8,%rsp # For alignment.
|
||||
pushq %rax # Push return value on old stack.
|
||||
pushq %rdx
|
||||
|
||||
@ -571,6 +587,7 @@ __morestack:
|
||||
|
||||
popq %rdx # Restore return value.
|
||||
popq %rax
|
||||
addq $8,%rsp
|
||||
|
||||
.cfi_remember_state
|
||||
popq %rbp
|
||||
|
@ -549,6 +549,7 @@ __generic_morestack (size_t *pframe_size, void *old_stack, size_t param_size)
|
||||
char *to;
|
||||
void *ret;
|
||||
size_t i;
|
||||
size_t aligned;
|
||||
|
||||
current = __morestack_current_segment;
|
||||
|
||||
@ -580,15 +581,19 @@ __generic_morestack (size_t *pframe_size, void *old_stack, size_t param_size)
|
||||
|
||||
*pframe_size = current->size - param_size;
|
||||
|
||||
/* Align the returned stack to a 32-byte boundary. */
|
||||
aligned = (param_size + 31) & ~ (size_t) 31;
|
||||
|
||||
#ifdef STACK_GROWS_DOWNWARD
|
||||
{
|
||||
char *bottom = (char *) (current + 1) + current->size;
|
||||
to = bottom - param_size;
|
||||
ret = bottom - param_size;
|
||||
to = bottom - aligned;
|
||||
ret = bottom - aligned;
|
||||
}
|
||||
#else
|
||||
to = current + 1;
|
||||
ret = (char *) (current + 1) + param_size;
|
||||
to += aligned - param_size;
|
||||
ret = (char *) (current + 1) + aligned;
|
||||
#endif
|
||||
|
||||
/* We don't call memcpy to avoid worrying about the dynamic linker
|
||||
|
Loading…
x
Reference in New Issue
Block a user