1314564Sdim//===-- RegisterContextDarwin_arm64.cpp ---------------------------*- C++ 2314564Sdim//-*-===// 3275072Semaste// 4353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5353358Sdim// See https://llvm.org/LICENSE.txt for license information. 6353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7275072Semaste// 8275072Semaste//===----------------------------------------------------------------------===// 9275072Semaste 10275072Semaste#include "RegisterContextDarwin_arm64.h" 11341825Sdim#include "RegisterContextDarwinConstants.h" 12275072Semaste 13314564Sdim#include "lldb/Target/Process.h" 14314564Sdim#include "lldb/Target/Thread.h" 15321369Sdim#include "lldb/Utility/DataBufferHeap.h" 16321369Sdim#include "lldb/Utility/DataExtractor.h" 17321369Sdim#include "lldb/Utility/Endian.h" 18321369Sdim#include "lldb/Utility/Log.h" 19344779Sdim#include "lldb/Utility/RegisterValue.h" 20344779Sdim#include "lldb/Utility/Scalar.h" 21275072Semaste#include "llvm/ADT/STLExtras.h" 22275072Semaste#include "llvm/Support/Compiler.h" 23275072Semaste 24275072Semaste#include "Plugins/Process/Utility/InstructionUtils.h" 25275072Semaste 26353358Sdim#include <memory> 27353358Sdim 28360784Sdim#if defined(__APPLE__) && (defined(__arm64__) || defined(__aarch64__)) 29360784Sdim#include <sys/types.h> 30360784Sdim#include <sys/sysctl.h> 31275072Semaste#endif 32275072Semaste 33341825Sdim#include "Utility/ARM64_DWARF_Registers.h" 34275072Semaste 35275072Semasteusing namespace lldb; 36275072Semasteusing namespace lldb_private; 37275072Semaste 38314564Sdim#define GPR_OFFSET(idx) ((idx)*8) 39314564Sdim#define GPR_OFFSET_NAME(reg) \ 40314564Sdim (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::GPR, reg)) 41275072Semaste 42314564Sdim#define FPU_OFFSET(idx) ((idx)*16 + sizeof(RegisterContextDarwin_arm64::GPR)) 43314564Sdim#define FPU_OFFSET_NAME(reg) \ 44314564Sdim (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::FPU, reg)) 45275072Semaste 46314564Sdim#define EXC_OFFSET_NAME(reg) \ 47314564Sdim (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::EXC, reg) + \ 48314564Sdim sizeof(RegisterContextDarwin_arm64::GPR) + \ 49314564Sdim sizeof(RegisterContextDarwin_arm64::FPU)) 50314564Sdim#define DBG_OFFSET_NAME(reg) \ 51314564Sdim (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::DBG, reg) + \ 52314564Sdim sizeof(RegisterContextDarwin_arm64::GPR) + \ 53314564Sdim sizeof(RegisterContextDarwin_arm64::FPU) + \ 54314564Sdim sizeof(RegisterContextDarwin_arm64::EXC)) 55275072Semaste 56314564Sdim#define DEFINE_DBG(reg, i) \ 57314564Sdim #reg, NULL, \ 58314564Sdim sizeof(((RegisterContextDarwin_arm64::DBG *) NULL)->reg[i]), \ 59314564Sdim DBG_OFFSET_NAME(reg[i]), eEncodingUint, eFormatHex, \ 60314564Sdim {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 61314564Sdim LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 62314564Sdim LLDB_INVALID_REGNUM }, \ 63314564Sdim NULL, NULL, NULL, 0 64314564Sdim#define REG_CONTEXT_SIZE \ 65314564Sdim (sizeof(RegisterContextDarwin_arm64::GPR) + \ 66314564Sdim sizeof(RegisterContextDarwin_arm64::FPU) + \ 67314564Sdim sizeof(RegisterContextDarwin_arm64::EXC)) 68275072Semaste 69275072Semaste// Include RegisterInfos_arm64 to declare our g_register_infos_arm64 structure. 70275072Semaste#define DECLARE_REGISTER_INFOS_ARM64_STRUCT 71275072Semaste#include "RegisterInfos_arm64.h" 72275072Semaste#undef DECLARE_REGISTER_INFOS_ARM64_STRUCT 73275072Semaste 74275072Semaste// General purpose registers 75314564Sdimstatic uint32_t g_gpr_regnums[] = { 76314564Sdim gpr_x0, gpr_x1, gpr_x2, gpr_x3, gpr_x4, gpr_x5, gpr_x6, 77314564Sdim gpr_x7, gpr_x8, gpr_x9, gpr_x10, gpr_x11, gpr_x12, gpr_x13, 78314564Sdim gpr_x14, gpr_x15, gpr_x16, gpr_x17, gpr_x18, gpr_x19, gpr_x20, 79314564Sdim gpr_x21, gpr_x22, gpr_x23, gpr_x24, gpr_x25, gpr_x26, gpr_x27, 80314564Sdim gpr_x28, gpr_fp, gpr_lr, gpr_sp, gpr_pc, gpr_cpsr}; 81275072Semaste 82275072Semaste// Floating point registers 83314564Sdimstatic uint32_t g_fpu_regnums[] = { 84314564Sdim fpu_v0, fpu_v1, fpu_v2, fpu_v3, fpu_v4, fpu_v5, fpu_v6, 85314564Sdim fpu_v7, fpu_v8, fpu_v9, fpu_v10, fpu_v11, fpu_v12, fpu_v13, 86314564Sdim fpu_v14, fpu_v15, fpu_v16, fpu_v17, fpu_v18, fpu_v19, fpu_v20, 87314564Sdim fpu_v21, fpu_v22, fpu_v23, fpu_v24, fpu_v25, fpu_v26, fpu_v27, 88314564Sdim fpu_v28, fpu_v29, fpu_v30, fpu_v31, fpu_fpsr, fpu_fpcr}; 89275072Semaste 90275072Semaste// Exception registers 91275072Semaste 92314564Sdimstatic uint32_t g_exc_regnums[] = {exc_far, exc_esr, exc_exception}; 93275072Semaste 94314564Sdimstatic size_t k_num_register_infos = 95314564Sdim llvm::array_lengthof(g_register_infos_arm64_le); 96275072Semaste 97314564SdimRegisterContextDarwin_arm64::RegisterContextDarwin_arm64( 98314564Sdim Thread &thread, uint32_t concrete_frame_idx) 99314564Sdim : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() { 100314564Sdim uint32_t i; 101314564Sdim for (i = 0; i < kNumErrors; i++) { 102314564Sdim gpr_errs[i] = -1; 103314564Sdim fpu_errs[i] = -1; 104314564Sdim exc_errs[i] = -1; 105314564Sdim } 106296417Sdim} 107296417Sdim 108314564SdimRegisterContextDarwin_arm64::~RegisterContextDarwin_arm64() {} 109296417Sdim 110314564Sdimvoid RegisterContextDarwin_arm64::InvalidateAllRegisters() { 111314564Sdim InvalidateAllRegisterStates(); 112275072Semaste} 113275072Semaste 114314564Sdimsize_t RegisterContextDarwin_arm64::GetRegisterCount() { 115314564Sdim assert(k_num_register_infos == k_num_registers); 116314564Sdim return k_num_registers; 117275072Semaste} 118275072Semaste 119275072Semasteconst RegisterInfo * 120314564SdimRegisterContextDarwin_arm64::GetRegisterInfoAtIndex(size_t reg) { 121314564Sdim assert(k_num_register_infos == k_num_registers); 122314564Sdim if (reg < k_num_registers) 123314564Sdim return &g_register_infos_arm64_le[reg]; 124353358Sdim return nullptr; 125275072Semaste} 126275072Semaste 127314564Sdimsize_t RegisterContextDarwin_arm64::GetRegisterInfosCount() { 128314564Sdim return k_num_register_infos; 129275072Semaste} 130275072Semaste 131314564Sdimconst RegisterInfo *RegisterContextDarwin_arm64::GetRegisterInfos() { 132314564Sdim return g_register_infos_arm64_le; 133275072Semaste} 134275072Semaste 135275072Semaste// Number of registers in each register set 136275072Semasteconst size_t k_num_gpr_registers = llvm::array_lengthof(g_gpr_regnums); 137275072Semasteconst size_t k_num_fpu_registers = llvm::array_lengthof(g_fpu_regnums); 138275072Semasteconst size_t k_num_exc_registers = llvm::array_lengthof(g_exc_regnums); 139275072Semaste 140341825Sdim// Register set definitions. The first definitions at register set index of 141341825Sdim// zero is for all registers, followed by other registers sets. The register 142341825Sdim// information for the all register set need not be filled in. 143314564Sdimstatic const RegisterSet g_reg_sets[] = { 144314564Sdim { 145314564Sdim "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums, 146314564Sdim }, 147314564Sdim {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums}, 148314564Sdim {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}}; 149275072Semaste 150275072Semasteconst size_t k_num_regsets = llvm::array_lengthof(g_reg_sets); 151275072Semaste 152314564Sdimsize_t RegisterContextDarwin_arm64::GetRegisterSetCount() { 153314564Sdim return k_num_regsets; 154275072Semaste} 155275072Semaste 156314564Sdimconst RegisterSet *RegisterContextDarwin_arm64::GetRegisterSet(size_t reg_set) { 157314564Sdim if (reg_set < k_num_regsets) 158314564Sdim return &g_reg_sets[reg_set]; 159353358Sdim return nullptr; 160275072Semaste} 161275072Semaste 162275072Semaste// Register information definitions for arm64 163314564Sdimint RegisterContextDarwin_arm64::GetSetForNativeRegNum(int reg) { 164314564Sdim if (reg < fpu_v0) 165314564Sdim return GPRRegSet; 166314564Sdim else if (reg < exc_far) 167314564Sdim return FPURegSet; 168314564Sdim else if (reg < k_num_registers) 169314564Sdim return EXCRegSet; 170314564Sdim return -1; 171275072Semaste} 172275072Semaste 173314564Sdimint RegisterContextDarwin_arm64::ReadGPR(bool force) { 174314564Sdim int set = GPRRegSet; 175314564Sdim if (force || !RegisterSetIsCached(set)) { 176314564Sdim SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr)); 177314564Sdim } 178314564Sdim return GetError(GPRRegSet, Read); 179275072Semaste} 180275072Semaste 181314564Sdimint RegisterContextDarwin_arm64::ReadFPU(bool force) { 182314564Sdim int set = FPURegSet; 183314564Sdim if (force || !RegisterSetIsCached(set)) { 184314564Sdim SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu)); 185314564Sdim } 186314564Sdim return GetError(FPURegSet, Read); 187275072Semaste} 188275072Semaste 189314564Sdimint RegisterContextDarwin_arm64::ReadEXC(bool force) { 190314564Sdim int set = EXCRegSet; 191314564Sdim if (force || !RegisterSetIsCached(set)) { 192314564Sdim SetError(set, Read, DoReadEXC(GetThreadID(), set, exc)); 193314564Sdim } 194314564Sdim return GetError(EXCRegSet, Read); 195275072Semaste} 196275072Semaste 197314564Sdimint RegisterContextDarwin_arm64::ReadDBG(bool force) { 198314564Sdim int set = DBGRegSet; 199314564Sdim if (force || !RegisterSetIsCached(set)) { 200314564Sdim SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg)); 201314564Sdim } 202314564Sdim return GetError(DBGRegSet, Read); 203275072Semaste} 204275072Semaste 205314564Sdimint RegisterContextDarwin_arm64::WriteGPR() { 206314564Sdim int set = GPRRegSet; 207314564Sdim if (!RegisterSetIsCached(set)) { 208314564Sdim SetError(set, Write, -1); 209314564Sdim return KERN_INVALID_ARGUMENT; 210314564Sdim } 211314564Sdim SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr)); 212314564Sdim SetError(set, Read, -1); 213314564Sdim return GetError(GPRRegSet, Write); 214275072Semaste} 215275072Semaste 216314564Sdimint RegisterContextDarwin_arm64::WriteFPU() { 217314564Sdim int set = FPURegSet; 218314564Sdim if (!RegisterSetIsCached(set)) { 219314564Sdim SetError(set, Write, -1); 220314564Sdim return KERN_INVALID_ARGUMENT; 221314564Sdim } 222314564Sdim SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu)); 223314564Sdim SetError(set, Read, -1); 224314564Sdim return GetError(FPURegSet, Write); 225275072Semaste} 226275072Semaste 227314564Sdimint RegisterContextDarwin_arm64::WriteEXC() { 228314564Sdim int set = EXCRegSet; 229314564Sdim if (!RegisterSetIsCached(set)) { 230314564Sdim SetError(set, Write, -1); 231314564Sdim return KERN_INVALID_ARGUMENT; 232314564Sdim } 233314564Sdim SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc)); 234314564Sdim SetError(set, Read, -1); 235314564Sdim return GetError(EXCRegSet, Write); 236275072Semaste} 237275072Semaste 238314564Sdimint RegisterContextDarwin_arm64::WriteDBG() { 239314564Sdim int set = DBGRegSet; 240314564Sdim if (!RegisterSetIsCached(set)) { 241314564Sdim SetError(set, Write, -1); 242314564Sdim return KERN_INVALID_ARGUMENT; 243314564Sdim } 244314564Sdim SetError(set, Write, DoWriteDBG(GetThreadID(), set, dbg)); 245314564Sdim SetError(set, Read, -1); 246314564Sdim return GetError(DBGRegSet, Write); 247275072Semaste} 248275072Semaste 249314564Sdimint RegisterContextDarwin_arm64::ReadRegisterSet(uint32_t set, bool force) { 250314564Sdim switch (set) { 251314564Sdim case GPRRegSet: 252314564Sdim return ReadGPR(force); 253314564Sdim case FPURegSet: 254314564Sdim return ReadFPU(force); 255314564Sdim case EXCRegSet: 256314564Sdim return ReadEXC(force); 257314564Sdim case DBGRegSet: 258314564Sdim return ReadDBG(force); 259314564Sdim default: 260314564Sdim break; 261314564Sdim } 262314564Sdim return KERN_INVALID_ARGUMENT; 263275072Semaste} 264275072Semaste 265314564Sdimint RegisterContextDarwin_arm64::WriteRegisterSet(uint32_t set) { 266314564Sdim // Make sure we have a valid context to set. 267314564Sdim if (RegisterSetIsCached(set)) { 268314564Sdim switch (set) { 269314564Sdim case GPRRegSet: 270314564Sdim return WriteGPR(); 271314564Sdim case FPURegSet: 272314564Sdim return WriteFPU(); 273314564Sdim case EXCRegSet: 274314564Sdim return WriteEXC(); 275314564Sdim case DBGRegSet: 276314564Sdim return WriteDBG(); 277314564Sdim default: 278314564Sdim break; 279275072Semaste } 280314564Sdim } 281314564Sdim return KERN_INVALID_ARGUMENT; 282275072Semaste} 283275072Semaste 284314564Sdimvoid RegisterContextDarwin_arm64::LogDBGRegisters(Log *log, const DBG &dbg) { 285314564Sdim if (log) { 286314564Sdim for (uint32_t i = 0; i < 16; i++) 287360784Sdim LLDB_LOGF(log, 288360784Sdim "BVR%-2u/BCR%-2u = { 0x%8.8" PRIu64 ", 0x%8.8" PRIu64 289360784Sdim " } WVR%-2u/WCR%-2u " 290360784Sdim "= { 0x%8.8" PRIu64 ", 0x%8.8" PRIu64 " }", 291360784Sdim i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]); 292314564Sdim } 293275072Semaste} 294275072Semaste 295314564Sdimbool RegisterContextDarwin_arm64::ReadRegister(const RegisterInfo *reg_info, 296314564Sdim RegisterValue &value) { 297314564Sdim const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 298314564Sdim int set = RegisterContextDarwin_arm64::GetSetForNativeRegNum(reg); 299275072Semaste 300314564Sdim if (set == -1) 301314564Sdim return false; 302275072Semaste 303314564Sdim if (ReadRegisterSet(set, false) != KERN_SUCCESS) 304314564Sdim return false; 305275072Semaste 306314564Sdim switch (reg) { 307314564Sdim case gpr_x0: 308314564Sdim case gpr_x1: 309314564Sdim case gpr_x2: 310314564Sdim case gpr_x3: 311314564Sdim case gpr_x4: 312314564Sdim case gpr_x5: 313314564Sdim case gpr_x6: 314314564Sdim case gpr_x7: 315314564Sdim case gpr_x8: 316314564Sdim case gpr_x9: 317314564Sdim case gpr_x10: 318314564Sdim case gpr_x11: 319314564Sdim case gpr_x12: 320314564Sdim case gpr_x13: 321314564Sdim case gpr_x14: 322314564Sdim case gpr_x15: 323314564Sdim case gpr_x16: 324314564Sdim case gpr_x17: 325314564Sdim case gpr_x18: 326314564Sdim case gpr_x19: 327314564Sdim case gpr_x20: 328314564Sdim case gpr_x21: 329314564Sdim case gpr_x22: 330314564Sdim case gpr_x23: 331314564Sdim case gpr_x24: 332314564Sdim case gpr_x25: 333314564Sdim case gpr_x26: 334314564Sdim case gpr_x27: 335314564Sdim case gpr_x28: 336344779Sdim value.SetUInt64(gpr.x[reg - gpr_x0]); 337344779Sdim break; 338314564Sdim case gpr_fp: 339344779Sdim value.SetUInt64(gpr.fp); 340344779Sdim break; 341314564Sdim case gpr_sp: 342344779Sdim value.SetUInt64(gpr.sp); 343344779Sdim break; 344314564Sdim case gpr_lr: 345344779Sdim value.SetUInt64(gpr.lr); 346344779Sdim break; 347314564Sdim case gpr_pc: 348344779Sdim value.SetUInt64(gpr.pc); 349344779Sdim break; 350314564Sdim case gpr_cpsr: 351344779Sdim value.SetUInt64(gpr.cpsr); 352314564Sdim break; 353275072Semaste 354314564Sdim case gpr_w0: 355314564Sdim case gpr_w1: 356314564Sdim case gpr_w2: 357314564Sdim case gpr_w3: 358314564Sdim case gpr_w4: 359314564Sdim case gpr_w5: 360314564Sdim case gpr_w6: 361314564Sdim case gpr_w7: 362314564Sdim case gpr_w8: 363314564Sdim case gpr_w9: 364314564Sdim case gpr_w10: 365314564Sdim case gpr_w11: 366314564Sdim case gpr_w12: 367314564Sdim case gpr_w13: 368314564Sdim case gpr_w14: 369314564Sdim case gpr_w15: 370314564Sdim case gpr_w16: 371314564Sdim case gpr_w17: 372314564Sdim case gpr_w18: 373314564Sdim case gpr_w19: 374314564Sdim case gpr_w20: 375314564Sdim case gpr_w21: 376314564Sdim case gpr_w22: 377314564Sdim case gpr_w23: 378314564Sdim case gpr_w24: 379314564Sdim case gpr_w25: 380314564Sdim case gpr_w26: 381314564Sdim case gpr_w27: 382314564Sdim case gpr_w28: { 383314564Sdim ProcessSP process_sp(m_thread.GetProcess()); 384314564Sdim if (process_sp.get()) { 385314564Sdim DataExtractor regdata(&gpr.x[reg - gpr_w0], 8, process_sp->GetByteOrder(), 386314564Sdim process_sp->GetAddressByteSize()); 387314564Sdim offset_t offset = 0; 388314564Sdim uint64_t retval = regdata.GetMaxU64(&offset, 8); 389314564Sdim uint32_t retval_lower32 = static_cast<uint32_t>(retval & 0xffffffff); 390314564Sdim value.SetUInt32(retval_lower32); 391314564Sdim } 392314564Sdim } break; 393275072Semaste 394314564Sdim case fpu_v0: 395314564Sdim case fpu_v1: 396314564Sdim case fpu_v2: 397314564Sdim case fpu_v3: 398314564Sdim case fpu_v4: 399314564Sdim case fpu_v5: 400314564Sdim case fpu_v6: 401314564Sdim case fpu_v7: 402314564Sdim case fpu_v8: 403314564Sdim case fpu_v9: 404314564Sdim case fpu_v10: 405314564Sdim case fpu_v11: 406314564Sdim case fpu_v12: 407314564Sdim case fpu_v13: 408314564Sdim case fpu_v14: 409314564Sdim case fpu_v15: 410314564Sdim case fpu_v16: 411314564Sdim case fpu_v17: 412314564Sdim case fpu_v18: 413314564Sdim case fpu_v19: 414314564Sdim case fpu_v20: 415314564Sdim case fpu_v21: 416314564Sdim case fpu_v22: 417314564Sdim case fpu_v23: 418314564Sdim case fpu_v24: 419314564Sdim case fpu_v25: 420314564Sdim case fpu_v26: 421314564Sdim case fpu_v27: 422314564Sdim case fpu_v28: 423314564Sdim case fpu_v29: 424314564Sdim case fpu_v30: 425314564Sdim case fpu_v31: 426360784Sdim value.SetBytes(fpu.v[reg - fpu_v0].bytes, reg_info->byte_size, 427314564Sdim endian::InlHostByteOrder()); 428314564Sdim break; 429275072Semaste 430314564Sdim case fpu_s0: 431314564Sdim case fpu_s1: 432314564Sdim case fpu_s2: 433314564Sdim case fpu_s3: 434314564Sdim case fpu_s4: 435314564Sdim case fpu_s5: 436314564Sdim case fpu_s6: 437314564Sdim case fpu_s7: 438314564Sdim case fpu_s8: 439314564Sdim case fpu_s9: 440314564Sdim case fpu_s10: 441314564Sdim case fpu_s11: 442314564Sdim case fpu_s12: 443314564Sdim case fpu_s13: 444314564Sdim case fpu_s14: 445314564Sdim case fpu_s15: 446314564Sdim case fpu_s16: 447314564Sdim case fpu_s17: 448314564Sdim case fpu_s18: 449314564Sdim case fpu_s19: 450314564Sdim case fpu_s20: 451314564Sdim case fpu_s21: 452314564Sdim case fpu_s22: 453314564Sdim case fpu_s23: 454314564Sdim case fpu_s24: 455314564Sdim case fpu_s25: 456314564Sdim case fpu_s26: 457314564Sdim case fpu_s27: 458314564Sdim case fpu_s28: 459314564Sdim case fpu_s29: 460314564Sdim case fpu_s30: 461314564Sdim case fpu_s31: { 462314564Sdim ProcessSP process_sp(m_thread.GetProcess()); 463314564Sdim if (process_sp.get()) { 464314564Sdim DataExtractor regdata(&fpu.v[reg - fpu_s0], 4, process_sp->GetByteOrder(), 465314564Sdim process_sp->GetAddressByteSize()); 466314564Sdim offset_t offset = 0; 467314564Sdim value.SetFloat(regdata.GetFloat(&offset)); 468314564Sdim } 469314564Sdim } break; 470275072Semaste 471314564Sdim case fpu_d0: 472314564Sdim case fpu_d1: 473314564Sdim case fpu_d2: 474314564Sdim case fpu_d3: 475314564Sdim case fpu_d4: 476314564Sdim case fpu_d5: 477314564Sdim case fpu_d6: 478314564Sdim case fpu_d7: 479314564Sdim case fpu_d8: 480314564Sdim case fpu_d9: 481314564Sdim case fpu_d10: 482314564Sdim case fpu_d11: 483314564Sdim case fpu_d12: 484314564Sdim case fpu_d13: 485314564Sdim case fpu_d14: 486314564Sdim case fpu_d15: 487314564Sdim case fpu_d16: 488314564Sdim case fpu_d17: 489314564Sdim case fpu_d18: 490314564Sdim case fpu_d19: 491314564Sdim case fpu_d20: 492314564Sdim case fpu_d21: 493314564Sdim case fpu_d22: 494314564Sdim case fpu_d23: 495314564Sdim case fpu_d24: 496314564Sdim case fpu_d25: 497314564Sdim case fpu_d26: 498314564Sdim case fpu_d27: 499314564Sdim case fpu_d28: 500314564Sdim case fpu_d29: 501314564Sdim case fpu_d30: 502314564Sdim case fpu_d31: { 503314564Sdim ProcessSP process_sp(m_thread.GetProcess()); 504314564Sdim if (process_sp.get()) { 505360784Sdim DataExtractor regdata(&fpu.v[reg - fpu_d0], 8, process_sp->GetByteOrder(), 506314564Sdim process_sp->GetAddressByteSize()); 507314564Sdim offset_t offset = 0; 508314564Sdim value.SetDouble(regdata.GetDouble(&offset)); 509314564Sdim } 510314564Sdim } break; 511275072Semaste 512314564Sdim case fpu_fpsr: 513314564Sdim value.SetUInt32(fpu.fpsr); 514314564Sdim break; 515275072Semaste 516314564Sdim case fpu_fpcr: 517314564Sdim value.SetUInt32(fpu.fpcr); 518314564Sdim break; 519275072Semaste 520314564Sdim case exc_exception: 521314564Sdim value.SetUInt32(exc.exception); 522314564Sdim break; 523314564Sdim case exc_esr: 524314564Sdim value.SetUInt32(exc.esr); 525314564Sdim break; 526314564Sdim case exc_far: 527314564Sdim value.SetUInt64(exc.far); 528314564Sdim break; 529314564Sdim 530314564Sdim default: 531314564Sdim value.SetValueToInvalid(); 532314564Sdim return false; 533314564Sdim } 534314564Sdim return true; 535275072Semaste} 536275072Semaste 537314564Sdimbool RegisterContextDarwin_arm64::WriteRegister(const RegisterInfo *reg_info, 538314564Sdim const RegisterValue &value) { 539314564Sdim const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 540314564Sdim int set = GetSetForNativeRegNum(reg); 541275072Semaste 542314564Sdim if (set == -1) 543314564Sdim return false; 544275072Semaste 545314564Sdim if (ReadRegisterSet(set, false) != KERN_SUCCESS) 546314564Sdim return false; 547275072Semaste 548314564Sdim switch (reg) { 549314564Sdim case gpr_x0: 550314564Sdim case gpr_x1: 551314564Sdim case gpr_x2: 552314564Sdim case gpr_x3: 553314564Sdim case gpr_x4: 554314564Sdim case gpr_x5: 555314564Sdim case gpr_x6: 556314564Sdim case gpr_x7: 557314564Sdim case gpr_x8: 558314564Sdim case gpr_x9: 559314564Sdim case gpr_x10: 560314564Sdim case gpr_x11: 561314564Sdim case gpr_x12: 562314564Sdim case gpr_x13: 563314564Sdim case gpr_x14: 564314564Sdim case gpr_x15: 565314564Sdim case gpr_x16: 566314564Sdim case gpr_x17: 567314564Sdim case gpr_x18: 568314564Sdim case gpr_x19: 569314564Sdim case gpr_x20: 570314564Sdim case gpr_x21: 571314564Sdim case gpr_x22: 572314564Sdim case gpr_x23: 573314564Sdim case gpr_x24: 574314564Sdim case gpr_x25: 575314564Sdim case gpr_x26: 576314564Sdim case gpr_x27: 577314564Sdim case gpr_x28: 578314564Sdim case gpr_fp: 579314564Sdim case gpr_sp: 580314564Sdim case gpr_lr: 581314564Sdim case gpr_pc: 582314564Sdim case gpr_cpsr: 583314564Sdim gpr.x[reg - gpr_x0] = value.GetAsUInt64(); 584314564Sdim break; 585275072Semaste 586314564Sdim case fpu_v0: 587314564Sdim case fpu_v1: 588314564Sdim case fpu_v2: 589314564Sdim case fpu_v3: 590314564Sdim case fpu_v4: 591314564Sdim case fpu_v5: 592314564Sdim case fpu_v6: 593314564Sdim case fpu_v7: 594314564Sdim case fpu_v8: 595314564Sdim case fpu_v9: 596314564Sdim case fpu_v10: 597314564Sdim case fpu_v11: 598314564Sdim case fpu_v12: 599314564Sdim case fpu_v13: 600314564Sdim case fpu_v14: 601314564Sdim case fpu_v15: 602314564Sdim case fpu_v16: 603314564Sdim case fpu_v17: 604314564Sdim case fpu_v18: 605314564Sdim case fpu_v19: 606314564Sdim case fpu_v20: 607314564Sdim case fpu_v21: 608314564Sdim case fpu_v22: 609314564Sdim case fpu_v23: 610314564Sdim case fpu_v24: 611314564Sdim case fpu_v25: 612314564Sdim case fpu_v26: 613314564Sdim case fpu_v27: 614314564Sdim case fpu_v28: 615314564Sdim case fpu_v29: 616314564Sdim case fpu_v30: 617314564Sdim case fpu_v31: 618360784Sdim ::memcpy(fpu.v[reg - fpu_v0].bytes, value.GetBytes(), 619353358Sdim value.GetByteSize()); 620314564Sdim break; 621275072Semaste 622314564Sdim case fpu_fpsr: 623314564Sdim fpu.fpsr = value.GetAsUInt32(); 624314564Sdim break; 625275072Semaste 626314564Sdim case fpu_fpcr: 627314564Sdim fpu.fpcr = value.GetAsUInt32(); 628314564Sdim break; 629275072Semaste 630314564Sdim case exc_exception: 631314564Sdim exc.exception = value.GetAsUInt32(); 632314564Sdim break; 633314564Sdim case exc_esr: 634314564Sdim exc.esr = value.GetAsUInt32(); 635314564Sdim break; 636314564Sdim case exc_far: 637314564Sdim exc.far = value.GetAsUInt64(); 638314564Sdim break; 639275072Semaste 640314564Sdim default: 641314564Sdim return false; 642314564Sdim } 643314564Sdim return WriteRegisterSet(set) == KERN_SUCCESS; 644275072Semaste} 645275072Semaste 646314564Sdimbool RegisterContextDarwin_arm64::ReadAllRegisterValues( 647314564Sdim lldb::DataBufferSP &data_sp) { 648353358Sdim data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0); 649353358Sdim if (ReadGPR(false) == KERN_SUCCESS && ReadFPU(false) == KERN_SUCCESS && 650353358Sdim ReadEXC(false) == KERN_SUCCESS) { 651314564Sdim uint8_t *dst = data_sp->GetBytes(); 652314564Sdim ::memcpy(dst, &gpr, sizeof(gpr)); 653314564Sdim dst += sizeof(gpr); 654275072Semaste 655314564Sdim ::memcpy(dst, &fpu, sizeof(fpu)); 656314564Sdim dst += sizeof(gpr); 657275072Semaste 658314564Sdim ::memcpy(dst, &exc, sizeof(exc)); 659314564Sdim return true; 660314564Sdim } 661314564Sdim return false; 662275072Semaste} 663275072Semaste 664314564Sdimbool RegisterContextDarwin_arm64::WriteAllRegisterValues( 665314564Sdim const lldb::DataBufferSP &data_sp) { 666314564Sdim if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) { 667314564Sdim const uint8_t *src = data_sp->GetBytes(); 668314564Sdim ::memcpy(&gpr, src, sizeof(gpr)); 669314564Sdim src += sizeof(gpr); 670275072Semaste 671314564Sdim ::memcpy(&fpu, src, sizeof(fpu)); 672314564Sdim src += sizeof(gpr); 673275072Semaste 674314564Sdim ::memcpy(&exc, src, sizeof(exc)); 675314564Sdim uint32_t success_count = 0; 676314564Sdim if (WriteGPR() == KERN_SUCCESS) 677314564Sdim ++success_count; 678314564Sdim if (WriteFPU() == KERN_SUCCESS) 679314564Sdim ++success_count; 680314564Sdim if (WriteEXC() == KERN_SUCCESS) 681314564Sdim ++success_count; 682314564Sdim return success_count == 3; 683314564Sdim } 684314564Sdim return false; 685275072Semaste} 686275072Semaste 687314564Sdimuint32_t RegisterContextDarwin_arm64::ConvertRegisterKindToRegisterNumber( 688314564Sdim RegisterKind kind, uint32_t reg) { 689314564Sdim if (kind == eRegisterKindGeneric) { 690314564Sdim switch (reg) { 691314564Sdim case LLDB_REGNUM_GENERIC_PC: 692314564Sdim return gpr_pc; 693314564Sdim case LLDB_REGNUM_GENERIC_SP: 694314564Sdim return gpr_sp; 695314564Sdim case LLDB_REGNUM_GENERIC_FP: 696314564Sdim return gpr_fp; 697314564Sdim case LLDB_REGNUM_GENERIC_RA: 698314564Sdim return gpr_lr; 699314564Sdim case LLDB_REGNUM_GENERIC_FLAGS: 700314564Sdim return gpr_cpsr; 701314564Sdim default: 702314564Sdim break; 703275072Semaste } 704314564Sdim } else if (kind == eRegisterKindDWARF) { 705314564Sdim switch (reg) { 706314564Sdim case arm64_dwarf::x0: 707314564Sdim return gpr_x0; 708314564Sdim case arm64_dwarf::x1: 709314564Sdim return gpr_x1; 710314564Sdim case arm64_dwarf::x2: 711314564Sdim return gpr_x2; 712314564Sdim case arm64_dwarf::x3: 713314564Sdim return gpr_x3; 714314564Sdim case arm64_dwarf::x4: 715314564Sdim return gpr_x4; 716314564Sdim case arm64_dwarf::x5: 717314564Sdim return gpr_x5; 718314564Sdim case arm64_dwarf::x6: 719314564Sdim return gpr_x6; 720314564Sdim case arm64_dwarf::x7: 721314564Sdim return gpr_x7; 722314564Sdim case arm64_dwarf::x8: 723314564Sdim return gpr_x8; 724314564Sdim case arm64_dwarf::x9: 725314564Sdim return gpr_x9; 726314564Sdim case arm64_dwarf::x10: 727314564Sdim return gpr_x10; 728314564Sdim case arm64_dwarf::x11: 729314564Sdim return gpr_x11; 730314564Sdim case arm64_dwarf::x12: 731314564Sdim return gpr_x12; 732314564Sdim case arm64_dwarf::x13: 733314564Sdim return gpr_x13; 734314564Sdim case arm64_dwarf::x14: 735314564Sdim return gpr_x14; 736314564Sdim case arm64_dwarf::x15: 737314564Sdim return gpr_x15; 738314564Sdim case arm64_dwarf::x16: 739314564Sdim return gpr_x16; 740314564Sdim case arm64_dwarf::x17: 741314564Sdim return gpr_x17; 742314564Sdim case arm64_dwarf::x18: 743314564Sdim return gpr_x18; 744314564Sdim case arm64_dwarf::x19: 745314564Sdim return gpr_x19; 746314564Sdim case arm64_dwarf::x20: 747314564Sdim return gpr_x20; 748314564Sdim case arm64_dwarf::x21: 749314564Sdim return gpr_x21; 750314564Sdim case arm64_dwarf::x22: 751314564Sdim return gpr_x22; 752314564Sdim case arm64_dwarf::x23: 753314564Sdim return gpr_x23; 754314564Sdim case arm64_dwarf::x24: 755314564Sdim return gpr_x24; 756314564Sdim case arm64_dwarf::x25: 757314564Sdim return gpr_x25; 758314564Sdim case arm64_dwarf::x26: 759314564Sdim return gpr_x26; 760314564Sdim case arm64_dwarf::x27: 761314564Sdim return gpr_x27; 762314564Sdim case arm64_dwarf::x28: 763314564Sdim return gpr_x28; 764275072Semaste 765314564Sdim case arm64_dwarf::fp: 766314564Sdim return gpr_fp; 767314564Sdim case arm64_dwarf::sp: 768314564Sdim return gpr_sp; 769314564Sdim case arm64_dwarf::lr: 770314564Sdim return gpr_lr; 771314564Sdim case arm64_dwarf::pc: 772314564Sdim return gpr_pc; 773314564Sdim case arm64_dwarf::cpsr: 774314564Sdim return gpr_cpsr; 775275072Semaste 776314564Sdim case arm64_dwarf::v0: 777314564Sdim return fpu_v0; 778314564Sdim case arm64_dwarf::v1: 779314564Sdim return fpu_v1; 780314564Sdim case arm64_dwarf::v2: 781314564Sdim return fpu_v2; 782314564Sdim case arm64_dwarf::v3: 783314564Sdim return fpu_v3; 784314564Sdim case arm64_dwarf::v4: 785314564Sdim return fpu_v4; 786314564Sdim case arm64_dwarf::v5: 787314564Sdim return fpu_v5; 788314564Sdim case arm64_dwarf::v6: 789314564Sdim return fpu_v6; 790314564Sdim case arm64_dwarf::v7: 791314564Sdim return fpu_v7; 792314564Sdim case arm64_dwarf::v8: 793314564Sdim return fpu_v8; 794314564Sdim case arm64_dwarf::v9: 795314564Sdim return fpu_v9; 796314564Sdim case arm64_dwarf::v10: 797314564Sdim return fpu_v10; 798314564Sdim case arm64_dwarf::v11: 799314564Sdim return fpu_v11; 800314564Sdim case arm64_dwarf::v12: 801314564Sdim return fpu_v12; 802314564Sdim case arm64_dwarf::v13: 803314564Sdim return fpu_v13; 804314564Sdim case arm64_dwarf::v14: 805314564Sdim return fpu_v14; 806314564Sdim case arm64_dwarf::v15: 807314564Sdim return fpu_v15; 808314564Sdim case arm64_dwarf::v16: 809314564Sdim return fpu_v16; 810314564Sdim case arm64_dwarf::v17: 811314564Sdim return fpu_v17; 812314564Sdim case arm64_dwarf::v18: 813314564Sdim return fpu_v18; 814314564Sdim case arm64_dwarf::v19: 815314564Sdim return fpu_v19; 816314564Sdim case arm64_dwarf::v20: 817314564Sdim return fpu_v20; 818314564Sdim case arm64_dwarf::v21: 819314564Sdim return fpu_v21; 820314564Sdim case arm64_dwarf::v22: 821314564Sdim return fpu_v22; 822314564Sdim case arm64_dwarf::v23: 823314564Sdim return fpu_v23; 824314564Sdim case arm64_dwarf::v24: 825314564Sdim return fpu_v24; 826314564Sdim case arm64_dwarf::v25: 827314564Sdim return fpu_v25; 828314564Sdim case arm64_dwarf::v26: 829314564Sdim return fpu_v26; 830314564Sdim case arm64_dwarf::v27: 831314564Sdim return fpu_v27; 832314564Sdim case arm64_dwarf::v28: 833314564Sdim return fpu_v28; 834314564Sdim case arm64_dwarf::v29: 835314564Sdim return fpu_v29; 836314564Sdim case arm64_dwarf::v30: 837314564Sdim return fpu_v30; 838314564Sdim case arm64_dwarf::v31: 839314564Sdim return fpu_v31; 840275072Semaste 841314564Sdim default: 842314564Sdim break; 843275072Semaste } 844314564Sdim } else if (kind == eRegisterKindEHFrame) { 845314564Sdim switch (reg) { 846314564Sdim case arm64_ehframe::x0: 847314564Sdim return gpr_x0; 848314564Sdim case arm64_ehframe::x1: 849314564Sdim return gpr_x1; 850314564Sdim case arm64_ehframe::x2: 851314564Sdim return gpr_x2; 852314564Sdim case arm64_ehframe::x3: 853314564Sdim return gpr_x3; 854314564Sdim case arm64_ehframe::x4: 855314564Sdim return gpr_x4; 856314564Sdim case arm64_ehframe::x5: 857314564Sdim return gpr_x5; 858314564Sdim case arm64_ehframe::x6: 859314564Sdim return gpr_x6; 860314564Sdim case arm64_ehframe::x7: 861314564Sdim return gpr_x7; 862314564Sdim case arm64_ehframe::x8: 863314564Sdim return gpr_x8; 864314564Sdim case arm64_ehframe::x9: 865314564Sdim return gpr_x9; 866314564Sdim case arm64_ehframe::x10: 867314564Sdim return gpr_x10; 868314564Sdim case arm64_ehframe::x11: 869314564Sdim return gpr_x11; 870314564Sdim case arm64_ehframe::x12: 871314564Sdim return gpr_x12; 872314564Sdim case arm64_ehframe::x13: 873314564Sdim return gpr_x13; 874314564Sdim case arm64_ehframe::x14: 875314564Sdim return gpr_x14; 876314564Sdim case arm64_ehframe::x15: 877314564Sdim return gpr_x15; 878314564Sdim case arm64_ehframe::x16: 879314564Sdim return gpr_x16; 880314564Sdim case arm64_ehframe::x17: 881314564Sdim return gpr_x17; 882314564Sdim case arm64_ehframe::x18: 883314564Sdim return gpr_x18; 884314564Sdim case arm64_ehframe::x19: 885314564Sdim return gpr_x19; 886314564Sdim case arm64_ehframe::x20: 887314564Sdim return gpr_x20; 888314564Sdim case arm64_ehframe::x21: 889314564Sdim return gpr_x21; 890314564Sdim case arm64_ehframe::x22: 891314564Sdim return gpr_x22; 892314564Sdim case arm64_ehframe::x23: 893314564Sdim return gpr_x23; 894314564Sdim case arm64_ehframe::x24: 895314564Sdim return gpr_x24; 896314564Sdim case arm64_ehframe::x25: 897314564Sdim return gpr_x25; 898314564Sdim case arm64_ehframe::x26: 899314564Sdim return gpr_x26; 900314564Sdim case arm64_ehframe::x27: 901314564Sdim return gpr_x27; 902314564Sdim case arm64_ehframe::x28: 903314564Sdim return gpr_x28; 904314564Sdim case arm64_ehframe::fp: 905314564Sdim return gpr_fp; 906314564Sdim case arm64_ehframe::sp: 907314564Sdim return gpr_sp; 908314564Sdim case arm64_ehframe::lr: 909314564Sdim return gpr_lr; 910314564Sdim case arm64_ehframe::pc: 911314564Sdim return gpr_pc; 912314564Sdim case arm64_ehframe::cpsr: 913314564Sdim return gpr_cpsr; 914275072Semaste } 915314564Sdim } else if (kind == eRegisterKindLLDB) { 916314564Sdim return reg; 917314564Sdim } 918314564Sdim return LLDB_INVALID_REGNUM; 919275072Semaste} 920275072Semaste 921314564Sdimuint32_t RegisterContextDarwin_arm64::NumSupportedHardwareWatchpoints() { 922341825Sdim#if defined(__APPLE__) && (defined(__arm64__) || defined(__aarch64__)) 923314564Sdim // autodetect how many watchpoints are supported dynamically... 924314564Sdim static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX; 925314564Sdim if (g_num_supported_hw_watchpoints == UINT32_MAX) { 926314564Sdim size_t len; 927314564Sdim uint32_t n = 0; 928314564Sdim len = sizeof(n); 929314564Sdim if (::sysctlbyname("hw.optional.watchpoint", &n, &len, NULL, 0) == 0) { 930314564Sdim g_num_supported_hw_watchpoints = n; 931275072Semaste } 932314564Sdim } 933314564Sdim return g_num_supported_hw_watchpoints; 934275072Semaste#else 935314564Sdim // TODO: figure out remote case here! 936314564Sdim return 2; 937275072Semaste#endif 938275072Semaste} 939275072Semaste 940314564Sdimuint32_t RegisterContextDarwin_arm64::SetHardwareWatchpoint(lldb::addr_t addr, 941314564Sdim size_t size, 942314564Sdim bool read, 943314564Sdim bool write) { 944314564Sdim // if (log) log->Printf 945314564Sdim // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint(addr = %8.8p, 946314564Sdim // size = %u, read = %u, write = %u)", addr, size, read, write); 947275072Semaste 948314564Sdim const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); 949275072Semaste 950314564Sdim // Can't watch zero bytes 951314564Sdim if (size == 0) 952314564Sdim return LLDB_INVALID_INDEX32; 953275072Semaste 954314564Sdim // We must watch for either read or write 955344779Sdim if (!read && !write) 956314564Sdim return LLDB_INVALID_INDEX32; 957275072Semaste 958314564Sdim // Can't watch more than 4 bytes per WVR/WCR pair 959314564Sdim if (size > 4) 960314564Sdim return LLDB_INVALID_INDEX32; 961275072Semaste 962314564Sdim // We can only watch up to four bytes that follow a 4 byte aligned address 963314564Sdim // per watchpoint register pair. Since we have at most so we can only watch 964314564Sdim // until the next 4 byte boundary and we need to make sure we can properly 965314564Sdim // encode this. 966314564Sdim uint32_t addr_word_offset = addr % 4; 967314564Sdim // if (log) log->Printf 968314564Sdim // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() - 969314564Sdim // addr_word_offset = 0x%8.8x", addr_word_offset); 970275072Semaste 971314564Sdim uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset; 972314564Sdim // if (log) log->Printf 973314564Sdim // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() - byte_mask = 974314564Sdim // 0x%8.8x", byte_mask); 975314564Sdim if (byte_mask > 0xfu) 976314564Sdim return LLDB_INVALID_INDEX32; 977275072Semaste 978314564Sdim // Read the debug state 979314564Sdim int kret = ReadDBG(false); 980275072Semaste 981314564Sdim if (kret == KERN_SUCCESS) { 982314564Sdim // Check to make sure we have the needed hardware support 983314564Sdim uint32_t i = 0; 984275072Semaste 985314564Sdim for (i = 0; i < num_hw_watchpoints; ++i) { 986314564Sdim if ((dbg.wcr[i] & WCR_ENABLE) == 0) 987314564Sdim break; // We found an available hw breakpoint slot (in i) 988314564Sdim } 989275072Semaste 990314564Sdim // See if we found an available hw breakpoint slot above 991314564Sdim if (i < num_hw_watchpoints) { 992314564Sdim // Make the byte_mask into a valid Byte Address Select mask 993314564Sdim uint32_t byte_address_select = byte_mask << 5; 994314564Sdim // Make sure bits 1:0 are clear in our address 995314564Sdim dbg.wvr[i] = addr & ~((lldb::addr_t)3); 996314564Sdim dbg.wcr[i] = byte_address_select | // Which bytes that follow the IMVA 997314564Sdim // that we will watch 998314564Sdim S_USER | // Stop only in user mode 999314564Sdim (read ? WCR_LOAD : 0) | // Stop on read access? 1000314564Sdim (write ? WCR_STORE : 0) | // Stop on write access? 1001314564Sdim WCR_ENABLE; // Enable this watchpoint; 1002275072Semaste 1003314564Sdim kret = WriteDBG(); 1004314564Sdim // if (log) log->Printf 1005314564Sdim // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() 1006314564Sdim // WriteDBG() => 0x%8.8x.", kret); 1007275072Semaste 1008314564Sdim if (kret == KERN_SUCCESS) 1009314564Sdim return i; 1010314564Sdim } else { 1011314564Sdim // if (log) log->Printf 1012314564Sdim // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint(): 1013314564Sdim // All hardware resources (%u) are in use.", 1014314564Sdim // num_hw_watchpoints); 1015275072Semaste } 1016314564Sdim } 1017314564Sdim return LLDB_INVALID_INDEX32; 1018275072Semaste} 1019275072Semaste 1020314564Sdimbool RegisterContextDarwin_arm64::ClearHardwareWatchpoint(uint32_t hw_index) { 1021314564Sdim int kret = ReadDBG(false); 1022275072Semaste 1023314564Sdim const uint32_t num_hw_points = NumSupportedHardwareWatchpoints(); 1024314564Sdim if (kret == KERN_SUCCESS) { 1025314564Sdim if (hw_index < num_hw_points) { 1026314564Sdim dbg.wcr[hw_index] = 0; 1027314564Sdim // if (log) log->Printf 1028314564Sdim // ("RegisterContextDarwin_arm64::ClearHardwareWatchpoint( %u ) 1029314564Sdim // - WVR%u = 0x%8.8x WCR%u = 0x%8.8x", 1030314564Sdim // hw_index, 1031314564Sdim // hw_index, 1032314564Sdim // dbg.wvr[hw_index], 1033314564Sdim // hw_index, 1034314564Sdim // dbg.wcr[hw_index]); 1035275072Semaste 1036314564Sdim kret = WriteDBG(); 1037275072Semaste 1038314564Sdim if (kret == KERN_SUCCESS) 1039314564Sdim return true; 1040275072Semaste } 1041314564Sdim } 1042314564Sdim return false; 1043275072Semaste} 1044