1052 lines · cpp
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-exception6//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 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 // Aliases94 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_dp101};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_stmm7145 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 the160// register state structures are defined correctly and have the correct sizes161// and offsets.162#define DEFINE_GPR(reg, alt) \163 #reg, alt, sizeof(((RegisterContextDarwin_x86_64::GPR *) NULL)->reg), \164 GPR_OFFSET(reg), eEncodingUint, eFormatHex165#define DEFINE_FPU_UINT(reg) \166 #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::FPU *) NULL)->reg), \167 FPU_OFFSET(reg), eEncodingUint, eFormatHex168#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, eFormatHex179 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 bit186static 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 452static size_t k_num_register_infos = std::size(g_register_infos);453 454RegisterContextDarwin_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 465RegisterContextDarwin_x86_64::~RegisterContextDarwin_x86_64() = default;466 467void RegisterContextDarwin_x86_64::InvalidateAllRegisters() {468 InvalidateAllRegisterStates();469}470 471size_t RegisterContextDarwin_x86_64::GetRegisterCount() {472 assert(k_num_register_infos == k_num_registers);473 return k_num_registers;474}475 476const RegisterInfo *477RegisterContextDarwin_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 484size_t RegisterContextDarwin_x86_64::GetRegisterInfosCount() {485 return k_num_register_infos;486}487 488const lldb_private::RegisterInfo *489RegisterContextDarwin_x86_64::GetRegisterInfos() {490 return g_register_infos;491}492 493static 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 498static 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 506static uint32_t g_exc_regnums[] = {exc_trapno, exc_err, exc_faultvaddr};507 508// Number of registers in each register set509const size_t k_num_gpr_registers = std::size(g_gpr_regnums);510const size_t k_num_fpu_registers = std::size(g_fpu_regnums);511const size_t k_num_exc_registers = std::size(g_exc_regnums);512 513// Register set definitions. The first definitions at register set index of514// zero is for all registers, followed by other registers sets. The register515// information for the all register set need not be filled in.516static 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 523const size_t k_num_regsets = std::size(g_reg_sets);524 525size_t RegisterContextDarwin_x86_64::GetRegisterSetCount() {526 return k_num_regsets;527}528 529const RegisterSet *530RegisterContextDarwin_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 536int 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 546int 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 554int 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 562int 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 570int 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 581int 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 592int 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 603int 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 617int 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 632bool 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 757bool 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 883bool 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 900bool 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 923uint32_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 1032bool 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 do1041 else1042 gpr.rflags |= trace_bit;1043 } else {1044 if (gpr.rflags & trace_bit)1045 gpr.rflags &= ~trace_bit;1046 else1047 return true; // trace bit is clear, there is nothing to do1048 }1049 1050 return WriteGPR() == 0;1051}1052