github.com/akaros/go-akaros@v0.0.0-20181004170632-85005d477eab/src/runtime/sys_x86.c (about)

     1  // Copyright 2013 The Go Authors.  All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build amd64 amd64p32 386
     6  
     7  #include "runtime.h"
     8  
     9  // adjust Gobuf as it if executed a call to fn with context ctxt
    10  // and then did an immediate gosave.
    11  void
    12  runtime·gostartcall(Gobuf *gobuf, void (*fn)(void), void *ctxt)
    13  {
    14  	uintptr *sp;
    15  	
    16  	sp = (uintptr*)gobuf->sp;
    17  	if(sizeof(uintreg) > sizeof(uintptr))
    18  		*--sp = 0;
    19  	*--sp = (uintptr)gobuf->pc;
    20  	gobuf->sp = (uintptr)sp;
    21  	gobuf->pc = (uintptr)fn;
    22  	gobuf->ctxt = ctxt;
    23  }
    24  
    25  // Called to rewind context saved during morestack back to beginning of function.
    26  // To help us, the linker emits a jmp back to the beginning right after the
    27  // call to morestack. We just have to decode and apply that jump.
    28  void
    29  runtime·rewindmorestack(Gobuf *gobuf)
    30  {
    31  	byte *pc;
    32  
    33  	pc = (byte*)gobuf->pc;
    34  	if(pc[0] == 0xe9) { // jmp 4-byte offset
    35  		gobuf->pc = gobuf->pc + 5 + *(int32*)(pc+1);
    36  		return;
    37  	}
    38  	if(pc[0] == 0xeb) { // jmp 1-byte offset
    39  		gobuf->pc = gobuf->pc + 2 + *(int8*)(pc+1);
    40  		return;
    41  	}
    42  	if(pc[0] == 0xcc) {
    43  		// This is a breakpoint inserted by gdb.  We could use
    44  		// runtime·findfunc to find the function.  But if we
    45  		// do that, then we will continue execution at the
    46  		// function entry point, and we will not hit the gdb
    47  		// breakpoint.  So for this case we don't change
    48  		// gobuf->pc, so that when we return we will execute
    49  		// the jump instruction and carry on.  This means that
    50  		// stack unwinding may not work entirely correctly
    51  		// (http://golang.org/issue/5723) but the user is
    52  		// running under gdb anyhow.
    53  		return;
    54  	}
    55  	runtime·printf("runtime: pc=%p %x %x %x %x %x\n", pc, pc[0], pc[1], pc[2], pc[3], pc[4]);
    56  	runtime·throw("runtime: misuse of rewindmorestack");
    57  }