Patchwork [gccgo] Some cleanups to the stack split code

login
register
mail settings
Submitter Ian Taylor
Date Sept. 14, 2010, 12:07 a.m.
Message ID <mcrsk1d192k.fsf@google.com>
Download mbox | patch
Permalink /patch/64665/
State New
Headers show

Comments

Ian Taylor - Sept. 14, 2010, 12:07 a.m.
I committed this patch to the gccgo branch to implement some minor
cleanups to the x86 specific stack split code.  The only substantive
change is to have the correct stack alignment before calling the code
written in C.

Ian

Patch

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.