--- old/usr/src/lib/common/i386/crt1.s	2015-12-18 13:15:18.016305133 -0500
+++ new/usr/src/lib/common/i386/crt1.s	2015-12-18 13:15:18.019953845 -0500
@@ -161,8 +161,19 @@
 	leal	16(%ebp,%eax,4),%edx	/* envp */
 	movl	%edx,_environ		/* copy to _environ */
 1:
+	/*
+	 * The stack needs to be 16-byte aligned with a 4-byte bias.  See
+	 * comment in lib/libc/i386/gen/makectxt.c.
+	 *
+	 * Note: If you change it, you need to change it in the following
+	 * files as well:
+	 *
+	 *  - lib/libc/i386/threads/machdep.c
+	 *  - lib/libc/i386/gen/makectxt.c
+	 *  - lib/common/i386/crti.s
+	 */
 	andl	$-16,%esp	/* make main() and exit() be called with */
-	subl	$4,%esp		/* a 16-byte aligned stack pointer */
+	subl	$4,%esp		/* a properly aligned stack pointer */
 	pushl	%edx
 	leal	12(%ebp),%edx	/* argv */
 	movl	%edx,___Argv
--- old/usr/src/lib/common/i386/crti.s	2015-12-18 13:15:18.129736478 -0500
+++ new/usr/src/lib/common/i386/crti.s	2015-12-18 13:15:18.133843349 -0500
@@ -40,13 +40,15 @@
 	.file	"crti.s"
 
 /*
- * Note that when _init and _fini are called we have 16-byte alignment per the
- * ABI. We need to make sure that our asm leaves it such that subsequent calls
- * will be aligned. gcc expects stack alignment before the call instruction is
- * executed. Specifically if we call function foo(), the stack pointer will be
- * 0xc aligned after executing the call instruction and before executing foo's
- * prologue. Note that because 16-byte alignment also ensures 4-byte alignment
- * we will not be breaking compatibility with older applications.
+ * Note that when _init and _fini are called the stack needs to be 16-byte
+ * aligned with a 4-byte bias.  See comment in lib/libc/i386/gen/makectxt.c.
+ *
+ * Note: If you change it, you need to change it in the following files as
+ * well:
+ *
+ *  - lib/libc/i386/threads/machdep.c
+ *  - lib/libc/i386/gen/makectxt.c
+ *  - lib/common/i386/crt1.s
  */
 
 /*
--- old/usr/src/lib/libc/i386/gen/makectxt.c	2015-12-18 13:15:18.239239012 -0500
+++ new/usr/src/lib/libc/i386/gen/makectxt.c	2015-12-18 13:15:18.243363604 -0500
@@ -27,8 +27,6 @@
 /*	Copyright (c) 1988 AT&T	*/
 /*	  All Rights Reserved  	*/
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #pragma weak _makecontext = makecontext
 
 #include "lint.h"
@@ -46,6 +44,32 @@
  * uc_stack, and which will return to the ucontext_t specified by uc_link.
  */
 
+/*
+ * The original i386 ABI said that the stack pointer need be only 4-byte
+ * aligned before a function call (STACK_ALIGN == 4).  The ABI supplement
+ * version 1.0 changed the required alignment to 16-byte for the benefit of
+ * floating point code compiled using sse2.  The compiler assumes this
+ * alignment and maintains it for calls it generates.  If the stack is
+ * initially properly aligned, it will continue to be so aligned.  If it is
+ * not initially so aligned, it will never become so aligned.
+ *
+ * One slightly confusing detail to keep in mind is that the 16-byte
+ * alignment (%esp & 0xf == 0) is true just *before* the call instruction.
+ * The call instruction will then push a return value, decrementing %esp by
+ * 4.  Therefore, if one dumps %esp at the at the very first instruction in
+ * a function, it will end with a 0xc.  The compiler expects this and
+ * compensates for it properly.
+ *
+ * Note: If you change this value, you need to change it in the following
+ * files as well:
+ *
+ *  - lib/libc/i386/threads/machdep.c
+ *  - lib/common/i386/crti.s
+ *  - lib/common/i386/crt1.s
+ */
+#undef	STACK_ALIGN
+#define	STACK_ALIGN	16
+
 static void resumecontext(void);
 
 void
@@ -60,22 +84,27 @@
 
 	size = sizeof (long) * (argc + 1);
 
-	sp = (long *)(((uintptr_t)ucp->uc_stack.ss_sp +
+	tsp = (long *)(((uintptr_t)ucp->uc_stack.ss_sp +
 	    ucp->uc_stack.ss_size - size) & ~(STACK_ALIGN - 1));
 
-	tsp = sp + 1;
-
-	va_start(ap, argc);
-
-	while (argc-- > 0) {
-		*tsp++ = va_arg(ap, long);
-	}
-
-	va_end(ap);
+	/*
+	 * Since we're emulating the call instruction, we must push the
+	 * return address (which involves adjusting the stack pointer to
+	 * have the proper 4-byte bias).
+	 */
+	sp = tsp - 1;
 
 	*sp = (long)resumecontext;		/* return address */
 
 	ucp->uc_mcontext.gregs[UESP] = (greg_t)sp;
+
+	/*
+	 * "push" all the arguments
+	 */
+	va_start(ap, argc);
+	while (argc-- > 0)
+		*tsp++ = va_arg(ap, long);
+	va_end(ap);
 }
 
 
--- old/usr/src/lib/libc/i386/threads/machdep.c	2015-12-18 13:15:18.350968765 -0500
+++ new/usr/src/lib/libc/i386/threads/machdep.c	2015-12-18 13:15:18.355271351 -0500
@@ -29,14 +29,15 @@
 #include <setjmp.h>
 
 /*
- * The i386 ABI says that the stack pointer need be only 4-byte aligned
- * before a function call (STACK_ALIGN == 4).  We use a 16-byte stack
- * alignment for the benefit of floating point code compiled using sse2.
- * Even though the i386 ABI doesn't require it, both cc and gcc
- * assume this alignment on entry to a function and maintain it
- * for calls made from that function.  If the stack is initially
- * aligned on a 16-byte boundary, it will continue to be so aligned.
- * If it is not initially so aligned, it will never become so aligned.
+ * The stack needs to be 16-byte aligned with a 4-byte bias.  See comment in
+ * lib/libc/i386/gen/makectxt.c.
+ *
+ * Note: If you change it, you need to change it in the following files as
+ * well:
+ *
+ *  - lib/libc/i386/gen/makectxt.c
+ *  - lib/common/i386/crti.s
+ *  - lib/common/i386/crt1.s
  */
 #undef	STACK_ALIGN
 #define	STACK_ALIGN	16
