2017-04-21 06:55:53 +00:00
|
|
|
package native
|
2016-01-15 05:26:54 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2016-02-09 06:24:14 +00:00
|
|
|
"unsafe"
|
2017-04-17 21:13:00 +00:00
|
|
|
|
2021-03-04 18:28:28 +00:00
|
|
|
"github.com/go-delve/delve/pkg/dwarf/op"
|
|
|
|
"github.com/go-delve/delve/pkg/dwarf/regnum"
|
2019-01-04 18:39:25 +00:00
|
|
|
"github.com/go-delve/delve/pkg/proc"
|
|
|
|
"github.com/go-delve/delve/pkg/proc/winutil"
|
2016-01-15 05:26:54 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// SetPC sets the RIP register to the value specified by `pc`.
|
2021-03-04 18:28:28 +00:00
|
|
|
func (thread *nativeThread) setPC(pc uint64) error {
|
2018-10-18 08:15:36 +00:00
|
|
|
context := winutil.NewCONTEXT()
|
2016-02-17 10:23:17 +00:00
|
|
|
context.ContextFlags = _CONTEXT_ALL
|
2016-01-15 05:26:54 +00:00
|
|
|
|
2016-02-17 10:23:17 +00:00
|
|
|
err := _GetThreadContext(thread.os.hThread, context)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
2016-01-15 05:26:54 +00:00
|
|
|
}
|
|
|
|
|
2016-02-17 10:23:17 +00:00
|
|
|
context.Rip = pc
|
2016-01-15 05:26:54 +00:00
|
|
|
|
2016-02-17 10:23:17 +00:00
|
|
|
return _SetThreadContext(thread.os.hThread, context)
|
2016-01-15 05:26:54 +00:00
|
|
|
}
|
|
|
|
|
2021-03-04 18:28:28 +00:00
|
|
|
// SetReg changes the value of the specified register.
|
|
|
|
func (thread *nativeThread) SetReg(regNum uint64, reg *op.DwarfRegister) error {
|
2018-10-18 08:15:36 +00:00
|
|
|
context := winutil.NewCONTEXT()
|
2018-05-04 17:31:45 +00:00
|
|
|
context.ContextFlags = _CONTEXT_ALL
|
|
|
|
|
|
|
|
err := _GetThreadContext(thread.os.hThread, context)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-03-04 18:28:28 +00:00
|
|
|
var p *uint64
|
|
|
|
|
|
|
|
switch regNum {
|
|
|
|
case regnum.AMD64_Rax:
|
|
|
|
p = &context.Rax
|
|
|
|
case regnum.AMD64_Rbx:
|
|
|
|
p = &context.Rbx
|
|
|
|
case regnum.AMD64_Rcx:
|
|
|
|
p = &context.Rcx
|
|
|
|
case regnum.AMD64_Rdx:
|
|
|
|
p = &context.Rdx
|
|
|
|
case regnum.AMD64_Rsi:
|
|
|
|
p = &context.Rsi
|
|
|
|
case regnum.AMD64_Rdi:
|
|
|
|
p = &context.Rdi
|
|
|
|
case regnum.AMD64_Rbp:
|
|
|
|
p = &context.Rbp
|
|
|
|
case regnum.AMD64_Rsp:
|
|
|
|
p = &context.Rsp
|
|
|
|
case regnum.AMD64_R8:
|
|
|
|
p = &context.R8
|
|
|
|
case regnum.AMD64_R9:
|
|
|
|
p = &context.R9
|
|
|
|
case regnum.AMD64_R10:
|
|
|
|
p = &context.R10
|
|
|
|
case regnum.AMD64_R11:
|
|
|
|
p = &context.R11
|
|
|
|
case regnum.AMD64_R12:
|
|
|
|
p = &context.R12
|
|
|
|
case regnum.AMD64_R13:
|
|
|
|
p = &context.R13
|
|
|
|
case regnum.AMD64_R14:
|
|
|
|
p = &context.R14
|
|
|
|
case regnum.AMD64_R15:
|
|
|
|
p = &context.R15
|
|
|
|
case regnum.AMD64_Rip:
|
|
|
|
p = &context.Rip
|
2018-07-31 16:32:30 +00:00
|
|
|
}
|
|
|
|
|
2021-03-04 18:28:28 +00:00
|
|
|
if p != nil {
|
|
|
|
if reg.Bytes != nil && len(reg.Bytes) != 8 {
|
|
|
|
return fmt.Errorf("wrong number of bytes for register %s (%d)", regnum.AMD64ToName(regNum), len(reg.Bytes))
|
|
|
|
}
|
|
|
|
*p = reg.Uint64Val
|
2022-05-05 15:41:40 +00:00
|
|
|
} else if regNum == regnum.AMD64_Rflags {
|
|
|
|
context.Eflags = uint32(reg.Uint64Val)
|
2021-03-04 18:28:28 +00:00
|
|
|
} else {
|
|
|
|
if regNum < regnum.AMD64_XMM0 || regNum > regnum.AMD64_XMM0+15 {
|
|
|
|
return fmt.Errorf("can not set register %s", regnum.AMD64ToName(regNum))
|
|
|
|
}
|
|
|
|
reg.FillBytes()
|
|
|
|
if len(reg.Bytes) > 16 {
|
|
|
|
return fmt.Errorf("too many bytes when setting register %s", regnum.AMD64ToName(regNum))
|
|
|
|
}
|
|
|
|
copy(context.FltSave.XmmRegisters[(regNum-regnum.AMD64_XMM0)*16:], reg.Bytes)
|
|
|
|
}
|
2018-07-31 16:32:30 +00:00
|
|
|
|
|
|
|
return _SetThreadContext(thread.os.hThread, context)
|
|
|
|
}
|
|
|
|
|
2020-05-13 18:56:50 +00:00
|
|
|
func registers(thread *nativeThread) (proc.Registers, error) {
|
2018-10-18 08:15:36 +00:00
|
|
|
context := winutil.NewCONTEXT()
|
2016-01-15 05:26:54 +00:00
|
|
|
|
2016-02-17 10:23:17 +00:00
|
|
|
context.ContextFlags = _CONTEXT_ALL
|
|
|
|
err := _GetThreadContext(thread.os.hThread, context)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2016-01-15 05:26:54 +00:00
|
|
|
}
|
|
|
|
|
2016-02-09 06:24:14 +00:00
|
|
|
var threadInfo _THREAD_BASIC_INFORMATION
|
2016-02-17 10:23:17 +00:00
|
|
|
status := _NtQueryInformationThread(thread.os.hThread, _ThreadBasicInformation, uintptr(unsafe.Pointer(&threadInfo)), uint32(unsafe.Sizeof(threadInfo)), nil)
|
2016-02-09 06:24:14 +00:00
|
|
|
if !_NT_SUCCESS(status) {
|
2016-02-17 10:23:17 +00:00
|
|
|
return nil, fmt.Errorf("NtQueryInformationThread failed: it returns 0x%x", status)
|
2016-01-15 05:26:54 +00:00
|
|
|
}
|
|
|
|
|
2020-05-13 18:56:50 +00:00
|
|
|
return winutil.NewAMD64Registers(context, uint64(threadInfo.TebBaseAddress)), nil
|
2016-01-15 05:26:54 +00:00
|
|
|
}
|