brintos

brintos / llvm-project-archived public Read only

0
0
Text · 26.2 KiB · 8e16d2e Raw
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