Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h
96381 views
//===-- RegisterContextDarwin_arm.h -----------------------------*- C++ -*-===//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#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM_H9#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM_H1011#include "lldb/Target/RegisterContext.h"12#include "lldb/lldb-private.h"1314// BCR address match type15#define BCR_M_IMVA_MATCH ((uint32_t)(0u << 21))16#define BCR_M_CONTEXT_ID_MATCH ((uint32_t)(1u << 21))17#define BCR_M_IMVA_MISMATCH ((uint32_t)(2u << 21))18#define BCR_M_RESERVED ((uint32_t)(3u << 21))1920// Link a BVR/BCR or WVR/WCR pair to another21#define E_ENABLE_LINKING ((uint32_t)(1u << 20))2223// Byte Address Select24#define BAS_IMVA_PLUS_0 ((uint32_t)(1u << 5))25#define BAS_IMVA_PLUS_1 ((uint32_t)(1u << 6))26#define BAS_IMVA_PLUS_2 ((uint32_t)(1u << 7))27#define BAS_IMVA_PLUS_3 ((uint32_t)(1u << 8))28#define BAS_IMVA_0_1 ((uint32_t)(3u << 5))29#define BAS_IMVA_2_3 ((uint32_t)(3u << 7))30#define BAS_IMVA_ALL ((uint32_t)(0xfu << 5))3132// Break only in privileged or user mode33#define S_RSVD ((uint32_t)(0u << 1))34#define S_PRIV ((uint32_t)(1u << 1))35#define S_USER ((uint32_t)(2u << 1))36#define S_PRIV_USER ((S_PRIV) | (S_USER))3738#define BCR_ENABLE ((uint32_t)(1u))39#define WCR_ENABLE ((uint32_t)(1u))4041// Watchpoint load/store42#define WCR_LOAD ((uint32_t)(1u << 3))43#define WCR_STORE ((uint32_t)(1u << 4))4445class RegisterContextDarwin_arm : public lldb_private::RegisterContext {46public:47RegisterContextDarwin_arm(lldb_private::Thread &thread,48uint32_t concrete_frame_idx);4950~RegisterContextDarwin_arm() override;5152void InvalidateAllRegisters() override;5354size_t GetRegisterCount() override;5556const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;5758size_t GetRegisterSetCount() override;5960const lldb_private::RegisterSet *GetRegisterSet(size_t set) override;6162bool ReadRegister(const lldb_private::RegisterInfo *reg_info,63lldb_private::RegisterValue ®_value) override;6465bool WriteRegister(const lldb_private::RegisterInfo *reg_info,66const lldb_private::RegisterValue ®_value) override;6768bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override;6970bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;7172uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,73uint32_t num) override;7475uint32_t NumSupportedHardwareBreakpoints() override;7677uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;7879bool ClearHardwareBreakpoint(uint32_t hw_idx) override;8081uint32_t NumSupportedHardwareWatchpoints() override;8283uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,84bool write) override;8586bool ClearHardwareWatchpoint(uint32_t hw_index) override;8788struct GPR {89uint32_t r[16]; // R0-R1590uint32_t cpsr; // CPSR91};9293struct QReg {94uint8_t bytes[16];95};9697struct FPU {98union {99uint32_t s[32];100uint64_t d[32];101QReg q[16]; // the 128-bit NEON registers102} floats;103uint32_t fpscr;104};105106// struct NeonReg107// {108// uint8_t bytes[16];109// };110//111// struct VFPv3112// {113// union {114// uint32_t s[32];115// uint64_t d[32];116// NeonReg q[16];117// } v3;118// uint32_t fpscr;119// };120121struct EXC {122uint32_t exception;123uint32_t fsr; /* Fault status */124uint32_t far; /* Virtual Fault Address */125};126127struct DBG {128uint32_t bvr[16];129uint32_t bcr[16];130uint32_t wvr[16];131uint32_t wcr[16];132};133134static void LogDBGRegisters(lldb_private::Log *log, const DBG &dbg);135136protected:137enum {138GPRRegSet = 1, // ARM_THREAD_STATE139GPRAltRegSet = 9, // ARM_THREAD_STATE32140FPURegSet = 2, // ARM_VFP_STATE141EXCRegSet = 3, // ARM_EXCEPTION_STATE142DBGRegSet = 4 // ARM_DEBUG_STATE143};144145enum {146GPRWordCount = sizeof(GPR) / sizeof(uint32_t),147FPUWordCount = sizeof(FPU) / sizeof(uint32_t),148EXCWordCount = sizeof(EXC) / sizeof(uint32_t),149DBGWordCount = sizeof(DBG) / sizeof(uint32_t)150};151152enum { Read = 0, Write = 1, kNumErrors = 2 };153154GPR gpr;155FPU fpu;156EXC exc;157DBG dbg;158int gpr_errs[2]; // Read/Write errors159int fpu_errs[2]; // Read/Write errors160int exc_errs[2]; // Read/Write errors161int dbg_errs[2]; // Read/Write errors162163void InvalidateAllRegisterStates() {164SetError(GPRRegSet, Read, -1);165SetError(FPURegSet, Read, -1);166SetError(EXCRegSet, Read, -1);167}168169int GetError(int flavor, uint32_t err_idx) const {170if (err_idx < kNumErrors) {171switch (flavor) {172// When getting all errors, just OR all values together to see if173// we got any kind of error.174case GPRRegSet:175return gpr_errs[err_idx];176case FPURegSet:177return fpu_errs[err_idx];178case EXCRegSet:179return exc_errs[err_idx];180case DBGRegSet:181return dbg_errs[err_idx];182default:183break;184}185}186return -1;187}188189bool SetError(int flavor, uint32_t err_idx, int err) {190if (err_idx < kNumErrors) {191switch (flavor) {192case GPRRegSet:193gpr_errs[err_idx] = err;194return true;195196case FPURegSet:197fpu_errs[err_idx] = err;198return true;199200case EXCRegSet:201exc_errs[err_idx] = err;202return true;203204case DBGRegSet:205exc_errs[err_idx] = err;206return true;207208default:209break;210}211}212return false;213}214215bool RegisterSetIsCached(int set) const { return GetError(set, Read) == 0; }216217int ReadGPR(bool force);218219int ReadFPU(bool force);220221int ReadEXC(bool force);222223int ReadDBG(bool force);224225int WriteGPR();226227int WriteFPU();228229int WriteEXC();230231int WriteDBG();232233// Subclasses override these to do the actual reading.234virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) { return -1; }235236virtual int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) = 0;237238virtual int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) = 0;239240virtual int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) = 0;241242virtual int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) = 0;243244virtual int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) = 0;245246virtual int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) = 0;247248virtual int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) = 0;249250int ReadRegisterSet(uint32_t set, bool force);251252int WriteRegisterSet(uint32_t set);253254static uint32_t GetRegisterNumber(uint32_t reg_kind, uint32_t reg_num);255256static int GetSetForNativeRegNum(int reg_num);257258static size_t GetRegisterInfosCount();259260static const lldb_private::RegisterInfo *GetRegisterInfos();261};262263#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_ARM_H264265266