summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid du Colombier <0intro@gmail.com>2014-02-14 22:27:47 +0100
committerDavid du Colombier <0intro@gmail.com>2014-02-14 22:27:47 +0100
commit0578e03b85d046cebf658fe2751efa986fec6f04 (patch)
treed1551ee11878008b9632518b6b5b251cce0762ce /src
parent1a3d66455013201dbbc25107b3f0c94aa656eb25 (diff)
downloadgo-0578e03b85d046cebf658fe2751efa986fec6f04.tar.gz
runtime: fix "invalid address in sys call" on Plan 9
Rfork is not splitting the stack when creating a new thread, so the parent and child are executing on the same stack. However, if the parent returns and keeps executing before the child can read the arguments from the parent stack, the child will not see the right arguments. The solution is to load the needed pieces from the parent stack into register before INT $64. Thanks to Russ Cox for the explanation. LGTM=rsc R=rsc CC=ality, golang-codereviews https://codereview.appspot.com/64140043
Diffstat (limited to 'src')
-rw-r--r--src/pkg/runtime/sys_plan9_386.s10
1 files changed, 4 insertions, 6 deletions
diff --git a/src/pkg/runtime/sys_plan9_386.s b/src/pkg/runtime/sys_plan9_386.s
index bed0f7ebe..2513af9cb 100644
--- a/src/pkg/runtime/sys_plan9_386.s
+++ b/src/pkg/runtime/sys_plan9_386.s
@@ -81,6 +81,10 @@ TEXT runtime·plan9_semrelease(SB),NOSPLIT,$0
TEXT runtime·rfork(SB),NOSPLIT,$0
MOVL $19, AX // rfork
+ MOVL stack+8(SP), CX
+ MOVL mm+12(SP), BX // m
+ MOVL gg+16(SP), DX // g
+ MOVL fn+20(SP), SI // fn
INT $64
// In parent, return.
@@ -88,13 +92,7 @@ TEXT runtime·rfork(SB),NOSPLIT,$0
JEQ 2(PC)
RET
- // In child on old stack.
- MOVL mm+12(SP), BX // m
- MOVL gg+16(SP), DX // g
- MOVL fn+20(SP), SI // fn
-
// set SP to be on the new child stack
- MOVL stack+8(SP), CX
MOVL CX, SP
// Initialize m, g.