Home | History | Annotate | Download | only in Utility
      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 &reg_value);
     78 
     79     virtual bool
     80     WriteRegister (const lldb_private::RegisterInfo *reg_info,
     81                    const lldb_private::RegisterValue &reg_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