1 //===-- RegisterContextDarwin_arm.h -----------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef liblldb_RegisterContextDarwin_arm_h_ 11 #define liblldb_RegisterContextDarwin_arm_h_ 12 13 // C Includes 14 // C++ Includes 15 // Other libraries and framework includes 16 // Project includes 17 #include "lldb/Target/RegisterContext.h" 18 #include "lldb/lldb-private.h" 19 20 // BCR address match type 21 #define BCR_M_IMVA_MATCH ((uint32_t)(0u << 21)) 22 #define BCR_M_CONTEXT_ID_MATCH ((uint32_t)(1u << 21)) 23 #define BCR_M_IMVA_MISMATCH ((uint32_t)(2u << 21)) 24 #define BCR_M_RESERVED ((uint32_t)(3u << 21)) 25 26 // Link a BVR/BCR or WVR/WCR pair to another 27 #define E_ENABLE_LINKING ((uint32_t)(1u << 20)) 28 29 // Byte Address Select 30 #define BAS_IMVA_PLUS_0 ((uint32_t)(1u << 5)) 31 #define BAS_IMVA_PLUS_1 ((uint32_t)(1u << 6)) 32 #define BAS_IMVA_PLUS_2 ((uint32_t)(1u << 7)) 33 #define BAS_IMVA_PLUS_3 ((uint32_t)(1u << 8)) 34 #define BAS_IMVA_0_1 ((uint32_t)(3u << 5)) 35 #define BAS_IMVA_2_3 ((uint32_t)(3u << 7)) 36 #define BAS_IMVA_ALL ((uint32_t)(0xfu << 5)) 37 38 // Break only in privileged or user mode 39 #define S_RSVD ((uint32_t)(0u << 1)) 40 #define S_PRIV ((uint32_t)(1u << 1)) 41 #define S_USER ((uint32_t)(2u << 1)) 42 #define S_PRIV_USER ((S_PRIV) | (S_USER)) 43 44 #define BCR_ENABLE ((uint32_t)(1u)) 45 #define WCR_ENABLE ((uint32_t)(1u)) 46 47 // Watchpoint load/store 48 #define WCR_LOAD ((uint32_t)(1u << 3)) 49 #define WCR_STORE ((uint32_t)(1u << 4)) 50 51 class RegisterContextDarwin_arm : public lldb_private::RegisterContext { 52 public: 53 RegisterContextDarwin_arm(lldb_private::Thread &thread, 54 uint32_t concrete_frame_idx); 55 56 ~RegisterContextDarwin_arm() override; 57 58 void InvalidateAllRegisters() override; 59 60 size_t GetRegisterCount() override; 61 62 const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; 63 64 size_t GetRegisterSetCount() override; 65 66 const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; 67 68 bool ReadRegister(const lldb_private::RegisterInfo *reg_info, 69 lldb_private::RegisterValue ®_value) override; 70 71 bool WriteRegister(const lldb_private::RegisterInfo *reg_info, 72 const lldb_private::RegisterValue ®_value) override; 73 74 bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; 75 76 bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; 77 78 uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, 79 uint32_t num) override; 80 81 uint32_t NumSupportedHardwareBreakpoints() override; 82 83 uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override; 84 85 bool ClearHardwareBreakpoint(uint32_t hw_idx) override; 86 87 uint32_t NumSupportedHardwareWatchpoints() override; 88 89 uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, 90 bool write) override; 91 92 bool ClearHardwareWatchpoint(uint32_t hw_index) override; 93 94 struct GPR { 95 uint32_t r[16]; // R0-R15 96 uint32_t cpsr; // CPSR 97 }; 98 99 struct QReg { 100 uint8_t bytes[16]; 101 }; 102 103 struct FPU { 104 union { 105 uint32_t s[32]; 106 uint64_t d[32]; 107 QReg q[16]; // the 128-bit NEON registers 108 } floats; 109 uint32_t fpscr; 110 }; 111 112 // struct NeonReg 113 // { 114 // uint8_t bytes[16]; 115 // }; 116 // 117 // struct VFPv3 118 // { 119 // union { 120 // uint32_t s[32]; 121 // uint64_t d[32]; 122 // NeonReg q[16]; 123 // } v3; 124 // uint32_t fpscr; 125 // }; 126 127 struct EXC { 128 uint32_t exception; 129 uint32_t fsr; /* Fault status */ 130 uint32_t far; /* Virtual Fault Address */ 131 }; 132 133 struct DBG { 134 uint32_t bvr[16]; 135 uint32_t bcr[16]; 136 uint32_t wvr[16]; 137 uint32_t wcr[16]; 138 }; 139 140 static void LogDBGRegisters(lldb_private::Log *log, const DBG &dbg); 141 142 protected: 143 enum { 144 GPRRegSet = 1, // ARM_THREAD_STATE 145 GPRAltRegSet = 9, // ARM_THREAD_STATE32 146 FPURegSet = 2, // ARM_VFP_STATE 147 EXCRegSet = 3, // ARM_EXCEPTION_STATE 148 DBGRegSet = 4 // ARM_DEBUG_STATE 149 }; 150 151 enum { 152 GPRWordCount = sizeof(GPR) / sizeof(uint32_t), 153 FPUWordCount = sizeof(FPU) / sizeof(uint32_t), 154 EXCWordCount = sizeof(EXC) / sizeof(uint32_t), 155 DBGWordCount = sizeof(DBG) / sizeof(uint32_t) 156 }; 157 158 enum { Read = 0, Write = 1, kNumErrors = 2 }; 159 160 GPR gpr; 161 FPU fpu; 162 EXC exc; 163 DBG dbg; 164 int gpr_errs[2]; // Read/Write errors 165 int fpu_errs[2]; // Read/Write errors 166 int exc_errs[2]; // Read/Write errors 167 int dbg_errs[2]; // Read/Write errors 168 169 void InvalidateAllRegisterStates() { 170 SetError(GPRRegSet, Read, -1); 171 SetError(FPURegSet, Read, -1); 172 SetError(EXCRegSet, Read, -1); 173 } 174 175 int GetError(int flavor, uint32_t err_idx) const { 176 if (err_idx < kNumErrors) { 177 switch (flavor) { 178 // When getting all errors, just OR all values together to see if 179 // we got any kind of error. 180 case GPRRegSet: 181 return gpr_errs[err_idx]; 182 case FPURegSet: 183 return fpu_errs[err_idx]; 184 case EXCRegSet: 185 return exc_errs[err_idx]; 186 case DBGRegSet: 187 return dbg_errs[err_idx]; 188 default: 189 break; 190 } 191 } 192 return -1; 193 } 194 195 bool SetError(int flavor, uint32_t err_idx, int err) { 196 if (err_idx < kNumErrors) { 197 switch (flavor) { 198 case GPRRegSet: 199 gpr_errs[err_idx] = err; 200 return true; 201 202 case FPURegSet: 203 fpu_errs[err_idx] = err; 204 return true; 205 206 case EXCRegSet: 207 exc_errs[err_idx] = err; 208 return true; 209 210 case DBGRegSet: 211 exc_errs[err_idx] = err; 212 return true; 213 214 default: 215 break; 216 } 217 } 218 return false; 219 } 220 221 bool RegisterSetIsCached(int set) const { return GetError(set, Read) == 0; } 222 223 int ReadGPR(bool force); 224 225 int ReadFPU(bool force); 226 227 int ReadEXC(bool force); 228 229 int ReadDBG(bool force); 230 231 int WriteGPR(); 232 233 int WriteFPU(); 234 235 int WriteEXC(); 236 237 int WriteDBG(); 238 239 // Subclasses override these to do the actual reading. 240 virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) { return -1; } 241 242 virtual int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) = 0; 243 244 virtual int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) = 0; 245 246 virtual int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) = 0; 247 248 virtual int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) = 0; 249 250 virtual int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) = 0; 251 252 virtual int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) = 0; 253 254 virtual int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) = 0; 255 256 int ReadRegisterSet(uint32_t set, bool force); 257 258 int WriteRegisterSet(uint32_t set); 259 260 static uint32_t GetRegisterNumber(uint32_t reg_kind, uint32_t reg_num); 261 262 static int GetSetForNativeRegNum(int reg_num); 263 264 static size_t GetRegisterInfosCount(); 265 266 static const lldb_private::RegisterInfo *GetRegisterInfos(); 267 }; 268 269 #endif // liblldb_RegisterContextDarwin_arm_h_ 270