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, 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 {DEFINE_GPR(eax, nullptr), 169 {ehframe_eax, dwarf_eax, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 170 gpr_eax}, 171 nullptr, 172 nullptr, 173 nullptr, 174 }, 175 {DEFINE_GPR(ebx, nullptr), 176 {ehframe_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 177 gpr_ebx}, 178 nullptr, 179 nullptr, 180 nullptr, 181 }, 182 {DEFINE_GPR(ecx, nullptr), 183 {ehframe_ecx, dwarf_ecx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 184 gpr_ecx}, 185 nullptr, 186 nullptr, 187 nullptr, 188 }, 189 {DEFINE_GPR(edx, nullptr), 190 {ehframe_edx, dwarf_edx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 191 gpr_edx}, 192 nullptr, 193 nullptr, 194 nullptr, 195 }, 196 {DEFINE_GPR(edi, nullptr), 197 {ehframe_edi, dwarf_edi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 198 gpr_edi}, 199 nullptr, 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 nullptr, 209 }, 210 {DEFINE_GPR(ebp, "fp"), 211 {ehframe_ebp, dwarf_ebp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, 212 gpr_ebp}, 213 nullptr, 214 nullptr, 215 nullptr, 216 }, 217 {DEFINE_GPR(esp, "sp"), 218 {ehframe_esp, dwarf_esp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, 219 gpr_esp}, 220 nullptr, 221 nullptr, 222 nullptr, 223 }, 224 {DEFINE_GPR(ss, nullptr), 225 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 226 LLDB_INVALID_REGNUM, gpr_ss}, 227 nullptr, 228 nullptr, 229 nullptr, 230 }, 231 {DEFINE_GPR(eflags, "flags"), 232 {ehframe_eflags, dwarf_eflags, LLDB_REGNUM_GENERIC_FLAGS, 233 LLDB_INVALID_REGNUM, gpr_eflags}, 234 nullptr, 235 nullptr, 236 nullptr, 237 }, 238 {DEFINE_GPR(eip, "pc"), 239 {ehframe_eip, dwarf_eip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, 240 gpr_eip}, 241 nullptr, 242 nullptr, 243 nullptr, 244 }, 245 {DEFINE_GPR(cs, nullptr), 246 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 247 LLDB_INVALID_REGNUM, gpr_cs}, 248 nullptr, 249 nullptr, 250 nullptr, 251 }, 252 {DEFINE_GPR(ds, nullptr), 253 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 254 LLDB_INVALID_REGNUM, gpr_ds}, 255 nullptr, 256 nullptr, 257 nullptr, 258 }, 259 {DEFINE_GPR(es, nullptr), 260 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 261 LLDB_INVALID_REGNUM, gpr_es}, 262 nullptr, 263 nullptr, 264 nullptr, 265 }, 266 {DEFINE_GPR(fs, nullptr), 267 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 268 LLDB_INVALID_REGNUM, gpr_fs}, 269 nullptr, 270 nullptr, 271 nullptr, 272 }, 273 {DEFINE_GPR(gs, nullptr), 274 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 275 LLDB_INVALID_REGNUM, gpr_gs}, 276 nullptr, 277 nullptr, 278 nullptr, 279 }, 280 281 {DEFINE_FPU_UINT(fcw), 282 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 283 LLDB_INVALID_REGNUM, fpu_fcw}, 284 nullptr, 285 nullptr, 286 nullptr, 287 }, 288 {DEFINE_FPU_UINT(fsw), 289 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 290 LLDB_INVALID_REGNUM, fpu_fsw}, 291 nullptr, 292 nullptr, 293 nullptr, 294 }, 295 {DEFINE_FPU_UINT(ftw), 296 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 297 LLDB_INVALID_REGNUM, fpu_ftw}, 298 nullptr, 299 nullptr, 300 nullptr, 301 }, 302 {DEFINE_FPU_UINT(fop), 303 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 304 LLDB_INVALID_REGNUM, fpu_fop}, 305 nullptr, 306 nullptr, 307 nullptr, 308 }, 309 {DEFINE_FPU_UINT(ip), 310 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 311 LLDB_INVALID_REGNUM, fpu_ip}, 312 nullptr, 313 nullptr, 314 nullptr, 315 }, 316 {DEFINE_FPU_UINT(cs), 317 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 318 LLDB_INVALID_REGNUM, fpu_cs}, 319 nullptr, 320 nullptr, 321 nullptr, 322 }, 323 {DEFINE_FPU_UINT(dp), 324 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 325 LLDB_INVALID_REGNUM, fpu_dp}, 326 nullptr, 327 nullptr, 328 nullptr, 329 }, 330 {DEFINE_FPU_UINT(ds), 331 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 332 LLDB_INVALID_REGNUM, fpu_ds}, 333 nullptr, 334 nullptr, 335 nullptr, 336 }, 337 {DEFINE_FPU_UINT(mxcsr), 338 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 339 LLDB_INVALID_REGNUM, fpu_mxcsr}, 340 nullptr, 341 nullptr, 342 nullptr, 343 }, 344 {DEFINE_FPU_UINT(mxcsrmask), 345 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 346 LLDB_INVALID_REGNUM, fpu_mxcsrmask}, 347 nullptr, 348 nullptr, 349 nullptr, 350 }, 351 {DEFINE_FPU_VECT(stmm, 0)}, 352 {DEFINE_FPU_VECT(stmm, 1)}, 353 {DEFINE_FPU_VECT(stmm, 2)}, 354 {DEFINE_FPU_VECT(stmm, 3)}, 355 {DEFINE_FPU_VECT(stmm, 4)}, 356 {DEFINE_FPU_VECT(stmm, 5)}, 357 {DEFINE_FPU_VECT(stmm, 6)}, 358 {DEFINE_FPU_VECT(stmm, 7)}, 359 {DEFINE_FPU_VECT(xmm, 0)}, 360 {DEFINE_FPU_VECT(xmm, 1)}, 361 {DEFINE_FPU_VECT(xmm, 2)}, 362 {DEFINE_FPU_VECT(xmm, 3)}, 363 {DEFINE_FPU_VECT(xmm, 4)}, 364 {DEFINE_FPU_VECT(xmm, 5)}, 365 {DEFINE_FPU_VECT(xmm, 6)}, 366 {DEFINE_FPU_VECT(xmm, 7)}, 367 368 {DEFINE_EXC(trapno), 369 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 370 LLDB_INVALID_REGNUM, exc_trapno}, 371 nullptr, 372 nullptr, 373 nullptr, 374 }, 375 {DEFINE_EXC(err), 376 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 377 LLDB_INVALID_REGNUM, exc_err}, 378 nullptr, 379 nullptr, 380 nullptr, 381 }, 382 {DEFINE_EXC(faultvaddr), 383 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 384 LLDB_INVALID_REGNUM, exc_faultvaddr}, 385 nullptr, 386 nullptr, 387 nullptr, 388 }}; 389 390 static size_t k_num_register_infos = std::size(g_register_infos); 391 392 RegisterContextDarwin_i386::RegisterContextDarwin_i386( 393 Thread &thread, uint32_t concrete_frame_idx) 394 : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() { 395 uint32_t i; 396 for (i = 0; i < kNumErrors; i++) { 397 gpr_errs[i] = -1; 398 fpu_errs[i] = -1; 399 exc_errs[i] = -1; 400 } 401 } 402 403 RegisterContextDarwin_i386::~RegisterContextDarwin_i386() = default; 404 405 void RegisterContextDarwin_i386::InvalidateAllRegisters() { 406 InvalidateAllRegisterStates(); 407 } 408 409 size_t RegisterContextDarwin_i386::GetRegisterCount() { 410 assert(k_num_register_infos == k_num_registers); 411 return k_num_registers; 412 } 413 414 const RegisterInfo * 415 RegisterContextDarwin_i386::GetRegisterInfoAtIndex(size_t reg) { 416 assert(k_num_register_infos == k_num_registers); 417 if (reg < k_num_registers) 418 return &g_register_infos[reg]; 419 return nullptr; 420 } 421 422 size_t RegisterContextDarwin_i386::GetRegisterInfosCount() { 423 return k_num_register_infos; 424 } 425 426 const RegisterInfo *RegisterContextDarwin_i386::GetRegisterInfos() { 427 return g_register_infos; 428 } 429 430 // General purpose registers 431 static uint32_t g_gpr_regnums[] = { 432 gpr_eax, gpr_ebx, gpr_ecx, gpr_edx, gpr_edi, gpr_esi, gpr_ebp, gpr_esp, 433 gpr_ss, gpr_eflags, gpr_eip, gpr_cs, gpr_ds, gpr_es, gpr_fs, gpr_gs}; 434 435 // Floating point registers 436 static uint32_t g_fpu_regnums[] = { 437 fpu_fcw, fpu_fsw, fpu_ftw, fpu_fop, fpu_ip, fpu_cs, 438 fpu_dp, fpu_ds, fpu_mxcsr, fpu_mxcsrmask, fpu_stmm0, fpu_stmm1, 439 fpu_stmm2, fpu_stmm3, fpu_stmm4, fpu_stmm5, fpu_stmm6, fpu_stmm7, 440 fpu_xmm0, fpu_xmm1, fpu_xmm2, fpu_xmm3, fpu_xmm4, fpu_xmm5, 441 fpu_xmm6, fpu_xmm7}; 442 443 // Exception registers 444 445 static uint32_t g_exc_regnums[] = {exc_trapno, exc_err, exc_faultvaddr}; 446 447 // Number of registers in each register set 448 const size_t k_num_gpr_registers = std::size(g_gpr_regnums); 449 const size_t k_num_fpu_registers = std::size(g_fpu_regnums); 450 const size_t k_num_exc_registers = std::size(g_exc_regnums); 451 452 // Register set definitions. The first definitions at register set index of 453 // zero is for all registers, followed by other registers sets. The register 454 // information for the all register set need not be filled in. 455 static const RegisterSet g_reg_sets[] = { 456 { 457 "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums, 458 }, 459 {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums}, 460 {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}}; 461 462 const size_t k_num_regsets = std::size(g_reg_sets); 463 464 size_t RegisterContextDarwin_i386::GetRegisterSetCount() { 465 return k_num_regsets; 466 } 467 468 const RegisterSet *RegisterContextDarwin_i386::GetRegisterSet(size_t reg_set) { 469 if (reg_set < k_num_regsets) 470 return &g_reg_sets[reg_set]; 471 return nullptr; 472 } 473 474 // Register information definitions for 32 bit i386. 475 int RegisterContextDarwin_i386::GetSetForNativeRegNum(int reg_num) { 476 if (reg_num < fpu_fcw) 477 return GPRRegSet; 478 else if (reg_num < exc_trapno) 479 return FPURegSet; 480 else if (reg_num < k_num_registers) 481 return EXCRegSet; 482 return -1; 483 } 484 485 void RegisterContextDarwin_i386::LogGPR(Log *log, const char *title) { 486 if (log) { 487 if (title) 488 LLDB_LOGF(log, "%s", title); 489 for (uint32_t i = 0; i < k_num_gpr_registers; i++) { 490 uint32_t reg = gpr_eax + i; 491 LLDB_LOGF(log, "%12s = 0x%8.8x", g_register_infos[reg].name, 492 (&gpr.eax)[reg]); 493 } 494 } 495 } 496 497 int RegisterContextDarwin_i386::ReadGPR(bool force) { 498 int set = GPRRegSet; 499 if (force || !RegisterSetIsCached(set)) { 500 SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr)); 501 } 502 return GetError(set, Read); 503 } 504 505 int RegisterContextDarwin_i386::ReadFPU(bool force) { 506 int set = FPURegSet; 507 if (force || !RegisterSetIsCached(set)) { 508 SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu)); 509 } 510 return GetError(set, Read); 511 } 512 513 int RegisterContextDarwin_i386::ReadEXC(bool force) { 514 int set = EXCRegSet; 515 if (force || !RegisterSetIsCached(set)) { 516 SetError(set, Read, DoReadEXC(GetThreadID(), set, exc)); 517 } 518 return GetError(set, Read); 519 } 520 521 int RegisterContextDarwin_i386::WriteGPR() { 522 int set = GPRRegSet; 523 if (!RegisterSetIsCached(set)) { 524 SetError(set, Write, -1); 525 return -1; 526 } 527 SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr)); 528 SetError(set, Read, -1); 529 return GetError(set, Write); 530 } 531 532 int RegisterContextDarwin_i386::WriteFPU() { 533 int set = FPURegSet; 534 if (!RegisterSetIsCached(set)) { 535 SetError(set, Write, -1); 536 return -1; 537 } 538 SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu)); 539 SetError(set, Read, -1); 540 return GetError(set, Write); 541 } 542 543 int RegisterContextDarwin_i386::WriteEXC() { 544 int set = EXCRegSet; 545 if (!RegisterSetIsCached(set)) { 546 SetError(set, Write, -1); 547 return -1; 548 } 549 SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc)); 550 SetError(set, Read, -1); 551 return GetError(set, Write); 552 } 553 554 int RegisterContextDarwin_i386::ReadRegisterSet(uint32_t set, bool force) { 555 switch (set) { 556 case GPRRegSet: 557 return ReadGPR(force); 558 case FPURegSet: 559 return ReadFPU(force); 560 case EXCRegSet: 561 return ReadEXC(force); 562 default: 563 break; 564 } 565 return -1; 566 } 567 568 int RegisterContextDarwin_i386::WriteRegisterSet(uint32_t set) { 569 // Make sure we have a valid context to set. 570 if (RegisterSetIsCached(set)) { 571 switch (set) { 572 case GPRRegSet: 573 return WriteGPR(); 574 case FPURegSet: 575 return WriteFPU(); 576 case EXCRegSet: 577 return WriteEXC(); 578 default: 579 break; 580 } 581 } 582 return -1; 583 } 584 585 bool RegisterContextDarwin_i386::ReadRegister(const RegisterInfo *reg_info, 586 RegisterValue &value) { 587 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 588 int set = RegisterContextDarwin_i386::GetSetForNativeRegNum(reg); 589 590 if (set == -1) 591 return false; 592 593 if (ReadRegisterSet(set, false) != 0) 594 return false; 595 596 switch (reg) { 597 case gpr_eax: 598 case gpr_ebx: 599 case gpr_ecx: 600 case gpr_edx: 601 case gpr_edi: 602 case gpr_esi: 603 case gpr_ebp: 604 case gpr_esp: 605 case gpr_ss: 606 case gpr_eflags: 607 case gpr_eip: 608 case gpr_cs: 609 case gpr_ds: 610 case gpr_es: 611 case gpr_fs: 612 case gpr_gs: 613 value = (&gpr.eax)[reg - gpr_eax]; 614 break; 615 616 case fpu_fcw: 617 value = fpu.fcw; 618 break; 619 620 case fpu_fsw: 621 value = fpu.fsw; 622 break; 623 624 case fpu_ftw: 625 value = fpu.ftw; 626 break; 627 628 case fpu_fop: 629 value = fpu.fop; 630 break; 631 632 case fpu_ip: 633 value = fpu.ip; 634 break; 635 636 case fpu_cs: 637 value = fpu.cs; 638 break; 639 640 case fpu_dp: 641 value = fpu.dp; 642 break; 643 644 case fpu_ds: 645 value = fpu.ds; 646 break; 647 648 case fpu_mxcsr: 649 value = fpu.mxcsr; 650 break; 651 652 case fpu_mxcsrmask: 653 value = fpu.mxcsrmask; 654 break; 655 656 case fpu_stmm0: 657 case fpu_stmm1: 658 case fpu_stmm2: 659 case fpu_stmm3: 660 case fpu_stmm4: 661 case fpu_stmm5: 662 case fpu_stmm6: 663 case fpu_stmm7: 664 // These values don't fit into scalar types, 665 // RegisterContext::ReadRegisterBytes() must be used for these registers 666 //::memcpy (reg_value.value.vector.uint8, fpu.stmm[reg - fpu_stmm0].bytes, 667 //10); 668 return false; 669 670 case fpu_xmm0: 671 case fpu_xmm1: 672 case fpu_xmm2: 673 case fpu_xmm3: 674 case fpu_xmm4: 675 case fpu_xmm5: 676 case fpu_xmm6: 677 case fpu_xmm7: 678 // These values don't fit into scalar types, 679 // RegisterContext::ReadRegisterBytes() must be used for these registers 680 //::memcpy (reg_value.value.vector.uint8, fpu.xmm[reg - fpu_xmm0].bytes, 681 //16); 682 return false; 683 684 case exc_trapno: 685 value = exc.trapno; 686 break; 687 688 case exc_err: 689 value = exc.err; 690 break; 691 692 case exc_faultvaddr: 693 value = exc.faultvaddr; 694 break; 695 696 default: 697 return false; 698 } 699 return true; 700 } 701 702 bool RegisterContextDarwin_i386::WriteRegister(const RegisterInfo *reg_info, 703 const RegisterValue &value) { 704 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 705 int set = GetSetForNativeRegNum(reg); 706 707 if (set == -1) 708 return false; 709 710 if (ReadRegisterSet(set, false) != 0) 711 return false; 712 713 switch (reg) { 714 case gpr_eax: 715 case gpr_ebx: 716 case gpr_ecx: 717 case gpr_edx: 718 case gpr_edi: 719 case gpr_esi: 720 case gpr_ebp: 721 case gpr_esp: 722 case gpr_ss: 723 case gpr_eflags: 724 case gpr_eip: 725 case gpr_cs: 726 case gpr_ds: 727 case gpr_es: 728 case gpr_fs: 729 case gpr_gs: 730 (&gpr.eax)[reg - gpr_eax] = value.GetAsUInt32(); 731 break; 732 733 case fpu_fcw: 734 fpu.fcw = value.GetAsUInt16(); 735 break; 736 737 case fpu_fsw: 738 fpu.fsw = value.GetAsUInt16(); 739 break; 740 741 case fpu_ftw: 742 fpu.ftw = value.GetAsUInt8(); 743 break; 744 745 case fpu_fop: 746 fpu.fop = value.GetAsUInt16(); 747 break; 748 749 case fpu_ip: 750 fpu.ip = value.GetAsUInt32(); 751 break; 752 753 case fpu_cs: 754 fpu.cs = value.GetAsUInt16(); 755 break; 756 757 case fpu_dp: 758 fpu.dp = value.GetAsUInt32(); 759 break; 760 761 case fpu_ds: 762 fpu.ds = value.GetAsUInt16(); 763 break; 764 765 case fpu_mxcsr: 766 fpu.mxcsr = value.GetAsUInt32(); 767 break; 768 769 case fpu_mxcsrmask: 770 fpu.mxcsrmask = value.GetAsUInt32(); 771 break; 772 773 case fpu_stmm0: 774 case fpu_stmm1: 775 case fpu_stmm2: 776 case fpu_stmm3: 777 case fpu_stmm4: 778 case fpu_stmm5: 779 case fpu_stmm6: 780 case fpu_stmm7: 781 // These values don't fit into scalar types, 782 // RegisterContext::ReadRegisterBytes() must be used for these registers 783 ::memcpy(fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(), 784 value.GetByteSize()); 785 return false; 786 787 case fpu_xmm0: 788 case fpu_xmm1: 789 case fpu_xmm2: 790 case fpu_xmm3: 791 case fpu_xmm4: 792 case fpu_xmm5: 793 case fpu_xmm6: 794 case fpu_xmm7: 795 // These values don't fit into scalar types, 796 // RegisterContext::ReadRegisterBytes() must be used for these registers 797 ::memcpy(fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(), 798 value.GetByteSize()); 799 return false; 800 801 case exc_trapno: 802 exc.trapno = value.GetAsUInt32(); 803 break; 804 805 case exc_err: 806 exc.err = value.GetAsUInt32(); 807 break; 808 809 case exc_faultvaddr: 810 exc.faultvaddr = value.GetAsUInt32(); 811 break; 812 813 default: 814 return false; 815 } 816 return WriteRegisterSet(set) == 0; 817 } 818 819 bool RegisterContextDarwin_i386::ReadAllRegisterValues( 820 lldb::WritableDataBufferSP &data_sp) { 821 data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0); 822 if (ReadGPR(false) == 0 && ReadFPU(false) == 0 && ReadEXC(false) == 0) { 823 uint8_t *dst = data_sp->GetBytes(); 824 ::memcpy(dst, &gpr, sizeof(gpr)); 825 dst += sizeof(gpr); 826 827 ::memcpy(dst, &fpu, sizeof(fpu)); 828 dst += sizeof(gpr); 829 830 ::memcpy(dst, &exc, sizeof(exc)); 831 return true; 832 } 833 return false; 834 } 835 836 bool RegisterContextDarwin_i386::WriteAllRegisterValues( 837 const lldb::DataBufferSP &data_sp) { 838 if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) { 839 const uint8_t *src = data_sp->GetBytes(); 840 ::memcpy(&gpr, src, sizeof(gpr)); 841 src += sizeof(gpr); 842 843 ::memcpy(&fpu, src, sizeof(fpu)); 844 src += sizeof(gpr); 845 846 ::memcpy(&exc, src, sizeof(exc)); 847 uint32_t success_count = 0; 848 if (WriteGPR() == 0) 849 ++success_count; 850 if (WriteFPU() == 0) 851 ++success_count; 852 if (WriteEXC() == 0) 853 ++success_count; 854 return success_count == 3; 855 } 856 return false; 857 } 858 859 uint32_t RegisterContextDarwin_i386::ConvertRegisterKindToRegisterNumber( 860 lldb::RegisterKind kind, uint32_t reg) { 861 if (kind == eRegisterKindGeneric) { 862 switch (reg) { 863 case LLDB_REGNUM_GENERIC_PC: 864 return gpr_eip; 865 case LLDB_REGNUM_GENERIC_SP: 866 return gpr_esp; 867 case LLDB_REGNUM_GENERIC_FP: 868 return gpr_ebp; 869 case LLDB_REGNUM_GENERIC_FLAGS: 870 return gpr_eflags; 871 case LLDB_REGNUM_GENERIC_RA: 872 default: 873 break; 874 } 875 } else if (kind == eRegisterKindEHFrame || kind == eRegisterKindDWARF) { 876 switch (reg) { 877 case dwarf_eax: 878 return gpr_eax; 879 case dwarf_ecx: 880 return gpr_ecx; 881 case dwarf_edx: 882 return gpr_edx; 883 case dwarf_ebx: 884 return gpr_ebx; 885 case dwarf_esp: 886 return gpr_esp; 887 case dwarf_ebp: 888 return gpr_ebp; 889 case dwarf_esi: 890 return gpr_esi; 891 case dwarf_edi: 892 return gpr_edi; 893 case dwarf_eip: 894 return gpr_eip; 895 case dwarf_eflags: 896 return gpr_eflags; 897 case dwarf_stmm0: 898 return fpu_stmm0; 899 case dwarf_stmm1: 900 return fpu_stmm1; 901 case dwarf_stmm2: 902 return fpu_stmm2; 903 case dwarf_stmm3: 904 return fpu_stmm3; 905 case dwarf_stmm4: 906 return fpu_stmm4; 907 case dwarf_stmm5: 908 return fpu_stmm5; 909 case dwarf_stmm6: 910 return fpu_stmm6; 911 case dwarf_stmm7: 912 return fpu_stmm7; 913 case dwarf_xmm0: 914 return fpu_xmm0; 915 case dwarf_xmm1: 916 return fpu_xmm1; 917 case dwarf_xmm2: 918 return fpu_xmm2; 919 case dwarf_xmm3: 920 return fpu_xmm3; 921 case dwarf_xmm4: 922 return fpu_xmm4; 923 case dwarf_xmm5: 924 return fpu_xmm5; 925 case dwarf_xmm6: 926 return fpu_xmm6; 927 case dwarf_xmm7: 928 return fpu_xmm7; 929 default: 930 break; 931 } 932 } else if (kind == eRegisterKindLLDB) { 933 return reg; 934 } 935 return LLDB_INVALID_REGNUM; 936 } 937 938 bool RegisterContextDarwin_i386::HardwareSingleStep(bool enable) { 939 if (ReadGPR(false) != 0) 940 return false; 941 942 const uint32_t trace_bit = 0x100u; 943 if (enable) { 944 // If the trace bit is already set, there is nothing to do 945 if (gpr.eflags & trace_bit) 946 return true; 947 else 948 gpr.eflags |= trace_bit; 949 } else { 950 // If the trace bit is already cleared, there is nothing to do 951 if (gpr.eflags & trace_bit) 952 gpr.eflags &= ~trace_bit; 953 else 954 return true; 955 } 956 957 return WriteGPR() == 0; 958 } 959