1 //===-- RegisterContextDarwin_i386.cpp --------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 11 // C Includes 12 #include <stddef.h> // offsetof 13 14 // C++ Includes 15 // Other libraries and framework includes 16 #include "lldb/Core/DataBufferHeap.h" 17 #include "lldb/Core/DataExtractor.h" 18 #include "lldb/Core/Log.h" 19 #include "lldb/Core/RegisterValue.h" 20 #include "lldb/Core/Scalar.h" 21 #include "lldb/Host/Endian.h" 22 #include "llvm/ADT/STLExtras.h" 23 #include "llvm/Support/Compiler.h" 24 25 // Support building against older versions of LLVM, this macro was added 26 // recently. 27 #ifndef LLVM_EXTENSION 28 #define LLVM_EXTENSION 29 #endif 30 31 // Project includes 32 #include "RegisterContextDarwin_i386.h" 33 34 using namespace lldb; 35 using namespace lldb_private; 36 37 enum 38 { 39 gpr_eax = 0, 40 gpr_ebx, 41 gpr_ecx, 42 gpr_edx, 43 gpr_edi, 44 gpr_esi, 45 gpr_ebp, 46 gpr_esp, 47 gpr_ss, 48 gpr_eflags, 49 gpr_eip, 50 gpr_cs, 51 gpr_ds, 52 gpr_es, 53 gpr_fs, 54 gpr_gs, 55 56 fpu_fcw, 57 fpu_fsw, 58 fpu_ftw, 59 fpu_fop, 60 fpu_ip, 61 fpu_cs, 62 fpu_dp, 63 fpu_ds, 64 fpu_mxcsr, 65 fpu_mxcsrmask, 66 fpu_stmm0, 67 fpu_stmm1, 68 fpu_stmm2, 69 fpu_stmm3, 70 fpu_stmm4, 71 fpu_stmm5, 72 fpu_stmm6, 73 fpu_stmm7, 74 fpu_xmm0, 75 fpu_xmm1, 76 fpu_xmm2, 77 fpu_xmm3, 78 fpu_xmm4, 79 fpu_xmm5, 80 fpu_xmm6, 81 fpu_xmm7, 82 83 exc_trapno, 84 exc_err, 85 exc_faultvaddr, 86 87 k_num_registers, 88 89 // Aliases 90 fpu_fctrl = fpu_fcw, 91 fpu_fstat = fpu_fsw, 92 fpu_ftag = fpu_ftw, 93 fpu_fiseg = fpu_cs, 94 fpu_fioff = fpu_ip, 95 fpu_foseg = fpu_ds, 96 fpu_fooff = fpu_dp 97 }; 98 99 enum 100 { 101 ehframe_eax = 0, 102 ehframe_ecx, 103 ehframe_edx, 104 ehframe_ebx, 105 ehframe_ebp, 106 ehframe_esp, 107 ehframe_esi, 108 ehframe_edi, 109 ehframe_eip, 110 ehframe_eflags 111 }; 112 113 enum 114 { 115 dwarf_eax = 0, 116 dwarf_ecx, 117 dwarf_edx, 118 dwarf_ebx, 119 dwarf_esp, 120 dwarf_ebp, 121 dwarf_esi, 122 dwarf_edi, 123 dwarf_eip, 124 dwarf_eflags, 125 dwarf_stmm0 = 11, 126 dwarf_stmm1, 127 dwarf_stmm2, 128 dwarf_stmm3, 129 dwarf_stmm4, 130 dwarf_stmm5, 131 dwarf_stmm6, 132 dwarf_stmm7, 133 dwarf_xmm0 = 21, 134 dwarf_xmm1, 135 dwarf_xmm2, 136 dwarf_xmm3, 137 dwarf_xmm4, 138 dwarf_xmm5, 139 dwarf_xmm6, 140 dwarf_xmm7 141 }; 142 143 144 #define GPR_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_i386::GPR, reg)) 145 #define FPU_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_i386::FPU, reg) + sizeof (RegisterContextDarwin_i386::GPR)) 146 #define EXC_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_i386::EXC, reg) + sizeof (RegisterContextDarwin_i386::GPR) + sizeof (RegisterContextDarwin_i386::FPU)) 147 148 // These macros will auto define the register name, alt name, register size, 149 // register offset, encoding, format and native register. This ensures that 150 // the register state structures are defined correctly and have the correct 151 // sizes and offsets. 152 #define DEFINE_GPR(reg, alt) #reg, alt, sizeof(((RegisterContextDarwin_i386::GPR *)NULL)->reg), GPR_OFFSET(reg), eEncodingUint, eFormatHex 153 #define DEFINE_FPU_UINT(reg) #reg, NULL, sizeof(((RegisterContextDarwin_i386::FPU *)NULL)->reg), FPU_OFFSET(reg), eEncodingUint, eFormatHex 154 #define DEFINE_FPU_VECT(reg, i) #reg#i, NULL, sizeof(((RegisterContextDarwin_i386::FPU *)NULL)->reg[i].bytes), FPU_OFFSET(reg[i]), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_##reg##i, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_##reg##i }, NULL, NULL 155 156 #define DEFINE_EXC(reg) #reg, NULL, sizeof(((RegisterContextDarwin_i386::EXC *)NULL)->reg), EXC_OFFSET(reg), eEncodingUint, eFormatHex 157 #define REG_CONTEXT_SIZE (sizeof (RegisterContextDarwin_i386::GPR) + sizeof (RegisterContextDarwin_i386::FPU) + sizeof (RegisterContextDarwin_i386::EXC)) 158 159 static RegisterInfo g_register_infos[] = 160 { 161 // Macro auto defines most stuff eh_frame DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVALIDATE REGS 162 // =============================== ======================= =================== ========================= ================== ================= ========== =============== 163 { DEFINE_GPR(eax , NULL) , { ehframe_eax , dwarf_eax , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_eax }, NULL, NULL}, 164 { DEFINE_GPR(ebx , NULL) , { ehframe_ebx , dwarf_ebx , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_ebx }, NULL, NULL}, 165 { DEFINE_GPR(ecx , NULL) , { ehframe_ecx , dwarf_ecx , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_ecx }, NULL, NULL}, 166 { DEFINE_GPR(edx , NULL) , { ehframe_edx , dwarf_edx , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_edx }, NULL, NULL}, 167 { DEFINE_GPR(edi , NULL) , { ehframe_edi , dwarf_edi , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_edi }, NULL, NULL}, 168 { DEFINE_GPR(esi , NULL) , { ehframe_esi , dwarf_esi , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_esi }, NULL, NULL}, 169 { DEFINE_GPR(ebp , "fp") , { ehframe_ebp , dwarf_ebp , LLDB_REGNUM_GENERIC_FP , LLDB_INVALID_REGNUM, gpr_ebp }, NULL, NULL}, 170 { DEFINE_GPR(esp , "sp") , { ehframe_esp , dwarf_esp , LLDB_REGNUM_GENERIC_SP , LLDB_INVALID_REGNUM, gpr_esp }, NULL, NULL}, 171 { DEFINE_GPR(ss , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_ss }, NULL, NULL}, 172 { DEFINE_GPR(eflags , "flags") , { ehframe_eflags , dwarf_eflags , LLDB_REGNUM_GENERIC_FLAGS , LLDB_INVALID_REGNUM, gpr_eflags }, NULL, NULL}, 173 { DEFINE_GPR(eip , "pc") , { ehframe_eip , dwarf_eip , LLDB_REGNUM_GENERIC_PC , LLDB_INVALID_REGNUM, gpr_eip }, NULL, NULL}, 174 { DEFINE_GPR(cs , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_cs }, NULL, NULL}, 175 { DEFINE_GPR(ds , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_ds }, NULL, NULL}, 176 { DEFINE_GPR(es , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_es }, NULL, NULL}, 177 { DEFINE_GPR(fs , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_fs }, NULL, NULL}, 178 { DEFINE_GPR(gs , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, gpr_gs }, NULL, NULL}, 179 180 { DEFINE_FPU_UINT(fcw) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_fcw }, NULL, NULL}, 181 { DEFINE_FPU_UINT(fsw) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_fsw }, NULL, NULL}, 182 { DEFINE_FPU_UINT(ftw) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_ftw }, NULL, NULL}, 183 { DEFINE_FPU_UINT(fop) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_fop }, NULL, NULL}, 184 { DEFINE_FPU_UINT(ip) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_ip }, NULL, NULL}, 185 { DEFINE_FPU_UINT(cs) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_cs }, NULL, NULL}, 186 { DEFINE_FPU_UINT(dp) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_dp }, NULL, NULL}, 187 { DEFINE_FPU_UINT(ds) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_ds }, NULL, NULL}, 188 { DEFINE_FPU_UINT(mxcsr) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_mxcsr }, NULL, NULL}, 189 { DEFINE_FPU_UINT(mxcsrmask) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_mxcsrmask}, NULL, NULL}, 190 { DEFINE_FPU_VECT(stmm,0) }, 191 { DEFINE_FPU_VECT(stmm,1) }, 192 { DEFINE_FPU_VECT(stmm,2) }, 193 { DEFINE_FPU_VECT(stmm,3) }, 194 { DEFINE_FPU_VECT(stmm,4) }, 195 { DEFINE_FPU_VECT(stmm,5) }, 196 { DEFINE_FPU_VECT(stmm,6) }, 197 { DEFINE_FPU_VECT(stmm,7) }, 198 { DEFINE_FPU_VECT(xmm,0) }, 199 { DEFINE_FPU_VECT(xmm,1) }, 200 { DEFINE_FPU_VECT(xmm,2) }, 201 { DEFINE_FPU_VECT(xmm,3) }, 202 { DEFINE_FPU_VECT(xmm,4) }, 203 { DEFINE_FPU_VECT(xmm,5) }, 204 { DEFINE_FPU_VECT(xmm,6) }, 205 { DEFINE_FPU_VECT(xmm,7) }, 206 207 { DEFINE_EXC(trapno) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, exc_trapno }, NULL, NULL}, 208 { DEFINE_EXC(err) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, exc_err }, NULL, NULL}, 209 { DEFINE_EXC(faultvaddr) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, exc_faultvaddr }, NULL, NULL} 210 }; 211 212 static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos); 213 214 RegisterContextDarwin_i386::RegisterContextDarwin_i386 (Thread &thread, uint32_t concrete_frame_idx) : 215 RegisterContext(thread, concrete_frame_idx), 216 gpr(), 217 fpu(), 218 exc() 219 { 220 uint32_t i; 221 for (i=0; i<kNumErrors; i++) 222 { 223 gpr_errs[i] = -1; 224 fpu_errs[i] = -1; 225 exc_errs[i] = -1; 226 } 227 } 228 229 RegisterContextDarwin_i386::~RegisterContextDarwin_i386() 230 { 231 } 232 233 234 void 235 RegisterContextDarwin_i386::InvalidateAllRegisters () 236 { 237 InvalidateAllRegisterStates(); 238 } 239 240 241 size_t 242 RegisterContextDarwin_i386::GetRegisterCount () 243 { 244 assert(k_num_register_infos == k_num_registers); 245 return k_num_registers; 246 } 247 248 const RegisterInfo * 249 RegisterContextDarwin_i386::GetRegisterInfoAtIndex (size_t reg) 250 { 251 assert(k_num_register_infos == k_num_registers); 252 if (reg < k_num_registers) 253 return &g_register_infos[reg]; 254 return NULL; 255 } 256 257 size_t 258 RegisterContextDarwin_i386::GetRegisterInfosCount () 259 { 260 return k_num_register_infos; 261 } 262 263 const RegisterInfo * 264 RegisterContextDarwin_i386::GetRegisterInfos () 265 { 266 return g_register_infos; 267 } 268 269 270 // General purpose registers 271 static uint32_t 272 g_gpr_regnums[] = 273 { 274 gpr_eax, 275 gpr_ebx, 276 gpr_ecx, 277 gpr_edx, 278 gpr_edi, 279 gpr_esi, 280 gpr_ebp, 281 gpr_esp, 282 gpr_ss, 283 gpr_eflags, 284 gpr_eip, 285 gpr_cs, 286 gpr_ds, 287 gpr_es, 288 gpr_fs, 289 gpr_gs 290 }; 291 292 // Floating point registers 293 static uint32_t 294 g_fpu_regnums[] = 295 { 296 fpu_fcw, 297 fpu_fsw, 298 fpu_ftw, 299 fpu_fop, 300 fpu_ip, 301 fpu_cs, 302 fpu_dp, 303 fpu_ds, 304 fpu_mxcsr, 305 fpu_mxcsrmask, 306 fpu_stmm0, 307 fpu_stmm1, 308 fpu_stmm2, 309 fpu_stmm3, 310 fpu_stmm4, 311 fpu_stmm5, 312 fpu_stmm6, 313 fpu_stmm7, 314 fpu_xmm0, 315 fpu_xmm1, 316 fpu_xmm2, 317 fpu_xmm3, 318 fpu_xmm4, 319 fpu_xmm5, 320 fpu_xmm6, 321 fpu_xmm7 322 }; 323 324 // Exception registers 325 326 static uint32_t 327 g_exc_regnums[] = 328 { 329 exc_trapno, 330 exc_err, 331 exc_faultvaddr 332 }; 333 334 // Number of registers in each register set 335 const size_t k_num_gpr_registers = llvm::array_lengthof(g_gpr_regnums); 336 const size_t k_num_fpu_registers = llvm::array_lengthof(g_fpu_regnums); 337 const size_t k_num_exc_registers = llvm::array_lengthof(g_exc_regnums); 338 339 //---------------------------------------------------------------------- 340 // Register set definitions. The first definitions at register set index 341 // of zero is for all registers, followed by other registers sets. The 342 // register information for the all register set need not be filled in. 343 //---------------------------------------------------------------------- 344 static const RegisterSet g_reg_sets[] = 345 { 346 { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums, }, 347 { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums }, 348 { "Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums } 349 }; 350 351 const size_t k_num_regsets = llvm::array_lengthof(g_reg_sets); 352 353 354 size_t 355 RegisterContextDarwin_i386::GetRegisterSetCount () 356 { 357 return k_num_regsets; 358 } 359 360 const RegisterSet * 361 RegisterContextDarwin_i386::GetRegisterSet (size_t reg_set) 362 { 363 if (reg_set < k_num_regsets) 364 return &g_reg_sets[reg_set]; 365 return NULL; 366 } 367 368 369 //---------------------------------------------------------------------- 370 // Register information definitions for 32 bit i386. 371 //---------------------------------------------------------------------- 372 int 373 RegisterContextDarwin_i386::GetSetForNativeRegNum (int reg_num) 374 { 375 if (reg_num < fpu_fcw) 376 return GPRRegSet; 377 else if (reg_num < exc_trapno) 378 return FPURegSet; 379 else if (reg_num < k_num_registers) 380 return EXCRegSet; 381 return -1; 382 } 383 384 385 void 386 RegisterContextDarwin_i386::LogGPR(Log *log, const char *title) 387 { 388 if (log) 389 { 390 if (title) 391 log->Printf ("%s", title); 392 for (uint32_t i=0; i<k_num_gpr_registers; i++) 393 { 394 uint32_t reg = gpr_eax + i; 395 log->Printf("%12s = 0x%8.8x", g_register_infos[reg].name, (&gpr.eax)[reg]); 396 } 397 } 398 } 399 400 401 402 int 403 RegisterContextDarwin_i386::ReadGPR (bool force) 404 { 405 int set = GPRRegSet; 406 if (force || !RegisterSetIsCached(set)) 407 { 408 SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr)); 409 } 410 return GetError(set, Read); 411 } 412 413 int 414 RegisterContextDarwin_i386::ReadFPU (bool force) 415 { 416 int set = FPURegSet; 417 if (force || !RegisterSetIsCached(set)) 418 { 419 SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu)); 420 } 421 return GetError(set, Read); 422 } 423 424 int 425 RegisterContextDarwin_i386::ReadEXC (bool force) 426 { 427 int set = EXCRegSet; 428 if (force || !RegisterSetIsCached(set)) 429 { 430 SetError(set, Read, DoReadEXC(GetThreadID(), set, exc)); 431 } 432 return GetError(set, Read); 433 } 434 435 int 436 RegisterContextDarwin_i386::WriteGPR () 437 { 438 int set = GPRRegSet; 439 if (!RegisterSetIsCached(set)) 440 { 441 SetError (set, Write, -1); 442 return -1; 443 } 444 SetError (set, Write, DoWriteGPR(GetThreadID(), set, gpr)); 445 SetError (set, Read, -1); 446 return GetError(set, Write); 447 } 448 449 int 450 RegisterContextDarwin_i386::WriteFPU () 451 { 452 int set = FPURegSet; 453 if (!RegisterSetIsCached(set)) 454 { 455 SetError (set, Write, -1); 456 return -1; 457 } 458 SetError (set, Write, DoWriteFPU(GetThreadID(), set, fpu)); 459 SetError (set, Read, -1); 460 return GetError(set, Write); 461 } 462 463 int 464 RegisterContextDarwin_i386::WriteEXC () 465 { 466 int set = EXCRegSet; 467 if (!RegisterSetIsCached(set)) 468 { 469 SetError (set, Write, -1); 470 return -1; 471 } 472 SetError (set, Write, DoWriteEXC(GetThreadID(), set, exc)); 473 SetError (set, Read, -1); 474 return GetError(set, Write); 475 } 476 477 int 478 RegisterContextDarwin_i386::ReadRegisterSet (uint32_t set, bool force) 479 { 480 switch (set) 481 { 482 case GPRRegSet: return ReadGPR(force); 483 case FPURegSet: return ReadFPU(force); 484 case EXCRegSet: return ReadEXC(force); 485 default: break; 486 } 487 return -1; 488 } 489 490 int 491 RegisterContextDarwin_i386::WriteRegisterSet (uint32_t set) 492 { 493 // Make sure we have a valid context to set. 494 if (RegisterSetIsCached(set)) 495 { 496 switch (set) 497 { 498 case GPRRegSet: return WriteGPR(); 499 case FPURegSet: return WriteFPU(); 500 case EXCRegSet: return WriteEXC(); 501 default: break; 502 } 503 } 504 return -1; 505 } 506 507 bool 508 RegisterContextDarwin_i386::ReadRegister (const RegisterInfo *reg_info, 509 RegisterValue &value) 510 { 511 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 512 int set = RegisterContextDarwin_i386::GetSetForNativeRegNum (reg); 513 514 if (set == -1) 515 return false; 516 517 if (ReadRegisterSet(set, false) != 0) 518 return false; 519 520 switch (reg) 521 { 522 case gpr_eax: 523 case gpr_ebx: 524 case gpr_ecx: 525 case gpr_edx: 526 case gpr_edi: 527 case gpr_esi: 528 case gpr_ebp: 529 case gpr_esp: 530 case gpr_ss: 531 case gpr_eflags: 532 case gpr_eip: 533 case gpr_cs: 534 case gpr_ds: 535 case gpr_es: 536 case gpr_fs: 537 case gpr_gs: 538 value = (&gpr.eax)[reg - gpr_eax]; 539 break; 540 541 case fpu_fcw: 542 value = fpu.fcw; 543 break; 544 545 case fpu_fsw: 546 value = fpu.fsw; 547 break; 548 549 case fpu_ftw: 550 value = fpu.ftw; 551 break; 552 553 case fpu_fop: 554 value = fpu.fop; 555 break; 556 557 case fpu_ip: 558 value = fpu.ip; 559 break; 560 561 case fpu_cs: 562 value = fpu.cs; 563 break; 564 565 case fpu_dp: 566 value = fpu.dp; 567 break; 568 569 case fpu_ds: 570 value = fpu.ds; 571 break; 572 573 case fpu_mxcsr: 574 value = fpu.mxcsr; 575 break; 576 577 case fpu_mxcsrmask: 578 value = fpu.mxcsrmask; 579 break; 580 581 case fpu_stmm0: 582 case fpu_stmm1: 583 case fpu_stmm2: 584 case fpu_stmm3: 585 case fpu_stmm4: 586 case fpu_stmm5: 587 case fpu_stmm6: 588 case fpu_stmm7: 589 // These values don't fit into scalar types, 590 // RegisterContext::ReadRegisterBytes() must be used for these 591 // registers 592 //::memcpy (reg_value.value.vector.uint8, fpu.stmm[reg - fpu_stmm0].bytes, 10); 593 return false; 594 595 case fpu_xmm0: 596 case fpu_xmm1: 597 case fpu_xmm2: 598 case fpu_xmm3: 599 case fpu_xmm4: 600 case fpu_xmm5: 601 case fpu_xmm6: 602 case fpu_xmm7: 603 // These values don't fit into scalar types, RegisterContext::ReadRegisterBytes() 604 // must be used for these registers 605 //::memcpy (reg_value.value.vector.uint8, fpu.xmm[reg - fpu_xmm0].bytes, 16); 606 return false; 607 608 case exc_trapno: 609 value = exc.trapno; 610 break; 611 612 case exc_err: 613 value = exc.err; 614 break; 615 616 case exc_faultvaddr: 617 value = exc.faultvaddr; 618 break; 619 620 default: 621 return false; 622 } 623 return true; 624 } 625 626 627 bool 628 RegisterContextDarwin_i386::WriteRegister (const RegisterInfo *reg_info, 629 const RegisterValue &value) 630 { 631 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 632 int set = GetSetForNativeRegNum (reg); 633 634 if (set == -1) 635 return false; 636 637 if (ReadRegisterSet(set, false) != 0) 638 return false; 639 640 switch (reg) 641 { 642 case gpr_eax: 643 case gpr_ebx: 644 case gpr_ecx: 645 case gpr_edx: 646 case gpr_edi: 647 case gpr_esi: 648 case gpr_ebp: 649 case gpr_esp: 650 case gpr_ss: 651 case gpr_eflags: 652 case gpr_eip: 653 case gpr_cs: 654 case gpr_ds: 655 case gpr_es: 656 case gpr_fs: 657 case gpr_gs: 658 (&gpr.eax)[reg - gpr_eax] = value.GetAsUInt32(); 659 break; 660 661 case fpu_fcw: 662 fpu.fcw = value.GetAsUInt16(); 663 break; 664 665 case fpu_fsw: 666 fpu.fsw = value.GetAsUInt16(); 667 break; 668 669 case fpu_ftw: 670 fpu.ftw = value.GetAsUInt8(); 671 break; 672 673 case fpu_fop: 674 fpu.fop = value.GetAsUInt16(); 675 break; 676 677 case fpu_ip: 678 fpu.ip = value.GetAsUInt32(); 679 break; 680 681 case fpu_cs: 682 fpu.cs = value.GetAsUInt16(); 683 break; 684 685 case fpu_dp: 686 fpu.dp = value.GetAsUInt32(); 687 break; 688 689 case fpu_ds: 690 fpu.ds = value.GetAsUInt16(); 691 break; 692 693 case fpu_mxcsr: 694 fpu.mxcsr = value.GetAsUInt32(); 695 break; 696 697 case fpu_mxcsrmask: 698 fpu.mxcsrmask = value.GetAsUInt32(); 699 break; 700 701 case fpu_stmm0: 702 case fpu_stmm1: 703 case fpu_stmm2: 704 case fpu_stmm3: 705 case fpu_stmm4: 706 case fpu_stmm5: 707 case fpu_stmm6: 708 case fpu_stmm7: 709 // These values don't fit into scalar types, RegisterContext::ReadRegisterBytes() 710 // must be used for these registers 711 ::memcpy (fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(), value.GetByteSize()); 712 return false; 713 714 case fpu_xmm0: 715 case fpu_xmm1: 716 case fpu_xmm2: 717 case fpu_xmm3: 718 case fpu_xmm4: 719 case fpu_xmm5: 720 case fpu_xmm6: 721 case fpu_xmm7: 722 // These values don't fit into scalar types, RegisterContext::ReadRegisterBytes() 723 // must be used for these registers 724 ::memcpy (fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(), value.GetByteSize()); 725 return false; 726 727 case exc_trapno: 728 exc.trapno = value.GetAsUInt32(); 729 break; 730 731 case exc_err: 732 exc.err = value.GetAsUInt32(); 733 break; 734 735 case exc_faultvaddr: 736 exc.faultvaddr = value.GetAsUInt32(); 737 break; 738 739 default: 740 return false; 741 } 742 return WriteRegisterSet(set) == 0; 743 } 744 745 bool 746 RegisterContextDarwin_i386::ReadAllRegisterValues (lldb::DataBufferSP &data_sp) 747 { 748 data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0)); 749 if (data_sp && 750 ReadGPR (false) == 0 && 751 ReadFPU (false) == 0 && 752 ReadEXC (false) == 0) 753 { 754 uint8_t *dst = data_sp->GetBytes(); 755 ::memcpy (dst, &gpr, sizeof(gpr)); 756 dst += sizeof(gpr); 757 758 ::memcpy (dst, &fpu, sizeof(fpu)); 759 dst += sizeof(gpr); 760 761 ::memcpy (dst, &exc, sizeof(exc)); 762 return true; 763 } 764 return false; 765 } 766 767 bool 768 RegisterContextDarwin_i386::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) 769 { 770 if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) 771 { 772 const uint8_t *src = data_sp->GetBytes(); 773 ::memcpy (&gpr, src, sizeof(gpr)); 774 src += sizeof(gpr); 775 776 ::memcpy (&fpu, src, sizeof(fpu)); 777 src += sizeof(gpr); 778 779 ::memcpy (&exc, src, sizeof(exc)); 780 uint32_t success_count = 0; 781 if (WriteGPR() == 0) 782 ++success_count; 783 if (WriteFPU() == 0) 784 ++success_count; 785 if (WriteEXC() == 0) 786 ++success_count; 787 return success_count == 3; 788 } 789 return false; 790 } 791 792 793 uint32_t 794 RegisterContextDarwin_i386::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t reg) 795 { 796 if (kind == eRegisterKindGeneric) 797 { 798 switch (reg) 799 { 800 case LLDB_REGNUM_GENERIC_PC: return gpr_eip; 801 case LLDB_REGNUM_GENERIC_SP: return gpr_esp; 802 case LLDB_REGNUM_GENERIC_FP: return gpr_ebp; 803 case LLDB_REGNUM_GENERIC_FLAGS: return gpr_eflags; 804 case LLDB_REGNUM_GENERIC_RA: 805 default: 806 break; 807 } 808 } 809 else if (kind == eRegisterKindEHFrame || kind == eRegisterKindDWARF) 810 { 811 switch (reg) 812 { 813 case dwarf_eax: return gpr_eax; 814 case dwarf_ecx: return gpr_ecx; 815 case dwarf_edx: return gpr_edx; 816 case dwarf_ebx: return gpr_ebx; 817 case dwarf_esp: return gpr_esp; 818 case dwarf_ebp: return gpr_ebp; 819 case dwarf_esi: return gpr_esi; 820 case dwarf_edi: return gpr_edi; 821 case dwarf_eip: return gpr_eip; 822 case dwarf_eflags: return gpr_eflags; 823 case dwarf_stmm0: return fpu_stmm0; 824 case dwarf_stmm1: return fpu_stmm1; 825 case dwarf_stmm2: return fpu_stmm2; 826 case dwarf_stmm3: return fpu_stmm3; 827 case dwarf_stmm4: return fpu_stmm4; 828 case dwarf_stmm5: return fpu_stmm5; 829 case dwarf_stmm6: return fpu_stmm6; 830 case dwarf_stmm7: return fpu_stmm7; 831 case dwarf_xmm0: return fpu_xmm0; 832 case dwarf_xmm1: return fpu_xmm1; 833 case dwarf_xmm2: return fpu_xmm2; 834 case dwarf_xmm3: return fpu_xmm3; 835 case dwarf_xmm4: return fpu_xmm4; 836 case dwarf_xmm5: return fpu_xmm5; 837 case dwarf_xmm6: return fpu_xmm6; 838 case dwarf_xmm7: return fpu_xmm7; 839 default: 840 break; 841 } 842 } 843 else if (kind == eRegisterKindLLDB) 844 { 845 return reg; 846 } 847 return LLDB_INVALID_REGNUM; 848 } 849 850 851 bool 852 RegisterContextDarwin_i386::HardwareSingleStep (bool enable) 853 { 854 if (ReadGPR(false) != 0) 855 return false; 856 857 const uint32_t trace_bit = 0x100u; 858 if (enable) 859 { 860 // If the trace bit is already set, there is nothing to do 861 if (gpr.eflags & trace_bit) 862 return true; 863 else 864 gpr.eflags |= trace_bit; 865 } 866 else 867 { 868 // If the trace bit is already cleared, there is nothing to do 869 if (gpr.eflags & trace_bit) 870 gpr.eflags &= ~trace_bit; 871 else 872 return true; 873 } 874 875 return WriteGPR() == 0; 876 } 877 878 879 880