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 struct savefpu& extended = state.extended_registers; 54 55 SetFloatRegister(X86_64_REGISTER_ST0, 56 (double)(*(long double*)(extended.fp_fxsave.fp[0].value))); 57 SetFloatRegister(X86_64_REGISTER_ST1, 58 (double)(*(long double*)(extended.fp_fxsave.fp[1].value))); 59 SetFloatRegister(X86_64_REGISTER_ST2, 60 (double)(*(long double*)(extended.fp_fxsave.fp[2].value))); 61 SetFloatRegister(X86_64_REGISTER_ST3, 62 (double)(*(long double*)(extended.fp_fxsave.fp[3].value))); 63 SetFloatRegister(X86_64_REGISTER_ST4, 64 (double)(*(long double*)(extended.fp_fxsave.fp[4].value))); 65 SetFloatRegister(X86_64_REGISTER_ST5, 66 (double)(*(long double*)(extended.fp_fxsave.fp[5].value))); 67 SetFloatRegister(X86_64_REGISTER_ST6, 68 (double)(*(long double*)(extended.fp_fxsave.fp[6].value))); 69 SetFloatRegister(X86_64_REGISTER_ST7, 70 (double)(*(long double*)(extended.fp_fxsave.fp[7].value))); 71 72 SetMMXRegister(X86_64_REGISTER_MM0, extended.fp_fxsave.mmx[0].value); 73 SetMMXRegister(X86_64_REGISTER_MM1, extended.fp_fxsave.mmx[1].value); 74 SetMMXRegister(X86_64_REGISTER_MM2, extended.fp_fxsave.mmx[2].value); 75 SetMMXRegister(X86_64_REGISTER_MM3, extended.fp_fxsave.mmx[3].value); 76 SetMMXRegister(X86_64_REGISTER_MM4, extended.fp_fxsave.mmx[4].value); 77 SetMMXRegister(X86_64_REGISTER_MM5, extended.fp_fxsave.mmx[5].value); 78 SetMMXRegister(X86_64_REGISTER_MM6, extended.fp_fxsave.mmx[6].value); 79 SetMMXRegister(X86_64_REGISTER_MM7, extended.fp_fxsave.mmx[7].value); 80 81 // The YMM register value is split in two halves in the saved CPU context, 82 // so we have to reassemble it here. 83 // TODO check extended.xstate_hdr to see if the YMM values are present at 84 // all. 85 SetXMMRegister(X86_64_REGISTER_XMM0, extended.fp_ymm[0].value, 86 extended.fp_fxsave.xmm[0].value); 87 SetXMMRegister(X86_64_REGISTER_XMM1, extended.fp_ymm[1].value, 88 extended.fp_fxsave.xmm[1].value); 89 SetXMMRegister(X86_64_REGISTER_XMM2, extended.fp_ymm[2].value, 90 extended.fp_fxsave.xmm[2].value); 91 SetXMMRegister(X86_64_REGISTER_XMM3, extended.fp_ymm[3].value, 92 extended.fp_fxsave.xmm[3].value); 93 SetXMMRegister(X86_64_REGISTER_XMM4, extended.fp_ymm[4].value, 94 extended.fp_fxsave.xmm[4].value); 95 SetXMMRegister(X86_64_REGISTER_XMM5, extended.fp_ymm[5].value, 96 extended.fp_fxsave.xmm[5].value); 97 SetXMMRegister(X86_64_REGISTER_XMM6, extended.fp_ymm[6].value, 98 extended.fp_fxsave.xmm[6].value); 99 SetXMMRegister(X86_64_REGISTER_XMM7, extended.fp_ymm[7].value, 100 extended.fp_fxsave.xmm[7].value); 101 SetXMMRegister(X86_64_REGISTER_XMM8, extended.fp_ymm[8].value, 102 extended.fp_fxsave.xmm[8].value); 103 SetXMMRegister(X86_64_REGISTER_XMM9, extended.fp_ymm[9].value, 104 extended.fp_fxsave.xmm[9].value); 105 SetXMMRegister(X86_64_REGISTER_XMM10, extended.fp_ymm[10].value, 106 extended.fp_fxsave.xmm[10].value); 107 SetXMMRegister(X86_64_REGISTER_XMM11, extended.fp_ymm[11].value, 108 extended.fp_fxsave.xmm[11].value); 109 SetXMMRegister(X86_64_REGISTER_XMM12, extended.fp_ymm[12].value, 110 extended.fp_fxsave.xmm[12].value); 111 SetXMMRegister(X86_64_REGISTER_XMM13, extended.fp_ymm[13].value, 112 extended.fp_fxsave.xmm[13].value); 113 SetXMMRegister(X86_64_REGISTER_XMM14, extended.fp_ymm[14].value, 114 extended.fp_fxsave.xmm[14].value); 115 SetXMMRegister(X86_64_REGISTER_XMM15, extended.fp_ymm[15].value, 116 extended.fp_fxsave.xmm[15].value); 117 118 fInterruptVector = state.vector; 119 } 120 121 122 CpuStateX8664::~CpuStateX8664() 123 { 124 } 125 126 127 status_t 128 CpuStateX8664::Clone(CpuState*& _clone) const 129 { 130 CpuStateX8664* newState = new(std::nothrow) CpuStateX8664(); 131 if (newState == NULL) 132 return B_NO_MEMORY; 133 134 135 memcpy(newState->fIntRegisters, fIntRegisters, sizeof(fIntRegisters)); 136 memcpy(newState->fFloatRegisters, fFloatRegisters, 137 sizeof(fFloatRegisters)); 138 memcpy(newState->fMMXRegisters, fMMXRegisters, sizeof(fMMXRegisters)); 139 memcpy(newState->fXMMRegisters, fXMMRegisters, sizeof(fXMMRegisters)); 140 141 newState->fSetRegisters = fSetRegisters; 142 newState->fInterruptVector = fInterruptVector; 143 144 _clone = newState; 145 146 return B_OK; 147 } 148 149 150 status_t 151 CpuStateX8664::UpdateDebugState(void* state, size_t size) const 152 { 153 if (size != sizeof(x86_64_debug_cpu_state)) 154 return B_BAD_VALUE; 155 156 x86_64_debug_cpu_state* x64State = (x86_64_debug_cpu_state*)state; 157 158 x64State->rip = InstructionPointer(); 159 x64State->rsp = StackPointer(); 160 x64State->rbp = StackFramePointer(); 161 x64State->rax = IntRegisterValue(X86_64_REGISTER_RAX); 162 x64State->rbx = IntRegisterValue(X86_64_REGISTER_RBX); 163 x64State->rcx = IntRegisterValue(X86_64_REGISTER_RCX); 164 x64State->rdx = IntRegisterValue(X86_64_REGISTER_RDX); 165 x64State->rsi = IntRegisterValue(X86_64_REGISTER_RSI); 166 x64State->rdi = IntRegisterValue(X86_64_REGISTER_RDI); 167 x64State->r8 = IntRegisterValue(X86_64_REGISTER_R8); 168 x64State->r9 = IntRegisterValue(X86_64_REGISTER_R9); 169 x64State->r10 = IntRegisterValue(X86_64_REGISTER_R10); 170 x64State->r11 = IntRegisterValue(X86_64_REGISTER_R11); 171 x64State->r12 = IntRegisterValue(X86_64_REGISTER_R12); 172 x64State->r13 = IntRegisterValue(X86_64_REGISTER_R13); 173 x64State->r14 = IntRegisterValue(X86_64_REGISTER_R14); 174 x64State->r15 = IntRegisterValue(X86_64_REGISTER_R15); 175 x64State->cs = IntRegisterValue(X86_64_REGISTER_CS); 176 x64State->ds = IntRegisterValue(X86_64_REGISTER_DS); 177 x64State->es = IntRegisterValue(X86_64_REGISTER_ES); 178 x64State->fs = IntRegisterValue(X86_64_REGISTER_FS); 179 x64State->gs = IntRegisterValue(X86_64_REGISTER_GS); 180 x64State->ss = IntRegisterValue(X86_64_REGISTER_SS); 181 182 for (int32 i = 0; i < 8; i++) { 183 *(long double*)(x64State->extended_registers.fp_fxsave.fp[i].value) 184 = (long double)FloatRegisterValue(X86_64_REGISTER_ST0 + i); 185 186 if (IsRegisterSet(X86_64_REGISTER_MM0 + i)) { 187 memcpy(&x64State->extended_registers.fp_fxsave.mmx[i], 188 &fMMXRegisters[i], sizeof(x86_64_fp_register)); 189 } 190 } 191 192 for (int32 i = 0; i < 16; i++) { 193 if (IsRegisterSet(X86_64_REGISTER_XMM0 + i)) { 194 memcpy(&x64State->extended_registers.fp_fxsave.xmm[i], 195 &fXMMRegisters[i], sizeof(x86_64_xmm_register)); 196 } else { 197 memset(&x64State->extended_registers.fp_fxsave.xmm[i], 198 0, sizeof(x86_64_xmm_register)); 199 } 200 } 201 202 return B_OK; 203 } 204 205 206 target_addr_t 207 CpuStateX8664::InstructionPointer() const 208 { 209 return IsRegisterSet(X86_64_REGISTER_RIP) 210 ? IntRegisterValue(X86_64_REGISTER_RIP) : 0; 211 } 212 213 214 void 215 CpuStateX8664::SetInstructionPointer(target_addr_t address) 216 { 217 SetIntRegister(X86_64_REGISTER_RIP, address); 218 } 219 220 221 target_addr_t 222 CpuStateX8664::StackFramePointer() const 223 { 224 return IsRegisterSet(X86_64_REGISTER_RBP) 225 ? IntRegisterValue(X86_64_REGISTER_RBP) : 0; 226 } 227 228 229 target_addr_t 230 CpuStateX8664::StackPointer() const 231 { 232 return IsRegisterSet(X86_64_REGISTER_RSP) 233 ? IntRegisterValue(X86_64_REGISTER_RSP) : 0; 234 } 235 236 237 bool 238 CpuStateX8664::GetRegisterValue(const Register* reg, BVariant& _value) const 239 { 240 int32 index = reg->Index(); 241 if (!IsRegisterSet(index)) 242 return false; 243 244 if (index >= X86_64_XMM_REGISTER_END) 245 return false; 246 247 if (BVariant::TypeIsInteger(reg->ValueType())) { 248 if (reg->BitSize() == 16) 249 _value.SetTo((uint16)fIntRegisters[index]); 250 else 251 _value.SetTo(fIntRegisters[index]); 252 } else if (BVariant::TypeIsFloat(reg->ValueType())) { 253 index -= X86_64_REGISTER_ST0; 254 if (reg->ValueType() == B_FLOAT_TYPE) 255 _value.SetTo((float)fFloatRegisters[index]); 256 else 257 _value.SetTo(fFloatRegisters[index]); 258 } else { 259 if (index >= X86_64_REGISTER_MM0 && index < X86_64_REGISTER_XMM0) { 260 index -= X86_64_REGISTER_MM0; 261 _value.SetTo(fMMXRegisters[index].value); 262 } else { 263 index -= X86_64_REGISTER_XMM0; 264 _value.SetTo(fXMMRegisters[index].value); 265 } 266 } 267 268 return true; 269 } 270 271 272 bool 273 CpuStateX8664::SetRegisterValue(const Register* reg, const BVariant& value) 274 { 275 int32 index = reg->Index(); 276 if (index >= X86_64_XMM_REGISTER_END) 277 return false; 278 279 if (index < X86_64_INT_REGISTER_END) 280 fIntRegisters[index] = value.ToUInt64(); 281 else if (index >= X86_64_REGISTER_ST0 && index < X86_64_FP_REGISTER_END) 282 fFloatRegisters[index - X86_64_REGISTER_ST0] = value.ToDouble(); 283 else if (index >= X86_64_REGISTER_MM0 && index < X86_64_MMX_REGISTER_END) { 284 if (value.Size() > sizeof(int64)) 285 return false; 286 memset(&fMMXRegisters[index - X86_64_REGISTER_MM0], 0, 287 sizeof(x86_64_fp_register)); 288 memcpy(fMMXRegisters[index - X86_64_REGISTER_MM0].value, 289 value.ToPointer(), value.Size()); 290 } else if (index >= X86_64_REGISTER_XMM0 291 && index < X86_64_XMM_REGISTER_END) { 292 if (value.Size() > sizeof(x86_64_xmm_register)) 293 return false; 294 295 memset(&fXMMRegisters[index - X86_64_REGISTER_XMM0], 0, 296 sizeof(x86_64_xmm_register)); 297 memcpy(fXMMRegisters[index - X86_64_REGISTER_XMM0].value, 298 value.ToPointer(), value.Size()); 299 } else 300 return false; 301 302 fSetRegisters[index] = 1; 303 return true; 304 } 305 306 307 bool 308 CpuStateX8664::IsRegisterSet(int32 index) const 309 { 310 return index >= 0 && index < X86_64_REGISTER_COUNT && fSetRegisters[index]; 311 } 312 313 314 uint64 315 CpuStateX8664::IntRegisterValue(int32 index) const 316 { 317 if (!IsRegisterSet(index) || index >= X86_64_INT_REGISTER_END) 318 return 0; 319 320 return fIntRegisters[index]; 321 } 322 323 324 void 325 CpuStateX8664::SetIntRegister(int32 index, uint64 value) 326 { 327 if (index < 0 || index >= X86_64_INT_REGISTER_END) 328 return; 329 330 fIntRegisters[index] = value; 331 fSetRegisters[index] = 1; 332 } 333 334 335 double 336 CpuStateX8664::FloatRegisterValue(int32 index) const 337 { 338 if (index < X86_64_REGISTER_ST0 || index >= X86_64_FP_REGISTER_END 339 || !IsRegisterSet(index)) { 340 return 0.0; 341 } 342 343 return fFloatRegisters[index - X86_64_REGISTER_ST0]; 344 } 345 346 347 void 348 CpuStateX8664::SetFloatRegister(int32 index, double value) 349 { 350 if (index < X86_64_REGISTER_ST0 || index >= X86_64_FP_REGISTER_END) 351 return; 352 353 fFloatRegisters[index - X86_64_REGISTER_ST0] = value; 354 fSetRegisters[index] = 1; 355 } 356 357 358 const void* 359 CpuStateX8664::MMXRegisterValue(int32 index) const 360 { 361 if (index < X86_64_REGISTER_MM0 || index >= X86_64_MMX_REGISTER_END 362 || !IsRegisterSet(index)) { 363 return 0; 364 } 365 366 return fMMXRegisters[index - X86_64_REGISTER_MM0].value; 367 } 368 369 370 void 371 CpuStateX8664::SetMMXRegister(int32 index, const uint8* value) 372 { 373 if (index < X86_64_REGISTER_MM0 || index >= X86_64_MMX_REGISTER_END) 374 return; 375 376 memcpy(fMMXRegisters[index - X86_64_REGISTER_MM0].value, value, 377 sizeof(uint64)); 378 fSetRegisters[index] = 1; 379 } 380 381 382 const void* 383 CpuStateX8664::XMMRegisterValue(int32 index) const 384 { 385 if (index < X86_64_REGISTER_XMM0 || index >= X86_64_XMM_REGISTER_END 386 || !IsRegisterSet(index)) { 387 return NULL; 388 } 389 390 return fXMMRegisters[index - X86_64_REGISTER_XMM0].value; 391 } 392 393 394 void 395 CpuStateX8664::SetXMMRegister(int32 index, const uint8* highValue, const uint8* lowValue) 396 { 397 if (index < X86_64_REGISTER_XMM0 || index >= X86_64_XMM_REGISTER_END) 398 return; 399 400 memcpy(&fXMMRegisters[index - X86_64_REGISTER_XMM0].value[0], lowValue, 401 sizeof(x86_64_xmm_register)); 402 memcpy(&fXMMRegisters[index - X86_64_REGISTER_XMM0].value[2], highValue, 403 sizeof(x86_64_xmm_register)); 404 fSetRegisters[index] = 1; 405 } 406 407 408 void 409 CpuStateX8664::UnsetRegister(int32 index) 410 { 411 if (index < 0 || index >= X86_64_REGISTER_COUNT) 412 return; 413 414 fSetRegisters[index] = 0; 415 } 416