xref: /haiku/src/kits/debugger/arch/x86/CpuStateX86.cpp (revision 385ee03ba83b7a40d315e17b03031b3ca37820c0)
1 /*
2  * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Copyright 2011-2014, Rene Gollent, rene@gollent.com.
4  * Distributed under the terms of the MIT License.
5  */
6 
7 #include "CpuStateX86.h"
8 
9 #include <new>
10 
11 #include <string.h>
12 
13 #include "Register.h"
14 
15 
16 CpuStateX86::CpuStateX86()
17 	:
18 	fSetRegisters(),
19 	fInterruptVector(0)
20 {
21 }
22 
23 
24 CpuStateX86::CpuStateX86(const x86_debug_cpu_state& state)
25 	:
26 	fSetRegisters(),
27 	fInterruptVector(0)
28 {
29 	SetIntRegister(X86_REGISTER_EIP, state.eip);
30 	SetIntRegister(X86_REGISTER_ESP, state.user_esp);
31 	SetIntRegister(X86_REGISTER_EBP, state.ebp);
32 	SetIntRegister(X86_REGISTER_EAX, state.eax);
33 	SetIntRegister(X86_REGISTER_EBX, state.ebx);
34 	SetIntRegister(X86_REGISTER_ECX, state.ecx);
35 	SetIntRegister(X86_REGISTER_EDX, state.edx);
36 	SetIntRegister(X86_REGISTER_ESI, state.esi);
37 	SetIntRegister(X86_REGISTER_EDI, state.edi);
38 	SetIntRegister(X86_REGISTER_CS, state.cs);
39 	SetIntRegister(X86_REGISTER_DS, state.ds);
40 	SetIntRegister(X86_REGISTER_ES, state.es);
41 	SetIntRegister(X86_REGISTER_FS, state.fs);
42 	SetIntRegister(X86_REGISTER_GS, state.gs);
43 	SetIntRegister(X86_REGISTER_SS, state.user_ss);
44 
45 	const x86_extended_registers& extended = state.extended_registers;
46 	SetFloatRegister(X86_REGISTER_ST0,
47 		(double)(*(long double*)(extended.fp_registers[0].value)));
48 	SetFloatRegister(X86_REGISTER_ST1,
49 		(double)(*(long double*)(extended.fp_registers[1].value)));
50 	SetFloatRegister(X86_REGISTER_ST2,
51 		(double)(*(long double*)(extended.fp_registers[2].value)));
52 	SetFloatRegister(X86_REGISTER_ST3,
53 		(double)(*(long double*)(extended.fp_registers[3].value)));
54 	SetFloatRegister(X86_REGISTER_ST4,
55 		(double)(*(long double*)(extended.fp_registers[4].value)));
56 	SetFloatRegister(X86_REGISTER_ST5,
57 		(double)(*(long double*)(extended.fp_registers[5].value)));
58 	SetFloatRegister(X86_REGISTER_ST6,
59 		(double)(*(long double*)(extended.fp_registers[6].value)));
60 	SetFloatRegister(X86_REGISTER_ST7,
61 		(double)(*(long double*)(extended.fp_registers[7].value)));
62 
63 	SetMMXRegister(X86_REGISTER_MM0, extended.mmx_registers[0].value);
64 	SetMMXRegister(X86_REGISTER_MM1, extended.mmx_registers[1].value);
65 	SetMMXRegister(X86_REGISTER_MM2, extended.mmx_registers[2].value);
66 	SetMMXRegister(X86_REGISTER_MM3, extended.mmx_registers[3].value);
67 	SetMMXRegister(X86_REGISTER_MM4, extended.mmx_registers[4].value);
68 	SetMMXRegister(X86_REGISTER_MM5, extended.mmx_registers[5].value);
69 	SetMMXRegister(X86_REGISTER_MM6, extended.mmx_registers[6].value);
70 	SetMMXRegister(X86_REGISTER_MM7, extended.mmx_registers[7].value);
71 
72 	SetXMMRegister(X86_REGISTER_XMM0, extended.xmm_registers[0].value);
73 	SetXMMRegister(X86_REGISTER_XMM1, extended.xmm_registers[1].value);
74 	SetXMMRegister(X86_REGISTER_XMM2, extended.xmm_registers[2].value);
75 	SetXMMRegister(X86_REGISTER_XMM3, extended.xmm_registers[3].value);
76 	SetXMMRegister(X86_REGISTER_XMM4, extended.xmm_registers[4].value);
77 	SetXMMRegister(X86_REGISTER_XMM5, extended.xmm_registers[5].value);
78 	SetXMMRegister(X86_REGISTER_XMM6, extended.xmm_registers[6].value);
79 	SetXMMRegister(X86_REGISTER_XMM7, extended.xmm_registers[7].value);
80 
81 	fInterruptVector = state.vector;
82 }
83 
84 
85 CpuStateX86::~CpuStateX86()
86 {
87 }
88 
89 
90 status_t
91 CpuStateX86::Clone(CpuState*& _clone) const
92 {
93 	CpuStateX86* newState = new(std::nothrow) CpuStateX86();
94 	if (newState == NULL)
95 		return B_NO_MEMORY;
96 
97 
98 	memcpy(newState->fIntRegisters, fIntRegisters, sizeof(fIntRegisters));
99 	memcpy(newState->fFloatRegisters, fFloatRegisters,
100 		sizeof(fFloatRegisters));
101 	memcpy(newState->fMMXRegisters, fMMXRegisters, sizeof(fMMXRegisters));
102 	memcpy(newState->fXMMRegisters, fXMMRegisters, sizeof(fXMMRegisters));
103 
104 	newState->fSetRegisters = fSetRegisters;
105 	newState->fInterruptVector = fInterruptVector;
106 
107 	_clone = newState;
108 
109 	return B_OK;
110 }
111 
112 
113 status_t
114 CpuStateX86::UpdateDebugState(void* state, size_t size) const
115 {
116 	if (size != sizeof(x86_debug_cpu_state))
117 		return B_BAD_VALUE;
118 
119 	x86_debug_cpu_state* x86State = (x86_debug_cpu_state*)state;
120 
121 	x86State->eip = InstructionPointer();
122 	x86State->user_esp = StackPointer();
123 	x86State->ebp = StackFramePointer();
124 	x86State->eax = IntRegisterValue(X86_REGISTER_EAX);
125 	x86State->ebx = IntRegisterValue(X86_REGISTER_EBX);
126 	x86State->ecx = IntRegisterValue(X86_REGISTER_ECX);
127 	x86State->edx = IntRegisterValue(X86_REGISTER_EDX);
128 	x86State->esi = IntRegisterValue(X86_REGISTER_ESI);
129 	x86State->edi = IntRegisterValue(X86_REGISTER_EDI);
130 	x86State->cs = IntRegisterValue(X86_REGISTER_CS);
131 	x86State->ds = IntRegisterValue(X86_REGISTER_DS);
132 	x86State->es = IntRegisterValue(X86_REGISTER_ES);
133 	x86State->fs = IntRegisterValue(X86_REGISTER_FS);
134 	x86State->gs = IntRegisterValue(X86_REGISTER_GS);
135 	x86State->user_ss = IntRegisterValue(X86_REGISTER_SS);
136 	x86State->vector = fInterruptVector;
137 
138 	for (int32 i = 0; i < 8; i++) {
139 		*(long double*)(x86State->extended_registers.fp_registers[i].value)
140 			= (long double)FloatRegisterValue(X86_REGISTER_ST0 + i);
141 
142 		if (IsRegisterSet(X86_REGISTER_MM0 + i)) {
143 			memcpy(&x86State->extended_registers.mmx_registers[i],
144 				&fMMXRegisters[i], sizeof(x86_fp_register));
145 		}
146 
147 		if (IsRegisterSet(X86_REGISTER_XMM0 + i)) {
148 			memcpy(&x86State->extended_registers.xmm_registers[i],
149 				&fXMMRegisters[i], sizeof(x86_xmm_register));
150 		} else {
151 			memset(&x86State->extended_registers.xmm_registers[i],
152 				0, sizeof(x86_xmm_register));
153 		}
154 	}
155 
156 	return B_OK;
157 }
158 
159 
160 target_addr_t
161 CpuStateX86::InstructionPointer() const
162 {
163 	return IsRegisterSet(X86_REGISTER_EIP)
164 		? IntRegisterValue(X86_REGISTER_EIP) : 0;
165 }
166 
167 
168 void
169 CpuStateX86::SetInstructionPointer(target_addr_t address)
170 {
171 	SetIntRegister(X86_REGISTER_EIP, (uint32)address);
172 }
173 
174 
175 target_addr_t
176 CpuStateX86::StackFramePointer() const
177 {
178 	return IsRegisterSet(X86_REGISTER_EBP)
179 		? IntRegisterValue(X86_REGISTER_EBP) : 0;
180 }
181 
182 
183 target_addr_t
184 CpuStateX86::StackPointer() const
185 {
186 	return IsRegisterSet(X86_REGISTER_ESP)
187 		? IntRegisterValue(X86_REGISTER_ESP) : 0;
188 }
189 
190 
191 bool
192 CpuStateX86::GetRegisterValue(const Register* reg, BVariant& _value) const
193 {
194 	int32 index = reg->Index();
195 	if (!IsRegisterSet(index))
196 		return false;
197 
198 	if (index >= X86_XMM_REGISTER_END)
199 		return false;
200 
201 	if (BVariant::TypeIsInteger(reg->ValueType())) {
202 		if (reg->BitSize() == 16)
203 			_value.SetTo((uint16)fIntRegisters[index]);
204 		else
205 			_value.SetTo(fIntRegisters[index]);
206 	} else if (BVariant::TypeIsFloat(reg->ValueType())) {
207 		index -= X86_REGISTER_ST0;
208 		if (reg->ValueType() == B_FLOAT_TYPE)
209 			_value.SetTo((float)fFloatRegisters[index]);
210 		else
211 			_value.SetTo(fFloatRegisters[index]);
212 	} else {
213 		if (index >= X86_REGISTER_MM0 && index < X86_REGISTER_XMM0) {
214 			index -= X86_REGISTER_MM0;
215 			_value.SetTo(fMMXRegisters[index].value);
216 		} else {
217 			index -= X86_REGISTER_XMM0;
218 			_value.SetTo(fXMMRegisters[index].value);
219 		}
220 	}
221 
222 	return true;
223 }
224 
225 
226 bool
227 CpuStateX86::SetRegisterValue(const Register* reg, const BVariant& value)
228 {
229 	int32 index = reg->Index();
230 	if (index >= X86_XMM_REGISTER_END)
231 		return false;
232 
233 	if (index < X86_INT_REGISTER_END)
234 		fIntRegisters[index] = value.ToUInt32();
235 	else if (index >= X86_REGISTER_ST0 && index < X86_FP_REGISTER_END)
236 		fFloatRegisters[index - X86_REGISTER_ST0] = value.ToDouble();
237 	else if (index >= X86_REGISTER_MM0 && index < X86_MMX_REGISTER_END) {
238 		if (value.Size() > sizeof(int64))
239 			return false;
240 		memset(&fMMXRegisters[index - X86_REGISTER_MM0], 0,
241 			sizeof(x86_fp_register));
242 		memcpy(fMMXRegisters[index - X86_REGISTER_MM0].value,
243 			value.ToPointer(), value.Size());
244 	} else if (index >= X86_REGISTER_XMM0 && index < X86_XMM_REGISTER_END) {
245 		if (value.Size() > sizeof(x86_xmm_register))
246 			return false;
247 
248 		memset(&fXMMRegisters[index - X86_REGISTER_XMM0], 0,
249 			sizeof(x86_xmm_register));
250 		memcpy(fXMMRegisters[index - X86_REGISTER_XMM0].value,
251 			value.ToPointer(), value.Size());
252 	} else
253 		return false;
254 
255 	fSetRegisters[index] = 1;
256 	return true;
257 }
258 
259 
260 bool
261 CpuStateX86::IsRegisterSet(int32 index) const
262 {
263 	return index >= 0 && index < X86_REGISTER_COUNT && fSetRegisters[index];
264 }
265 
266 
267 uint32
268 CpuStateX86::IntRegisterValue(int32 index) const
269 {
270 	if (!IsRegisterSet(index) || index >= X86_INT_REGISTER_END)
271 		return 0;
272 
273 	return fIntRegisters[index];
274 }
275 
276 
277 void
278 CpuStateX86::SetIntRegister(int32 index, uint32 value)
279 {
280 	if (index < 0 || index >= X86_INT_REGISTER_END)
281 		return;
282 
283 	fIntRegisters[index] = value;
284 	fSetRegisters[index] = 1;
285 }
286 
287 
288 double
289 CpuStateX86::FloatRegisterValue(int32 index) const
290 {
291 	if (index < X86_REGISTER_ST0 || index >= X86_FP_REGISTER_END
292 		|| !IsRegisterSet(index)) {
293 		return 0.0;
294 	}
295 
296 	return fFloatRegisters[index - X86_REGISTER_ST0];
297 }
298 
299 
300 void
301 CpuStateX86::SetFloatRegister(int32 index, double value)
302 {
303 	if (index < X86_REGISTER_ST0 || index >= X86_FP_REGISTER_END)
304 		return;
305 
306 	fFloatRegisters[index - X86_REGISTER_ST0] = value;
307 	fSetRegisters[index] = 1;
308 }
309 
310 
311 const void*
312 CpuStateX86::MMXRegisterValue(int32 index) const
313 {
314 	if (index < X86_REGISTER_MM0 || index >= X86_MMX_REGISTER_END
315 		|| !IsRegisterSet(index)) {
316 		return 0;
317 	}
318 
319 	return fMMXRegisters[index - X86_REGISTER_MM0].value;
320 }
321 
322 
323 void
324 CpuStateX86::SetMMXRegister(int32 index, const uint8* value)
325 {
326 	if (index < X86_REGISTER_MM0 || index >= X86_MMX_REGISTER_END)
327 		return;
328 
329 	memcpy(fMMXRegisters[index - X86_REGISTER_MM0].value, value,
330 		sizeof(uint64));
331 	fSetRegisters[index] = 1;
332 }
333 
334 
335 const void*
336 CpuStateX86::XMMRegisterValue(int32 index) const
337 {
338 	if (index < X86_REGISTER_XMM0 || index >= X86_XMM_REGISTER_END
339 		|| !IsRegisterSet(index)) {
340 		return NULL;
341 	}
342 
343 	return fXMMRegisters[index - X86_REGISTER_XMM0].value;
344 }
345 
346 
347 void
348 CpuStateX86::SetXMMRegister(int32 index, const uint8* value)
349 {
350 	if (index < X86_REGISTER_XMM0 || index >= X86_XMM_REGISTER_END)
351 		return;
352 
353 	memcpy(fXMMRegisters[index - X86_REGISTER_XMM0].value, value,
354 		sizeof(x86_xmm_register));
355 	fSetRegisters[index] = 1;
356 }
357 
358 
359 void
360 CpuStateX86::UnsetRegister(int32 index)
361 {
362 	if (index < 0 || index >= X86_REGISTER_COUNT)
363 		return;
364 
365 	fSetRegisters[index] = 0;
366 }
367