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