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