blob: c05573a53113bf1581675d1f1e3d7b4771f4c602 [file] [log] [blame] [edit]
// Copyright 2025 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package windows
import (
"internal/goarch"
"unsafe"
)
// NOTE(rsc): CONTEXT_CONTROL is actually 0x400001 and should include PC, SP, and LR.
// However, empirically, LR doesn't come along on Windows 10
// unless you also set CONTEXT_INTEGER (0x400002).
// Without LR, we skip over the next-to-bottom function in profiles
// when the bottom function is frameless.
// So we set both here, to make a working CONTEXT_CONTROL.
const CONTEXT_CONTROL = 0x400003
type Neon128 struct {
Low uint64
High int64
}
// See https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-arm64_nt_context
type Context struct {
ContextFlags uint32
Cpsr uint32
X [31]uint64 // fp is x[29], lr is x[30]
XSp uint64
Pc uint64
V [32]Neon128
Fpcr uint32
Fpsr uint32
Bcr [8]uint32
Bvr [8]uint64
Wcr [2]uint32
Wvr [2]uint64
}
func (c *Context) PC() uintptr { return uintptr(c.Pc) }
func (c *Context) SP() uintptr { return uintptr(c.XSp) }
func (c *Context) LR() uintptr { return uintptr(c.X[30]) }
func (c *Context) SetPC(x uintptr) { c.Pc = uint64(x) }
func (c *Context) SetSP(x uintptr) { c.XSp = uint64(x) }
func (c *Context) SetLR(x uintptr) { c.X[30] = uint64(x) }
func (c *Context) SetFP(x uintptr) { c.X[29] = uint64(x) }
func (c *Context) PushCall(targetPC, resumePC uintptr) {
// Push LR. The injected call is responsible
// for restoring LR. gentraceback is aware of
// this extra slot. See sigctxt.pushCall in
// signal_arm64.go.
sp := c.SP() - goarch.StackAlign
c.SetSP(sp)
*(*uint64)(unsafe.Pointer(sp)) = uint64(c.LR())
c.SetLR(resumePC)
c.SetPC(targetPC)
}
type DISPATCHER_CONTEXT struct {
ControlPc uint64
ImageBase uint64
FunctionEntry uintptr
EstablisherFrame uint64
TargetIp uint64
Context *Context
LanguageHandler uintptr
HandlerData uintptr
}
func (c *DISPATCHER_CONTEXT) Ctx() *Context {
return c.Context
}