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