--- old/usr/src/uts/intel/ia32/os/sendsig.c	Wed Oct  5 00:32:41 2016
+++ new/usr/src/uts/intel/ia32/os/sendsig.c	Wed Oct  5 00:32:41 2016
@@ -20,6 +20,9 @@
  */
 
 /*
+ * Copyright 2015 Joyent, Inc.
+ */
+/*
  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
@@ -87,6 +90,8 @@
 #include <sys/kdi.h>
 #include <sys/contract_impl.h>
 #include <sys/x86_archext.h>
+#include <sys/brand.h>
+#include <sys/sdt.h>
 
 /*
  * Construct the execution environment for the user's signal
@@ -186,7 +191,18 @@
 	newstack = sigismember(&PTOU(curproc)->u_sigonstack, sig) &&
 	    !(lwp->lwp_sigaltstack.ss_flags & (SS_ONSTACK|SS_DISABLE));
 
-	if (newstack) {
+	/*
+	 * If this is a branded process, the brand may provide an alternate
+	 * stack pointer for signal delivery:
+	 */
+	if (PROC_IS_BRANDED(p) && BROP(p)->b_sendsig_stack != NULL) {
+		/*
+		 * Use the stack pointer value provided by the brand,
+		 * accounting for the 128-byte reserved region.
+		 */
+		newstack = 0;
+		fp = BROP(p)->b_sendsig_stack(sig) - STACK_RESERVE;
+	} else if (newstack) {
 		fp = (caddr_t)(SA((uintptr_t)lwp->lwp_sigaltstack.ss_sp) +
 		    SA(lwp->lwp_sigaltstack.ss_size) - STACK_ALIGN);
 	} else {
@@ -296,6 +312,8 @@
 	kmem_free(tuc, sizeof (*tuc));
 	tuc = NULL;
 
+	DTRACE_PROBE3(oldcontext__set, klwp_t *, lwp,
+	    uintptr_t, lwp->lwp_oldcontext, uintptr_t, (uintptr_t)uc);
 	lwp->lwp_oldcontext = (uintptr_t)uc;
 
 	if (newstack) {
@@ -345,6 +363,14 @@
 	}
 
 	/*
+	 * Allow the brand to perform additional book-keeping once the signal
+	 * handling frame has been fully assembled:
+	 */
+	if (PROC_IS_BRANDED(p) && BROP(p)->b_sendsig != NULL) {
+		BROP(p)->b_sendsig(sig);
+	}
+
+	/*
 	 * Don't set lwp_eosys here.  sendsig() is called via psig() after
 	 * lwp_eosys is handled, so setting it here would affect the next
 	 * system call.
@@ -420,7 +446,17 @@
 	newstack = sigismember(&PTOU(curproc)->u_sigonstack, sig) &&
 	    !(lwp->lwp_sigaltstack.ss_flags & (SS_ONSTACK|SS_DISABLE));
 
-	if (newstack) {
+	/*
+	 * If this is a branded process, the brand may provide an alternate
+	 * stack pointer for signal delivery:
+	 */
+	if (PROC_IS_BRANDED(p) && BROP(p)->b_sendsig_stack != NULL) {
+		/*
+		 * Use the stack pointer value provided by the brand:
+		 */
+		newstack = 0;
+		fp = BROP(p)->b_sendsig_stack(sig);
+	} else if (newstack) {
 		fp = (caddr_t)(SA32((uintptr_t)lwp->lwp_sigaltstack.ss_sp) +
 		    SA32(lwp->lwp_sigaltstack.ss_size) - STACK_ALIGN32);
 	} else if ((rp->r_ss & 0xffff) != UDS_SEL) {
@@ -435,8 +471,9 @@
 			    USEGD_GETBASE(&ldt[SELTOIDX(rp->r_ss)]);
 		else
 			fp = (caddr_t)rp->r_sp;
-	} else
+	} else {
 		fp = (caddr_t)rp->r_sp;
+	}
 
 	/*
 	 * Force proper stack pointer alignment, even in the face of a
@@ -517,6 +554,8 @@
 	kmem_free(tuc, sizeof (*tuc));
 	tuc = NULL;
 
+	DTRACE_PROBE3(oldcontext__set, klwp_t *, lwp,
+	    uintptr_t, lwp->lwp_oldcontext, uintptr_t, (uintptr_t)uc);
 	lwp->lwp_oldcontext = (uintptr_t)uc;
 
 	if (newstack) {
@@ -566,6 +605,14 @@
 	}
 
 	/*
+	 * Allow the brand to perform additional book-keeping once the signal
+	 * handling frame has been fully assembled:
+	 */
+	if (PROC_IS_BRANDED(p) && BROP(p)->b_sendsig != NULL) {
+		BROP(p)->b_sendsig(sig);
+	}
+
+	/*
 	 * Don't set lwp_eosys here.  sendsig() is called via psig() after
 	 * lwp_eosys is handled, so setting it here would affect the next
 	 * system call.
@@ -643,7 +690,17 @@
 	newstack = sigismember(&PTOU(curproc)->u_sigonstack, sig) &&
 	    !(lwp->lwp_sigaltstack.ss_flags & (SS_ONSTACK|SS_DISABLE));
 
-	if (newstack) {
+	/*
+	 * If this is a branded process, the brand may provide an alternate
+	 * stack pointer for signal delivery:
+	 */
+	if (PROC_IS_BRANDED(p) && BROP(p)->b_sendsig_stack != NULL) {
+		/*
+		 * Use the stack pointer value provided by the brand:
+		 */
+		newstack = 0;
+		fp = BROP(p)->b_sendsig_stack(sig);
+	} else if (newstack) {
 		fp = (caddr_t)(SA((uintptr_t)lwp->lwp_sigaltstack.ss_sp) +
 		    SA(lwp->lwp_sigaltstack.ss_size) - STACK_ALIGN);
 	} else if ((rp->r_ss & 0xffff) != UDS_SEL) {
@@ -658,8 +715,9 @@
 			    USEGD_GETBASE(&ldt[SELTOIDX(rp->r_ss)]);
 		else
 			fp = (caddr_t)rp->r_sp;
-	} else
+	} else {
 		fp = (caddr_t)rp->r_sp;
+	}
 
 	/*
 	 * Force proper stack pointer alignment, even in the face of a
@@ -737,6 +795,8 @@
 	kmem_free(tuc, sizeof (*tuc));
 	tuc = NULL;
 
+	DTRACE_PROBE3(oldcontext__set, klwp_t *, lwp,
+	    uintptr_t, lwp->lwp_oldcontext, uintptr_t, (uintptr_t)uc);
 	lwp->lwp_oldcontext = (uintptr_t)uc;
 
 	if (newstack) {
@@ -773,6 +833,14 @@
 		rp->r_ss = UDS_SEL;
 	}
 
+	/*
+	 * Allow the brand to perform additional book-keeping once the signal
+	 * handling frame has been fully assembled:
+	 */
+	if (PROC_IS_BRANDED(p) && BROP(p)->b_sendsig != NULL) {
+		BROP(p)->b_sendsig(sig);
+	}
+
 	/*
 	 * Don't set lwp_eosys here.  sendsig() is called via psig() after
 	 * lwp_eosys is handled, so setting it here would affect the next
