aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/asm_386.s
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2018-05-03 10:30:31 -0700
committerKeith Randall <khr@golang.org>2018-05-19 17:38:01 +0000
commite86c26789dbc11c50c4c49bee55ea015847a97b7 (patch)
treea6c1cdd109f457edab95df6f29229595cb97a505 /src/runtime/asm_386.s
parente9137299bf74e1bcac358b569f86aef73c7c2ea6 (diff)
downloadgo-e86c26789dbc11c50c4c49bee55ea015847a97b7.tar.gz
go-e86c26789dbc11c50c4c49bee55ea015847a97b7.zip
runtime: fix darwin 386/amd64 stack switches
A few libc_ calls were missing stack switches. Unfortunately, adding the stack switches revealed a deeper problem. systemstack() is fundamentally flawed because when you do systemstack(func() { ... }) There's no way to mark the anonymous function as nosplit. At first I thought it didn't matter, as that function runs on the g0 stack. But nosplit is still required, because some syscalls are done when stack bounds are not set up correctly (e.g. in a signal handler, which runs on the g0 stack, but g is still pointing at the g stack). Instead use asmcgocall and funcPC, so we can be nosplit all the way down. Mid-stack inlining now pushes darwin over the nosplit limit also. Leaving that as a TODO. Update #23168 This might fix the cause of occasional darwin hangs. Update #25181 Update #17490 Change-Id: If9c3ef052822c7679f5a1dd192443f714483327e Reviewed-on: https://go-review.googlesource.com/111258 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/runtime/asm_386.s')
-rw-r--r--src/runtime/asm_386.s14
1 files changed, 14 insertions, 0 deletions
diff --git a/src/runtime/asm_386.s b/src/runtime/asm_386.s
index 63fa17af62..54d5eaa014 100644
--- a/src/runtime/asm_386.s
+++ b/src/runtime/asm_386.s
@@ -697,6 +697,8 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-12
// come in on the m->g0 stack already.
get_tls(CX)
MOVL g(CX), BP
+ CMPL BP, $0
+ JEQ nosave // Don't even have a G yet.
MOVL g_m(BP), BP
MOVL m_g0(BP), SI
MOVL g(CX), DI
@@ -728,6 +730,18 @@ noswitch:
MOVL AX, ret+8(FP)
RET
+nosave:
+ // Now on a scheduling stack (a pthread-created stack).
+ SUBL $32, SP
+ ANDL $~15, SP // alignment, perhaps unnecessary
+ MOVL DX, 4(SP) // save original stack pointer
+ MOVL BX, 0(SP) // first argument in x86-32 ABI
+ CALL AX
+
+ MOVL 4(SP), CX // restore original stack pointer
+ MOVL CX, SP
+ MOVL AX, ret+8(FP)
+ RET
// cgocallback(void (*fn)(void*), void *frame, uintptr framesize, uintptr ctxt)
// Turn the fn into a Go func (by taking its address) and call