Index: config/i386/morestack.S
===================================================================
--- config/i386/morestack.S	(revision 164260)
+++ config/i386/morestack.S	(working copy)
@@ -1,5 +1,5 @@
 # x86/x86_64 support for -fsplit-stack.
-# Copyright (C) 2009 Free Software Foundation, Inc.
+# Copyright (C) 2009, 2010 Free Software Foundation, Inc.
 # Contributed by Ian Lance Taylor <iant@google.com>.
 
 # This file is part of GCC.
@@ -47,13 +47,13 @@
 # the stack which we should not use.
 
 # void *__generic_morestack (size_t *frame_size, void *old_stack,
-#			      size_t param_size);
+#			     size_t param_size);
 
-# The __morestack routine arranges for the caller to return to a stub
-# on the new stack.  The stub is responsible for restoring the old
-# stack pointer and returning to the caller's caller.  This calls
-# __generic_releasestack to retrieve the old stack pointer and
-# release the newly allocated stack.
+# The __morestack routine has to arrange for the caller to return to a
+# stub on the new stack.  The stub is responsible for restoring the
+# old stack pointer and returning to the caller's caller.  This calls
+# __generic_releasestack to retrieve the old stack pointer and release
+# the newly allocated stack.
 
 # void *__generic_releasestack (size_t *available);
 
@@ -71,10 +71,6 @@
 # the call to __generic_morestack.  That then returns to the caller of
 # the original caller.
 
-# This entry point is for split-stack code which calls non-split-stack
-# code.  When the linker sees this case, it converts the call to
-# __morestack to call __morestack_non_split instead.  We just bump the
-# requested stack space by 16K.
 
 # The amount of extra space we ask for.  In general this has to be
 # enough for the dynamic loader to find a symbol and for a signal
@@ -86,6 +82,12 @@
 #define BACKOFF (1536)
 #endif
 
+
+# This entry point is for split-stack code which calls non-split-stack
+# code.  When the linker sees this case, it converts the call to
+# __morestack to call __morestack_non_split instead.  We just bump the
+# requested stack space by 16K.
+
 	.global __morestack_non_split
 
 #ifdef __ELF__
@@ -106,6 +108,9 @@ __morestack_non_split:
 
 # __morestack_non_split falls through into __morestack.
 
+
+# The __morestack function.
+
 	.global	__morestack
 
 #ifdef __ELF__
@@ -116,8 +121,12 @@ __morestack:
 .LFB1:
 	.cfi_startproc
 
+
 #ifndef __x86_64__
 
+
+# The 32-bit __morestack function.
+
 	# We use a cleanup to restore the stack guard if an exception
 	# is thrown through this code.
 #ifndef __PIC__
@@ -172,10 +181,10 @@ __morestack:
 	subl	8(%ebp),%eax		# The end of the stack space.
 	addl	$BACKOFF,%eax		# Back off 512 bytes.
 
+.LEHB0:
 	# FIXME: The offset must match
 	# TARGET_THREAD_SPLIT_STACK_OFFSET in
 	# gcc/config/i386/linux.h.
-.LEHB0:
 	movl	%eax,%gs:0x30		# Save the new stack boundary.
 
 	call	__morestack_unblock_signals
@@ -204,12 +213,15 @@ __morestack:
 	pushl	%eax
 	pushl	%edx
 
-	call	__morestack_block_signals
-
+	# Push the arguments to __generic_releasestack now so that the
+	# stack is at a 16-byte boundary for
+	# __morestack_block_signals.
 	pushl	$0			# Where the available space is returned.
 	leal	0(%esp),%eax		# Push its address.
 	push	%eax
 
+	call	__morestack_block_signals
+
 	call	__generic_releasestack
 
 	subl	4(%esp),%eax		# Subtract available space.
@@ -232,9 +244,11 @@ __morestack:
 
 	pushl	%eax			# Push return value on old stack.
 	pushl	%edx
+	subl	$8,%esp			# Align stack to 16-byte boundary.
 
 	call	__morestack_unblock_signals
 
+	addl	$8,%esp
 	popl	%edx			# Restore return value.
 	popl	%eax
 
@@ -272,6 +286,9 @@ __morestack:
 
 #else /* defined(__x86_64__) */
 
+
+# The 64-bit __morestack function.
+
 	# We use a cleanup to restore the stack guard if an exception
 	# is thrown through this code.
 #ifndef __PIC__
@@ -306,7 +323,7 @@ __morestack:
 	# and %r9 may be used for parameters.  We also preserve %rax
 	# which the caller may use to hold %r10.
 
-	push	%rax
+	pushq	%rax
 	pushq	%rdi
 	pushq	%rsi
 	pushq	%rdx
@@ -315,11 +332,13 @@ __morestack:
 	pushq	%r9
 
 	pushq	%r11
+	pushq	$0			# For alignment.
 
 	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.
 
 	call	__generic_morestack
@@ -329,10 +348,10 @@ __morestack:
 	subq	%r10,%rax		# The end of the stack space.
 	addq	$BACKOFF,%rax		# Back off 1024 bytes.
 
+.LEHB0:
 	# FIXME: The offset must match
 	# TARGET_THREAD_SPLIT_STACK_OFFSET in
 	# gcc/config/i386/linux64.h.
-.LEHB0:
 	movq	%rax,%fs:0x70		# Save the new stack boundary.
 
 	call	__morestack_unblock_signals
@@ -362,6 +381,7 @@ __morestack:
 
 	call	__morestack_block_signals
 
+	pushq	$0			# For alignment.
 	pushq	$0			# Where the available space is returned.
 	leaq	0(%rsp),%rdi		# Pass its address.
 
@@ -372,7 +392,7 @@ __morestack:
 .LEHE0:
 	movq	%rax,%fs:0x70		# Save the new stack boundary.
 
-	addq	$8,%rsp			# Remove value from stack.
+	addq	$16,%rsp		# Remove values from stack.
 
 	# We need to restore the old stack pointer, which is in %rbp,
 	# before we unblock signals.  We also need to restore %rax and
@@ -427,7 +447,10 @@ __morestack:
 	.size	__morestack, . - __morestack
 #endif
 
-	.globl __gcc_personality_v0
+
+# The exception table.  This tells the personality routine to execute
+# the exception handler.
+
 	.section	.gcc_except_table,"a",@progbits
 	.align	4
 .LLSDA1:
@@ -442,6 +465,8 @@ __morestack:
 	.uleb128 0		# action
 .LLSDACSE1:
 
+
+	.globl __gcc_personality_v0
 #ifdef __PIC__
 	# Build a position independent reference to the basic
         # personality function.
@@ -461,6 +486,7 @@ DW.ref.__gcc_personality_v0:
 #endif
 #endif
 
+
 # Initialize the stack test value when the program starts or when a
 # new thread starts.  We don't know how large the main stack is, so we
 # guess conservatively.  We might be able to use getrlimit here.
@@ -507,6 +533,7 @@ __stack_split_initialize:
 	.size	__stack_split_initialize, . - __stack_split_initialize
 #endif
 
+
 # Make __stack_split_initialize a high priority constructor.  FIXME:
 # This is ELF specific.
 
