Home | History | Annotate | Download | only in runtime
      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 package runtime
      8 
      9 import "unsafe"
     10 
     11 // adjust Gobuf as it if executed a call to fn with context ctxt
     12 // and then did an immediate gosave.
     13 func gostartcall(buf *gobuf, fn, ctxt unsafe.Pointer) {
     14 	sp := buf.sp
     15 	if regSize > ptrSize {
     16 		sp -= ptrSize
     17 		*(*uintptr)(unsafe.Pointer(sp)) = 0
     18 	}
     19 	sp -= ptrSize
     20 	*(*uintptr)(unsafe.Pointer(sp)) = buf.pc
     21 	buf.sp = sp
     22 	buf.pc = uintptr(fn)
     23 	buf.ctxt = ctxt
     24 }
     25 
     26 // Called to rewind context saved during morestack back to beginning of function.
     27 // To help us, the linker emits a jmp back to the beginning right after the
     28 // call to morestack. We just have to decode and apply that jump.
     29 func rewindmorestack(buf *gobuf) {
     30 	pc := (*[8]byte)(unsafe.Pointer(buf.pc))
     31 	if pc[0] == 0xe9 { // jmp 4-byte offset
     32 		buf.pc = buf.pc + 5 + uintptr(int64(*(*int32)(unsafe.Pointer(&pc[1]))))
     33 		return
     34 	}
     35 	if pc[0] == 0xeb { // jmp 1-byte offset
     36 		buf.pc = buf.pc + 2 + uintptr(int64(*(*int8)(unsafe.Pointer(&pc[1]))))
     37 		return
     38 	}
     39 	if pc[0] == 0xcc {
     40 		// This is a breakpoint inserted by gdb.  We could use
     41 		// runtimefindfunc to find the function.  But if we
     42 		// do that, then we will continue execution at the
     43 		// function entry point, and we will not hit the gdb
     44 		// breakpoint.  So for this case we don't change
     45 		// buf.pc, so that when we return we will execute
     46 		// the jump instruction and carry on.  This means that
     47 		// stack unwinding may not work entirely correctly
     48 		// (https://golang.org/issue/5723) but the user is
     49 		// running under gdb anyhow.
     50 		return
     51 	}
     52 	print("runtime: pc=", pc, " ", hex(pc[0]), " ", hex(pc[1]), " ", hex(pc[2]), " ", hex(pc[3]), " ", hex(pc[4]), "\n")
     53 	throw("runtime: misuse of rewindmorestack")
     54 }
     55