112651Skvn//===-- RegisterContextDarwin_arm.h -----------------------------*- C++ -*-===// 212651Skvn// 312651Skvn// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 412651Skvn// See https://llvm.org/LICENSE.txt for license information. 512651Skvn// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 612651Skvn// 712651Skvn//===----------------------------------------------------------------------===// 812651Skvn 912651Skvn#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM_H 1012651Skvn#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM_H 1112651Skvn 1212651Skvn#include "lldb/Target/RegisterContext.h" 1312651Skvn#include "lldb/lldb-private.h" 1412651Skvn 1512651Skvn// BCR address match type 1612651Skvn#define BCR_M_IMVA_MATCH ((uint32_t)(0u << 21)) 1712651Skvn#define BCR_M_CONTEXT_ID_MATCH ((uint32_t)(1u << 21)) 1812651Skvn#define BCR_M_IMVA_MISMATCH ((uint32_t)(2u << 21)) 1912651Skvn#define BCR_M_RESERVED ((uint32_t)(3u << 21)) 2012651Skvn 2112651Skvn// Link a BVR/BCR or WVR/WCR pair to another 2212651Skvn#define E_ENABLE_LINKING ((uint32_t)(1u << 20)) 2312651Skvn 2412651Skvn// Byte Address Select 2512651Skvn#define BAS_IMVA_PLUS_0 ((uint32_t)(1u << 5)) 2612651Skvn#define BAS_IMVA_PLUS_1 ((uint32_t)(1u << 6)) 2712651Skvn#define BAS_IMVA_PLUS_2 ((uint32_t)(1u << 7)) 2812651Skvn#define BAS_IMVA_PLUS_3 ((uint32_t)(1u << 8)) 2912651Skvn#define BAS_IMVA_0_1 ((uint32_t)(3u << 5)) 3012651Skvn#define BAS_IMVA_2_3 ((uint32_t)(3u << 7)) 3112651Skvn#define BAS_IMVA_ALL ((uint32_t)(0xfu << 5)) 3212651Skvn 3312651Skvn// Break only in privileged or user mode 3412651Skvn#define S_RSVD ((uint32_t)(0u << 1)) 3512651Skvn#define S_PRIV ((uint32_t)(1u << 1)) 3612651Skvn#define S_USER ((uint32_t)(2u << 1)) 3712651Skvn#define S_PRIV_USER ((S_PRIV) | (S_USER)) 3812651Skvn 3912651Skvn#define BCR_ENABLE ((uint32_t)(1u)) 4012651Skvn#define WCR_ENABLE ((uint32_t)(1u)) 4112651Skvn 4212651Skvn// Watchpoint load/store 4312651Skvn#define WCR_LOAD ((uint32_t)(1u << 3)) 4412651Skvn#define WCR_STORE ((uint32_t)(1u << 4)) 4512651Skvn 4612651Skvnclass RegisterContextDarwin_arm : public lldb_private::RegisterContext { 4712651Skvnpublic: 4812651Skvn RegisterContextDarwin_arm(lldb_private::Thread &thread, 4912651Skvn uint32_t concrete_frame_idx); 5012651Skvn 5112651Skvn ~RegisterContextDarwin_arm() override; 5212651Skvn 5312651Skvn void InvalidateAllRegisters() override; 5412651Skvn 5512651Skvn size_t GetRegisterCount() override; 5612651Skvn 5712651Skvn const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; 5812651Skvn 5912651Skvn size_t GetRegisterSetCount() override; 6012651Skvn 6112651Skvn const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; 6212651Skvn 6312651Skvn bool ReadRegister(const lldb_private::RegisterInfo *reg_info, 6412651Skvn lldb_private::RegisterValue ®_value) override; 6512651Skvn 6612651Skvn bool WriteRegister(const lldb_private::RegisterInfo *reg_info, 6712651Skvn const lldb_private::RegisterValue ®_value) override; 6812651Skvn 6912651Skvn bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; 7012651Skvn 7112651Skvn bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; 7212651Skvn 7312651Skvn uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, 7412651Skvn uint32_t num) override; 7512651Skvn 7612651Skvn uint32_t NumSupportedHardwareBreakpoints() override; 7712651Skvn 7812651Skvn uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override; 7912651Skvn 8012651Skvn bool ClearHardwareBreakpoint(uint32_t hw_idx) override; 8112651Skvn 8212651Skvn uint32_t NumSupportedHardwareWatchpoints() override; 8312651Skvn 8412651Skvn uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, 8512651Skvn bool write) override; 8612651Skvn 8712651Skvn bool ClearHardwareWatchpoint(uint32_t hw_index) override; 8812651Skvn 8912651Skvn struct GPR { 9012651Skvn uint32_t r[16]; // R0-R15 9112651Skvn uint32_t cpsr; // CPSR 9212651Skvn }; 9312651Skvn 9412651Skvn struct QReg { 9512651Skvn uint8_t bytes[16]; 9612651Skvn }; 9712651Skvn 9812651Skvn struct FPU { 9912651Skvn union { 10012651Skvn uint32_t s[32]; 10112651Skvn uint64_t d[32]; 10212651Skvn QReg q[16]; // the 128-bit NEON registers 10312651Skvn } floats; 10412651Skvn uint32_t fpscr; 10512651Skvn }; 10612651Skvn 10712651Skvn // struct NeonReg 10812651Skvn // { 10912651Skvn // uint8_t bytes[16]; 11012651Skvn // }; 11112651Skvn // 11212651Skvn // struct VFPv3 11312651Skvn // { 11412651Skvn // union { 11512651Skvn // uint32_t s[32]; 11612651Skvn // uint64_t d[32]; 11712651Skvn // NeonReg q[16]; 11812651Skvn // } v3; 11912651Skvn // uint32_t fpscr; 12012651Skvn // }; 12112651Skvn 12212651Skvn struct EXC { 12312651Skvn uint32_t exception; 12412651Skvn uint32_t fsr; /* Fault status */ 12512651Skvn uint32_t far; /* Virtual Fault Address */ 12612651Skvn }; 12712651Skvn 12812651Skvn struct DBG { 12912651Skvn uint32_t bvr[16]; 13012651Skvn uint32_t bcr[16]; 13112651Skvn uint32_t wvr[16]; 13212651Skvn uint32_t wcr[16]; 13312651Skvn }; 13412651Skvn 13512651Skvn static void LogDBGRegisters(lldb_private::Log *log, const DBG &dbg); 13612651Skvn 13712651Skvnprotected: 13812651Skvn enum { 13912651Skvn GPRRegSet = 1, // ARM_THREAD_STATE 14012651Skvn GPRAltRegSet = 9, // ARM_THREAD_STATE32 14112651Skvn FPURegSet = 2, // ARM_VFP_STATE 14212651Skvn EXCRegSet = 3, // ARM_EXCEPTION_STATE 14312651Skvn DBGRegSet = 4 // ARM_DEBUG_STATE 14412651Skvn }; 14512651Skvn 14612651Skvn enum { 14712651Skvn GPRWordCount = sizeof(GPR) / sizeof(uint32_t), 14812651Skvn FPUWordCount = sizeof(FPU) / sizeof(uint32_t), 14912651Skvn EXCWordCount = sizeof(EXC) / sizeof(uint32_t), 15012651Skvn DBGWordCount = sizeof(DBG) / sizeof(uint32_t) 15112651Skvn }; 15212651Skvn 15312651Skvn enum { Read = 0, Write = 1, kNumErrors = 2 }; 15412651Skvn 15512651Skvn GPR gpr; 15612651Skvn FPU fpu; 15712651Skvn EXC exc; 15812651Skvn DBG dbg; 15912651Skvn int gpr_errs[2]; // Read/Write errors 16012651Skvn int fpu_errs[2]; // Read/Write errors 16112651Skvn int exc_errs[2]; // Read/Write errors 16212651Skvn int dbg_errs[2]; // Read/Write errors 16312651Skvn 16412651Skvn void InvalidateAllRegisterStates() { 16512651Skvn SetError(GPRRegSet, Read, -1); 16612651Skvn SetError(FPURegSet, Read, -1); 16712651Skvn SetError(EXCRegSet, Read, -1); 16812651Skvn } 16912651Skvn 17012651Skvn int GetError(int flavor, uint32_t err_idx) const { 17112651Skvn if (err_idx < kNumErrors) { 17212651Skvn switch (flavor) { 17312651Skvn // When getting all errors, just OR all values together to see if 17412651Skvn // we got any kind of error. 17512651Skvn case GPRRegSet: 17612651Skvn return gpr_errs[err_idx]; 17712651Skvn case FPURegSet: 17812651Skvn return fpu_errs[err_idx]; 17912651Skvn case EXCRegSet: 18012651Skvn return exc_errs[err_idx]; 18112651Skvn case DBGRegSet: 18212651Skvn return dbg_errs[err_idx]; 18312651Skvn default: 18412651Skvn break; 18512651Skvn } 18612651Skvn } 18712651Skvn return -1; 18812651Skvn } 18912651Skvn 19012651Skvn bool SetError(int flavor, uint32_t err_idx, int err) { 19112651Skvn if (err_idx < kNumErrors) { 19212651Skvn switch (flavor) { 19312651Skvn case GPRRegSet: 19412651Skvn gpr_errs[err_idx] = err; 19512651Skvn return true; 19612651Skvn 19712651Skvn case FPURegSet: 19812651Skvn fpu_errs[err_idx] = err; 19912651Skvn return true; 20012651Skvn 20112651Skvn case EXCRegSet: 20212651Skvn exc_errs[err_idx] = err; 20312651Skvn return true; 20412651Skvn 20512651Skvn case DBGRegSet: 20612651Skvn exc_errs[err_idx] = err; 20712651Skvn return true; 20812651Skvn 20912651Skvn default: 21012651Skvn break; 21112651Skvn } 21212651Skvn } 21312651Skvn return false; 21412651Skvn } 21512651Skvn 21612651Skvn bool RegisterSetIsCached(int set) const { return GetError(set, Read) == 0; } 21712651Skvn 21812651Skvn int ReadGPR(bool force); 21912651Skvn 22012651Skvn int ReadFPU(bool force); 22112651Skvn 22212651Skvn int ReadEXC(bool force); 22312651Skvn 22412651Skvn int ReadDBG(bool force); 22512651Skvn 22612651Skvn int WriteGPR(); 22712651Skvn 22812651Skvn int WriteFPU(); 22912651Skvn 23012651Skvn int WriteEXC(); 23112651Skvn 23212651Skvn int WriteDBG(); 23312651Skvn 23412651Skvn // Subclasses override these to do the actual reading. 23512651Skvn virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) { return -1; } 23612651Skvn 23712651Skvn virtual int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) = 0; 23812651Skvn 23912651Skvn virtual int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) = 0; 24012651Skvn 24112651Skvn virtual int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) = 0; 24212651Skvn 24312651Skvn virtual int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) = 0; 24412651Skvn 24512651Skvn virtual int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) = 0; 24612651Skvn 24712651Skvn virtual int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) = 0; 24812651Skvn 24912651Skvn virtual int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) = 0; 25012651Skvn 251 int ReadRegisterSet(uint32_t set, bool force); 252 253 int WriteRegisterSet(uint32_t set); 254 255 static uint32_t GetRegisterNumber(uint32_t reg_kind, uint32_t reg_num); 256 257 static int GetSetForNativeRegNum(int reg_num); 258 259 static size_t GetRegisterInfosCount(); 260 261 static const lldb_private::RegisterInfo *GetRegisterInfos(); 262}; 263 264#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM_H 265