Debugger: Split into core library and application.
[haiku.git] / src / kits / debugger / arch / x86_64 / CpuStateX8664.cpp
blob36e4b089b8fdf4c8a9e486bd72e0f0e8543017fd
1 /*
2 * Copyright 2012, Alex Smith, alex@alex-smith.me.uk.
3 * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
4 * Copyright 2011-2013, Rene Gollent, rene@gollent.com.
5 * Distributed under the terms of the MIT License.
6 */
8 #include "CpuStateX8664.h"
10 #include <new>
12 #include <string.h>
14 #include "Register.h"
17 CpuStateX8664::CpuStateX8664()
19 fSetRegisters()
24 CpuStateX8664::CpuStateX8664(const x86_64_debug_cpu_state& state)
26 fSetRegisters(),
27 fInterruptVector(0)
29 SetIntRegister(X86_64_REGISTER_RIP, state.rip);
30 SetIntRegister(X86_64_REGISTER_RSP, state.rsp);
31 SetIntRegister(X86_64_REGISTER_RBP, state.rbp);
32 SetIntRegister(X86_64_REGISTER_RAX, state.rax);
33 SetIntRegister(X86_64_REGISTER_RBX, state.rbx);
34 SetIntRegister(X86_64_REGISTER_RCX, state.rcx);
35 SetIntRegister(X86_64_REGISTER_RDX, state.rdx);
36 SetIntRegister(X86_64_REGISTER_RSI, state.rsi);
37 SetIntRegister(X86_64_REGISTER_RDI, state.rdi);
38 SetIntRegister(X86_64_REGISTER_R8, state.r8);
39 SetIntRegister(X86_64_REGISTER_R9, state.r9);
40 SetIntRegister(X86_64_REGISTER_R10, state.r10);
41 SetIntRegister(X86_64_REGISTER_R11, state.r11);
42 SetIntRegister(X86_64_REGISTER_R12, state.r12);
43 SetIntRegister(X86_64_REGISTER_R13, state.r13);
44 SetIntRegister(X86_64_REGISTER_R14, state.r14);
45 SetIntRegister(X86_64_REGISTER_R15, state.r15);
46 SetIntRegister(X86_64_REGISTER_CS, state.cs);
47 SetIntRegister(X86_64_REGISTER_DS, state.ds);
48 SetIntRegister(X86_64_REGISTER_ES, state.es);
49 SetIntRegister(X86_64_REGISTER_FS, state.fs);
50 SetIntRegister(X86_64_REGISTER_GS, state.gs);
51 SetIntRegister(X86_64_REGISTER_SS, state.ss);
53 const x86_64_extended_registers& extended = state.extended_registers;
55 SetFloatRegister(X86_64_REGISTER_ST0,
56 (double)(*(long double*)(extended.fp_registers[0].value)));
57 SetFloatRegister(X86_64_REGISTER_ST1,
58 (double)(*(long double*)(extended.fp_registers[1].value)));
59 SetFloatRegister(X86_64_REGISTER_ST2,
60 (double)(*(long double*)(extended.fp_registers[2].value)));
61 SetFloatRegister(X86_64_REGISTER_ST3,
62 (double)(*(long double*)(extended.fp_registers[3].value)));
63 SetFloatRegister(X86_64_REGISTER_ST4,
64 (double)(*(long double*)(extended.fp_registers[4].value)));
65 SetFloatRegister(X86_64_REGISTER_ST5,
66 (double)(*(long double*)(extended.fp_registers[5].value)));
67 SetFloatRegister(X86_64_REGISTER_ST6,
68 (double)(*(long double*)(extended.fp_registers[6].value)));
69 SetFloatRegister(X86_64_REGISTER_ST7,
70 (double)(*(long double*)(extended.fp_registers[7].value)));
72 SetMMXRegister(X86_64_REGISTER_MM0, extended.mmx_registers[0].value);
73 SetMMXRegister(X86_64_REGISTER_MM1, extended.mmx_registers[1].value);
74 SetMMXRegister(X86_64_REGISTER_MM2, extended.mmx_registers[2].value);
75 SetMMXRegister(X86_64_REGISTER_MM3, extended.mmx_registers[3].value);
76 SetMMXRegister(X86_64_REGISTER_MM4, extended.mmx_registers[4].value);
77 SetMMXRegister(X86_64_REGISTER_MM5, extended.mmx_registers[5].value);
78 SetMMXRegister(X86_64_REGISTER_MM6, extended.mmx_registers[6].value);
79 SetMMXRegister(X86_64_REGISTER_MM7, extended.mmx_registers[7].value);
81 SetXMMRegister(X86_64_REGISTER_XMM0, extended.xmm_registers[0].value);
82 SetXMMRegister(X86_64_REGISTER_XMM1, extended.xmm_registers[1].value);
83 SetXMMRegister(X86_64_REGISTER_XMM2, extended.xmm_registers[2].value);
84 SetXMMRegister(X86_64_REGISTER_XMM3, extended.xmm_registers[3].value);
85 SetXMMRegister(X86_64_REGISTER_XMM4, extended.xmm_registers[4].value);
86 SetXMMRegister(X86_64_REGISTER_XMM5, extended.xmm_registers[5].value);
87 SetXMMRegister(X86_64_REGISTER_XMM6, extended.xmm_registers[6].value);
88 SetXMMRegister(X86_64_REGISTER_XMM7, extended.xmm_registers[7].value);
89 SetXMMRegister(X86_64_REGISTER_XMM8, extended.xmm_registers[8].value);
90 SetXMMRegister(X86_64_REGISTER_XMM9, extended.xmm_registers[9].value);
91 SetXMMRegister(X86_64_REGISTER_XMM10, extended.xmm_registers[10].value);
92 SetXMMRegister(X86_64_REGISTER_XMM11, extended.xmm_registers[11].value);
93 SetXMMRegister(X86_64_REGISTER_XMM12, extended.xmm_registers[12].value);
94 SetXMMRegister(X86_64_REGISTER_XMM13, extended.xmm_registers[13].value);
95 SetXMMRegister(X86_64_REGISTER_XMM14, extended.xmm_registers[14].value);
96 SetXMMRegister(X86_64_REGISTER_XMM15, extended.xmm_registers[15].value);
98 fInterruptVector = state.vector;
102 CpuStateX8664::~CpuStateX8664()
107 status_t
108 CpuStateX8664::Clone(CpuState*& _clone) const
110 CpuStateX8664* newState = new(std::nothrow) CpuStateX8664();
111 if (newState == NULL)
112 return B_NO_MEMORY;
115 memcpy(newState->fIntRegisters, fIntRegisters, sizeof(fIntRegisters));
116 memcpy(newState->fFloatRegisters, fFloatRegisters,
117 sizeof(fFloatRegisters));
118 memcpy(newState->fMMXRegisters, fMMXRegisters, sizeof(fMMXRegisters));
119 memcpy(newState->fXMMRegisters, fXMMRegisters, sizeof(fXMMRegisters));
121 newState->fSetRegisters = fSetRegisters;
122 newState->fInterruptVector = fInterruptVector;
124 _clone = newState;
126 return B_OK;
130 status_t
131 CpuStateX8664::UpdateDebugState(void* state, size_t size) const
133 if (size != sizeof(x86_64_debug_cpu_state))
134 return B_BAD_VALUE;
136 x86_64_debug_cpu_state* x64State = (x86_64_debug_cpu_state*)state;
138 x64State->rip = InstructionPointer();
139 x64State->rsp = StackPointer();
140 x64State->rbp = StackFramePointer();
141 x64State->rax = IntRegisterValue(X86_64_REGISTER_RAX);
142 x64State->rbx = IntRegisterValue(X86_64_REGISTER_RBX);
143 x64State->rcx = IntRegisterValue(X86_64_REGISTER_RCX);
144 x64State->rdx = IntRegisterValue(X86_64_REGISTER_RDX);
145 x64State->rsi = IntRegisterValue(X86_64_REGISTER_RSI);
146 x64State->rdi = IntRegisterValue(X86_64_REGISTER_RDI);
147 x64State->r8 = IntRegisterValue(X86_64_REGISTER_R8);
148 x64State->r9 = IntRegisterValue(X86_64_REGISTER_R9);
149 x64State->r10 = IntRegisterValue(X86_64_REGISTER_R10);
150 x64State->r11 = IntRegisterValue(X86_64_REGISTER_R11);
151 x64State->r12 = IntRegisterValue(X86_64_REGISTER_R12);
152 x64State->r13 = IntRegisterValue(X86_64_REGISTER_R13);
153 x64State->r14 = IntRegisterValue(X86_64_REGISTER_R14);
154 x64State->r15 = IntRegisterValue(X86_64_REGISTER_R15);
155 x64State->cs = IntRegisterValue(X86_64_REGISTER_CS);
156 x64State->ds = IntRegisterValue(X86_64_REGISTER_DS);
157 x64State->es = IntRegisterValue(X86_64_REGISTER_ES);
158 x64State->fs = IntRegisterValue(X86_64_REGISTER_FS);
159 x64State->gs = IntRegisterValue(X86_64_REGISTER_GS);
160 x64State->ss = IntRegisterValue(X86_64_REGISTER_SS);
162 for (int32 i = 0; i < 8; i++) {
163 *(long double*)(x64State->extended_registers.fp_registers[i].value)
164 = (long double)FloatRegisterValue(X86_64_REGISTER_ST0 + i);
166 if (IsRegisterSet(X86_64_REGISTER_MM0 + i)) {
167 memcpy(&x64State->extended_registers.mmx_registers[i],
168 &fMMXRegisters[i], sizeof(x86_64_fp_register));
172 for (int32 i = 0; i < 16; i++) {
173 if (IsRegisterSet(X86_64_REGISTER_XMM0 + i)) {
174 memcpy(&x64State->extended_registers.xmm_registers[i],
175 &fXMMRegisters[i], sizeof(x86_64_xmm_register));
176 } else {
177 memset(&x64State->extended_registers.xmm_registers[i],
178 0, sizeof(x86_64_xmm_register));
182 return B_OK;
186 target_addr_t
187 CpuStateX8664::InstructionPointer() const
189 return IsRegisterSet(X86_64_REGISTER_RIP)
190 ? IntRegisterValue(X86_64_REGISTER_RIP) : 0;
194 void
195 CpuStateX8664::SetInstructionPointer(target_addr_t address)
197 SetIntRegister(X86_64_REGISTER_RIP, address);
201 target_addr_t
202 CpuStateX8664::StackFramePointer() const
204 return IsRegisterSet(X86_64_REGISTER_RBP)
205 ? IntRegisterValue(X86_64_REGISTER_RBP) : 0;
209 target_addr_t
210 CpuStateX8664::StackPointer() const
212 return IsRegisterSet(X86_64_REGISTER_RSP)
213 ? IntRegisterValue(X86_64_REGISTER_RSP) : 0;
217 bool
218 CpuStateX8664::GetRegisterValue(const Register* reg, BVariant& _value) const
220 int32 index = reg->Index();
221 if (!IsRegisterSet(index))
222 return false;
224 if (index >= X86_64_XMM_REGISTER_END)
225 return false;
227 if (BVariant::TypeIsInteger(reg->ValueType())) {
228 if (reg->BitSize() == 16)
229 _value.SetTo((uint16)fIntRegisters[index]);
230 else
231 _value.SetTo(fIntRegisters[index]);
232 } else if (BVariant::TypeIsFloat(reg->ValueType())) {
233 index -= X86_64_REGISTER_ST0;
234 if (reg->ValueType() == B_FLOAT_TYPE)
235 _value.SetTo((float)fFloatRegisters[index]);
236 else
237 _value.SetTo(fFloatRegisters[index]);
238 } else {
239 if (index >= X86_64_REGISTER_MM0 && index < X86_64_REGISTER_XMM0) {
240 index -= X86_64_REGISTER_MM0;
241 _value.SetTo(fMMXRegisters[index].value);
242 } else {
243 index -= X86_64_REGISTER_XMM0;
244 _value.SetTo(fXMMRegisters[index].value);
248 return true;
252 bool
253 CpuStateX8664::SetRegisterValue(const Register* reg, const BVariant& value)
255 int32 index = reg->Index();
256 if (index >= X86_64_XMM_REGISTER_END)
257 return false;
259 if (index < X86_64_INT_REGISTER_END)
260 fIntRegisters[index] = value.ToUInt64();
261 else if (index >= X86_64_REGISTER_ST0 && index < X86_64_FP_REGISTER_END)
262 fFloatRegisters[index - X86_64_REGISTER_ST0] = value.ToDouble();
263 else if (index >= X86_64_REGISTER_MM0 && index < X86_64_MMX_REGISTER_END) {
264 if (value.Size() > sizeof(int64))
265 return false;
266 memset(&fMMXRegisters[index - X86_64_REGISTER_MM0], 0,
267 sizeof(x86_64_fp_register));
268 memcpy(fMMXRegisters[index - X86_64_REGISTER_MM0].value,
269 value.ToPointer(), value.Size());
270 } else if (index >= X86_64_REGISTER_XMM0
271 && index < X86_64_XMM_REGISTER_END) {
272 if (value.Size() > sizeof(x86_64_xmm_register))
273 return false;
275 memset(&fXMMRegisters[index - X86_64_REGISTER_XMM0], 0,
276 sizeof(x86_64_xmm_register));
277 memcpy(fXMMRegisters[index - X86_64_REGISTER_XMM0].value,
278 value.ToPointer(), value.Size());
279 } else
280 return false;
282 fSetRegisters[index] = 1;
283 return true;
287 bool
288 CpuStateX8664::IsRegisterSet(int32 index) const
290 return index >= 0 && index < X86_64_REGISTER_COUNT && fSetRegisters[index];
294 uint64
295 CpuStateX8664::IntRegisterValue(int32 index) const
297 if (!IsRegisterSet(index) || index >= X86_64_INT_REGISTER_END)
298 return 0;
300 return fIntRegisters[index];
304 void
305 CpuStateX8664::SetIntRegister(int32 index, uint64 value)
307 if (index < 0 || index >= X86_64_INT_REGISTER_END)
308 return;
310 fIntRegisters[index] = value;
311 fSetRegisters[index] = 1;
315 double
316 CpuStateX8664::FloatRegisterValue(int32 index) const
318 if (index < X86_64_REGISTER_ST0 || index >= X86_64_FP_REGISTER_END
319 || !IsRegisterSet(index)) {
320 return 0.0;
323 return fFloatRegisters[index - X86_64_REGISTER_ST0];
327 void
328 CpuStateX8664::SetFloatRegister(int32 index, double value)
330 if (index < X86_64_REGISTER_ST0 || index >= X86_64_FP_REGISTER_END)
331 return;
333 fFloatRegisters[index - X86_64_REGISTER_ST0] = value;
334 fSetRegisters[index] = 1;
338 const void*
339 CpuStateX8664::MMXRegisterValue(int32 index) const
341 if (index < X86_64_REGISTER_MM0 || index >= X86_64_MMX_REGISTER_END
342 || !IsRegisterSet(index)) {
343 return 0;
346 return fMMXRegisters[index - X86_64_REGISTER_MM0].value;
350 void
351 CpuStateX8664::SetMMXRegister(int32 index, const uint8* value)
353 if (index < X86_64_REGISTER_MM0 || index >= X86_64_MMX_REGISTER_END)
354 return;
356 memcpy(fMMXRegisters[index - X86_64_REGISTER_MM0].value, value,
357 sizeof(uint64));
358 fSetRegisters[index] = 1;
362 const void*
363 CpuStateX8664::XMMRegisterValue(int32 index) const
365 if (index < X86_64_REGISTER_XMM0 || index >= X86_64_XMM_REGISTER_END
366 || !IsRegisterSet(index)) {
367 return NULL;
370 return fXMMRegisters[index - X86_64_REGISTER_XMM0].value;
374 void
375 CpuStateX8664::SetXMMRegister(int32 index, const uint8* value)
377 if (index < X86_64_REGISTER_XMM0 || index >= X86_64_XMM_REGISTER_END)
378 return;
380 memcpy(fXMMRegisters[index - X86_64_REGISTER_XMM0].value, value,
381 sizeof(x86_64_xmm_register));
382 fSetRegisters[index] = 1;
386 void
387 CpuStateX8664::UnsetRegister(int32 index)
389 if (index < 0 || index >= X86_64_REGISTER_COUNT)
390 return;
392 fSetRegisters[index] = 0;