aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2015-11-19 15:51:39 -0500
committerRuss Cox <rsc@golang.org>2015-11-23 01:14:55 +0000
commitedc3452f4aba40ef97961ca43f0ffb60f1e30e9c (patch)
treedc83ff961ddcdebba12d3d6d04014678c3cf5c83
parenta28f3ef1c2e3cd033a0ea73f13795a450c3dc9f5 (diff)
downloadgo-edc3452f4aba40ef97961ca43f0ffb60f1e30e9c.tar.gz
go-edc3452f4aba40ef97961ca43f0ffb60f1e30e9c.zip
[release-branch.go1.5] runtime: make asmcgocall work without a g
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 <iant@golang.org> Reviewed-by: Aram Hăvărneanu <aram@mgk.ro> Run-TryBot: Russ Cox <rsc@golang.org> Reviewed-on: https://go-review.googlesource.com/17129
-rw-r--r--src/runtime/asm_amd64.s27
1 files changed, 26 insertions, 1 deletions
diff --git a/src/runtime/asm_amd64.s b/src/runtime/asm_amd64.s
index 3b4ca4d012..980b1ca3e6 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.