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