github.com/undoio/delve@v1.9.0/pkg/proc/winutil/regs.go (about) 1 package winutil 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "fmt" 7 "unsafe" 8 9 "github.com/undoio/delve/pkg/proc" 10 ) 11 12 // AMD64Registers represents CPU registers on an AMD64 processor. 13 type AMD64Registers struct { 14 rax uint64 15 rbx uint64 16 rcx uint64 17 rdx uint64 18 rdi uint64 19 rsi uint64 20 rbp uint64 21 rsp uint64 22 r8 uint64 23 r9 uint64 24 r10 uint64 25 r11 uint64 26 r12 uint64 27 r13 uint64 28 r14 uint64 29 r15 uint64 30 rip uint64 31 eflags uint64 32 cs uint64 33 fs uint64 34 gs uint64 35 tls uint64 36 Context *CONTEXT 37 fltSave *XMM_SAVE_AREA32 38 } 39 40 // NewAMD64Registers creates a new AMD64Registers struct from a CONTEXT 41 // struct and the TEB base address of the thread. 42 func NewAMD64Registers(context *CONTEXT, TebBaseAddress uint64) *AMD64Registers { 43 regs := &AMD64Registers{ 44 rax: uint64(context.Rax), 45 rbx: uint64(context.Rbx), 46 rcx: uint64(context.Rcx), 47 rdx: uint64(context.Rdx), 48 rdi: uint64(context.Rdi), 49 rsi: uint64(context.Rsi), 50 rbp: uint64(context.Rbp), 51 rsp: uint64(context.Rsp), 52 r8: uint64(context.R8), 53 r9: uint64(context.R9), 54 r10: uint64(context.R10), 55 r11: uint64(context.R11), 56 r12: uint64(context.R12), 57 r13: uint64(context.R13), 58 r14: uint64(context.R14), 59 r15: uint64(context.R15), 60 rip: uint64(context.Rip), 61 eflags: uint64(context.EFlags), 62 cs: uint64(context.SegCs), 63 fs: uint64(context.SegFs), 64 gs: uint64(context.SegGs), 65 tls: TebBaseAddress, 66 } 67 68 regs.fltSave = &context.FltSave 69 regs.Context = context 70 71 return regs 72 } 73 74 // Slice returns the registers as a list of (name, value) pairs. 75 func (r *AMD64Registers) Slice(floatingPoint bool) ([]proc.Register, error) { 76 var regs = []struct { 77 k string 78 v uint64 79 }{ 80 {"Rip", r.rip}, 81 {"Rsp", r.rsp}, 82 {"Rax", r.rax}, 83 {"Rbx", r.rbx}, 84 {"Rcx", r.rcx}, 85 {"Rdx", r.rdx}, 86 {"Rdi", r.rdi}, 87 {"Rsi", r.rsi}, 88 {"Rbp", r.rbp}, 89 {"R8", r.r8}, 90 {"R9", r.r9}, 91 {"R10", r.r10}, 92 {"R11", r.r11}, 93 {"R12", r.r12}, 94 {"R13", r.r13}, 95 {"R14", r.r14}, 96 {"R15", r.r15}, 97 {"Rflags", r.eflags}, 98 {"Cs", r.cs}, 99 {"Fs", r.fs}, 100 {"Gs", r.gs}, 101 {"TLS", r.tls}, 102 } 103 outlen := len(regs) 104 if r.fltSave != nil && floatingPoint { 105 outlen += 6 + 8 + 2 + 16 106 } 107 out := make([]proc.Register, 0, outlen) 108 for _, reg := range regs { 109 out = proc.AppendUint64Register(out, reg.k, reg.v) 110 } 111 if r.fltSave != nil && floatingPoint { 112 out = proc.AppendUint64Register(out, "CW", uint64(r.fltSave.ControlWord)) 113 out = proc.AppendUint64Register(out, "SW", uint64(r.fltSave.StatusWord)) 114 out = proc.AppendUint64Register(out, "TW", uint64(uint16(r.fltSave.TagWord))) 115 out = proc.AppendUint64Register(out, "FOP", uint64(r.fltSave.ErrorOpcode)) 116 out = proc.AppendUint64Register(out, "FIP", uint64(r.fltSave.ErrorSelector)<<32|uint64(r.fltSave.ErrorOffset)) 117 out = proc.AppendUint64Register(out, "FDP", uint64(r.fltSave.DataSelector)<<32|uint64(r.fltSave.DataOffset)) 118 119 for i := range r.fltSave.FloatRegisters { 120 var buf bytes.Buffer 121 binary.Write(&buf, binary.LittleEndian, r.fltSave.FloatRegisters[i].Low) 122 binary.Write(&buf, binary.LittleEndian, r.fltSave.FloatRegisters[i].High) 123 out = proc.AppendBytesRegister(out, fmt.Sprintf("ST(%d)", i), buf.Bytes()) 124 } 125 126 out = proc.AppendUint64Register(out, "MXCSR", uint64(r.fltSave.MxCsr)) 127 out = proc.AppendUint64Register(out, "MXCSR_MASK", uint64(r.fltSave.MxCsr_Mask)) 128 129 for i := 0; i < len(r.fltSave.XmmRegisters); i += 16 { 130 out = proc.AppendBytesRegister(out, fmt.Sprintf("XMM%d", i/16), r.fltSave.XmmRegisters[i:i+16]) 131 } 132 } 133 return out, nil 134 } 135 136 // PC returns the current program counter 137 // i.e. the RIP CPU register. 138 func (r *AMD64Registers) PC() uint64 { 139 return r.rip 140 } 141 142 // SP returns the stack pointer location, 143 // i.e. the RSP register. 144 func (r *AMD64Registers) SP() uint64 { 145 return r.rsp 146 } 147 148 func (r *AMD64Registers) BP() uint64 { 149 return r.rbp 150 } 151 152 // LR returns the link register. 153 func (r *AMD64Registers) LR() uint64 { 154 return 0 155 } 156 157 // TLS returns the value of the register 158 // that contains the location of the thread 159 // local storage segment. 160 func (r *AMD64Registers) TLS() uint64 { 161 return r.tls 162 } 163 164 // GAddr returns the address of the G variable if it is known, 0 and false 165 // otherwise. 166 func (r *AMD64Registers) GAddr() (uint64, bool) { 167 return 0, false 168 } 169 170 // Copy returns a copy of these registers that is guaranteed not to change. 171 func (r *AMD64Registers) Copy() (proc.Registers, error) { 172 var rr AMD64Registers 173 rr = *r 174 rr.Context = NewCONTEXT() 175 *(rr.Context) = *(r.Context) 176 rr.fltSave = &rr.Context.FltSave 177 return &rr, nil 178 } 179 180 // M128A tracks the _M128A windows struct. 181 type M128A struct { 182 Low uint64 183 High int64 184 } 185 186 // XMM_SAVE_AREA32 tracks the _XMM_SAVE_AREA32 windows struct. 187 type XMM_SAVE_AREA32 struct { 188 ControlWord uint16 189 StatusWord uint16 190 TagWord byte 191 Reserved1 byte 192 ErrorOpcode uint16 193 ErrorOffset uint32 194 ErrorSelector uint16 195 Reserved2 uint16 196 DataOffset uint32 197 DataSelector uint16 198 Reserved3 uint16 199 MxCsr uint32 200 MxCsr_Mask uint32 201 FloatRegisters [8]M128A 202 XmmRegisters [256]byte 203 Reserved4 [96]byte 204 } 205 206 // CONTEXT tracks the _CONTEXT of windows. 207 type CONTEXT struct { 208 P1Home uint64 209 P2Home uint64 210 P3Home uint64 211 P4Home uint64 212 P5Home uint64 213 P6Home uint64 214 215 ContextFlags uint32 216 MxCsr uint32 217 218 SegCs uint16 219 SegDs uint16 220 SegEs uint16 221 SegFs uint16 222 SegGs uint16 223 SegSs uint16 224 EFlags uint32 225 226 Dr0 uint64 227 Dr1 uint64 228 Dr2 uint64 229 Dr3 uint64 230 Dr6 uint64 231 Dr7 uint64 232 233 Rax uint64 234 Rcx uint64 235 Rdx uint64 236 Rbx uint64 237 Rsp uint64 238 Rbp uint64 239 Rsi uint64 240 Rdi uint64 241 R8 uint64 242 R9 uint64 243 R10 uint64 244 R11 uint64 245 R12 uint64 246 R13 uint64 247 R14 uint64 248 R15 uint64 249 250 Rip uint64 251 252 FltSave XMM_SAVE_AREA32 253 254 VectorRegister [26]M128A 255 VectorControl uint64 256 257 DebugControl uint64 258 LastBranchToRip uint64 259 LastBranchFromRip uint64 260 LastExceptionToRip uint64 261 LastExceptionFromRip uint64 262 } 263 264 // NewCONTEXT allocates Windows CONTEXT structure aligned to 16 bytes. 265 func NewCONTEXT() *CONTEXT { 266 var c *CONTEXT 267 buf := make([]byte, unsafe.Sizeof(*c)+15) 268 return (*CONTEXT)(unsafe.Pointer((uintptr(unsafe.Pointer(&buf[15]))) &^ 15)) 269 }