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