xref: /haiku/src/kits/debugger/arch/x86_64/CpuStateX8664.cpp (revision 5e7964b0a929555415798dea3373db9ac4611caa)
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  */
7 
8 #include "CpuStateX8664.h"
9 
10 #include <new>
11 
12 #include <string.h>
13 
14 #include "Register.h"
15 
16 
17 CpuStateX8664::CpuStateX8664()
18 	:
19 	fSetRegisters()
20 {
21 }
22 
23 
24 CpuStateX8664::CpuStateX8664(const x86_64_debug_cpu_state& state)
25 	:
26 	fSetRegisters(),
27 	fInterruptVector(0)
28 {
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);
52 
53 	const x86_64_extended_registers& extended = state.extended_registers;
54 
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)));
71 
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);
80 
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);
97 
98 	fInterruptVector = state.vector;
99 }
100 
101 
102 CpuStateX8664::~CpuStateX8664()
103 {
104 }
105 
106 
107 status_t
108 CpuStateX8664::Clone(CpuState*& _clone) const
109 {
110 	CpuStateX8664* newState = new(std::nothrow) CpuStateX8664();
111 	if (newState == NULL)
112 		return B_NO_MEMORY;
113 
114 
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));
120 
121 	newState->fSetRegisters = fSetRegisters;
122 	newState->fInterruptVector = fInterruptVector;
123 
124 	_clone = newState;
125 
126 	return B_OK;
127 }
128 
129 
130 status_t
131 CpuStateX8664::UpdateDebugState(void* state, size_t size) const
132 {
133 	if (size != sizeof(x86_64_debug_cpu_state))
134 		return B_BAD_VALUE;
135 
136 	x86_64_debug_cpu_state* x64State = (x86_64_debug_cpu_state*)state;
137 
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);
161 
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);
165 
166 		if (IsRegisterSet(X86_64_REGISTER_MM0 + i)) {
167 			memcpy(&x64State->extended_registers.mmx_registers[i],
168 				&fMMXRegisters[i], sizeof(x86_64_fp_register));
169 		}
170 	}
171 
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));
179 		}
180 	}
181 
182 	return B_OK;
183 }
184 
185 
186 target_addr_t
187 CpuStateX8664::InstructionPointer() const
188 {
189 	return IsRegisterSet(X86_64_REGISTER_RIP)
190 		? IntRegisterValue(X86_64_REGISTER_RIP) : 0;
191 }
192 
193 
194 void
195 CpuStateX8664::SetInstructionPointer(target_addr_t address)
196 {
197 	SetIntRegister(X86_64_REGISTER_RIP, address);
198 }
199 
200 
201 target_addr_t
202 CpuStateX8664::StackFramePointer() const
203 {
204 	return IsRegisterSet(X86_64_REGISTER_RBP)
205 		? IntRegisterValue(X86_64_REGISTER_RBP) : 0;
206 }
207 
208 
209 target_addr_t
210 CpuStateX8664::StackPointer() const
211 {
212 	return IsRegisterSet(X86_64_REGISTER_RSP)
213 		? IntRegisterValue(X86_64_REGISTER_RSP) : 0;
214 }
215 
216 
217 bool
218 CpuStateX8664::GetRegisterValue(const Register* reg, BVariant& _value) const
219 {
220 	int32 index = reg->Index();
221 	if (!IsRegisterSet(index))
222 		return false;
223 
224 	if (index >= X86_64_XMM_REGISTER_END)
225 		return false;
226 
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);
245 		}
246 	}
247 
248 	return true;
249 }
250 
251 
252 bool
253 CpuStateX8664::SetRegisterValue(const Register* reg, const BVariant& value)
254 {
255 	int32 index = reg->Index();
256 	if (index >= X86_64_XMM_REGISTER_END)
257 		return false;
258 
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;
274 
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;
281 
282 	fSetRegisters[index] = 1;
283 	return true;
284 }
285 
286 
287 bool
288 CpuStateX8664::IsRegisterSet(int32 index) const
289 {
290 	return index >= 0 && index < X86_64_REGISTER_COUNT && fSetRegisters[index];
291 }
292 
293 
294 uint64
295 CpuStateX8664::IntRegisterValue(int32 index) const
296 {
297 	if (!IsRegisterSet(index) || index >= X86_64_INT_REGISTER_END)
298 		return 0;
299 
300 	return fIntRegisters[index];
301 }
302 
303 
304 void
305 CpuStateX8664::SetIntRegister(int32 index, uint64 value)
306 {
307 	if (index < 0 || index >= X86_64_INT_REGISTER_END)
308 		return;
309 
310 	fIntRegisters[index] = value;
311 	fSetRegisters[index] = 1;
312 }
313 
314 
315 double
316 CpuStateX8664::FloatRegisterValue(int32 index) const
317 {
318 	if (index < X86_64_REGISTER_ST0 || index >= X86_64_FP_REGISTER_END
319 		|| !IsRegisterSet(index)) {
320 		return 0.0;
321 	}
322 
323 	return fFloatRegisters[index - X86_64_REGISTER_ST0];
324 }
325 
326 
327 void
328 CpuStateX8664::SetFloatRegister(int32 index, double value)
329 {
330 	if (index < X86_64_REGISTER_ST0 || index >= X86_64_FP_REGISTER_END)
331 		return;
332 
333 	fFloatRegisters[index - X86_64_REGISTER_ST0] = value;
334 	fSetRegisters[index] = 1;
335 }
336 
337 
338 const void*
339 CpuStateX8664::MMXRegisterValue(int32 index) const
340 {
341 	if (index < X86_64_REGISTER_MM0 || index >= X86_64_MMX_REGISTER_END
342 		|| !IsRegisterSet(index)) {
343 		return 0;
344 	}
345 
346 	return fMMXRegisters[index - X86_64_REGISTER_MM0].value;
347 }
348 
349 
350 void
351 CpuStateX8664::SetMMXRegister(int32 index, const uint8* value)
352 {
353 	if (index < X86_64_REGISTER_MM0 || index >= X86_64_MMX_REGISTER_END)
354 		return;
355 
356 	memcpy(fMMXRegisters[index - X86_64_REGISTER_MM0].value, value,
357 		sizeof(uint64));
358 	fSetRegisters[index] = 1;
359 }
360 
361 
362 const void*
363 CpuStateX8664::XMMRegisterValue(int32 index) const
364 {
365 	if (index < X86_64_REGISTER_XMM0 || index >= X86_64_XMM_REGISTER_END
366 		|| !IsRegisterSet(index)) {
367 		return NULL;
368 	}
369 
370 	return fXMMRegisters[index - X86_64_REGISTER_XMM0].value;
371 }
372 
373 
374 void
375 CpuStateX8664::SetXMMRegister(int32 index, const uint8* value)
376 {
377 	if (index < X86_64_REGISTER_XMM0 || index >= X86_64_XMM_REGISTER_END)
378 		return;
379 
380 	memcpy(fXMMRegisters[index - X86_64_REGISTER_XMM0].value, value,
381 		sizeof(x86_64_xmm_register));
382 	fSetRegisters[index] = 1;
383 }
384 
385 
386 void
387 CpuStateX8664::UnsetRegister(int32 index)
388 {
389 	if (index < 0 || index >= X86_64_REGISTER_COUNT)
390 		return;
391 
392 	fSetRegisters[index] = 0;
393 }
394