components/golang/patches/0054-release-branch.go1.5-runtime-make-asmcgocall-work-wi.patch
author Shawn Ferry <shawn.ferry@oracle.com>
Wed, 30 Mar 2016 12:56:49 -0400
changeset 5747 4441137c3e4a
parent 5331 9c955076ffe3
permissions -rw-r--r--
22853886 ruby/gem specs and tests should be faceted out via default transforms

From edc3452f4aba40ef97961ca43f0ffb60f1e30e9c Mon Sep 17 00:00:00 2001
From: Russ Cox <[email protected]>
Date: Thu, 19 Nov 2015 15:51:39 -0500
Subject: [PATCH 54/63] [release-branch.go1.5] runtime: make asmcgocall work
 without a g
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Solaris needs to make system calls without a g,
and Solaris uses asmcgocall to make system calls.
I know, I know.

I hope this makes CL 16915, fixing #12277, work on Solaris.

Change-Id: If988dfd37f418b302da9c7096f598e5113ecea87
Reviewed-on: https://go-review.googlesource.com/17072
Reviewed-by: Ian Lance Taylor <[email protected]>
Reviewed-by: Aram Hăvărneanu <[email protected]>
Run-TryBot: Russ Cox <[email protected]>
Reviewed-on: https://go-review.googlesource.com/17129
---
 src/runtime/asm_amd64.s | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/src/runtime/asm_amd64.s b/src/runtime/asm_amd64.s
index 3b4ca4d..980b1ca 100644
--- a/src/runtime/asm_amd64.s
+++ b/src/runtime/asm_amd64.s
@@ -661,6 +661,8 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-20
 	// come in on the m->g0 stack already.
 	get_tls(CX)
 	MOVQ	g(CX), R8
+	CMPQ	R8, $0
+	JEQ	nosave
 	MOVQ	g_m(R8), R8
 	MOVQ	m_g0(R8), SI
 	MOVQ	g(CX), DI
@@ -670,11 +672,11 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-20
 	CMPQ	SI, DI
 	JEQ	nosave
 	
+	// Switch to system stack.
 	MOVQ	m_g0(R8), SI
 	CALL	gosave<>(SB)
 	MOVQ	SI, g(CX)
 	MOVQ	(g_sched+gobuf_sp)(SI), SP
-nosave:
 
 	// Now on a scheduling stack (a pthread-created stack).
 	// Make sure we have enough room for 4 stack-backed fast-call
@@ -700,6 +702,29 @@ nosave:
 	MOVL	AX, ret+16(FP)
 	RET
 
+nosave:
+	// Running on a system stack, perhaps even without a g.
+	// Having no g can happen during thread creation or thread teardown
+	// (see needm/dropm on Solaris, for example).
+	// This code is like the above sequence but without saving/restoring g
+	// and without worrying about the stack moving out from under us
+	// (because we're on a system stack, not a goroutine stack).
+	// The above code could be used directly if already on a system stack,
+	// but then the only path through this code would be a rare case on Solaris.
+	// Using this code for all "already on system stack" calls exercises it more,
+	// which should help keep it correct.
+	SUBQ	$64, SP
+	ANDQ	$~15, SP
+	MOVQ	$0, 48(SP)		// where above code stores g, in case someone looks during debugging
+	MOVQ	DX, 40(SP)	// save original stack pointer
+	MOVQ	BX, DI		// DI = first argument in AMD64 ABI
+	MOVQ	BX, CX		// CX = first argument in Win64
+	CALL	AX
+	MOVQ	40(SP), SI	// restore original stack pointer
+	MOVQ	SI, SP
+	MOVL	AX, ret+16(FP)
+	RET
+
 // cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
 // Turn the fn into a Go func (by taking its address) and call
 // cgocallback_gofunc.
-- 
2.6.1