mirror of git://gcc.gnu.org/git/gcc.git
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>
|
2012-11-04 Thomas Schwinge <thomas@codesourcery.com>
|
||||||
|
|
||||||
* configure: Regenerate.
|
* configure: Regenerate.
|
||||||
|
|
|
||||||
|
|
@ -200,18 +200,19 @@ __morestack_non_split:
|
||||||
|
|
||||||
jb 2f # Get more space if we need it.
|
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
|
# If the instruction that we return to is
|
||||||
# leaq 24(%rbp), %r11n
|
# leaq 24(%rbp), %r11n
|
||||||
# then we have been called by a varargs function that expects
|
# 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
|
# %ebp to hold a real value. That can only work if we do the
|
||||||
# full stack split routine. FIXME: This is fragile.
|
# full stack split routine. FIXME: This is fragile.
|
||||||
movq 8(%rsp),%rax
|
movq 8(%rsp),%rax
|
||||||
|
incq %rax # Skip ret instruction in caller.
|
||||||
cmpl $0x185d8d4c,(%rax)
|
cmpl $0x185d8d4c,(%rax)
|
||||||
je 2f
|
je 2f
|
||||||
|
|
||||||
|
# This breaks call/return prediction, as described above.
|
||||||
|
incq 8(%rsp) # Increment the return address.
|
||||||
|
|
||||||
popq %rax # Restore register.
|
popq %rax # Restore register.
|
||||||
|
|
||||||
.cfi_adjust_cfa_offset -8 # Adjust for popped 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
|
# argument size is pushed then the new stack frame size is
|
||||||
# pushed.
|
# pushed.
|
||||||
|
|
||||||
# Align stack to 16-byte boundary with enough space for saving
|
# In the body of a non-leaf function, the stack pointer will
|
||||||
# registers and passing parameters to functions we call.
|
# be aligned to a 16-byte boundary. That is CFA + 12 in the
|
||||||
subl $40,%esp
|
# 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
|
# Because our cleanup code may need to clobber %ebx, we need
|
||||||
# to save it here so the unwinder can restore the value used
|
# to save it here so the unwinder can restore the value used
|
||||||
|
|
@ -393,13 +398,15 @@ __morestack:
|
||||||
|
|
||||||
movl %ebp,%esp # Restore stack pointer.
|
movl %ebp,%esp # Restore stack pointer.
|
||||||
|
|
||||||
|
# As before, we now have %esp % 16 == 12.
|
||||||
|
|
||||||
pushl %eax # Push return value on old stack.
|
pushl %eax # Push return value on old stack.
|
||||||
pushl %edx
|
pushl %edx
|
||||||
subl $8,%esp # Align stack to 16-byte boundary.
|
subl $4,%esp # Align stack to 16-byte boundary.
|
||||||
|
|
||||||
call __morestack_unblock_signals
|
call __morestack_unblock_signals
|
||||||
|
|
||||||
addl $8,%esp
|
addl $4,%esp
|
||||||
popl %edx # Restore return value.
|
popl %edx # Restore return value.
|
||||||
popl %eax
|
popl %eax
|
||||||
|
|
||||||
|
|
@ -485,15 +492,21 @@ __morestack:
|
||||||
pushq %r9
|
pushq %r9
|
||||||
|
|
||||||
pushq %r11
|
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
|
call __morestack_block_signals
|
||||||
|
|
||||||
leaq -8(%rbp),%rdi # Address of new frame size.
|
leaq -8(%rbp),%rdi # Address of new frame size.
|
||||||
leaq 24(%rbp),%rsi # The caller's parameters.
|
leaq 24(%rbp),%rsi # The caller's parameters.
|
||||||
addq $8,%rsp
|
|
||||||
popq %rdx # The size of the parameters.
|
popq %rdx # The size of the parameters.
|
||||||
|
|
||||||
|
subq $8,%rsp # Align stack.
|
||||||
|
|
||||||
call __generic_morestack
|
call __generic_morestack
|
||||||
|
|
||||||
movq -8(%rbp),%r10 # Reload modified frame size
|
movq -8(%rbp),%r10 # Reload modified frame size
|
||||||
|
|
@ -564,6 +577,9 @@ __morestack:
|
||||||
|
|
||||||
movq %rbp,%rsp # Restore stack pointer.
|
movq %rbp,%rsp # Restore stack pointer.
|
||||||
|
|
||||||
|
# Now (%rsp & 16) == 8.
|
||||||
|
|
||||||
|
subq $8,%rsp # For alignment.
|
||||||
pushq %rax # Push return value on old stack.
|
pushq %rax # Push return value on old stack.
|
||||||
pushq %rdx
|
pushq %rdx
|
||||||
|
|
||||||
|
|
@ -571,6 +587,7 @@ __morestack:
|
||||||
|
|
||||||
popq %rdx # Restore return value.
|
popq %rdx # Restore return value.
|
||||||
popq %rax
|
popq %rax
|
||||||
|
addq $8,%rsp
|
||||||
|
|
||||||
.cfi_remember_state
|
.cfi_remember_state
|
||||||
popq %rbp
|
popq %rbp
|
||||||
|
|
|
||||||
|
|
@ -549,6 +549,7 @@ __generic_morestack (size_t *pframe_size, void *old_stack, size_t param_size)
|
||||||
char *to;
|
char *to;
|
||||||
void *ret;
|
void *ret;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
size_t aligned;
|
||||||
|
|
||||||
current = __morestack_current_segment;
|
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;
|
*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
|
#ifdef STACK_GROWS_DOWNWARD
|
||||||
{
|
{
|
||||||
char *bottom = (char *) (current + 1) + current->size;
|
char *bottom = (char *) (current + 1) + current->size;
|
||||||
to = bottom - param_size;
|
to = bottom - aligned;
|
||||||
ret = bottom - param_size;
|
ret = bottom - aligned;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
to = current + 1;
|
to = current + 1;
|
||||||
ret = (char *) (current + 1) + param_size;
|
to += aligned - param_size;
|
||||||
|
ret = (char *) (current + 1) + aligned;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* We don't call memcpy to avoid worrying about the dynamic linker
|
/* We don't call memcpy to avoid worrying about the dynamic linker
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue