package amd64
import (
"encoding/binary"
"reflect"
"unsafe"
"github.com/tetratelabs/wazero/internal/wasmdebug"
)
func stackView(rbp , top uintptr ) []byte {
l := int (top - rbp )
var stackBuf []byte
{
hdr := (*reflect .SliceHeader )(unsafe .Pointer (&stackBuf ))
hdr .Data = rbp
hdr .Len = l
hdr .Cap = l
}
return stackBuf
}
func UnwindStack (_ , rbp , top uintptr , returnAddresses []uintptr ) []uintptr {
stackBuf := stackView (rbp , top )
for i := uint64 (0 ); i < uint64 (len (stackBuf )); {
callerRBP := binary .LittleEndian .Uint64 (stackBuf [i :])
retAddr := binary .LittleEndian .Uint64 (stackBuf [i +8 :])
returnAddresses = append (returnAddresses , uintptr (retAddr ))
i = callerRBP - uint64 (rbp )
if len (returnAddresses ) == wasmdebug .MaxFrames {
break
}
}
return returnAddresses
}
func GoCallStackView (stackPointerBeforeGoCall *uint64 ) []uint64 {
data := unsafe .Add (unsafe .Pointer (stackPointerBeforeGoCall ), 8 )
size := *stackPointerBeforeGoCall / 8
return unsafe .Slice ((*uint64 )(data ), size )
}
func AdjustClonedStack (oldRsp , oldTop , rsp , rbp , top uintptr ) {
diff := uint64 (rsp - oldRsp )
newBuf := stackView (rbp , top )
for i := uint64 (0 ); i < uint64 (len (newBuf )); {
callerRBP := binary .LittleEndian .Uint64 (newBuf [i :])
if callerRBP == 0 {
break
}
if i64 := int64 (callerRBP ); i64 < int64 (oldRsp ) || i64 >= int64 (oldTop ) {
panic ("BUG: callerRBP is out of range" )
}
if int (callerRBP ) < 0 {
panic ("BUG: callerRBP is negative" )
}
adjustedCallerRBP := callerRBP + diff
if int (adjustedCallerRBP ) < 0 {
panic ("BUG: adjustedCallerRBP is negative" )
}
binary .LittleEndian .PutUint64 (newBuf [i :], adjustedCallerRBP )
i = adjustedCallerRBP - uint64 (rbp )
}
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .