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/lldb-private.h" 18 #include "lldb/Target/RegisterContext.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 { 53 public: 54 55 RegisterContextDarwin_arm(lldb_private::Thread &thread, uint32_t concrete_frame_idx); 56 57 virtual 58 ~RegisterContextDarwin_arm(); 59 60 virtual void 61 InvalidateAllRegisters (); 62 63 virtual size_t 64 GetRegisterCount (); 65 66 virtual const lldb_private::RegisterInfo * 67 GetRegisterInfoAtIndex (size_t reg); 68 69 virtual size_t 70 GetRegisterSetCount (); 71 72 virtual const lldb_private::RegisterSet * 73 GetRegisterSet (size_t set); 74 75 virtual bool 76 ReadRegister (const lldb_private::RegisterInfo *reg_info, 77 lldb_private::RegisterValue ®_value); 78 79 virtual bool 80 WriteRegister (const lldb_private::RegisterInfo *reg_info, 81 const lldb_private::RegisterValue ®_value); 82 83 virtual bool 84 ReadAllRegisterValues (lldb::DataBufferSP &data_sp); 85 86 virtual bool 87 WriteAllRegisterValues (const lldb::DataBufferSP &data_sp); 88 89 virtual uint32_t 90 ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num); 91 92 virtual uint32_t 93 NumSupportedHardwareBreakpoints (); 94 95 virtual uint32_t 96 SetHardwareBreakpoint (lldb::addr_t addr, size_t size); 97 98 virtual bool 99 ClearHardwareBreakpoint (uint32_t hw_idx); 100 101 virtual uint32_t 102 NumSupportedHardwareWatchpoints (); 103 104 virtual uint32_t 105 SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write); 106 107 virtual bool 108 ClearHardwareWatchpoint (uint32_t hw_index); 109 110 struct GPR 111 { 112 uint32_t r[16]; // R0-R15 113 uint32_t cpsr; // CPSR 114 }; 115 116 117 struct QReg 118 { 119 uint8_t bytes[16]; 120 }; 121 122 struct FPU 123 { 124 union { 125 uint32_t s[32]; 126 uint64_t d[32]; 127 QReg q[16]; // the 128-bit NEON registers 128 } floats; 129 uint32_t fpscr; 130 }; 131 132 // struct NeonReg 133 // { 134 // uint8_t bytes[16]; 135 // }; 136 // 137 // struct VFPv3 138 // { 139 // union { 140 // uint32_t s[32]; 141 // uint64_t d[32]; 142 // NeonReg q[16]; 143 // } v3; 144 // uint32_t fpscr; 145 // }; 146 147 struct EXC 148 { 149 uint32_t exception; 150 uint32_t fsr; /* Fault status */ 151 uint32_t far; /* Virtual Fault Address */ 152 }; 153 154 struct DBG 155 { 156 uint32_t bvr[16]; 157 uint32_t bcr[16]; 158 uint32_t wvr[16]; 159 uint32_t wcr[16]; 160 }; 161 162 static void 163 LogDBGRegisters (lldb_private::Log *log, const DBG& dbg); 164 165 protected: 166 167 enum 168 { 169 GPRRegSet = 1, // ARM_THREAD_STATE 170 FPURegSet = 2, // ARM_VFP_STATE 171 EXCRegSet = 3, // ARM_EXCEPTION_STATE 172 DBGRegSet = 4 // ARM_DEBUG_STATE 173 }; 174 175 enum 176 { 177 GPRWordCount = sizeof(GPR)/sizeof(uint32_t), 178 FPUWordCount = sizeof(FPU)/sizeof(uint32_t), 179 EXCWordCount = sizeof(EXC)/sizeof(uint32_t), 180 DBGWordCount = sizeof(DBG)/sizeof(uint32_t) 181 }; 182 183 enum 184 { 185 Read = 0, 186 Write = 1, 187 kNumErrors = 2 188 }; 189 190 GPR gpr; 191 FPU fpu; 192 EXC exc; 193 DBG dbg; 194 int gpr_errs[2]; // Read/Write errors 195 int fpu_errs[2]; // Read/Write errors 196 int exc_errs[2]; // Read/Write errors 197 int dbg_errs[2]; // Read/Write errors 198 199 void 200 InvalidateAllRegisterStates() 201 { 202 SetError (GPRRegSet, Read, -1); 203 SetError (FPURegSet, Read, -1); 204 SetError (EXCRegSet, Read, -1); 205 } 206 207 int 208 GetError (int flavor, uint32_t err_idx) const 209 { 210 if (err_idx < kNumErrors) 211 { 212 switch (flavor) 213 { 214 // When getting all errors, just OR all values together to see if 215 // we got any kind of error. 216 case GPRRegSet: return gpr_errs[err_idx]; 217 case FPURegSet: return fpu_errs[err_idx]; 218 case EXCRegSet: return exc_errs[err_idx]; 219 case DBGRegSet: return dbg_errs[err_idx]; 220 default: break; 221 } 222 } 223 return -1; 224 } 225 226 bool 227 SetError (int flavor, uint32_t err_idx, int err) 228 { 229 if (err_idx < kNumErrors) 230 { 231 switch (flavor) 232 { 233 case GPRRegSet: 234 gpr_errs[err_idx] = err; 235 return true; 236 237 case FPURegSet: 238 fpu_errs[err_idx] = err; 239 return true; 240 241 case EXCRegSet: 242 exc_errs[err_idx] = err; 243 return true; 244 245 case DBGRegSet: 246 exc_errs[err_idx] = err; 247 return true; 248 249 default: break; 250 } 251 } 252 return false; 253 } 254 255 bool 256 RegisterSetIsCached (int set) const 257 { 258 return GetError(set, Read) == 0; 259 } 260 261 int 262 ReadGPR (bool force); 263 264 int 265 ReadFPU (bool force); 266 267 int 268 ReadEXC (bool force); 269 270 int 271 ReadDBG (bool force); 272 273 int 274 WriteGPR (); 275 276 int 277 WriteFPU (); 278 279 int 280 WriteEXC (); 281 282 int 283 WriteDBG (); 284 285 286 // Subclasses override these to do the actual reading. 287 virtual int 288 DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr) 289 { 290 return -1; 291 } 292 293 virtual int 294 DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu) = 0; 295 296 virtual int 297 DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc) = 0; 298 299 virtual int 300 DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg) = 0; 301 302 virtual int 303 DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr) = 0; 304 305 virtual int 306 DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu) = 0; 307 308 virtual int 309 DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc) = 0; 310 311 virtual int 312 DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg) = 0; 313 314 int 315 ReadRegisterSet (uint32_t set, bool force); 316 317 int 318 WriteRegisterSet (uint32_t set); 319 320 static uint32_t 321 GetRegisterNumber (uint32_t reg_kind, uint32_t reg_num); 322 323 static int 324 GetSetForNativeRegNum (int reg_num); 325 326 static size_t 327 GetRegisterInfosCount (); 328 329 static const lldb_private::RegisterInfo * 330 GetRegisterInfos (); 331 }; 332 333 #endif // liblldb_RegisterContextDarwin_arm_h_ 334