]> Cypherpunks repositories - gostls13.git/commitdiff
preserve AX across stack jump so C routines return correct value when triggering...
authorRob Pike <r@golang.org>
Sat, 12 Jul 2008 18:30:53 +0000 (11:30 -0700)
committerRob Pike <r@golang.org>
Sat, 12 Jul 2008 18:30:53 +0000 (11:30 -0700)
SVN=126935

src/runtime/rt0_amd64.s
src/runtime/rt2_amd64.c
src/runtime/runtime.c
src/runtime/runtime.h

index d6dba028641b13c396fcc1dcd503c44e544dddcb..71b1fd8f30ff86a59ab7197fe3b84b5c76f2ebb6 100644 (file)
@@ -72,6 +72,25 @@ TEXT gosave(SB), 7, $0
        MOVL    $0, AX                  // return 0
        RET
 
+/*
+ * support for morestack
+ */
+
+// return point when leaving new stack.  save AX, jmp to oldstack to switch back
+TEXT retfromnewstack(SB), 7, $0
+       MOVQ    AX, 16(R14)     // save AX in m->cret
+       MOVQ    $oldstack(SB), AX
+       JMP     AX
+
+// gogo, returning 2nd arg instead of 1
+TEXT gogoret(SB), 7, $0
+       MOVQ    16(SP), AX                      // return 2nd arg
+       MOVQ    8(SP), BX               // gobuf
+       MOVQ    0(BX), SP               // restore SP
+       MOVQ    8(BX), BX
+       MOVQ    BX, 0(SP)               // put PC on the stack
+       RET
+
 TEXT setspgoto(SB), 7, $0
        MOVQ    8(SP), AX               // SP
        MOVQ    16(SP), BX              // fn to call
index dac1c4684a6d16a921354bdc89255eba4924b459..a5f5d109a9e6dd6bd58f41f080f87f0f7d4da651 100644 (file)
@@ -8,8 +8,6 @@ extern int32    debug;
 
 static int8 spmark[] = "\xa7\xf1\xd9\x2a\x82\xc8\xd8\xfe";
 
-extern void morestack2();
-
 void
 traceback(uint8 *pc, uint8 *sp, void* r15)
 {
@@ -29,8 +27,8 @@ traceback(uint8 *pc, uint8 *sp, void* r15)
        name = "panic";
        for(;;){
                callpc = pc;
-               if((uint8*)morestack2 == pc) {
-                       // call site is morestack2(); pop to earlier stack block to get true caller
+               if((uint8*)retfromnewstack == pc) {
+                       // call site is retfromnewstack(); pop to earlier stack block to get true caller
                        stktop = (Stktop*)g.stackbase;
                        g.stackbase = stktop->oldbase;
                        g.stackguard = stktop->oldguard;
index 743e085e7a3cc3108953e1b2fb7f85768c0ddbe1..f8dfa954cc2ec1c9372577e605db53002cb6299d 100644 (file)
@@ -698,15 +698,15 @@ sys·gosched(void)
 //     CALL    sys·morestack(SB)
 //
 
-int32 debug = 0;
-
 void
-morestack2(void)
+oldstack(void)
 {
        Stktop *top;
        uint32 siz2;
        byte *sp;
-if(debug) prints("morestack2\n");
+if(debug) prints("oldstack m->cret = ");
+if(debug) sys·printpointer((void*)m->cret);
+if(debug) prints("\n");
 
        top = (Stktop*)m->curg->stackbase;
 
@@ -723,16 +723,16 @@ if(debug) prints("morestack2\n");
 
        m->morestack.SP = top->oldsp+8;
        m->morestack.PC = (byte*)(*(uint64*)(top->oldsp+8));
-if(debug) prints("morestack2 sp=");
+if(debug) prints("oldstack sp=");
 if(debug) sys·printpointer(m->morestack.SP);
 if(debug) prints(" pc=");
 if(debug) sys·printpointer(m->morestack.PC);
 if(debug) prints("\n");
-       gogo(&m->morestack);
+       gogoret(&m->morestack, m->cret);
 }
 
 void
-morestack1(void)
+newstack(void)
 {
        int32 siz1, siz2;
        Stktop *top;
@@ -742,7 +742,7 @@ morestack1(void)
        siz1 = m->morearg & 0xffffffffLL;
        siz2 = (m->morearg>>32) & 0xffffLL;
 
-if(debug) prints("morestack1 siz1=");
+if(debug) prints("newstack siz1=");
 if(debug) sys·printint(siz1);
 if(debug) prints(" siz2=");
 if(debug) sys·printint(siz2);
@@ -778,7 +778,7 @@ if(debug) prints("\n");
 if(debug) prints("fn=");
 if(debug) sys·printpointer(fn);
 if(debug) prints("\n");
-       setspgoto(sp, fn, morestack2);
+       setspgoto(sp, fn, retfromnewstack);
 
        *(int32*)345 = 123;
 }
@@ -793,7 +793,7 @@ sys·morestack(uint64 u)
 
        g = m->g0;
        m->moresp = (byte*)(&u-1);
-       setspgoto(m->sched.SP, morestack1, nil);
+       setspgoto(m->sched.SP, newstack, nil);
 
        *(int32*)234 = 123;
 }
index f7d31a1dd8d5b97400aa2f69a99616f027a3df52..3a2e3bde9ed3ca39f68d174fbcd14b8d62231818 100644 (file)
@@ -82,6 +82,7 @@ struct        M
 {
        G*      g0;             // g0 w interrupt stack - must not move
        uint64  morearg;        // arg to morestack - must not move
+       uint64  cret;   // return value from C - must not move
        G*      curg;           // current running goroutine
        Gobuf   sched;
        Gobuf   morestack;
@@ -148,6 +149,8 @@ extern int32        debug;
  */
 int32  gogo(Gobuf*);
 int32  gosave(Gobuf*);
+int32  gogoret(Gobuf*, uint64);
+void   retfromnewstack(void);
 void   setspgoto(byte*, void(*)(void), void(*)(void));
 void   FLUSH(void*);
 void*  getu(void);