Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
96381 views
//===-- RegisterContextDarwin_arm.cpp -------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "RegisterContextDarwin_arm.h"9#include "RegisterContextDarwinConstants.h"1011#include "lldb/Utility/DataBufferHeap.h"12#include "lldb/Utility/DataExtractor.h"13#include "lldb/Utility/Endian.h"14#include "lldb/Utility/Log.h"15#include "lldb/Utility/RegisterValue.h"16#include "lldb/Utility/Scalar.h"17#include "llvm/Support/Compiler.h"1819#include "Plugins/Process/Utility/InstructionUtils.h"2021#include <memory>2223#include "Utility/ARM_DWARF_Registers.h"24#include "Utility/ARM_ehframe_Registers.h"2526#include "llvm/ADT/STLExtras.h"2728using namespace lldb;29using namespace lldb_private;3031enum {32gpr_r0 = 0,33gpr_r1,34gpr_r2,35gpr_r3,36gpr_r4,37gpr_r5,38gpr_r6,39gpr_r7,40gpr_r8,41gpr_r9,42gpr_r10,43gpr_r11,44gpr_r12,45gpr_r13,46gpr_sp = gpr_r13,47gpr_r14,48gpr_lr = gpr_r14,49gpr_r15,50gpr_pc = gpr_r15,51gpr_cpsr,5253fpu_s0,54fpu_s1,55fpu_s2,56fpu_s3,57fpu_s4,58fpu_s5,59fpu_s6,60fpu_s7,61fpu_s8,62fpu_s9,63fpu_s10,64fpu_s11,65fpu_s12,66fpu_s13,67fpu_s14,68fpu_s15,69fpu_s16,70fpu_s17,71fpu_s18,72fpu_s19,73fpu_s20,74fpu_s21,75fpu_s22,76fpu_s23,77fpu_s24,78fpu_s25,79fpu_s26,80fpu_s27,81fpu_s28,82fpu_s29,83fpu_s30,84fpu_s31,85fpu_fpscr,8687exc_exception,88exc_fsr,89exc_far,9091dbg_bvr0,92dbg_bvr1,93dbg_bvr2,94dbg_bvr3,95dbg_bvr4,96dbg_bvr5,97dbg_bvr6,98dbg_bvr7,99dbg_bvr8,100dbg_bvr9,101dbg_bvr10,102dbg_bvr11,103dbg_bvr12,104dbg_bvr13,105dbg_bvr14,106dbg_bvr15,107108dbg_bcr0,109dbg_bcr1,110dbg_bcr2,111dbg_bcr3,112dbg_bcr4,113dbg_bcr5,114dbg_bcr6,115dbg_bcr7,116dbg_bcr8,117dbg_bcr9,118dbg_bcr10,119dbg_bcr11,120dbg_bcr12,121dbg_bcr13,122dbg_bcr14,123dbg_bcr15,124125dbg_wvr0,126dbg_wvr1,127dbg_wvr2,128dbg_wvr3,129dbg_wvr4,130dbg_wvr5,131dbg_wvr6,132dbg_wvr7,133dbg_wvr8,134dbg_wvr9,135dbg_wvr10,136dbg_wvr11,137dbg_wvr12,138dbg_wvr13,139dbg_wvr14,140dbg_wvr15,141142dbg_wcr0,143dbg_wcr1,144dbg_wcr2,145dbg_wcr3,146dbg_wcr4,147dbg_wcr5,148dbg_wcr6,149dbg_wcr7,150dbg_wcr8,151dbg_wcr9,152dbg_wcr10,153dbg_wcr11,154dbg_wcr12,155dbg_wcr13,156dbg_wcr14,157dbg_wcr15,158159k_num_registers160};161162#define GPR_OFFSET(idx) ((idx)*4)163#define FPU_OFFSET(idx) ((idx)*4 + sizeof(RegisterContextDarwin_arm::GPR))164#define EXC_OFFSET(idx) \165((idx)*4 + sizeof(RegisterContextDarwin_arm::GPR) + \166sizeof(RegisterContextDarwin_arm::FPU))167#define DBG_OFFSET(reg) \168((LLVM_EXTENSION offsetof(RegisterContextDarwin_arm::DBG, reg) + \169sizeof(RegisterContextDarwin_arm::GPR) + \170sizeof(RegisterContextDarwin_arm::FPU) + \171sizeof(RegisterContextDarwin_arm::EXC)))172173#define DEFINE_DBG(reg, i) \174#reg, NULL, sizeof(((RegisterContextDarwin_arm::DBG *) NULL)->reg[i]), \175DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, \176{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \177LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \178LLDB_INVALID_REGNUM }, \179nullptr, nullptr, nullptr,180#define REG_CONTEXT_SIZE \181(sizeof(RegisterContextDarwin_arm::GPR) + \182sizeof(RegisterContextDarwin_arm::FPU) + \183sizeof(RegisterContextDarwin_arm::EXC))184185static RegisterInfo g_register_infos[] = {186// General purpose registers187// NAME ALT SZ OFFSET ENCODING FORMAT188// EH_FRAME DWARF GENERIC189// PROCESS PLUGIN LLDB NATIVE190// ====== ======= == ============= ============= ============191// =============== =============== =========================192// ===================== =============193{"r0",194nullptr,1954,196GPR_OFFSET(0),197eEncodingUint,198eFormatHex,199{ehframe_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r0},200nullptr,201nullptr,202nullptr,203},204{"r1",205nullptr,2064,207GPR_OFFSET(1),208eEncodingUint,209eFormatHex,210{ehframe_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r1},211nullptr,212nullptr,213nullptr,214},215{"r2",216nullptr,2174,218GPR_OFFSET(2),219eEncodingUint,220eFormatHex,221{ehframe_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r2},222nullptr,223nullptr,224nullptr,225},226{"r3",227nullptr,2284,229GPR_OFFSET(3),230eEncodingUint,231eFormatHex,232{ehframe_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r3},233nullptr,234nullptr,235nullptr,236},237{"r4",238nullptr,2394,240GPR_OFFSET(4),241eEncodingUint,242eFormatHex,243{ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r4},244nullptr,245nullptr,246nullptr,247},248{"r5",249nullptr,2504,251GPR_OFFSET(5),252eEncodingUint,253eFormatHex,254{ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r5},255nullptr,256nullptr,257nullptr,258},259{"r6",260nullptr,2614,262GPR_OFFSET(6),263eEncodingUint,264eFormatHex,265{ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r6},266nullptr,267nullptr,268nullptr,269},270{"r7",271nullptr,2724,273GPR_OFFSET(7),274eEncodingUint,275eFormatHex,276{ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,277gpr_r7},278nullptr,279nullptr,280nullptr,281},282{"r8",283nullptr,2844,285GPR_OFFSET(8),286eEncodingUint,287eFormatHex,288{ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r8},289nullptr,290nullptr,291nullptr,292},293{"r9",294nullptr,2954,296GPR_OFFSET(9),297eEncodingUint,298eFormatHex,299{ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r9},300nullptr,301nullptr,302nullptr,303},304{"r10",305nullptr,3064,307GPR_OFFSET(10),308eEncodingUint,309eFormatHex,310{ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,311gpr_r10},312nullptr,313nullptr,314nullptr,315},316{"r11",317nullptr,3184,319GPR_OFFSET(11),320eEncodingUint,321eFormatHex,322{ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,323gpr_r11},324nullptr,325nullptr,326nullptr,327},328{"r12",329nullptr,3304,331GPR_OFFSET(12),332eEncodingUint,333eFormatHex,334{ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,335gpr_r12},336nullptr,337nullptr,338nullptr,339},340{"sp",341"r13",3424,343GPR_OFFSET(13),344eEncodingUint,345eFormatHex,346{ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,347gpr_sp},348nullptr,349nullptr,350nullptr,351},352{"lr",353"r14",3544,355GPR_OFFSET(14),356eEncodingUint,357eFormatHex,358{ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM,359gpr_lr},360nullptr,361nullptr,362nullptr,363},364{"pc",365"r15",3664,367GPR_OFFSET(15),368eEncodingUint,369eFormatHex,370{ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,371gpr_pc},372nullptr,373nullptr,374nullptr,375},376{"cpsr",377"psr",3784,379GPR_OFFSET(16),380eEncodingUint,381eFormatHex,382{ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM,383gpr_cpsr},384nullptr,385nullptr,386nullptr,387},388389{"s0",390nullptr,3914,392FPU_OFFSET(0),393eEncodingIEEE754,394eFormatFloat,395{LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,396fpu_s0},397nullptr,398nullptr,399nullptr,400},401{"s1",402nullptr,4034,404FPU_OFFSET(1),405eEncodingIEEE754,406eFormatFloat,407{LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,408fpu_s1},409nullptr,410nullptr,411nullptr,412},413{"s2",414nullptr,4154,416FPU_OFFSET(2),417eEncodingIEEE754,418eFormatFloat,419{LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,420fpu_s2},421nullptr,422nullptr,423nullptr,424},425{"s3",426nullptr,4274,428FPU_OFFSET(3),429eEncodingIEEE754,430eFormatFloat,431{LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,432fpu_s3},433nullptr,434nullptr,435nullptr,436},437{"s4",438nullptr,4394,440FPU_OFFSET(4),441eEncodingIEEE754,442eFormatFloat,443{LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,444fpu_s4},445nullptr,446nullptr,447nullptr,448},449{"s5",450nullptr,4514,452FPU_OFFSET(5),453eEncodingIEEE754,454eFormatFloat,455{LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,456fpu_s5},457nullptr,458nullptr,459nullptr,460},461{"s6",462nullptr,4634,464FPU_OFFSET(6),465eEncodingIEEE754,466eFormatFloat,467{LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,468fpu_s6},469nullptr,470nullptr,471nullptr,472},473{"s7",474nullptr,4754,476FPU_OFFSET(7),477eEncodingIEEE754,478eFormatFloat,479{LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,480fpu_s7},481nullptr,482nullptr,483nullptr,484},485{"s8",486nullptr,4874,488FPU_OFFSET(8),489eEncodingIEEE754,490eFormatFloat,491{LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,492fpu_s8},493nullptr,494nullptr,495nullptr,496},497{"s9",498nullptr,4994,500FPU_OFFSET(9),501eEncodingIEEE754,502eFormatFloat,503{LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,504fpu_s9},505nullptr,506nullptr,507nullptr,508},509{"s10",510nullptr,5114,512FPU_OFFSET(10),513eEncodingIEEE754,514eFormatFloat,515{LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,516fpu_s10},517nullptr,518nullptr,519nullptr,520},521{"s11",522nullptr,5234,524FPU_OFFSET(11),525eEncodingIEEE754,526eFormatFloat,527{LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,528fpu_s11},529nullptr,530nullptr,531nullptr,532},533{"s12",534nullptr,5354,536FPU_OFFSET(12),537eEncodingIEEE754,538eFormatFloat,539{LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,540fpu_s12},541nullptr,542nullptr,543nullptr,544},545{"s13",546nullptr,5474,548FPU_OFFSET(13),549eEncodingIEEE754,550eFormatFloat,551{LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,552fpu_s13},553nullptr,554nullptr,555nullptr,556},557{"s14",558nullptr,5594,560FPU_OFFSET(14),561eEncodingIEEE754,562eFormatFloat,563{LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,564fpu_s14},565nullptr,566nullptr,567nullptr,568},569{"s15",570nullptr,5714,572FPU_OFFSET(15),573eEncodingIEEE754,574eFormatFloat,575{LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,576fpu_s15},577nullptr,578nullptr,579nullptr,580},581{"s16",582nullptr,5834,584FPU_OFFSET(16),585eEncodingIEEE754,586eFormatFloat,587{LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,588fpu_s16},589nullptr,590nullptr,591nullptr,592},593{"s17",594nullptr,5954,596FPU_OFFSET(17),597eEncodingIEEE754,598eFormatFloat,599{LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,600fpu_s17},601nullptr,602nullptr,603nullptr,604},605{"s18",606nullptr,6074,608FPU_OFFSET(18),609eEncodingIEEE754,610eFormatFloat,611{LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,612fpu_s18},613nullptr,614nullptr,615nullptr,616},617{"s19",618nullptr,6194,620FPU_OFFSET(19),621eEncodingIEEE754,622eFormatFloat,623{LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,624fpu_s19},625nullptr,626nullptr,627nullptr,628},629{"s20",630nullptr,6314,632FPU_OFFSET(20),633eEncodingIEEE754,634eFormatFloat,635{LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,636fpu_s20},637nullptr,638nullptr,639nullptr,640},641{"s21",642nullptr,6434,644FPU_OFFSET(21),645eEncodingIEEE754,646eFormatFloat,647{LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,648fpu_s21},649nullptr,650nullptr,651nullptr,652},653{"s22",654nullptr,6554,656FPU_OFFSET(22),657eEncodingIEEE754,658eFormatFloat,659{LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,660fpu_s22},661nullptr,662nullptr,663nullptr,664},665{"s23",666nullptr,6674,668FPU_OFFSET(23),669eEncodingIEEE754,670eFormatFloat,671{LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,672fpu_s23},673nullptr,674nullptr,675nullptr,676},677{"s24",678nullptr,6794,680FPU_OFFSET(24),681eEncodingIEEE754,682eFormatFloat,683{LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,684fpu_s24},685nullptr,686nullptr,687nullptr,688},689{"s25",690nullptr,6914,692FPU_OFFSET(25),693eEncodingIEEE754,694eFormatFloat,695{LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,696fpu_s25},697nullptr,698nullptr,699nullptr,700},701{"s26",702nullptr,7034,704FPU_OFFSET(26),705eEncodingIEEE754,706eFormatFloat,707{LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,708fpu_s26},709nullptr,710nullptr,711nullptr,712},713{"s27",714nullptr,7154,716FPU_OFFSET(27),717eEncodingIEEE754,718eFormatFloat,719{LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,720fpu_s27},721nullptr,722nullptr,723nullptr,724},725{"s28",726nullptr,7274,728FPU_OFFSET(28),729eEncodingIEEE754,730eFormatFloat,731{LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,732fpu_s28},733nullptr,734nullptr,735nullptr,736},737{"s29",738nullptr,7394,740FPU_OFFSET(29),741eEncodingIEEE754,742eFormatFloat,743{LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,744fpu_s29},745nullptr,746nullptr,747nullptr,748},749{"s30",750nullptr,7514,752FPU_OFFSET(30),753eEncodingIEEE754,754eFormatFloat,755{LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,756fpu_s30},757nullptr,758nullptr,759nullptr,760},761{"s31",762nullptr,7634,764FPU_OFFSET(31),765eEncodingIEEE754,766eFormatFloat,767{LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,768fpu_s31},769nullptr,770nullptr,771nullptr,772},773{"fpscr",774nullptr,7754,776FPU_OFFSET(32),777eEncodingUint,778eFormatHex,779{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,780LLDB_INVALID_REGNUM, fpu_fpscr},781nullptr,782nullptr,783nullptr,784},785786{"exception",787nullptr,7884,789EXC_OFFSET(0),790eEncodingUint,791eFormatHex,792{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,793LLDB_INVALID_REGNUM, exc_exception},794nullptr,795nullptr,796nullptr,797},798{"fsr",799nullptr,8004,801EXC_OFFSET(1),802eEncodingUint,803eFormatHex,804{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,805LLDB_INVALID_REGNUM, exc_fsr},806nullptr,807nullptr,808nullptr,809},810{"far",811nullptr,8124,813EXC_OFFSET(2),814eEncodingUint,815eFormatHex,816{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,817LLDB_INVALID_REGNUM, exc_far},818nullptr,819nullptr,820nullptr,821},822823{DEFINE_DBG(bvr, 0)},824{DEFINE_DBG(bvr, 1)},825{DEFINE_DBG(bvr, 2)},826{DEFINE_DBG(bvr, 3)},827{DEFINE_DBG(bvr, 4)},828{DEFINE_DBG(bvr, 5)},829{DEFINE_DBG(bvr, 6)},830{DEFINE_DBG(bvr, 7)},831{DEFINE_DBG(bvr, 8)},832{DEFINE_DBG(bvr, 9)},833{DEFINE_DBG(bvr, 10)},834{DEFINE_DBG(bvr, 11)},835{DEFINE_DBG(bvr, 12)},836{DEFINE_DBG(bvr, 13)},837{DEFINE_DBG(bvr, 14)},838{DEFINE_DBG(bvr, 15)},839840{DEFINE_DBG(bcr, 0)},841{DEFINE_DBG(bcr, 1)},842{DEFINE_DBG(bcr, 2)},843{DEFINE_DBG(bcr, 3)},844{DEFINE_DBG(bcr, 4)},845{DEFINE_DBG(bcr, 5)},846{DEFINE_DBG(bcr, 6)},847{DEFINE_DBG(bcr, 7)},848{DEFINE_DBG(bcr, 8)},849{DEFINE_DBG(bcr, 9)},850{DEFINE_DBG(bcr, 10)},851{DEFINE_DBG(bcr, 11)},852{DEFINE_DBG(bcr, 12)},853{DEFINE_DBG(bcr, 13)},854{DEFINE_DBG(bcr, 14)},855{DEFINE_DBG(bcr, 15)},856857{DEFINE_DBG(wvr, 0)},858{DEFINE_DBG(wvr, 1)},859{DEFINE_DBG(wvr, 2)},860{DEFINE_DBG(wvr, 3)},861{DEFINE_DBG(wvr, 4)},862{DEFINE_DBG(wvr, 5)},863{DEFINE_DBG(wvr, 6)},864{DEFINE_DBG(wvr, 7)},865{DEFINE_DBG(wvr, 8)},866{DEFINE_DBG(wvr, 9)},867{DEFINE_DBG(wvr, 10)},868{DEFINE_DBG(wvr, 11)},869{DEFINE_DBG(wvr, 12)},870{DEFINE_DBG(wvr, 13)},871{DEFINE_DBG(wvr, 14)},872{DEFINE_DBG(wvr, 15)},873874{DEFINE_DBG(wcr, 0)},875{DEFINE_DBG(wcr, 1)},876{DEFINE_DBG(wcr, 2)},877{DEFINE_DBG(wcr, 3)},878{DEFINE_DBG(wcr, 4)},879{DEFINE_DBG(wcr, 5)},880{DEFINE_DBG(wcr, 6)},881{DEFINE_DBG(wcr, 7)},882{DEFINE_DBG(wcr, 8)},883{DEFINE_DBG(wcr, 9)},884{DEFINE_DBG(wcr, 10)},885{DEFINE_DBG(wcr, 11)},886{DEFINE_DBG(wcr, 12)},887{DEFINE_DBG(wcr, 13)},888{DEFINE_DBG(wcr, 14)},889{DEFINE_DBG(wcr, 15)}};890891// General purpose registers892static uint32_t g_gpr_regnums[] = {893gpr_r0, gpr_r1, gpr_r2, gpr_r3, gpr_r4, gpr_r5, gpr_r6, gpr_r7, gpr_r8,894gpr_r9, gpr_r10, gpr_r11, gpr_r12, gpr_sp, gpr_lr, gpr_pc, gpr_cpsr};895896// Floating point registers897static uint32_t g_fpu_regnums[] = {898fpu_s0, fpu_s1, fpu_s2, fpu_s3, fpu_s4, fpu_s5, fpu_s6,899fpu_s7, fpu_s8, fpu_s9, fpu_s10, fpu_s11, fpu_s12, fpu_s13,900fpu_s14, fpu_s15, fpu_s16, fpu_s17, fpu_s18, fpu_s19, fpu_s20,901fpu_s21, fpu_s22, fpu_s23, fpu_s24, fpu_s25, fpu_s26, fpu_s27,902fpu_s28, fpu_s29, fpu_s30, fpu_s31, fpu_fpscr,903};904905// Exception registers906907static uint32_t g_exc_regnums[] = {908exc_exception, exc_fsr, exc_far,909};910911static size_t k_num_register_infos = std::size(g_register_infos);912913RegisterContextDarwin_arm::RegisterContextDarwin_arm(914Thread &thread, uint32_t concrete_frame_idx)915: RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() {916uint32_t i;917for (i = 0; i < kNumErrors; i++) {918gpr_errs[i] = -1;919fpu_errs[i] = -1;920exc_errs[i] = -1;921}922}923924RegisterContextDarwin_arm::~RegisterContextDarwin_arm() = default;925926void RegisterContextDarwin_arm::InvalidateAllRegisters() {927InvalidateAllRegisterStates();928}929930size_t RegisterContextDarwin_arm::GetRegisterCount() {931assert(k_num_register_infos == k_num_registers);932return k_num_registers;933}934935const RegisterInfo *936RegisterContextDarwin_arm::GetRegisterInfoAtIndex(size_t reg) {937assert(k_num_register_infos == k_num_registers);938if (reg < k_num_registers)939return &g_register_infos[reg];940return nullptr;941}942943size_t RegisterContextDarwin_arm::GetRegisterInfosCount() {944return k_num_register_infos;945}946947const RegisterInfo *RegisterContextDarwin_arm::GetRegisterInfos() {948return g_register_infos;949}950951// Number of registers in each register set952const size_t k_num_gpr_registers = std::size(g_gpr_regnums);953const size_t k_num_fpu_registers = std::size(g_fpu_regnums);954const size_t k_num_exc_registers = std::size(g_exc_regnums);955956// Register set definitions. The first definitions at register set index of957// zero is for all registers, followed by other registers sets. The register958// information for the all register set need not be filled in.959static const RegisterSet g_reg_sets[] = {960{961"General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums,962},963{"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums},964{"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}};965966const size_t k_num_regsets = std::size(g_reg_sets);967968size_t RegisterContextDarwin_arm::GetRegisterSetCount() {969return k_num_regsets;970}971972const RegisterSet *RegisterContextDarwin_arm::GetRegisterSet(size_t reg_set) {973if (reg_set < k_num_regsets)974return &g_reg_sets[reg_set];975return nullptr;976}977978// Register information definitions for 32 bit i386.979int RegisterContextDarwin_arm::GetSetForNativeRegNum(int reg) {980if (reg < fpu_s0)981return GPRRegSet;982else if (reg < exc_exception)983return FPURegSet;984else if (reg < k_num_registers)985return EXCRegSet;986return -1;987}988989int RegisterContextDarwin_arm::ReadGPR(bool force) {990int set = GPRRegSet;991if (force || !RegisterSetIsCached(set)) {992SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));993}994return GetError(GPRRegSet, Read);995}996997int RegisterContextDarwin_arm::ReadFPU(bool force) {998int set = FPURegSet;999if (force || !RegisterSetIsCached(set)) {1000SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));1001}1002return GetError(FPURegSet, Read);1003}10041005int RegisterContextDarwin_arm::ReadEXC(bool force) {1006int set = EXCRegSet;1007if (force || !RegisterSetIsCached(set)) {1008SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));1009}1010return GetError(EXCRegSet, Read);1011}10121013int RegisterContextDarwin_arm::ReadDBG(bool force) {1014int set = DBGRegSet;1015if (force || !RegisterSetIsCached(set)) {1016SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg));1017}1018return GetError(DBGRegSet, Read);1019}10201021int RegisterContextDarwin_arm::WriteGPR() {1022int set = GPRRegSet;1023if (!RegisterSetIsCached(set)) {1024SetError(set, Write, -1);1025return KERN_INVALID_ARGUMENT;1026}1027SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr));1028SetError(set, Read, -1);1029return GetError(GPRRegSet, Write);1030}10311032int RegisterContextDarwin_arm::WriteFPU() {1033int set = FPURegSet;1034if (!RegisterSetIsCached(set)) {1035SetError(set, Write, -1);1036return KERN_INVALID_ARGUMENT;1037}1038SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu));1039SetError(set, Read, -1);1040return GetError(FPURegSet, Write);1041}10421043int RegisterContextDarwin_arm::WriteEXC() {1044int set = EXCRegSet;1045if (!RegisterSetIsCached(set)) {1046SetError(set, Write, -1);1047return KERN_INVALID_ARGUMENT;1048}1049SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc));1050SetError(set, Read, -1);1051return GetError(EXCRegSet, Write);1052}10531054int RegisterContextDarwin_arm::WriteDBG() {1055int set = DBGRegSet;1056if (!RegisterSetIsCached(set)) {1057SetError(set, Write, -1);1058return KERN_INVALID_ARGUMENT;1059}1060SetError(set, Write, DoWriteDBG(GetThreadID(), set, dbg));1061SetError(set, Read, -1);1062return GetError(DBGRegSet, Write);1063}10641065int RegisterContextDarwin_arm::ReadRegisterSet(uint32_t set, bool force) {1066switch (set) {1067case GPRRegSet:1068return ReadGPR(force);1069case GPRAltRegSet:1070return ReadGPR(force);1071case FPURegSet:1072return ReadFPU(force);1073case EXCRegSet:1074return ReadEXC(force);1075case DBGRegSet:1076return ReadDBG(force);1077default:1078break;1079}1080return KERN_INVALID_ARGUMENT;1081}10821083int RegisterContextDarwin_arm::WriteRegisterSet(uint32_t set) {1084// Make sure we have a valid context to set.1085if (RegisterSetIsCached(set)) {1086switch (set) {1087case GPRRegSet:1088return WriteGPR();1089case GPRAltRegSet:1090return WriteGPR();1091case FPURegSet:1092return WriteFPU();1093case EXCRegSet:1094return WriteEXC();1095case DBGRegSet:1096return WriteDBG();1097default:1098break;1099}1100}1101return KERN_INVALID_ARGUMENT;1102}11031104void RegisterContextDarwin_arm::LogDBGRegisters(Log *log, const DBG &dbg) {1105if (log) {1106for (uint32_t i = 0; i < 16; i++)1107LLDB_LOGF(log,1108"BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { "1109"0x%8.8x, 0x%8.8x }",1110i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]);1111}1112}11131114bool RegisterContextDarwin_arm::ReadRegister(const RegisterInfo *reg_info,1115RegisterValue &value) {1116const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];1117int set = RegisterContextDarwin_arm::GetSetForNativeRegNum(reg);11181119if (set == -1)1120return false;11211122if (ReadRegisterSet(set, false) != KERN_SUCCESS)1123return false;11241125switch (reg) {1126case gpr_r0:1127case gpr_r1:1128case gpr_r2:1129case gpr_r3:1130case gpr_r4:1131case gpr_r5:1132case gpr_r6:1133case gpr_r7:1134case gpr_r8:1135case gpr_r9:1136case gpr_r10:1137case gpr_r11:1138case gpr_r12:1139case gpr_sp:1140case gpr_lr:1141case gpr_pc:1142value.SetUInt32(gpr.r[reg - gpr_r0]);1143break;1144case gpr_cpsr:1145value.SetUInt32(gpr.cpsr);1146break;1147case fpu_s0:1148case fpu_s1:1149case fpu_s2:1150case fpu_s3:1151case fpu_s4:1152case fpu_s5:1153case fpu_s6:1154case fpu_s7:1155case fpu_s8:1156case fpu_s9:1157case fpu_s10:1158case fpu_s11:1159case fpu_s12:1160case fpu_s13:1161case fpu_s14:1162case fpu_s15:1163case fpu_s16:1164case fpu_s17:1165case fpu_s18:1166case fpu_s19:1167case fpu_s20:1168case fpu_s21:1169case fpu_s22:1170case fpu_s23:1171case fpu_s24:1172case fpu_s25:1173case fpu_s26:1174case fpu_s27:1175case fpu_s28:1176case fpu_s29:1177case fpu_s30:1178case fpu_s31:1179value.SetUInt32(fpu.floats.s[reg], RegisterValue::eTypeFloat);1180break;11811182case fpu_fpscr:1183value.SetUInt32(fpu.fpscr);1184break;11851186case exc_exception:1187value.SetUInt32(exc.exception);1188break;1189case exc_fsr:1190value.SetUInt32(exc.fsr);1191break;1192case exc_far:1193value.SetUInt32(exc.far);1194break;11951196default:1197value.SetValueToInvalid();1198return false;1199}1200return true;1201}12021203bool RegisterContextDarwin_arm::WriteRegister(const RegisterInfo *reg_info,1204const RegisterValue &value) {1205const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];1206int set = GetSetForNativeRegNum(reg);12071208if (set == -1)1209return false;12101211if (ReadRegisterSet(set, false) != KERN_SUCCESS)1212return false;12131214switch (reg) {1215case gpr_r0:1216case gpr_r1:1217case gpr_r2:1218case gpr_r3:1219case gpr_r4:1220case gpr_r5:1221case gpr_r6:1222case gpr_r7:1223case gpr_r8:1224case gpr_r9:1225case gpr_r10:1226case gpr_r11:1227case gpr_r12:1228case gpr_sp:1229case gpr_lr:1230case gpr_pc:1231case gpr_cpsr:1232gpr.r[reg - gpr_r0] = value.GetAsUInt32();1233break;12341235case fpu_s0:1236case fpu_s1:1237case fpu_s2:1238case fpu_s3:1239case fpu_s4:1240case fpu_s5:1241case fpu_s6:1242case fpu_s7:1243case fpu_s8:1244case fpu_s9:1245case fpu_s10:1246case fpu_s11:1247case fpu_s12:1248case fpu_s13:1249case fpu_s14:1250case fpu_s15:1251case fpu_s16:1252case fpu_s17:1253case fpu_s18:1254case fpu_s19:1255case fpu_s20:1256case fpu_s21:1257case fpu_s22:1258case fpu_s23:1259case fpu_s24:1260case fpu_s25:1261case fpu_s26:1262case fpu_s27:1263case fpu_s28:1264case fpu_s29:1265case fpu_s30:1266case fpu_s31:1267fpu.floats.s[reg] = value.GetAsUInt32();1268break;12691270case fpu_fpscr:1271fpu.fpscr = value.GetAsUInt32();1272break;12731274case exc_exception:1275exc.exception = value.GetAsUInt32();1276break;1277case exc_fsr:1278exc.fsr = value.GetAsUInt32();1279break;1280case exc_far:1281exc.far = value.GetAsUInt32();1282break;12831284default:1285return false;1286}1287return WriteRegisterSet(set) == KERN_SUCCESS;1288}12891290bool RegisterContextDarwin_arm::ReadAllRegisterValues(1291lldb::WritableDataBufferSP &data_sp) {1292data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0);1293if (data_sp && ReadGPR(false) == KERN_SUCCESS &&1294ReadFPU(false) == KERN_SUCCESS && ReadEXC(false) == KERN_SUCCESS) {1295uint8_t *dst = data_sp->GetBytes();1296::memcpy(dst, &gpr, sizeof(gpr));1297dst += sizeof(gpr);12981299::memcpy(dst, &fpu, sizeof(fpu));1300dst += sizeof(gpr);13011302::memcpy(dst, &exc, sizeof(exc));1303return true;1304}1305return false;1306}13071308bool RegisterContextDarwin_arm::WriteAllRegisterValues(1309const lldb::DataBufferSP &data_sp) {1310if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {1311const uint8_t *src = data_sp->GetBytes();1312::memcpy(&gpr, src, sizeof(gpr));1313src += sizeof(gpr);13141315::memcpy(&fpu, src, sizeof(fpu));1316src += sizeof(gpr);13171318::memcpy(&exc, src, sizeof(exc));1319uint32_t success_count = 0;1320if (WriteGPR() == KERN_SUCCESS)1321++success_count;1322if (WriteFPU() == KERN_SUCCESS)1323++success_count;1324if (WriteEXC() == KERN_SUCCESS)1325++success_count;1326return success_count == 3;1327}1328return false;1329}13301331uint32_t RegisterContextDarwin_arm::ConvertRegisterKindToRegisterNumber(1332lldb::RegisterKind kind, uint32_t reg) {1333if (kind == eRegisterKindGeneric) {1334switch (reg) {1335case LLDB_REGNUM_GENERIC_PC:1336return gpr_pc;1337case LLDB_REGNUM_GENERIC_SP:1338return gpr_sp;1339case LLDB_REGNUM_GENERIC_FP:1340return gpr_r7;1341case LLDB_REGNUM_GENERIC_RA:1342return gpr_lr;1343case LLDB_REGNUM_GENERIC_FLAGS:1344return gpr_cpsr;1345default:1346break;1347}1348} else if (kind == eRegisterKindDWARF) {1349switch (reg) {1350case dwarf_r0:1351return gpr_r0;1352case dwarf_r1:1353return gpr_r1;1354case dwarf_r2:1355return gpr_r2;1356case dwarf_r3:1357return gpr_r3;1358case dwarf_r4:1359return gpr_r4;1360case dwarf_r5:1361return gpr_r5;1362case dwarf_r6:1363return gpr_r6;1364case dwarf_r7:1365return gpr_r7;1366case dwarf_r8:1367return gpr_r8;1368case dwarf_r9:1369return gpr_r9;1370case dwarf_r10:1371return gpr_r10;1372case dwarf_r11:1373return gpr_r11;1374case dwarf_r12:1375return gpr_r12;1376case dwarf_sp:1377return gpr_sp;1378case dwarf_lr:1379return gpr_lr;1380case dwarf_pc:1381return gpr_pc;1382case dwarf_spsr:1383return gpr_cpsr;13841385case dwarf_s0:1386return fpu_s0;1387case dwarf_s1:1388return fpu_s1;1389case dwarf_s2:1390return fpu_s2;1391case dwarf_s3:1392return fpu_s3;1393case dwarf_s4:1394return fpu_s4;1395case dwarf_s5:1396return fpu_s5;1397case dwarf_s6:1398return fpu_s6;1399case dwarf_s7:1400return fpu_s7;1401case dwarf_s8:1402return fpu_s8;1403case dwarf_s9:1404return fpu_s9;1405case dwarf_s10:1406return fpu_s10;1407case dwarf_s11:1408return fpu_s11;1409case dwarf_s12:1410return fpu_s12;1411case dwarf_s13:1412return fpu_s13;1413case dwarf_s14:1414return fpu_s14;1415case dwarf_s15:1416return fpu_s15;1417case dwarf_s16:1418return fpu_s16;1419case dwarf_s17:1420return fpu_s17;1421case dwarf_s18:1422return fpu_s18;1423case dwarf_s19:1424return fpu_s19;1425case dwarf_s20:1426return fpu_s20;1427case dwarf_s21:1428return fpu_s21;1429case dwarf_s22:1430return fpu_s22;1431case dwarf_s23:1432return fpu_s23;1433case dwarf_s24:1434return fpu_s24;1435case dwarf_s25:1436return fpu_s25;1437case dwarf_s26:1438return fpu_s26;1439case dwarf_s27:1440return fpu_s27;1441case dwarf_s28:1442return fpu_s28;1443case dwarf_s29:1444return fpu_s29;1445case dwarf_s30:1446return fpu_s30;1447case dwarf_s31:1448return fpu_s31;14491450default:1451break;1452}1453} else if (kind == eRegisterKindEHFrame) {1454switch (reg) {1455case ehframe_r0:1456return gpr_r0;1457case ehframe_r1:1458return gpr_r1;1459case ehframe_r2:1460return gpr_r2;1461case ehframe_r3:1462return gpr_r3;1463case ehframe_r4:1464return gpr_r4;1465case ehframe_r5:1466return gpr_r5;1467case ehframe_r6:1468return gpr_r6;1469case ehframe_r7:1470return gpr_r7;1471case ehframe_r8:1472return gpr_r8;1473case ehframe_r9:1474return gpr_r9;1475case ehframe_r10:1476return gpr_r10;1477case ehframe_r11:1478return gpr_r11;1479case ehframe_r12:1480return gpr_r12;1481case ehframe_sp:1482return gpr_sp;1483case ehframe_lr:1484return gpr_lr;1485case ehframe_pc:1486return gpr_pc;1487case ehframe_cpsr:1488return gpr_cpsr;1489}1490} else if (kind == eRegisterKindLLDB) {1491return reg;1492}1493return LLDB_INVALID_REGNUM;1494}14951496uint32_t RegisterContextDarwin_arm::NumSupportedHardwareBreakpoints() {1497#if defined(__APPLE__) && defined(__arm__)1498// Set the init value to something that will let us know that we need to1499// autodetect how many breakpoints are supported dynamically...1500static uint32_t g_num_supported_hw_breakpoints = UINT32_MAX;1501if (g_num_supported_hw_breakpoints == UINT32_MAX) {1502// Set this to zero in case we can't tell if there are any HW breakpoints1503g_num_supported_hw_breakpoints = 0;15041505uint32_t register_DBGDIDR;15061507asm("mrc p14, 0, %0, c0, c0, 0" : "=r"(register_DBGDIDR));1508g_num_supported_hw_breakpoints = Bits32(register_DBGDIDR, 27, 24);1509// Zero is reserved for the BRP count, so don't increment it if it is zero1510if (g_num_supported_hw_breakpoints > 0)1511g_num_supported_hw_breakpoints++;1512}1513return g_num_supported_hw_breakpoints;1514#else1515// TODO: figure out remote case here!1516return 6;1517#endif1518}15191520uint32_t RegisterContextDarwin_arm::SetHardwareBreakpoint(lldb::addr_t addr,1521size_t size) {1522// Make sure our address isn't bogus1523if (addr & 1)1524return LLDB_INVALID_INDEX32;15251526int kret = ReadDBG(false);15271528if (kret == KERN_SUCCESS) {1529const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints();1530uint32_t i;1531for (i = 0; i < num_hw_breakpoints; ++i) {1532if ((dbg.bcr[i] & BCR_ENABLE) == 0)1533break; // We found an available hw breakpoint slot (in i)1534}15351536// See if we found an available hw breakpoint slot above1537if (i < num_hw_breakpoints) {1538// Make sure bits 1:0 are clear in our address1539dbg.bvr[i] = addr & ~((lldb::addr_t)3);15401541if (size == 2 || addr & 2) {1542uint32_t byte_addr_select = (addr & 2) ? BAS_IMVA_2_3 : BAS_IMVA_0_1;15431544// We have a thumb breakpoint1545// We have an ARM breakpoint1546dbg.bcr[i] = BCR_M_IMVA_MATCH | // Stop on address match1547byte_addr_select | // Set the correct byte address select1548// so we only trigger on the correct1549// opcode1550S_USER | // Which modes should this breakpoint stop in?1551BCR_ENABLE; // Enable this hardware breakpoint1552// if (log) log->Printf1553// ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(1554// addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x /1555// 0x%8.8x (Thumb)",1556// addr,1557// size,1558// i,1559// i,1560// dbg.bvr[i],1561// dbg.bcr[i]);1562} else if (size == 4) {1563// We have an ARM breakpoint1564dbg.bcr[i] =1565BCR_M_IMVA_MATCH | // Stop on address match1566BAS_IMVA_ALL | // Stop on any of the four bytes following the IMVA1567S_USER | // Which modes should this breakpoint stop in?1568BCR_ENABLE; // Enable this hardware breakpoint1569// if (log) log->Printf1570// ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(1571// addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x /1572// 0x%8.8x (ARM)",1573// addr,1574// size,1575// i,1576// i,1577// dbg.bvr[i],1578// dbg.bcr[i]);1579}15801581kret = WriteDBG();1582// if (log) log->Printf1583// ("RegisterContextDarwin_arm::EnableHardwareBreakpoint()1584// WriteDBG() => 0x%8.8x.", kret);15851586if (kret == KERN_SUCCESS)1587return i;1588}1589// else1590// {1591// if (log) log->Printf1592// ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(addr =1593// %8.8p, size = %u) => all hardware breakpoint resources are1594// being used.", addr, size);1595// }1596}15971598return LLDB_INVALID_INDEX32;1599}16001601bool RegisterContextDarwin_arm::ClearHardwareBreakpoint(uint32_t hw_index) {1602int kret = ReadDBG(false);16031604const uint32_t num_hw_points = NumSupportedHardwareBreakpoints();1605if (kret == KERN_SUCCESS) {1606if (hw_index < num_hw_points) {1607dbg.bcr[hw_index] = 0;1608// if (log) log->Printf1609// ("RegisterContextDarwin_arm::SetHardwareBreakpoint( %u ) -1610// BVR%u = 0x%8.8x BCR%u = 0x%8.8x",1611// hw_index,1612// hw_index,1613// dbg.bvr[hw_index],1614// hw_index,1615// dbg.bcr[hw_index]);16161617kret = WriteDBG();16181619if (kret == KERN_SUCCESS)1620return true;1621}1622}1623return false;1624}16251626uint32_t RegisterContextDarwin_arm::NumSupportedHardwareWatchpoints() {1627#if defined(__APPLE__) && defined(__arm__)1628// Set the init value to something that will let us know that we need to1629// autodetect how many watchpoints are supported dynamically...1630static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX;1631if (g_num_supported_hw_watchpoints == UINT32_MAX) {1632// Set this to zero in case we can't tell if there are any HW breakpoints1633g_num_supported_hw_watchpoints = 0;16341635uint32_t register_DBGDIDR;1636asm("mrc p14, 0, %0, c0, c0, 0" : "=r"(register_DBGDIDR));1637g_num_supported_hw_watchpoints = Bits32(register_DBGDIDR, 31, 28) + 1;1638}1639return g_num_supported_hw_watchpoints;1640#else1641// TODO: figure out remote case here!1642return 2;1643#endif1644}16451646uint32_t RegisterContextDarwin_arm::SetHardwareWatchpoint(lldb::addr_t addr,1647size_t size,1648bool read,1649bool write) {1650const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();16511652// Can't watch zero bytes1653if (size == 0)1654return LLDB_INVALID_INDEX32;16551656// We must watch for either read or write1657if (!read && !write)1658return LLDB_INVALID_INDEX32;16591660// Can't watch more than 4 bytes per WVR/WCR pair1661if (size > 4)1662return LLDB_INVALID_INDEX32;16631664// We can only watch up to four bytes that follow a 4 byte aligned address1665// per watchpoint register pair. Since we have at most so we can only watch1666// until the next 4 byte boundary and we need to make sure we can properly1667// encode this.1668uint32_t addr_word_offset = addr % 4;1669// if (log) log->Printf1670// ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() -1671// addr_word_offset = 0x%8.8x", addr_word_offset);16721673uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset;1674// if (log) log->Printf1675// ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - byte_mask =1676// 0x%8.8x", byte_mask);1677if (byte_mask > 0xfu)1678return LLDB_INVALID_INDEX32;16791680// Read the debug state1681int kret = ReadDBG(false);16821683if (kret == KERN_SUCCESS) {1684// Check to make sure we have the needed hardware support1685uint32_t i = 0;16861687for (i = 0; i < num_hw_watchpoints; ++i) {1688if ((dbg.wcr[i] & WCR_ENABLE) == 0)1689break; // We found an available hw breakpoint slot (in i)1690}16911692// See if we found an available hw breakpoint slot above1693if (i < num_hw_watchpoints) {1694// Make the byte_mask into a valid Byte Address Select mask1695uint32_t byte_address_select = byte_mask << 5;1696// Make sure bits 1:0 are clear in our address1697dbg.wvr[i] = addr & ~((lldb::addr_t)3);1698dbg.wcr[i] = byte_address_select | // Which bytes that follow the IMVA1699// that we will watch1700S_USER | // Stop only in user mode1701(read ? WCR_LOAD : 0) | // Stop on read access?1702(write ? WCR_STORE : 0) | // Stop on write access?1703WCR_ENABLE; // Enable this watchpoint;17041705kret = WriteDBG();1706// if (log) log->Printf1707// ("RegisterContextDarwin_arm::EnableHardwareWatchpoint()1708// WriteDBG() => 0x%8.8x.", kret);17091710if (kret == KERN_SUCCESS)1711return i;1712} else {1713// if (log) log->Printf1714// ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(): All1715// hardware resources (%u) are in use.", num_hw_watchpoints);1716}1717}1718return LLDB_INVALID_INDEX32;1719}17201721bool RegisterContextDarwin_arm::ClearHardwareWatchpoint(uint32_t hw_index) {1722int kret = ReadDBG(false);17231724const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();1725if (kret == KERN_SUCCESS) {1726if (hw_index < num_hw_points) {1727dbg.wcr[hw_index] = 0;1728// if (log) log->Printf1729// ("RegisterContextDarwin_arm::ClearHardwareWatchpoint( %u ) -1730// WVR%u = 0x%8.8x WCR%u = 0x%8.8x",1731// hw_index,1732// hw_index,1733// dbg.wvr[hw_index],1734// hw_index,1735// dbg.wcr[hw_index]);17361737kret = WriteDBG();17381739if (kret == KERN_SUCCESS)1740return true;1741}1742}1743return false;1744}174517461747