brintos

brintos / llvm-project-archived public Read only

0
0
Text · 27.3 KiB · 3bcd9a2 Raw
1042 lines · cpp
1//===-- RegisterContextDarwin_arm64.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 "RegisterContextDarwin_arm64.h"10#include "RegisterContextDarwinConstants.h"11 12#include "lldb/Target/Process.h"13#include "lldb/Target/Thread.h"14#include "lldb/Utility/DataBufferHeap.h"15#include "lldb/Utility/DataExtractor.h"16#include "lldb/Utility/Endian.h"17#include "lldb/Utility/Log.h"18#include "lldb/Utility/RegisterValue.h"19#include "lldb/Utility/Scalar.h"20#include "llvm/ADT/STLExtras.h"21#include "llvm/Support/Compiler.h"22 23#include "Plugins/Process/Utility/InstructionUtils.h"24 25#include <memory>26 27#if defined(__APPLE__) && (defined(__arm64__) || defined(__aarch64__))28#include <sys/types.h>29#include <sys/sysctl.h>30#endif31 32#include "Utility/ARM64_DWARF_Registers.h"33 34using namespace lldb;35using namespace lldb_private;36 37#define GPR_OFFSET(idx) ((idx)*8)38#define GPR_OFFSET_NAME(reg)                                                   \39  (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::GPR, reg))40 41#define FPU_OFFSET(idx) ((idx)*16 + sizeof(RegisterContextDarwin_arm64::GPR))42#define FPU_OFFSET_NAME(reg)                                                   \43  (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::FPU, reg))44 45#define EXC_OFFSET_NAME(reg)                                                   \46  (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::EXC, reg) +            \47   sizeof(RegisterContextDarwin_arm64::GPR) +                                  \48   sizeof(RegisterContextDarwin_arm64::FPU))49#define DBG_OFFSET_NAME(reg)                                                   \50  (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::DBG, reg) +            \51   sizeof(RegisterContextDarwin_arm64::GPR) +                                  \52   sizeof(RegisterContextDarwin_arm64::FPU) +                                  \53   sizeof(RegisterContextDarwin_arm64::EXC))54 55#define DEFINE_DBG(reg, i)                                                     \56  #reg, NULL,                                                                  \57      sizeof(((RegisterContextDarwin_arm64::DBG *) NULL)->reg[i]),             \58              DBG_OFFSET_NAME(reg[i]), eEncodingUint, eFormatHex,              \59                              {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,       \60                               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,       \61                               LLDB_INVALID_REGNUM },                          \62                               NULL, NULL, NULL63#define REG_CONTEXT_SIZE                                                       \64  (sizeof(RegisterContextDarwin_arm64::GPR) +                                  \65   sizeof(RegisterContextDarwin_arm64::FPU) +                                  \66   sizeof(RegisterContextDarwin_arm64::EXC))67 68// Include RegisterInfos_arm64 to declare our g_register_infos_arm64 structure.69#define DECLARE_REGISTER_INFOS_ARM64_STRUCT70#include "RegisterInfos_arm64.h"71#undef DECLARE_REGISTER_INFOS_ARM64_STRUCT72 73// General purpose registers74static uint32_t g_gpr_regnums[] = {75    gpr_x0,  gpr_x1,  gpr_x2,  gpr_x3,  gpr_x4,  gpr_x5,  gpr_x6,76    gpr_x7,  gpr_x8,  gpr_x9,  gpr_x10, gpr_x11, gpr_x12, gpr_x13,77    gpr_x14, gpr_x15, gpr_x16, gpr_x17, gpr_x18, gpr_x19, gpr_x20,78    gpr_x21, gpr_x22, gpr_x23, gpr_x24, gpr_x25, gpr_x26, gpr_x27,79    gpr_x28, gpr_fp,  gpr_lr,  gpr_sp,  gpr_pc,  gpr_cpsr};80 81// Floating point registers82static uint32_t g_fpu_regnums[] = {83    fpu_v0,  fpu_v1,  fpu_v2,  fpu_v3,  fpu_v4,   fpu_v5,  fpu_v6,84    fpu_v7,  fpu_v8,  fpu_v9,  fpu_v10, fpu_v11,  fpu_v12, fpu_v13,85    fpu_v14, fpu_v15, fpu_v16, fpu_v17, fpu_v18,  fpu_v19, fpu_v20,86    fpu_v21, fpu_v22, fpu_v23, fpu_v24, fpu_v25,  fpu_v26, fpu_v27,87    fpu_v28, fpu_v29, fpu_v30, fpu_v31, fpu_fpsr, fpu_fpcr};88 89// Exception registers90 91static uint32_t g_exc_regnums[] = {exc_far, exc_esr, exc_exception};92 93static size_t k_num_register_infos = std::size(g_register_infos_arm64_le);94 95RegisterContextDarwin_arm64::RegisterContextDarwin_arm64(96    Thread &thread, uint32_t concrete_frame_idx)97    : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc(), dbg() {98  uint32_t i;99  for (i = 0; i < kNumErrors; i++) {100    gpr_errs[i] = -1;101    fpu_errs[i] = -1;102    exc_errs[i] = -1;103  }104}105 106RegisterContextDarwin_arm64::~RegisterContextDarwin_arm64() = default;107 108void RegisterContextDarwin_arm64::InvalidateAllRegisters() {109  InvalidateAllRegisterStates();110}111 112size_t RegisterContextDarwin_arm64::GetRegisterCount() {113  assert(k_num_register_infos == k_num_registers);114  return k_num_registers;115}116 117const RegisterInfo *118RegisterContextDarwin_arm64::GetRegisterInfoAtIndex(size_t reg) {119  assert(k_num_register_infos == k_num_registers);120  if (reg < k_num_registers)121    return &g_register_infos_arm64_le[reg];122  return nullptr;123}124 125size_t RegisterContextDarwin_arm64::GetRegisterInfosCount() {126  return k_num_register_infos;127}128 129const RegisterInfo *RegisterContextDarwin_arm64::GetRegisterInfos() {130  return g_register_infos_arm64_le;131}132 133// Number of registers in each register set134const size_t k_num_gpr_registers = std::size(g_gpr_regnums);135const size_t k_num_fpu_registers = std::size(g_fpu_regnums);136const size_t k_num_exc_registers = std::size(g_exc_regnums);137 138// Register set definitions. The first definitions at register set index of139// zero is for all registers, followed by other registers sets. The register140// information for the all register set need not be filled in.141static const RegisterSet g_reg_sets[] = {142    {143        "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums,144    },145    {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums},146    {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}};147 148const size_t k_num_regsets = std::size(g_reg_sets);149 150size_t RegisterContextDarwin_arm64::GetRegisterSetCount() {151  return k_num_regsets;152}153 154const RegisterSet *RegisterContextDarwin_arm64::GetRegisterSet(size_t reg_set) {155  if (reg_set < k_num_regsets)156    return &g_reg_sets[reg_set];157  return nullptr;158}159 160// Register information definitions for arm64161int RegisterContextDarwin_arm64::GetSetForNativeRegNum(int reg) {162  if (reg < fpu_v0)163    return GPRRegSet;164  else if (reg < exc_far)165    return FPURegSet;166  else if (reg < k_num_registers)167    return EXCRegSet;168  return -1;169}170 171int RegisterContextDarwin_arm64::ReadGPR(bool force) {172  int set = GPRRegSet;173  if (force || !RegisterSetIsCached(set)) {174    SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));175  }176  return GetError(GPRRegSet, Read);177}178 179int RegisterContextDarwin_arm64::ReadFPU(bool force) {180  int set = FPURegSet;181  if (force || !RegisterSetIsCached(set)) {182    SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));183  }184  return GetError(FPURegSet, Read);185}186 187int RegisterContextDarwin_arm64::ReadEXC(bool force) {188  int set = EXCRegSet;189  if (force || !RegisterSetIsCached(set)) {190    SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));191  }192  return GetError(EXCRegSet, Read);193}194 195int RegisterContextDarwin_arm64::ReadDBG(bool force) {196  int set = DBGRegSet;197  if (force || !RegisterSetIsCached(set)) {198    SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg));199  }200  return GetError(DBGRegSet, Read);201}202 203int RegisterContextDarwin_arm64::WriteGPR() {204  int set = GPRRegSet;205  if (!RegisterSetIsCached(set)) {206    SetError(set, Write, -1);207    return KERN_INVALID_ARGUMENT;208  }209  SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr));210  SetError(set, Read, -1);211  return GetError(GPRRegSet, Write);212}213 214int RegisterContextDarwin_arm64::WriteFPU() {215  int set = FPURegSet;216  if (!RegisterSetIsCached(set)) {217    SetError(set, Write, -1);218    return KERN_INVALID_ARGUMENT;219  }220  SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu));221  SetError(set, Read, -1);222  return GetError(FPURegSet, Write);223}224 225int RegisterContextDarwin_arm64::WriteEXC() {226  int set = EXCRegSet;227  if (!RegisterSetIsCached(set)) {228    SetError(set, Write, -1);229    return KERN_INVALID_ARGUMENT;230  }231  SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc));232  SetError(set, Read, -1);233  return GetError(EXCRegSet, Write);234}235 236int RegisterContextDarwin_arm64::WriteDBG() {237  int set = DBGRegSet;238  if (!RegisterSetIsCached(set)) {239    SetError(set, Write, -1);240    return KERN_INVALID_ARGUMENT;241  }242  SetError(set, Write, DoWriteDBG(GetThreadID(), set, dbg));243  SetError(set, Read, -1);244  return GetError(DBGRegSet, Write);245}246 247int RegisterContextDarwin_arm64::ReadRegisterSet(uint32_t set, bool force) {248  switch (set) {249  case GPRRegSet:250    return ReadGPR(force);251  case FPURegSet:252    return ReadFPU(force);253  case EXCRegSet:254    return ReadEXC(force);255  case DBGRegSet:256    return ReadDBG(force);257  default:258    break;259  }260  return KERN_INVALID_ARGUMENT;261}262 263int RegisterContextDarwin_arm64::WriteRegisterSet(uint32_t set) {264  // Make sure we have a valid context to set.265  if (RegisterSetIsCached(set)) {266    switch (set) {267    case GPRRegSet:268      return WriteGPR();269    case FPURegSet:270      return WriteFPU();271    case EXCRegSet:272      return WriteEXC();273    case DBGRegSet:274      return WriteDBG();275    default:276      break;277    }278  }279  return KERN_INVALID_ARGUMENT;280}281 282void RegisterContextDarwin_arm64::LogDBGRegisters(Log *log, const DBG &dbg) {283  if (log) {284    for (uint32_t i = 0; i < 16; i++)285      LLDB_LOGF(log,286                "BVR%-2u/BCR%-2u = { 0x%8.8" PRIu64 ", 0x%8.8" PRIu64287                " } WVR%-2u/WCR%-2u "288                "= { 0x%8.8" PRIu64 ", 0x%8.8" PRIu64 " }",289                i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]);290  }291}292 293bool RegisterContextDarwin_arm64::ReadRegister(const RegisterInfo *reg_info,294                                               RegisterValue &value) {295  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];296  int set = RegisterContextDarwin_arm64::GetSetForNativeRegNum(reg);297 298  if (set == -1)299    return false;300 301  if (ReadRegisterSet(set, false) != KERN_SUCCESS)302    return false;303 304  switch (reg) {305  case gpr_x0:306  case gpr_x1:307  case gpr_x2:308  case gpr_x3:309  case gpr_x4:310  case gpr_x5:311  case gpr_x6:312  case gpr_x7:313  case gpr_x8:314  case gpr_x9:315  case gpr_x10:316  case gpr_x11:317  case gpr_x12:318  case gpr_x13:319  case gpr_x14:320  case gpr_x15:321  case gpr_x16:322  case gpr_x17:323  case gpr_x18:324  case gpr_x19:325  case gpr_x20:326  case gpr_x21:327  case gpr_x22:328  case gpr_x23:329  case gpr_x24:330  case gpr_x25:331  case gpr_x26:332  case gpr_x27:333  case gpr_x28:334    value.SetUInt64(gpr.x[reg - gpr_x0]);335    break;336  case gpr_fp:337    value.SetUInt64(gpr.fp);338    break;339  case gpr_sp:340    value.SetUInt64(gpr.sp);341    break;342  case gpr_lr:343    value.SetUInt64(gpr.lr);344    break;345  case gpr_pc:346    value.SetUInt64(gpr.pc);347    break;348  case gpr_cpsr:349    value.SetUInt64(gpr.cpsr);350    break;351 352  case gpr_w0:353  case gpr_w1:354  case gpr_w2:355  case gpr_w3:356  case gpr_w4:357  case gpr_w5:358  case gpr_w6:359  case gpr_w7:360  case gpr_w8:361  case gpr_w9:362  case gpr_w10:363  case gpr_w11:364  case gpr_w12:365  case gpr_w13:366  case gpr_w14:367  case gpr_w15:368  case gpr_w16:369  case gpr_w17:370  case gpr_w18:371  case gpr_w19:372  case gpr_w20:373  case gpr_w21:374  case gpr_w22:375  case gpr_w23:376  case gpr_w24:377  case gpr_w25:378  case gpr_w26:379  case gpr_w27:380  case gpr_w28: {381    ProcessSP process_sp(m_thread.GetProcess());382    if (process_sp.get()) {383      DataExtractor regdata(&gpr.x[reg - gpr_w0], 8, process_sp->GetByteOrder(),384                            process_sp->GetAddressByteSize());385      offset_t offset = 0;386      uint64_t retval = regdata.GetMaxU64(&offset, 8);387      uint32_t retval_lower32 = static_cast<uint32_t>(retval & 0xffffffff);388      value.SetUInt32(retval_lower32);389    }390  } break;391 392  case fpu_v0:393  case fpu_v1:394  case fpu_v2:395  case fpu_v3:396  case fpu_v4:397  case fpu_v5:398  case fpu_v6:399  case fpu_v7:400  case fpu_v8:401  case fpu_v9:402  case fpu_v10:403  case fpu_v11:404  case fpu_v12:405  case fpu_v13:406  case fpu_v14:407  case fpu_v15:408  case fpu_v16:409  case fpu_v17:410  case fpu_v18:411  case fpu_v19:412  case fpu_v20:413  case fpu_v21:414  case fpu_v22:415  case fpu_v23:416  case fpu_v24:417  case fpu_v25:418  case fpu_v26:419  case fpu_v27:420  case fpu_v28:421  case fpu_v29:422  case fpu_v30:423  case fpu_v31:424    value.SetBytes(fpu.v[reg - fpu_v0].bytes, reg_info->byte_size,425                   endian::InlHostByteOrder());426    break;427 428  case fpu_s0:429  case fpu_s1:430  case fpu_s2:431  case fpu_s3:432  case fpu_s4:433  case fpu_s5:434  case fpu_s6:435  case fpu_s7:436  case fpu_s8:437  case fpu_s9:438  case fpu_s10:439  case fpu_s11:440  case fpu_s12:441  case fpu_s13:442  case fpu_s14:443  case fpu_s15:444  case fpu_s16:445  case fpu_s17:446  case fpu_s18:447  case fpu_s19:448  case fpu_s20:449  case fpu_s21:450  case fpu_s22:451  case fpu_s23:452  case fpu_s24:453  case fpu_s25:454  case fpu_s26:455  case fpu_s27:456  case fpu_s28:457  case fpu_s29:458  case fpu_s30:459  case fpu_s31: {460    ProcessSP process_sp(m_thread.GetProcess());461    if (process_sp.get()) {462      DataExtractor regdata(&fpu.v[reg - fpu_s0], 4, process_sp->GetByteOrder(),463                            process_sp->GetAddressByteSize());464      offset_t offset = 0;465      value.SetFloat(regdata.GetFloat(&offset));466    }467  } break;468 469  case fpu_d0:470  case fpu_d1:471  case fpu_d2:472  case fpu_d3:473  case fpu_d4:474  case fpu_d5:475  case fpu_d6:476  case fpu_d7:477  case fpu_d8:478  case fpu_d9:479  case fpu_d10:480  case fpu_d11:481  case fpu_d12:482  case fpu_d13:483  case fpu_d14:484  case fpu_d15:485  case fpu_d16:486  case fpu_d17:487  case fpu_d18:488  case fpu_d19:489  case fpu_d20:490  case fpu_d21:491  case fpu_d22:492  case fpu_d23:493  case fpu_d24:494  case fpu_d25:495  case fpu_d26:496  case fpu_d27:497  case fpu_d28:498  case fpu_d29:499  case fpu_d30:500  case fpu_d31: {501    ProcessSP process_sp(m_thread.GetProcess());502    if (process_sp.get()) {503      DataExtractor regdata(&fpu.v[reg - fpu_d0], 8, process_sp->GetByteOrder(),504                            process_sp->GetAddressByteSize());505      offset_t offset = 0;506      value.SetDouble(regdata.GetDouble(&offset));507    }508  } break;509 510  case fpu_fpsr:511    value.SetUInt32(fpu.fpsr);512    break;513 514  case fpu_fpcr:515    value.SetUInt32(fpu.fpcr);516    break;517 518  case exc_exception:519    value.SetUInt32(exc.exception);520    break;521  case exc_esr:522    value.SetUInt32(exc.esr);523    break;524  case exc_far:525    value.SetUInt64(exc.far);526    break;527 528  default:529    value.SetValueToInvalid();530    return false;531  }532  return true;533}534 535bool RegisterContextDarwin_arm64::WriteRegister(const RegisterInfo *reg_info,536                                                const RegisterValue &value) {537  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];538  int set = GetSetForNativeRegNum(reg);539 540  if (set == -1)541    return false;542 543  if (ReadRegisterSet(set, false) != KERN_SUCCESS)544    return false;545 546  switch (reg) {547  case gpr_x0:548  case gpr_x1:549  case gpr_x2:550  case gpr_x3:551  case gpr_x4:552  case gpr_x5:553  case gpr_x6:554  case gpr_x7:555  case gpr_x8:556  case gpr_x9:557  case gpr_x10:558  case gpr_x11:559  case gpr_x12:560  case gpr_x13:561  case gpr_x14:562  case gpr_x15:563  case gpr_x16:564  case gpr_x17:565  case gpr_x18:566  case gpr_x19:567  case gpr_x20:568  case gpr_x21:569  case gpr_x22:570  case gpr_x23:571  case gpr_x24:572  case gpr_x25:573  case gpr_x26:574  case gpr_x27:575  case gpr_x28:576  case gpr_fp:577  case gpr_sp:578  case gpr_lr:579  case gpr_pc:580  case gpr_cpsr:581    gpr.x[reg - gpr_x0] = value.GetAsUInt64();582    break;583 584  case fpu_v0:585  case fpu_v1:586  case fpu_v2:587  case fpu_v3:588  case fpu_v4:589  case fpu_v5:590  case fpu_v6:591  case fpu_v7:592  case fpu_v8:593  case fpu_v9:594  case fpu_v10:595  case fpu_v11:596  case fpu_v12:597  case fpu_v13:598  case fpu_v14:599  case fpu_v15:600  case fpu_v16:601  case fpu_v17:602  case fpu_v18:603  case fpu_v19:604  case fpu_v20:605  case fpu_v21:606  case fpu_v22:607  case fpu_v23:608  case fpu_v24:609  case fpu_v25:610  case fpu_v26:611  case fpu_v27:612  case fpu_v28:613  case fpu_v29:614  case fpu_v30:615  case fpu_v31:616    ::memcpy(fpu.v[reg - fpu_v0].bytes, value.GetBytes(),617             value.GetByteSize());618    break;619 620  case fpu_fpsr:621    fpu.fpsr = value.GetAsUInt32();622    break;623 624  case fpu_fpcr:625    fpu.fpcr = value.GetAsUInt32();626    break;627 628  case exc_exception:629    exc.exception = value.GetAsUInt32();630    break;631  case exc_esr:632    exc.esr = value.GetAsUInt32();633    break;634  case exc_far:635    exc.far = value.GetAsUInt64();636    break;637 638  default:639    return false;640  }641  return WriteRegisterSet(set) == KERN_SUCCESS;642}643 644bool RegisterContextDarwin_arm64::ReadAllRegisterValues(645    lldb::WritableDataBufferSP &data_sp) {646  data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0);647  if (ReadGPR(false) == KERN_SUCCESS && ReadFPU(false) == KERN_SUCCESS &&648      ReadEXC(false) == KERN_SUCCESS) {649    uint8_t *dst = data_sp->GetBytes();650    ::memcpy(dst, &gpr, sizeof(gpr));651    dst += sizeof(gpr);652 653    ::memcpy(dst, &fpu, sizeof(fpu));654    dst += sizeof(gpr);655 656    ::memcpy(dst, &exc, sizeof(exc));657    return true;658  }659  return false;660}661 662bool RegisterContextDarwin_arm64::WriteAllRegisterValues(663    const lldb::DataBufferSP &data_sp) {664  if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {665    const uint8_t *src = data_sp->GetBytes();666    ::memcpy(&gpr, src, sizeof(gpr));667    src += sizeof(gpr);668 669    ::memcpy(&fpu, src, sizeof(fpu));670    src += sizeof(gpr);671 672    ::memcpy(&exc, src, sizeof(exc));673    uint32_t success_count = 0;674    if (WriteGPR() == KERN_SUCCESS)675      ++success_count;676    if (WriteFPU() == KERN_SUCCESS)677      ++success_count;678    if (WriteEXC() == KERN_SUCCESS)679      ++success_count;680    return success_count == 3;681  }682  return false;683}684 685uint32_t RegisterContextDarwin_arm64::ConvertRegisterKindToRegisterNumber(686    RegisterKind kind, uint32_t reg) {687  if (kind == eRegisterKindGeneric) {688    switch (reg) {689    case LLDB_REGNUM_GENERIC_PC:690      return gpr_pc;691    case LLDB_REGNUM_GENERIC_SP:692      return gpr_sp;693    case LLDB_REGNUM_GENERIC_FP:694      return gpr_fp;695    case LLDB_REGNUM_GENERIC_RA:696      return gpr_lr;697    case LLDB_REGNUM_GENERIC_FLAGS:698      return gpr_cpsr;699    default:700      break;701    }702  } else if (kind == eRegisterKindDWARF) {703    switch (reg) {704    case arm64_dwarf::x0:705      return gpr_x0;706    case arm64_dwarf::x1:707      return gpr_x1;708    case arm64_dwarf::x2:709      return gpr_x2;710    case arm64_dwarf::x3:711      return gpr_x3;712    case arm64_dwarf::x4:713      return gpr_x4;714    case arm64_dwarf::x5:715      return gpr_x5;716    case arm64_dwarf::x6:717      return gpr_x6;718    case arm64_dwarf::x7:719      return gpr_x7;720    case arm64_dwarf::x8:721      return gpr_x8;722    case arm64_dwarf::x9:723      return gpr_x9;724    case arm64_dwarf::x10:725      return gpr_x10;726    case arm64_dwarf::x11:727      return gpr_x11;728    case arm64_dwarf::x12:729      return gpr_x12;730    case arm64_dwarf::x13:731      return gpr_x13;732    case arm64_dwarf::x14:733      return gpr_x14;734    case arm64_dwarf::x15:735      return gpr_x15;736    case arm64_dwarf::x16:737      return gpr_x16;738    case arm64_dwarf::x17:739      return gpr_x17;740    case arm64_dwarf::x18:741      return gpr_x18;742    case arm64_dwarf::x19:743      return gpr_x19;744    case arm64_dwarf::x20:745      return gpr_x20;746    case arm64_dwarf::x21:747      return gpr_x21;748    case arm64_dwarf::x22:749      return gpr_x22;750    case arm64_dwarf::x23:751      return gpr_x23;752    case arm64_dwarf::x24:753      return gpr_x24;754    case arm64_dwarf::x25:755      return gpr_x25;756    case arm64_dwarf::x26:757      return gpr_x26;758    case arm64_dwarf::x27:759      return gpr_x27;760    case arm64_dwarf::x28:761      return gpr_x28;762 763    case arm64_dwarf::fp:764      return gpr_fp;765    case arm64_dwarf::sp:766      return gpr_sp;767    case arm64_dwarf::lr:768      return gpr_lr;769    case arm64_dwarf::pc:770      return gpr_pc;771    case arm64_dwarf::cpsr:772      return gpr_cpsr;773 774    case arm64_dwarf::v0:775      return fpu_v0;776    case arm64_dwarf::v1:777      return fpu_v1;778    case arm64_dwarf::v2:779      return fpu_v2;780    case arm64_dwarf::v3:781      return fpu_v3;782    case arm64_dwarf::v4:783      return fpu_v4;784    case arm64_dwarf::v5:785      return fpu_v5;786    case arm64_dwarf::v6:787      return fpu_v6;788    case arm64_dwarf::v7:789      return fpu_v7;790    case arm64_dwarf::v8:791      return fpu_v8;792    case arm64_dwarf::v9:793      return fpu_v9;794    case arm64_dwarf::v10:795      return fpu_v10;796    case arm64_dwarf::v11:797      return fpu_v11;798    case arm64_dwarf::v12:799      return fpu_v12;800    case arm64_dwarf::v13:801      return fpu_v13;802    case arm64_dwarf::v14:803      return fpu_v14;804    case arm64_dwarf::v15:805      return fpu_v15;806    case arm64_dwarf::v16:807      return fpu_v16;808    case arm64_dwarf::v17:809      return fpu_v17;810    case arm64_dwarf::v18:811      return fpu_v18;812    case arm64_dwarf::v19:813      return fpu_v19;814    case arm64_dwarf::v20:815      return fpu_v20;816    case arm64_dwarf::v21:817      return fpu_v21;818    case arm64_dwarf::v22:819      return fpu_v22;820    case arm64_dwarf::v23:821      return fpu_v23;822    case arm64_dwarf::v24:823      return fpu_v24;824    case arm64_dwarf::v25:825      return fpu_v25;826    case arm64_dwarf::v26:827      return fpu_v26;828    case arm64_dwarf::v27:829      return fpu_v27;830    case arm64_dwarf::v28:831      return fpu_v28;832    case arm64_dwarf::v29:833      return fpu_v29;834    case arm64_dwarf::v30:835      return fpu_v30;836    case arm64_dwarf::v31:837      return fpu_v31;838 839    default:840      break;841    }842  } else if (kind == eRegisterKindEHFrame) {843    switch (reg) {844    case arm64_ehframe::x0:845      return gpr_x0;846    case arm64_ehframe::x1:847      return gpr_x1;848    case arm64_ehframe::x2:849      return gpr_x2;850    case arm64_ehframe::x3:851      return gpr_x3;852    case arm64_ehframe::x4:853      return gpr_x4;854    case arm64_ehframe::x5:855      return gpr_x5;856    case arm64_ehframe::x6:857      return gpr_x6;858    case arm64_ehframe::x7:859      return gpr_x7;860    case arm64_ehframe::x8:861      return gpr_x8;862    case arm64_ehframe::x9:863      return gpr_x9;864    case arm64_ehframe::x10:865      return gpr_x10;866    case arm64_ehframe::x11:867      return gpr_x11;868    case arm64_ehframe::x12:869      return gpr_x12;870    case arm64_ehframe::x13:871      return gpr_x13;872    case arm64_ehframe::x14:873      return gpr_x14;874    case arm64_ehframe::x15:875      return gpr_x15;876    case arm64_ehframe::x16:877      return gpr_x16;878    case arm64_ehframe::x17:879      return gpr_x17;880    case arm64_ehframe::x18:881      return gpr_x18;882    case arm64_ehframe::x19:883      return gpr_x19;884    case arm64_ehframe::x20:885      return gpr_x20;886    case arm64_ehframe::x21:887      return gpr_x21;888    case arm64_ehframe::x22:889      return gpr_x22;890    case arm64_ehframe::x23:891      return gpr_x23;892    case arm64_ehframe::x24:893      return gpr_x24;894    case arm64_ehframe::x25:895      return gpr_x25;896    case arm64_ehframe::x26:897      return gpr_x26;898    case arm64_ehframe::x27:899      return gpr_x27;900    case arm64_ehframe::x28:901      return gpr_x28;902    case arm64_ehframe::fp:903      return gpr_fp;904    case arm64_ehframe::sp:905      return gpr_sp;906    case arm64_ehframe::lr:907      return gpr_lr;908    case arm64_ehframe::pc:909      return gpr_pc;910    case arm64_ehframe::cpsr:911      return gpr_cpsr;912    }913  } else if (kind == eRegisterKindLLDB) {914    return reg;915  }916  return LLDB_INVALID_REGNUM;917}918 919uint32_t RegisterContextDarwin_arm64::NumSupportedHardwareWatchpoints() {920#if defined(__APPLE__) && (defined(__arm64__) || defined(__aarch64__))921  // autodetect how many watchpoints are supported dynamically...922  static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX;923  if (g_num_supported_hw_watchpoints == UINT32_MAX) {924    size_t len;925    uint32_t n = 0;926    len = sizeof(n);927    if (::sysctlbyname("hw.optional.watchpoint", &n, &len, NULL, 0) == 0) {928      g_num_supported_hw_watchpoints = n;929    }930  }931  return g_num_supported_hw_watchpoints;932#else933  // TODO: figure out remote case here!934  return 2;935#endif936}937 938uint32_t RegisterContextDarwin_arm64::SetHardwareWatchpoint(lldb::addr_t addr,939                                                            size_t size,940                                                            bool read,941                                                            bool write) {942  //    if (log) log->Printf943  //    ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint(addr = %8.8p,944  //    size = %u, read = %u, write = %u)", addr, size, read, write);945 946  const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();947 948  // Can't watch zero bytes949  if (size == 0)950    return LLDB_INVALID_INDEX32;951 952  // We must watch for either read or write953  if (!read && !write)954    return LLDB_INVALID_INDEX32;955 956  // Can't watch more than 4 bytes per WVR/WCR pair957  if (size > 4)958    return LLDB_INVALID_INDEX32;959 960  // We can only watch up to four bytes that follow a 4 byte aligned address961  // per watchpoint register pair. Since we have at most so we can only watch962  // until the next 4 byte boundary and we need to make sure we can properly963  // encode this.964  uint32_t addr_word_offset = addr % 4;965  //    if (log) log->Printf966  //    ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() -967  //    addr_word_offset = 0x%8.8x", addr_word_offset);968 969  uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset;970  //    if (log) log->Printf971  //    ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() - byte_mask =972  //    0x%8.8x", byte_mask);973  if (byte_mask > 0xfu)974    return LLDB_INVALID_INDEX32;975 976  // Read the debug state977  int kret = ReadDBG(false);978 979  if (kret == KERN_SUCCESS) {980    // Check to make sure we have the needed hardware support981    uint32_t i = 0;982 983    for (i = 0; i < num_hw_watchpoints; ++i) {984      if ((dbg.wcr[i] & WCR_ENABLE) == 0)985        break; // We found an available hw breakpoint slot (in i)986    }987 988    // See if we found an available hw breakpoint slot above989    if (i < num_hw_watchpoints) {990      // Make the byte_mask into a valid Byte Address Select mask991      uint32_t byte_address_select = byte_mask << 5;992      // Make sure bits 1:0 are clear in our address993      dbg.wvr[i] = addr & ~((lldb::addr_t)3);994      dbg.wcr[i] = byte_address_select |     // Which bytes that follow the IMVA995                                             // that we will watch996                   S_USER |                  // Stop only in user mode997                   (read ? WCR_LOAD : 0) |   // Stop on read access?998                   (write ? WCR_STORE : 0) | // Stop on write access?999                   WCR_ENABLE;               // Enable this watchpoint;1000 1001      kret = WriteDBG();1002      //            if (log) log->Printf1003      //            ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint()1004      //            WriteDBG() => 0x%8.8x.", kret);1005 1006      if (kret == KERN_SUCCESS)1007        return i;1008    } else {1009      //            if (log) log->Printf1010      //            ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint():1011      //            All hardware resources (%u) are in use.",1012      //            num_hw_watchpoints);1013    }1014  }1015  return LLDB_INVALID_INDEX32;1016}1017 1018bool RegisterContextDarwin_arm64::ClearHardwareWatchpoint(uint32_t hw_index) {1019  int kret = ReadDBG(false);1020 1021  const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();1022  if (kret == KERN_SUCCESS) {1023    if (hw_index < num_hw_points) {1024      dbg.wcr[hw_index] = 0;1025      //            if (log) log->Printf1026      //            ("RegisterContextDarwin_arm64::ClearHardwareWatchpoint( %u )1027      //            - WVR%u = 0x%8.8x  WCR%u = 0x%8.8x",1028      //                    hw_index,1029      //                    hw_index,1030      //                    dbg.wvr[hw_index],1031      //                    hw_index,1032      //                    dbg.wcr[hw_index]);1033 1034      kret = WriteDBG();1035 1036      if (kret == KERN_SUCCESS)1037        return true;1038    }1039  }1040  return false;1041}1042