]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.5] runtime: make asmcgocall work without a g
authorRuss Cox <rsc@golang.org>
Thu, 19 Nov 2015 20:51:39 +0000 (15:51 -0500)
committerRuss Cox <rsc@golang.org>
Mon, 23 Nov 2015 01:14:55 +0000 (01:14 +0000)
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

src/runtime/asm_amd64.s

index 3b4ca4d012f88fdbc099e19fd3581bdf3356d674..980b1ca3e6c1d8cad116e567fba972297bfff523 100644 (file)
@@ -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.