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