github.com/undoio/delve@v1.9.0/pkg/proc/native/registers_windows_amd64.go (about) 1 package native 2 3 import ( 4 "fmt" 5 "unsafe" 6 7 "github.com/undoio/delve/pkg/dwarf/op" 8 "github.com/undoio/delve/pkg/dwarf/regnum" 9 "github.com/undoio/delve/pkg/proc" 10 "github.com/undoio/delve/pkg/proc/winutil" 11 ) 12 13 // SetPC sets the RIP register to the value specified by `pc`. 14 func (thread *nativeThread) setPC(pc uint64) error { 15 context := winutil.NewCONTEXT() 16 context.ContextFlags = _CONTEXT_ALL 17 18 err := _GetThreadContext(thread.os.hThread, context) 19 if err != nil { 20 return err 21 } 22 23 context.Rip = pc 24 25 return _SetThreadContext(thread.os.hThread, context) 26 } 27 28 // SetReg changes the value of the specified register. 29 func (thread *nativeThread) SetReg(regNum uint64, reg *op.DwarfRegister) error { 30 context := winutil.NewCONTEXT() 31 context.ContextFlags = _CONTEXT_ALL 32 33 err := _GetThreadContext(thread.os.hThread, context) 34 if err != nil { 35 return err 36 } 37 38 var p *uint64 39 40 switch regNum { 41 case regnum.AMD64_Rax: 42 p = &context.Rax 43 case regnum.AMD64_Rbx: 44 p = &context.Rbx 45 case regnum.AMD64_Rcx: 46 p = &context.Rcx 47 case regnum.AMD64_Rdx: 48 p = &context.Rdx 49 case regnum.AMD64_Rsi: 50 p = &context.Rsi 51 case regnum.AMD64_Rdi: 52 p = &context.Rdi 53 case regnum.AMD64_Rbp: 54 p = &context.Rbp 55 case regnum.AMD64_Rsp: 56 p = &context.Rsp 57 case regnum.AMD64_R8: 58 p = &context.R8 59 case regnum.AMD64_R9: 60 p = &context.R9 61 case regnum.AMD64_R10: 62 p = &context.R10 63 case regnum.AMD64_R11: 64 p = &context.R11 65 case regnum.AMD64_R12: 66 p = &context.R12 67 case regnum.AMD64_R13: 68 p = &context.R13 69 case regnum.AMD64_R14: 70 p = &context.R14 71 case regnum.AMD64_R15: 72 p = &context.R15 73 case regnum.AMD64_Rip: 74 p = &context.Rip 75 } 76 77 if p != nil { 78 if reg.Bytes != nil && len(reg.Bytes) != 8 { 79 return fmt.Errorf("wrong number of bytes for register %s (%d)", regnum.AMD64ToName(regNum), len(reg.Bytes)) 80 } 81 *p = reg.Uint64Val 82 } else if regNum == regnum.AMD64_Rflags { 83 context.EFlags = uint32(reg.Uint64Val) 84 } else { 85 if regNum < regnum.AMD64_XMM0 || regNum > regnum.AMD64_XMM0+15 { 86 return fmt.Errorf("can not set register %s", regnum.AMD64ToName(regNum)) 87 } 88 reg.FillBytes() 89 if len(reg.Bytes) > 16 { 90 return fmt.Errorf("too many bytes when setting register %s", regnum.AMD64ToName(regNum)) 91 } 92 copy(context.FltSave.XmmRegisters[(regNum-regnum.AMD64_XMM0)*16:], reg.Bytes) 93 } 94 95 return _SetThreadContext(thread.os.hThread, context) 96 } 97 98 func registers(thread *nativeThread) (proc.Registers, error) { 99 context := winutil.NewCONTEXT() 100 101 context.ContextFlags = _CONTEXT_ALL 102 err := _GetThreadContext(thread.os.hThread, context) 103 if err != nil { 104 return nil, err 105 } 106 107 var threadInfo _THREAD_BASIC_INFORMATION 108 status := _NtQueryInformationThread(thread.os.hThread, _ThreadBasicInformation, uintptr(unsafe.Pointer(&threadInfo)), uint32(unsafe.Sizeof(threadInfo)), nil) 109 if !_NT_SUCCESS(status) { 110 return nil, fmt.Errorf("NtQueryInformationThread failed: it returns 0x%x", status) 111 } 112 113 return winutil.NewAMD64Registers(context, uint64(threadInfo.TebBaseAddress)), nil 114 }