RegisterContextDarwin_arm64.cpp revision 353358
1155408Srwatson//===-- RegisterContextDarwin_arm64.cpp ---------------------------*- C++ 2155408Srwatson//-*-===// 3188315Srwatson// 4155408Srwatson// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5155408Srwatson// See https://llvm.org/LICENSE.txt for license information. 6155408Srwatson// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7155408Srwatson// 8155408Srwatson//===----------------------------------------------------------------------===// 9155408Srwatson 10155408Srwatson#include "RegisterContextDarwin_arm64.h" 11155408Srwatson#include "RegisterContextDarwinConstants.h" 12155408Srwatson 13155408Srwatson#include "lldb/Target/Process.h" 14155408Srwatson#include "lldb/Target/Thread.h" 15155408Srwatson#include "lldb/Utility/DataBufferHeap.h" 16155408Srwatson#include "lldb/Utility/DataExtractor.h" 17155408Srwatson#include "lldb/Utility/Endian.h" 18155408Srwatson#include "lldb/Utility/Log.h" 19155408Srwatson#include "lldb/Utility/RegisterValue.h" 20155408Srwatson#include "lldb/Utility/Scalar.h" 21155408Srwatson#include "llvm/ADT/STLExtras.h" 22155408Srwatson#include "llvm/Support/Compiler.h" 23155408Srwatson 24155408Srwatson#include "Plugins/Process/Utility/InstructionUtils.h" 25155408Srwatson 26155408Srwatson#include <memory> 27155408Srwatson 28155408Srwatson// Support building against older versions of LLVM, this macro was added 29155408Srwatson// recently. 30178186Srwatson#ifndef LLVM_EXTENSION 31178186Srwatson#define LLVM_EXTENSION 32178186Srwatson#endif 33155408Srwatson 34155408Srwatson#include "Utility/ARM64_DWARF_Registers.h" 35155408Srwatson 36155408Srwatsonusing namespace lldb; 37155408Srwatsonusing namespace lldb_private; 38155408Srwatson 39155408Srwatson#define GPR_OFFSET(idx) ((idx)*8) 40155408Srwatson#define GPR_OFFSET_NAME(reg) \ 41155408Srwatson (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::GPR, reg)) 42155408Srwatson 43155408Srwatson#define FPU_OFFSET(idx) ((idx)*16 + sizeof(RegisterContextDarwin_arm64::GPR)) 44155408Srwatson#define FPU_OFFSET_NAME(reg) \ 45184488Srwatson (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::FPU, reg)) 46155408Srwatson 47155408Srwatson#define EXC_OFFSET_NAME(reg) \ 48155408Srwatson (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::EXC, reg) + \ 49155408Srwatson sizeof(RegisterContextDarwin_arm64::GPR) + \ 50184508Srwatson sizeof(RegisterContextDarwin_arm64::FPU)) 51155408Srwatson#define DBG_OFFSET_NAME(reg) \ 52155408Srwatson (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::DBG, reg) + \ 53155408Srwatson sizeof(RegisterContextDarwin_arm64::GPR) + \ 54155408Srwatson sizeof(RegisterContextDarwin_arm64::FPU) + \ 55156880Srwatson sizeof(RegisterContextDarwin_arm64::EXC)) 56155408Srwatson 57155408Srwatson#define DEFINE_DBG(reg, i) \ 58155408Srwatson #reg, NULL, \ 59155408Srwatson sizeof(((RegisterContextDarwin_arm64::DBG *) NULL)->reg[i]), \ 60184545Srwatson DBG_OFFSET_NAME(reg[i]), eEncodingUint, eFormatHex, \ 61184545Srwatson {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 62184545Srwatson LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 63184545Srwatson LLDB_INVALID_REGNUM }, \ 64155408Srwatson NULL, NULL, NULL, 0 65155408Srwatson#define REG_CONTEXT_SIZE \ 66155408Srwatson (sizeof(RegisterContextDarwin_arm64::GPR) + \ 67155408Srwatson sizeof(RegisterContextDarwin_arm64::FPU) + \ 68155408Srwatson sizeof(RegisterContextDarwin_arm64::EXC)) 69155408Srwatson 70155408Srwatson// Include RegisterInfos_arm64 to declare our g_register_infos_arm64 structure. 71155408Srwatson#define DECLARE_REGISTER_INFOS_ARM64_STRUCT 72174894Swkoszek#include "RegisterInfos_arm64.h" 73159269Srwatson#undef DECLARE_REGISTER_INFOS_ARM64_STRUCT 74155408Srwatson 75155408Srwatson// General purpose registers 76155408Srwatsonstatic uint32_t g_gpr_regnums[] = { 77155408Srwatson gpr_x0, gpr_x1, gpr_x2, gpr_x3, gpr_x4, gpr_x5, gpr_x6, 78156883Srwatson gpr_x7, gpr_x8, gpr_x9, gpr_x10, gpr_x11, gpr_x12, gpr_x13, 79188315Srwatson gpr_x14, gpr_x15, gpr_x16, gpr_x17, gpr_x18, gpr_x19, gpr_x20, 80155408Srwatson gpr_x21, gpr_x22, gpr_x23, gpr_x24, gpr_x25, gpr_x26, gpr_x27, 81155408Srwatson gpr_x28, gpr_fp, gpr_lr, gpr_sp, gpr_pc, gpr_cpsr}; 82155408Srwatson 83155408Srwatson// Floating point registers 84155408Srwatsonstatic uint32_t g_fpu_regnums[] = { 85155408Srwatson fpu_v0, fpu_v1, fpu_v2, fpu_v3, fpu_v4, fpu_v5, fpu_v6, 86155408Srwatson fpu_v7, fpu_v8, fpu_v9, fpu_v10, fpu_v11, fpu_v12, fpu_v13, 87155408Srwatson fpu_v14, fpu_v15, fpu_v16, fpu_v17, fpu_v18, fpu_v19, fpu_v20, 88155408Srwatson fpu_v21, fpu_v22, fpu_v23, fpu_v24, fpu_v25, fpu_v26, fpu_v27, 89155408Srwatson fpu_v28, fpu_v29, fpu_v30, fpu_v31, fpu_fpsr, fpu_fpcr}; 90155408Srwatson 91155408Srwatson// Exception registers 92159269Srwatson 93159269Srwatsonstatic uint32_t g_exc_regnums[] = {exc_far, exc_esr, exc_exception}; 94159269Srwatson 95159269Srwatsonstatic size_t k_num_register_infos = 96159269Srwatson llvm::array_lengthof(g_register_infos_arm64_le); 97159269Srwatson 98159269SrwatsonRegisterContextDarwin_arm64::RegisterContextDarwin_arm64( 99159269Srwatson Thread &thread, uint32_t concrete_frame_idx) 100159269Srwatson : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() { 101159269Srwatson uint32_t i; 102159269Srwatson for (i = 0; i < kNumErrors; i++) { 103159269Srwatson gpr_errs[i] = -1; 104159269Srwatson fpu_errs[i] = -1; 105159269Srwatson exc_errs[i] = -1; 106159269Srwatson } 107159269Srwatson} 108159269Srwatson 109155408SrwatsonRegisterContextDarwin_arm64::~RegisterContextDarwin_arm64() {} 110155408Srwatson 111155408Srwatsonvoid RegisterContextDarwin_arm64::InvalidateAllRegisters() { 112155408Srwatson InvalidateAllRegisterStates(); 113155408Srwatson} 114155408Srwatson 115155408Srwatsonsize_t RegisterContextDarwin_arm64::GetRegisterCount() { 116155408Srwatson assert(k_num_register_infos == k_num_registers); 117155408Srwatson return k_num_registers; 118155408Srwatson} 119155408Srwatson 120155408Srwatsonconst RegisterInfo * 121184488SrwatsonRegisterContextDarwin_arm64::GetRegisterInfoAtIndex(size_t reg) { 122184488Srwatson assert(k_num_register_infos == k_num_registers); 123184488Srwatson if (reg < k_num_registers) 124184508Srwatson return &g_register_infos_arm64_le[reg]; 125184488Srwatson return nullptr; 126184488Srwatson} 127184508Srwatson 128184508Srwatsonsize_t RegisterContextDarwin_arm64::GetRegisterInfosCount() { 129184508Srwatson return k_num_register_infos; 130184508Srwatson} 131184508Srwatson 132184508Srwatsonconst RegisterInfo *RegisterContextDarwin_arm64::GetRegisterInfos() { 133184508Srwatson return g_register_infos_arm64_le; 134184508Srwatson} 135184488Srwatson 136184488Srwatson// Number of registers in each register set 137184488Srwatsonconst size_t k_num_gpr_registers = llvm::array_lengthof(g_gpr_regnums); 138184488Srwatsonconst size_t k_num_fpu_registers = llvm::array_lengthof(g_fpu_regnums); 139184488Srwatsonconst size_t k_num_exc_registers = llvm::array_lengthof(g_exc_regnums); 140184536Srwatson 141184536Srwatson// Register set definitions. The first definitions at register set index of 142184536Srwatson// zero is for all registers, followed by other registers sets. The register 143184536Srwatson// information for the all register set need not be filled in. 144184536Srwatsonstatic const RegisterSet g_reg_sets[] = { 145184536Srwatson { 146184536Srwatson "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums, 147155408Srwatson }, 148155408Srwatson {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums}, 149184536Srwatson {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}}; 150184536Srwatson 151155408Srwatsonconst size_t k_num_regsets = llvm::array_lengthof(g_reg_sets); 152184540Srwatson 153184540Srwatsonsize_t RegisterContextDarwin_arm64::GetRegisterSetCount() { 154184540Srwatson return k_num_regsets; 155155408Srwatson} 156155408Srwatson 157155408Srwatsonconst RegisterSet *RegisterContextDarwin_arm64::GetRegisterSet(size_t reg_set) { 158155408Srwatson if (reg_set < k_num_regsets) 159159269Srwatson return &g_reg_sets[reg_set]; 160159269Srwatson return nullptr; 161159269Srwatson} 162159269Srwatson 163159269Srwatson// Register information definitions for arm64 164159269Srwatsonint RegisterContextDarwin_arm64::GetSetForNativeRegNum(int reg) { 165159269Srwatson if (reg < fpu_v0) 166159269Srwatson return GPRRegSet; 167159269Srwatson else if (reg < exc_far) 168159269Srwatson return FPURegSet; 169159269Srwatson else if (reg < k_num_registers) 170184508Srwatson return EXCRegSet; 171184508Srwatson return -1; 172186662Srwatson} 173186662Srwatson 174159269Srwatsonint RegisterContextDarwin_arm64::ReadGPR(bool force) { 175155408Srwatson int set = GPRRegSet; 176155408Srwatson if (force || !RegisterSetIsCached(set)) { 177159269Srwatson SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr)); 178159269Srwatson } 179159269Srwatson return GetError(GPRRegSet, Read); 180155408Srwatson} 181155408Srwatson 182155408Srwatsonint RegisterContextDarwin_arm64::ReadFPU(bool force) { 183184508Srwatson int set = FPURegSet; 184184508Srwatson if (force || !RegisterSetIsCached(set)) { 185184508Srwatson SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu)); 186184508Srwatson } 187184508Srwatson return GetError(FPURegSet, Read); 188184508Srwatson} 189184508Srwatson 190184488Srwatsonint RegisterContextDarwin_arm64::ReadEXC(bool force) { 191184508Srwatson int set = EXCRegSet; 192184508Srwatson if (force || !RegisterSetIsCached(set)) { 193184508Srwatson SetError(set, Read, DoReadEXC(GetThreadID(), set, exc)); 194184508Srwatson } 195184508Srwatson return GetError(EXCRegSet, Read); 196184508Srwatson} 197155408Srwatson 198184488Srwatsonint RegisterContextDarwin_arm64::ReadDBG(bool force) { 199184488Srwatson int set = DBGRegSet; 200184488Srwatson if (force || !RegisterSetIsCached(set)) { 201184488Srwatson SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg)); 202155408Srwatson } 203155408Srwatson return GetError(DBGRegSet, Read); 204184488Srwatson} 205155408Srwatson 206184488Srwatsonint RegisterContextDarwin_arm64::WriteGPR() { 207184488Srwatson int set = GPRRegSet; 208184488Srwatson if (!RegisterSetIsCached(set)) { 209184488Srwatson SetError(set, Write, -1); 210184488Srwatson return KERN_INVALID_ARGUMENT; 211184488Srwatson } 212184488Srwatson SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr)); 213184488Srwatson SetError(set, Read, -1); 214155408Srwatson return GetError(GPRRegSet, Write); 215155408Srwatson} 216155408Srwatson 217155408Srwatsonint RegisterContextDarwin_arm64::WriteFPU() { 218155408Srwatson int set = FPURegSet; 219155408Srwatson if (!RegisterSetIsCached(set)) { 220155408Srwatson SetError(set, Write, -1); 221155408Srwatson return KERN_INVALID_ARGUMENT; 222155408Srwatson } 223155408Srwatson SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu)); 224155408Srwatson SetError(set, Read, -1); 225155408Srwatson return GetError(FPURegSet, Write); 226155408Srwatson} 227155408Srwatson 228155408Srwatsonint RegisterContextDarwin_arm64::WriteEXC() { 229155408Srwatson int set = EXCRegSet; 230161582Srwatson if (!RegisterSetIsCached(set)) { 231155408Srwatson SetError(set, Write, -1); 232155408Srwatson return KERN_INVALID_ARGUMENT; 233155408Srwatson } 234191143Srwatson SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc)); 235155408Srwatson SetError(set, Read, -1); 236155408Srwatson return GetError(EXCRegSet, Write); 237155408Srwatson} 238155408Srwatson 239155408Srwatsonint RegisterContextDarwin_arm64::WriteDBG() { 240161582Srwatson int set = DBGRegSet; 241155408Srwatson if (!RegisterSetIsCached(set)) { 242155408Srwatson SetError(set, Write, -1); 243155408Srwatson return KERN_INVALID_ARGUMENT; 244161582Srwatson } 245161582Srwatson SetError(set, Write, DoWriteDBG(GetThreadID(), set, dbg)); 246161582Srwatson SetError(set, Read, -1); 247161582Srwatson return GetError(DBGRegSet, Write); 248161582Srwatson} 249161582Srwatson 250161582Srwatsonint RegisterContextDarwin_arm64::ReadRegisterSet(uint32_t set, bool force) { 251161582Srwatson switch (set) { 252161582Srwatson case GPRRegSet: 253161582Srwatson return ReadGPR(force); 254155408Srwatson case FPURegSet: 255155408Srwatson return ReadFPU(force); 256155408Srwatson case EXCRegSet: 257155408Srwatson return ReadEXC(force); 258155408Srwatson case DBGRegSet: 259155408Srwatson return ReadDBG(force); 260155408Srwatson default: 261155408Srwatson break; 262155408Srwatson } 263155408Srwatson return KERN_INVALID_ARGUMENT; 264155408Srwatson} 265155408Srwatson 266155408Srwatsonint RegisterContextDarwin_arm64::WriteRegisterSet(uint32_t set) { 267155408Srwatson // Make sure we have a valid context to set. 268155408Srwatson if (RegisterSetIsCached(set)) { 269155408Srwatson switch (set) { 270155408Srwatson case GPRRegSet: 271155408Srwatson return WriteGPR(); 272155408Srwatson case FPURegSet: 273155408Srwatson return WriteFPU(); 274159269Srwatson case EXCRegSet: 275159269Srwatson return WriteEXC(); 276159269Srwatson case DBGRegSet: 277159269Srwatson return WriteDBG(); 278159269Srwatson default: 279159269Srwatson break; 280159269Srwatson } 281184488Srwatson } 282159269Srwatson return KERN_INVALID_ARGUMENT; 283159269Srwatson} 284159269Srwatson 285159269Srwatsonvoid RegisterContextDarwin_arm64::LogDBGRegisters(Log *log, const DBG &dbg) { 286159269Srwatson if (log) { 287159269Srwatson for (uint32_t i = 0; i < 16; i++) 288159269Srwatson log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8" PRIu64 ", 0x%8.8" PRIu64 289159269Srwatson " } WVR%-2u/WCR%-2u " 290159269Srwatson "= { 0x%8.8" PRIu64 ", 0x%8.8" PRIu64 " }", 291159269Srwatson i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]); 292159269Srwatson } 293159269Srwatson} 294159269Srwatson 295159269Srwatsonbool RegisterContextDarwin_arm64::ReadRegister(const RegisterInfo *reg_info, 296159269Srwatson RegisterValue &value) { 297159269Srwatson const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 298159269Srwatson int set = RegisterContextDarwin_arm64::GetSetForNativeRegNum(reg); 299159269Srwatson 300184488Srwatson if (set == -1) 301159269Srwatson return false; 302159269Srwatson 303159269Srwatson if (ReadRegisterSet(set, false) != KERN_SUCCESS) 304159269Srwatson return false; 305159269Srwatson 306159269Srwatson switch (reg) { 307184488Srwatson case gpr_x0: 308159269Srwatson case gpr_x1: 309159269Srwatson case gpr_x2: 310159269Srwatson case gpr_x3: 311159269Srwatson case gpr_x4: 312159269Srwatson case gpr_x5: 313159269Srwatson case gpr_x6: 314159269Srwatson case gpr_x7: 315159269Srwatson case gpr_x8: 316159269Srwatson case gpr_x9: 317159269Srwatson case gpr_x10: 318159269Srwatson case gpr_x11: 319159269Srwatson case gpr_x12: 320159269Srwatson case gpr_x13: 321159269Srwatson case gpr_x14: 322159269Srwatson case gpr_x15: 323159269Srwatson case gpr_x16: 324159269Srwatson case gpr_x17: 325184488Srwatson case gpr_x18: 326159269Srwatson case gpr_x19: 327159269Srwatson case gpr_x20: 328159269Srwatson case gpr_x21: 329159269Srwatson case gpr_x22: 330159269Srwatson case gpr_x23: 331159269Srwatson case gpr_x24: 332159269Srwatson case gpr_x25: 333159269Srwatson case gpr_x26: 334184488Srwatson case gpr_x27: 335159269Srwatson case gpr_x28: 336159269Srwatson value.SetUInt64(gpr.x[reg - gpr_x0]); 337159269Srwatson break; 338159269Srwatson case gpr_fp: 339159269Srwatson value.SetUInt64(gpr.fp); 340159269Srwatson break; 341159269Srwatson case gpr_sp: 342159269Srwatson value.SetUInt64(gpr.sp); 343159269Srwatson break; 344159269Srwatson case gpr_lr: 345159269Srwatson value.SetUInt64(gpr.lr); 346159269Srwatson break; 347159269Srwatson case gpr_pc: 348184488Srwatson value.SetUInt64(gpr.pc); 349159269Srwatson break; 350159269Srwatson case gpr_cpsr: 351159269Srwatson value.SetUInt64(gpr.cpsr); 352159269Srwatson break; 353159269Srwatson 354159269Srwatson case gpr_w0: 355184488Srwatson case gpr_w1: 356159269Srwatson case gpr_w2: 357159269Srwatson case gpr_w3: 358159269Srwatson case gpr_w4: 359159269Srwatson case gpr_w5: 360159269Srwatson case gpr_w6: 361159269Srwatson case gpr_w7: 362159269Srwatson case gpr_w8: 363159269Srwatson case gpr_w9: 364159269Srwatson case gpr_w10: 365159269Srwatson case gpr_w11: 366159269Srwatson case gpr_w12: 367159269Srwatson case gpr_w13: 368159269Srwatson case gpr_w14: 369184488Srwatson case gpr_w15: 370159269Srwatson case gpr_w16: 371159269Srwatson case gpr_w17: 372159269Srwatson case gpr_w18: 373159269Srwatson case gpr_w19: 374159269Srwatson case gpr_w20: 375159269Srwatson case gpr_w21: 376159269Srwatson case gpr_w22: 377159269Srwatson case gpr_w23: 378159269Srwatson case gpr_w24: 379159269Srwatson case gpr_w25: 380159269Srwatson case gpr_w26: 381184488Srwatson case gpr_w27: 382159269Srwatson case gpr_w28: { 383184488Srwatson ProcessSP process_sp(m_thread.GetProcess()); 384159269Srwatson if (process_sp.get()) { 385159269Srwatson DataExtractor regdata(&gpr.x[reg - gpr_w0], 8, process_sp->GetByteOrder(), 386170196Srwatson process_sp->GetAddressByteSize()); 387159269Srwatson offset_t offset = 0; 388159269Srwatson uint64_t retval = regdata.GetMaxU64(&offset, 8); 389159269Srwatson uint32_t retval_lower32 = static_cast<uint32_t>(retval & 0xffffffff); 390159269Srwatson value.SetUInt32(retval_lower32); 391159269Srwatson } 392159269Srwatson } break; 393159269Srwatson 394159269Srwatson case fpu_v0: 395159269Srwatson case fpu_v1: 396159269Srwatson case fpu_v2: 397159269Srwatson case fpu_v3: 398159269Srwatson case fpu_v4: 399159269Srwatson case fpu_v5: 400159269Srwatson case fpu_v6: 401159269Srwatson case fpu_v7: 402184488Srwatson case fpu_v8: 403159269Srwatson case fpu_v9: 404159269Srwatson case fpu_v10: 405159269Srwatson case fpu_v11: 406159269Srwatson case fpu_v12: 407159269Srwatson case fpu_v13: 408159269Srwatson case fpu_v14: 409159269Srwatson case fpu_v15: 410159269Srwatson case fpu_v16: 411159269Srwatson case fpu_v17: 412159269Srwatson case fpu_v18: 413159269Srwatson case fpu_v19: 414159269Srwatson case fpu_v20: 415159269Srwatson case fpu_v21: 416159269Srwatson case fpu_v22: 417159269Srwatson case fpu_v23: 418159269Srwatson case fpu_v24: 419159269Srwatson case fpu_v25: 420159269Srwatson case fpu_v26: 421159269Srwatson case fpu_v27: 422159269Srwatson case fpu_v28: 423159269Srwatson case fpu_v29: 424159269Srwatson case fpu_v30: 425159269Srwatson case fpu_v31: 426159269Srwatson value.SetBytes(fpu.v[reg - fpu_v0].bytes.buffer, reg_info->byte_size, 427159269Srwatson endian::InlHostByteOrder()); 428159269Srwatson break; 429159269Srwatson 430159269Srwatson case fpu_s0: 431159269Srwatson case fpu_s1: 432159269Srwatson case fpu_s2: 433159269Srwatson case fpu_s3: 434159269Srwatson case fpu_s4: 435159269Srwatson case fpu_s5: 436159269Srwatson case fpu_s6: 437159269Srwatson case fpu_s7: 438159269Srwatson case fpu_s8: 439186825Srwatson case fpu_s9: 440186825Srwatson case fpu_s10: 441186825Srwatson case fpu_s11: 442186825Srwatson case fpu_s12: 443184488Srwatson case fpu_s13: 444159269Srwatson case fpu_s14: 445184488Srwatson case fpu_s15: 446159269Srwatson case fpu_s16: 447159269Srwatson case fpu_s17: 448184488Srwatson case fpu_s18: 449184488Srwatson case fpu_s19: 450159269Srwatson case fpu_s20: 451159269Srwatson case fpu_s21: 452184488Srwatson case fpu_s22: 453159269Srwatson case fpu_s23: 454184488Srwatson case fpu_s24: 455159269Srwatson case fpu_s25: 456159269Srwatson case fpu_s26: 457159269Srwatson case fpu_s27: 458159269Srwatson case fpu_s28: 459159269Srwatson case fpu_s29: 460184489Srwatson case fpu_s30: 461184489Srwatson case fpu_s31: { 462155408Srwatson ProcessSP process_sp(m_thread.GetProcess()); 463155408Srwatson if (process_sp.get()) { 464155408Srwatson DataExtractor regdata(&fpu.v[reg - fpu_s0], 4, process_sp->GetByteOrder(), 465155408Srwatson process_sp->GetAddressByteSize()); 466184489Srwatson offset_t offset = 0; 467155408Srwatson value.SetFloat(regdata.GetFloat(&offset)); 468184488Srwatson } 469155408Srwatson } break; 470184489Srwatson 471184489Srwatson case fpu_d0: 472184489Srwatson case fpu_d1: 473184489Srwatson case fpu_d2: 474184489Srwatson case fpu_d3: 475184489Srwatson case fpu_d4: 476155408Srwatson case fpu_d5: 477155408Srwatson case fpu_d6: 478155408Srwatson case fpu_d7: 479156292Srwatson case fpu_d8: 480155408Srwatson case fpu_d9: 481155408Srwatson case fpu_d10: 482155408Srwatson case fpu_d11: 483155408Srwatson case fpu_d12: 484155408Srwatson case fpu_d13: 485155408Srwatson case fpu_d14: 486155408Srwatson case fpu_d15: 487155408Srwatson case fpu_d16: 488155408Srwatson case fpu_d17: 489155408Srwatson case fpu_d18: 490155408Srwatson case fpu_d19: 491155408Srwatson case fpu_d20: 492155408Srwatson case fpu_d21: 493155408Srwatson case fpu_d22: 494155408Srwatson case fpu_d23: 495155408Srwatson case fpu_d24: 496155408Srwatson case fpu_d25: 497184536Srwatson case fpu_d26: 498155408Srwatson case fpu_d27: 499161582Srwatson case fpu_d28: 500155408Srwatson case fpu_d29: 501155408Srwatson case fpu_d30: 502184488Srwatson case fpu_d31: { 503155408Srwatson ProcessSP process_sp(m_thread.GetProcess()); 504155408Srwatson if (process_sp.get()) { 505155408Srwatson DataExtractor regdata(&fpu.v[reg - fpu_s0], 8, process_sp->GetByteOrder(), 506155408Srwatson process_sp->GetAddressByteSize()); 507155408Srwatson offset_t offset = 0; 508155408Srwatson value.SetDouble(regdata.GetDouble(&offset)); 509155408Srwatson } 510159269Srwatson } break; 511159269Srwatson 512155408Srwatson case fpu_fpsr: 513155408Srwatson value.SetUInt32(fpu.fpsr); 514155408Srwatson break; 515155408Srwatson 516184488Srwatson case fpu_fpcr: 517155408Srwatson value.SetUInt32(fpu.fpcr); 518155408Srwatson break; 519155408Srwatson 520155408Srwatson case exc_exception: 521184488Srwatson value.SetUInt32(exc.exception); 522159269Srwatson break; 523184488Srwatson case exc_esr: 524159269Srwatson value.SetUInt32(exc.esr); 525159269Srwatson break; 526159269Srwatson case exc_far: 527184488Srwatson value.SetUInt64(exc.far); 528159269Srwatson break; 529184488Srwatson 530184488Srwatson default: 531184488Srwatson value.SetValueToInvalid(); 532159269Srwatson return false; 533159269Srwatson } 534159269Srwatson return true; 535159269Srwatson} 536159269Srwatson 537159269Srwatsonbool RegisterContextDarwin_arm64::WriteRegister(const RegisterInfo *reg_info, 538159269Srwatson const RegisterValue &value) { 539159269Srwatson const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 540159269Srwatson int set = GetSetForNativeRegNum(reg); 541159269Srwatson 542159269Srwatson if (set == -1) 543159269Srwatson return false; 544159269Srwatson 545159269Srwatson if (ReadRegisterSet(set, false) != KERN_SUCCESS) 546159269Srwatson return false; 547159269Srwatson 548159269Srwatson switch (reg) { 549184488Srwatson case gpr_x0: 550159269Srwatson case gpr_x1: 551159269Srwatson case gpr_x2: 552159269Srwatson case gpr_x3: 553159269Srwatson case gpr_x4: 554184488Srwatson case gpr_x5: 555184488Srwatson case gpr_x6: 556184488Srwatson case gpr_x7: 557155408Srwatson case gpr_x8: 558184488Srwatson case gpr_x9: 559184488Srwatson case gpr_x10: 560184488Srwatson case gpr_x11: 561184488Srwatson case gpr_x12: 562184488Srwatson case gpr_x13: 563155408Srwatson case gpr_x14: 564155408Srwatson case gpr_x15: 565155408Srwatson case gpr_x16: 566155408Srwatson case gpr_x17: 567155408Srwatson case gpr_x18: 568155408Srwatson case gpr_x19: 569155408Srwatson case gpr_x20: 570155408Srwatson case gpr_x21: 571155408Srwatson case gpr_x22: 572155408Srwatson case gpr_x23: 573155408Srwatson case gpr_x24: 574155408Srwatson case gpr_x25: 575184488Srwatson case gpr_x26: 576155408Srwatson case gpr_x27: 577155408Srwatson case gpr_x28: 578155408Srwatson case gpr_fp: 579155408Srwatson case gpr_sp: 580155408Srwatson case gpr_lr: 581155408Srwatson case gpr_pc: 582193951Skib case gpr_cpsr: 583184488Srwatson gpr.x[reg - gpr_x0] = value.GetAsUInt64(); 584184508Srwatson break; 585184488Srwatson 586159269Srwatson case fpu_v0: 587159269Srwatson case fpu_v1: 588159269Srwatson case fpu_v2: 589159269Srwatson case fpu_v3: 590159269Srwatson case fpu_v4: 591159269Srwatson case fpu_v5: 592159269Srwatson case fpu_v6: 593159269Srwatson case fpu_v7: 594159269Srwatson case fpu_v8: 595159269Srwatson case fpu_v9: 596159269Srwatson case fpu_v10: 597159269Srwatson case fpu_v11: 598159269Srwatson case fpu_v12: 599161582Srwatson case fpu_v13: 600161582Srwatson case fpu_v14: 601161582Srwatson case fpu_v15: 602155408Srwatson case fpu_v16: 603155408Srwatson case fpu_v17: 604155408Srwatson case fpu_v18: 605159269Srwatson case fpu_v19: 606155408Srwatson case fpu_v20: 607155408Srwatson case fpu_v21: 608155408Srwatson case fpu_v22: 609155408Srwatson case fpu_v23: 610159269Srwatson case fpu_v24: 611155408Srwatson case fpu_v25: 612155408Srwatson case fpu_v26: 613159269Srwatson case fpu_v27: 614155408Srwatson case fpu_v28: 615155408Srwatson case fpu_v29: 616155408Srwatson case fpu_v30: 617184488Srwatson case fpu_v31: 618155408Srwatson ::memcpy(fpu.v[reg - fpu_v0].bytes.buffer, value.GetBytes(), 619155408Srwatson value.GetByteSize()); 620155408Srwatson break; 621184536Srwatson 622155408Srwatson case fpu_fpsr: 623155408Srwatson fpu.fpsr = value.GetAsUInt32(); 624155408Srwatson break; 625184536Srwatson 626184536Srwatson case fpu_fpcr: 627184536Srwatson fpu.fpcr = value.GetAsUInt32(); 628184536Srwatson break; 629159269Srwatson 630159269Srwatson case exc_exception: 631159269Srwatson exc.exception = value.GetAsUInt32(); 632159269Srwatson break; 633184488Srwatson case exc_esr: 634184488Srwatson exc.esr = value.GetAsUInt32(); 635184488Srwatson break; 636159269Srwatson case exc_far: 637159269Srwatson exc.far = value.GetAsUInt64(); 638159269Srwatson break; 639159269Srwatson 640159269Srwatson default: 641184488Srwatson return false; 642184488Srwatson } 643159269Srwatson return WriteRegisterSet(set) == KERN_SUCCESS; 644159269Srwatson} 645159269Srwatson 646184488Srwatsonbool RegisterContextDarwin_arm64::ReadAllRegisterValues( 647184508Srwatson lldb::DataBufferSP &data_sp) { 648184488Srwatson data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0); 649225177Sattilio if (ReadGPR(false) == KERN_SUCCESS && ReadFPU(false) == KERN_SUCCESS && 650161582Srwatson ReadEXC(false) == KERN_SUCCESS) { 651159269Srwatson uint8_t *dst = data_sp->GetBytes(); 652155408Srwatson ::memcpy(dst, &gpr, sizeof(gpr)); 653155408Srwatson dst += sizeof(gpr); 654155408Srwatson 655155408Srwatson ::memcpy(dst, &fpu, sizeof(fpu)); 656155408Srwatson dst += sizeof(gpr); 657155408Srwatson 658155408Srwatson ::memcpy(dst, &exc, sizeof(exc)); 659155408Srwatson return true; 660155408Srwatson } 661155408Srwatson return false; 662155408Srwatson} 663155408Srwatson 664155408Srwatsonbool RegisterContextDarwin_arm64::WriteAllRegisterValues( 665155408Srwatson const lldb::DataBufferSP &data_sp) { 666155408Srwatson if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) { 667155408Srwatson const uint8_t *src = data_sp->GetBytes(); 668155408Srwatson ::memcpy(&gpr, src, sizeof(gpr)); 669155408Srwatson src += sizeof(gpr); 670155408Srwatson 671155408Srwatson ::memcpy(&fpu, src, sizeof(fpu)); 672155408Srwatson src += sizeof(gpr); 673155408Srwatson 674155408Srwatson ::memcpy(&exc, src, sizeof(exc)); 675155408Srwatson uint32_t success_count = 0; 676183381Sed if (WriteGPR() == KERN_SUCCESS) 677155408Srwatson ++success_count; 678155408Srwatson if (WriteFPU() == KERN_SUCCESS) 679155408Srwatson ++success_count; 680155408Srwatson if (WriteEXC() == KERN_SUCCESS) 681155408Srwatson ++success_count; 682155408Srwatson return success_count == 3; 683155408Srwatson } 684155408Srwatson return false; 685155408Srwatson} 686164033Srwatson 687164033Srwatsonuint32_t RegisterContextDarwin_arm64::ConvertRegisterKindToRegisterNumber( 688164033Srwatson RegisterKind kind, uint32_t reg) { 689155408Srwatson if (kind == eRegisterKindGeneric) { 690155408Srwatson switch (reg) { 691155408Srwatson case LLDB_REGNUM_GENERIC_PC: 692155408Srwatson return gpr_pc; 693155408Srwatson case LLDB_REGNUM_GENERIC_SP: 694155408Srwatson return gpr_sp; 695184488Srwatson case LLDB_REGNUM_GENERIC_FP: 696155408Srwatson return gpr_fp; 697155408Srwatson case LLDB_REGNUM_GENERIC_RA: 698155408Srwatson return gpr_lr; 699155408Srwatson case LLDB_REGNUM_GENERIC_FLAGS: 700184488Srwatson return gpr_cpsr; 701155408Srwatson default: 702155408Srwatson break; 703155408Srwatson } 704155408Srwatson } else if (kind == eRegisterKindDWARF) { 705155408Srwatson switch (reg) { 706184488Srwatson case arm64_dwarf::x0: 707155408Srwatson return gpr_x0; 708155408Srwatson case arm64_dwarf::x1: 709184488Srwatson return gpr_x1; 710184488Srwatson case arm64_dwarf::x2: 711155408Srwatson return gpr_x2; 712155408Srwatson case arm64_dwarf::x3: 713155408Srwatson return gpr_x3; 714155408Srwatson case arm64_dwarf::x4: 715155408Srwatson return gpr_x4; 716155408Srwatson case arm64_dwarf::x5: 717155408Srwatson return gpr_x5; 718155408Srwatson case arm64_dwarf::x6: 719155408Srwatson return gpr_x6; 720155408Srwatson case arm64_dwarf::x7: 721155408Srwatson return gpr_x7; 722155408Srwatson case arm64_dwarf::x8: 723155408Srwatson return gpr_x8; 724155408Srwatson case arm64_dwarf::x9: 725155408Srwatson return gpr_x9; 726184488Srwatson case arm64_dwarf::x10: 727155408Srwatson return gpr_x10; 728184488Srwatson case arm64_dwarf::x11: 729184488Srwatson return gpr_x11; 730155408Srwatson case arm64_dwarf::x12: 731155408Srwatson return gpr_x12; 732155408Srwatson case arm64_dwarf::x13: 733184488Srwatson return gpr_x13; 734155408Srwatson case arm64_dwarf::x14: 735155408Srwatson return gpr_x14; 736155408Srwatson case arm64_dwarf::x15: 737155408Srwatson return gpr_x15; 738156880Srwatson case arm64_dwarf::x16: 739156880Srwatson return gpr_x16; 740155408Srwatson case arm64_dwarf::x17: 741155408Srwatson return gpr_x17; 742155408Srwatson case arm64_dwarf::x18: 743155408Srwatson return gpr_x18; 744155408Srwatson case arm64_dwarf::x19: 745159269Srwatson return gpr_x19; 746155408Srwatson case arm64_dwarf::x20: 747159269Srwatson return gpr_x20; 748159269Srwatson case arm64_dwarf::x21: 749159269Srwatson return gpr_x21; 750155408Srwatson case arm64_dwarf::x22: 751155408Srwatson return gpr_x22; 752155408Srwatson case arm64_dwarf::x23: 753159269Srwatson return gpr_x23; 754159269Srwatson case arm64_dwarf::x24: 755159269Srwatson return gpr_x24; 756159269Srwatson case arm64_dwarf::x25: 757159269Srwatson return gpr_x25; 758159269Srwatson case arm64_dwarf::x26: 759155408Srwatson return gpr_x26; 760155408Srwatson case arm64_dwarf::x27: 761184488Srwatson return gpr_x27; 762155408Srwatson case arm64_dwarf::x28: 763155408Srwatson return gpr_x28; 764155408Srwatson 765155408Srwatson case arm64_dwarf::fp: 766184488Srwatson return gpr_fp; 767155408Srwatson case arm64_dwarf::sp: 768155408Srwatson return gpr_sp; 769155408Srwatson case arm64_dwarf::lr: 770155408Srwatson return gpr_lr; 771184488Srwatson case arm64_dwarf::pc: 772184536Srwatson return gpr_pc; 773184488Srwatson case arm64_dwarf::cpsr: 774155408Srwatson return gpr_cpsr; 775155408Srwatson 776155408Srwatson case arm64_dwarf::v0: 777155408Srwatson return fpu_v0; 778184488Srwatson case arm64_dwarf::v1: 779155408Srwatson return fpu_v1; 780155408Srwatson case arm64_dwarf::v2: 781155408Srwatson return fpu_v2; 782155408Srwatson case arm64_dwarf::v3: 783184488Srwatson return fpu_v3; 784155408Srwatson case arm64_dwarf::v4: 785155408Srwatson return fpu_v4; 786155408Srwatson case arm64_dwarf::v5: 787155408Srwatson return fpu_v5; 788155408Srwatson case arm64_dwarf::v6: 789155408Srwatson return fpu_v6; 790155408Srwatson case arm64_dwarf::v7: 791155408Srwatson return fpu_v7; 792155408Srwatson case arm64_dwarf::v8: 793155408Srwatson return fpu_v8; 794156880Srwatson case arm64_dwarf::v9: 795155408Srwatson return fpu_v9; 796156880Srwatson case arm64_dwarf::v10: 797156880Srwatson return fpu_v10; 798156880Srwatson case arm64_dwarf::v11: 799156880Srwatson return fpu_v11; 800156880Srwatson case arm64_dwarf::v12: 801156880Srwatson return fpu_v12; 802156880Srwatson case arm64_dwarf::v13: 803156880Srwatson return fpu_v13; 804156880Srwatson case arm64_dwarf::v14: 805156880Srwatson return fpu_v14; 806156880Srwatson case arm64_dwarf::v15: 807156880Srwatson return fpu_v15; 808156880Srwatson case arm64_dwarf::v16: 809156880Srwatson return fpu_v16; 810156880Srwatson case arm64_dwarf::v17: 811156880Srwatson return fpu_v17; 812156880Srwatson case arm64_dwarf::v18: 813156880Srwatson return fpu_v18; 814156880Srwatson case arm64_dwarf::v19: 815156880Srwatson return fpu_v19; 816156884Srwatson case arm64_dwarf::v20: 817156884Srwatson return fpu_v20; 818156884Srwatson case arm64_dwarf::v21: 819156884Srwatson return fpu_v21; 820156884Srwatson case arm64_dwarf::v22: 821156884Srwatson return fpu_v22; 822156884Srwatson case arm64_dwarf::v23: 823156884Srwatson return fpu_v23; 824156884Srwatson case arm64_dwarf::v24: 825156884Srwatson return fpu_v24; 826159269Srwatson case arm64_dwarf::v25: 827184488Srwatson return fpu_v25; 828159269Srwatson case arm64_dwarf::v26: 829159269Srwatson return fpu_v26; 830184488Srwatson case arm64_dwarf::v27: 831159269Srwatson return fpu_v27; 832159269Srwatson case arm64_dwarf::v28: 833159269Srwatson return fpu_v28; 834159269Srwatson case arm64_dwarf::v29: 835184488Srwatson return fpu_v29; 836159269Srwatson case arm64_dwarf::v30: 837159269Srwatson return fpu_v30; 838184488Srwatson case arm64_dwarf::v31: 839159269Srwatson return fpu_v31; 840159269Srwatson 841159269Srwatson default: 842159269Srwatson break; 843184488Srwatson } 844159269Srwatson } else if (kind == eRegisterKindEHFrame) { 845159269Srwatson switch (reg) { 846184488Srwatson case arm64_ehframe::x0: 847159269Srwatson return gpr_x0; 848159269Srwatson case arm64_ehframe::x1: 849159269Srwatson return gpr_x1; 850159269Srwatson case arm64_ehframe::x2: 851184488Srwatson return gpr_x2; 852159269Srwatson case arm64_ehframe::x3: 853159269Srwatson return gpr_x3; 854184488Srwatson case arm64_ehframe::x4: 855159269Srwatson return gpr_x4; 856159269Srwatson case arm64_ehframe::x5: 857159269Srwatson return gpr_x5; 858159269Srwatson case arm64_ehframe::x6: 859159269Srwatson return gpr_x6; 860159269Srwatson case arm64_ehframe::x7: 861159269Srwatson return gpr_x7; 862159269Srwatson case arm64_ehframe::x8: 863159269Srwatson return gpr_x8; 864159269Srwatson case arm64_ehframe::x9: 865159269Srwatson return gpr_x9; 866159269Srwatson case arm64_ehframe::x10: 867159269Srwatson return gpr_x10; 868159269Srwatson case arm64_ehframe::x11: 869159269Srwatson return gpr_x11; 870159269Srwatson case arm64_ehframe::x12: 871159269Srwatson return gpr_x12; 872159269Srwatson case arm64_ehframe::x13: 873159269Srwatson return gpr_x13; 874159269Srwatson case arm64_ehframe::x14: 875159269Srwatson return gpr_x14; 876159269Srwatson case arm64_ehframe::x15: 877159269Srwatson return gpr_x15; 878159269Srwatson case arm64_ehframe::x16: 879159269Srwatson return gpr_x16; 880159269Srwatson case arm64_ehframe::x17: 881184488Srwatson return gpr_x17; 882159269Srwatson case arm64_ehframe::x18: 883184488Srwatson return gpr_x18; 884159269Srwatson case arm64_ehframe::x19: 885159269Srwatson return gpr_x19; 886159269Srwatson case arm64_ehframe::x20: 887159269Srwatson return gpr_x20; 888159269Srwatson case arm64_ehframe::x21: 889159269Srwatson return gpr_x21; 890159269Srwatson case arm64_ehframe::x22: 891159269Srwatson return gpr_x22; 892184488Srwatson case arm64_ehframe::x23: 893159269Srwatson return gpr_x23; 894184488Srwatson case arm64_ehframe::x24: 895159269Srwatson return gpr_x24; 896159269Srwatson case arm64_ehframe::x25: 897159269Srwatson return gpr_x25; 898159269Srwatson case arm64_ehframe::x26: 899159269Srwatson return gpr_x26; 900159269Srwatson case arm64_ehframe::x27: 901159269Srwatson return gpr_x27; 902159269Srwatson case arm64_ehframe::x28: 903159269Srwatson return gpr_x28; 904184508Srwatson case arm64_ehframe::fp: 905184508Srwatson return gpr_fp; 906184488Srwatson case arm64_ehframe::sp: 907159269Srwatson return gpr_sp; 908184488Srwatson case arm64_ehframe::lr: 909184508Srwatson return gpr_lr; 910159269Srwatson case arm64_ehframe::pc: 911159269Srwatson return gpr_pc; 912159269Srwatson case arm64_ehframe::cpsr: 913161646Srwatson return gpr_cpsr; 914161646Srwatson } 915161646Srwatson } else if (kind == eRegisterKindLLDB) { 916161646Srwatson return reg; 917161646Srwatson } 918156880Srwatson return LLDB_INVALID_REGNUM; 919156880Srwatson} 920156880Srwatson 921156880Srwatsonuint32_t RegisterContextDarwin_arm64::NumSupportedHardwareWatchpoints() { 922156880Srwatson#if defined(__APPLE__) && (defined(__arm64__) || defined(__aarch64__)) 923156880Srwatson // autodetect how many watchpoints are supported dynamically... 924156880Srwatson static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX; 925156880Srwatson if (g_num_supported_hw_watchpoints == UINT32_MAX) { 926156880Srwatson size_t len; 927156880Srwatson uint32_t n = 0; 928156880Srwatson len = sizeof(n); 929156880Srwatson if (::sysctlbyname("hw.optional.watchpoint", &n, &len, NULL, 0) == 0) { 930156880Srwatson g_num_supported_hw_watchpoints = n; 931156880Srwatson } 932156880Srwatson } 933156880Srwatson return g_num_supported_hw_watchpoints; 934184510Srwatson#else 935156880Srwatson // TODO: figure out remote case here! 936156880Srwatson return 2; 937156880Srwatson#endif 938155408Srwatson} 939155408Srwatson 940155408Srwatsonuint32_t RegisterContextDarwin_arm64::SetHardwareWatchpoint(lldb::addr_t addr, 941155408Srwatson size_t size, 942155408Srwatson bool read, 943155408Srwatson bool write) { 944155408Srwatson // if (log) log->Printf 945184534Srwatson // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint(addr = %8.8p, 946184534Srwatson // size = %u, read = %u, write = %u)", addr, size, read, write); 947155408Srwatson 948155408Srwatson const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); 949155408Srwatson 950155408Srwatson // Can't watch zero bytes 951155408Srwatson if (size == 0) 952155408Srwatson return LLDB_INVALID_INDEX32; 953184508Srwatson 954155408Srwatson // We must watch for either read or write 955155408Srwatson if (!read && !write) 956155408Srwatson return LLDB_INVALID_INDEX32; 957155408Srwatson 958184488Srwatson // Can't watch more than 4 bytes per WVR/WCR pair 959184508Srwatson if (size > 4) 960184508Srwatson return LLDB_INVALID_INDEX32; 961184508Srwatson 962184508Srwatson // We can only watch up to four bytes that follow a 4 byte aligned address 963184508Srwatson // per watchpoint register pair. Since we have at most so we can only watch 964184508Srwatson // until the next 4 byte boundary and we need to make sure we can properly 965184488Srwatson // encode this. 966184508Srwatson uint32_t addr_word_offset = addr % 4; 967184508Srwatson // if (log) log->Printf 968184508Srwatson // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() - 969184508Srwatson // addr_word_offset = 0x%8.8x", addr_word_offset); 970184508Srwatson 971155408Srwatson uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset; 972184508Srwatson // if (log) log->Printf 973184508Srwatson // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() - byte_mask = 974184508Srwatson // 0x%8.8x", byte_mask); 975184508Srwatson if (byte_mask > 0xfu) 976184508Srwatson return LLDB_INVALID_INDEX32; 977184508Srwatson 978184508Srwatson // Read the debug state 979184508Srwatson int kret = ReadDBG(false); 980184508Srwatson 981184508Srwatson if (kret == KERN_SUCCESS) { 982184534Srwatson // Check to make sure we have the needed hardware support 983184534Srwatson uint32_t i = 0; 984184508Srwatson 985184508Srwatson for (i = 0; i < num_hw_watchpoints; ++i) { 986184508Srwatson if ((dbg.wcr[i] & WCR_ENABLE) == 0) 987173083Scsjp break; // We found an available hw breakpoint slot (in i) 988184534Srwatson } 989184534Srwatson 990184534Srwatson // See if we found an available hw breakpoint slot above 991184534Srwatson if (i < num_hw_watchpoints) { 992184536Srwatson // Make the byte_mask into a valid Byte Address Select mask 993184536Srwatson uint32_t byte_address_select = byte_mask << 5; 994184536Srwatson // Make sure bits 1:0 are clear in our address 995184534Srwatson dbg.wvr[i] = addr & ~((lldb::addr_t)3); 996184534Srwatson dbg.wcr[i] = byte_address_select | // Which bytes that follow the IMVA 997184536Srwatson // that we will watch 998184536Srwatson S_USER | // Stop only in user mode 999184534Srwatson (read ? WCR_LOAD : 0) | // Stop on read access? 1000184534Srwatson (write ? WCR_STORE : 0) | // Stop on write access? 1001184534Srwatson WCR_ENABLE; // Enable this watchpoint; 1002184534Srwatson 1003184534Srwatson kret = WriteDBG(); 1004184534Srwatson // if (log) log->Printf 1005184534Srwatson // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() 1006184534Srwatson // WriteDBG() => 0x%8.8x.", kret); 1007184534Srwatson 1008184534Srwatson if (kret == KERN_SUCCESS) 1009184534Srwatson return i; 1010184534Srwatson } else { 1011184536Srwatson // if (log) log->Printf 1012184536Srwatson // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint(): 1013184536Srwatson // All hardware resources (%u) are in use.", 1014184536Srwatson // num_hw_watchpoints); 1015184534Srwatson } 1016184536Srwatson } 1017184534Srwatson return LLDB_INVALID_INDEX32; 1018184534Srwatson} 1019184536Srwatson 1020184534Srwatsonbool RegisterContextDarwin_arm64::ClearHardwareWatchpoint(uint32_t hw_index) { 1021184508Srwatson int kret = ReadDBG(false); 1022184508Srwatson 1023184508Srwatson const uint32_t num_hw_points = NumSupportedHardwareWatchpoints(); 1024184534Srwatson if (kret == KERN_SUCCESS) { 1025155408Srwatson if (hw_index < num_hw_points) { 1026155408Srwatson dbg.wcr[hw_index] = 0; 1027155408Srwatson // if (log) log->Printf 1028155408Srwatson // ("RegisterContextDarwin_arm64::ClearHardwareWatchpoint( %u ) 1029155408Srwatson // - WVR%u = 0x%8.8x WCR%u = 0x%8.8x", 1030155408Srwatson // hw_index, 1031155408Srwatson // hw_index, 1032155408Srwatson // dbg.wvr[hw_index], 1033155408Srwatson // hw_index, 1034155408Srwatson // dbg.wcr[hw_index]); 1035155408Srwatson 1036155408Srwatson kret = WriteDBG(); 1037155408Srwatson 1038155408Srwatson if (kret == KERN_SUCCESS) 1039184488Srwatson return true; 1040155408Srwatson } 1041184488Srwatson } 1042155408Srwatson return false; 1043155408Srwatson} 1044155408Srwatson