Home | History | Annotate | Download | only in Utility
      1 //===-- RegisterContextDarwin_arm.cpp ---------------------------*- 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 #if defined(__APPLE__)
     11 
     12 #include "RegisterContextDarwin_arm.h"
     13 
     14 // C Includes
     15 #include <mach/mach_types.h>
     16 #include <mach/thread_act.h>
     17 
     18 // C++ Includes
     19 // Other libraries and framework includes
     20 #include "lldb/Core/DataBufferHeap.h"
     21 #include "lldb/Core/DataExtractor.h"
     22 #include "lldb/Core/Log.h"
     23 #include "lldb/Core/RegisterValue.h"
     24 #include "lldb/Core/Scalar.h"
     25 #include "lldb/Host/Endian.h"
     26 #include "llvm/Support/Compiler.h"
     27 
     28 #include "Plugins/Process/Utility/InstructionUtils.h"
     29 
     30 // Support building against older versions of LLVM, this macro was added
     31 // recently.
     32 #ifndef LLVM_EXTENSION
     33 #define LLVM_EXTENSION
     34 #endif
     35 
     36 // Project includes
     37 #include "ARM_GCC_Registers.h"
     38 #include "ARM_DWARF_Registers.h"
     39 
     40 using namespace lldb;
     41 using namespace lldb_private;
     42 
     43 enum
     44 {
     45     gpr_r0 = 0,
     46     gpr_r1,
     47     gpr_r2,
     48     gpr_r3,
     49     gpr_r4,
     50     gpr_r5,
     51     gpr_r6,
     52     gpr_r7,
     53     gpr_r8,
     54     gpr_r9,
     55     gpr_r10,
     56     gpr_r11,
     57     gpr_r12,
     58     gpr_r13, gpr_sp = gpr_r13,
     59     gpr_r14, gpr_lr = gpr_r14,
     60     gpr_r15, gpr_pc = gpr_r15,
     61     gpr_cpsr,
     62 
     63     fpu_s0,
     64     fpu_s1,
     65     fpu_s2,
     66     fpu_s3,
     67     fpu_s4,
     68     fpu_s5,
     69     fpu_s6,
     70     fpu_s7,
     71     fpu_s8,
     72     fpu_s9,
     73     fpu_s10,
     74     fpu_s11,
     75     fpu_s12,
     76     fpu_s13,
     77     fpu_s14,
     78     fpu_s15,
     79     fpu_s16,
     80     fpu_s17,
     81     fpu_s18,
     82     fpu_s19,
     83     fpu_s20,
     84     fpu_s21,
     85     fpu_s22,
     86     fpu_s23,
     87     fpu_s24,
     88     fpu_s25,
     89     fpu_s26,
     90     fpu_s27,
     91     fpu_s28,
     92     fpu_s29,
     93     fpu_s30,
     94     fpu_s31,
     95     fpu_fpscr,
     96 
     97     exc_exception,
     98     exc_fsr,
     99     exc_far,
    100 
    101     dbg_bvr0,
    102     dbg_bvr1,
    103     dbg_bvr2,
    104     dbg_bvr3,
    105     dbg_bvr4,
    106     dbg_bvr5,
    107     dbg_bvr6,
    108     dbg_bvr7,
    109     dbg_bvr8,
    110     dbg_bvr9,
    111     dbg_bvr10,
    112     dbg_bvr11,
    113     dbg_bvr12,
    114     dbg_bvr13,
    115     dbg_bvr14,
    116     dbg_bvr15,
    117 
    118     dbg_bcr0,
    119     dbg_bcr1,
    120     dbg_bcr2,
    121     dbg_bcr3,
    122     dbg_bcr4,
    123     dbg_bcr5,
    124     dbg_bcr6,
    125     dbg_bcr7,
    126     dbg_bcr8,
    127     dbg_bcr9,
    128     dbg_bcr10,
    129     dbg_bcr11,
    130     dbg_bcr12,
    131     dbg_bcr13,
    132     dbg_bcr14,
    133     dbg_bcr15,
    134 
    135     dbg_wvr0,
    136     dbg_wvr1,
    137     dbg_wvr2,
    138     dbg_wvr3,
    139     dbg_wvr4,
    140     dbg_wvr5,
    141     dbg_wvr6,
    142     dbg_wvr7,
    143     dbg_wvr8,
    144     dbg_wvr9,
    145     dbg_wvr10,
    146     dbg_wvr11,
    147     dbg_wvr12,
    148     dbg_wvr13,
    149     dbg_wvr14,
    150     dbg_wvr15,
    151 
    152     dbg_wcr0,
    153     dbg_wcr1,
    154     dbg_wcr2,
    155     dbg_wcr3,
    156     dbg_wcr4,
    157     dbg_wcr5,
    158     dbg_wcr6,
    159     dbg_wcr7,
    160     dbg_wcr8,
    161     dbg_wcr9,
    162     dbg_wcr10,
    163     dbg_wcr11,
    164     dbg_wcr12,
    165     dbg_wcr13,
    166     dbg_wcr14,
    167     dbg_wcr15,
    168 
    169     k_num_registers
    170 };
    171 
    172 
    173 RegisterContextDarwin_arm::RegisterContextDarwin_arm(Thread &thread, uint32_t concrete_frame_idx) :
    174     RegisterContext(thread, concrete_frame_idx),
    175     gpr(),
    176     fpu(),
    177     exc()
    178 {
    179     uint32_t i;
    180     for (i=0; i<kNumErrors; i++)
    181     {
    182         gpr_errs[i] = -1;
    183         fpu_errs[i] = -1;
    184         exc_errs[i] = -1;
    185     }
    186 }
    187 
    188 RegisterContextDarwin_arm::~RegisterContextDarwin_arm()
    189 {
    190 }
    191 
    192 
    193 #define GPR_OFFSET(idx) ((idx) * 4)
    194 #define FPU_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextDarwin_arm::GPR))
    195 #define EXC_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU))
    196 #define DBG_OFFSET(reg) ((LLVM_EXTENSION offsetof (RegisterContextDarwin_arm::DBG, reg) + sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU) + sizeof (RegisterContextDarwin_arm::EXC)))
    197 
    198 #define DEFINE_DBG(reg, i)  #reg, NULL, sizeof(((RegisterContextDarwin_arm::DBG *)NULL)->reg[i]), DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, dbg_##reg##i }, NULL, NULL
    199 #define REG_CONTEXT_SIZE (sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU) + sizeof (RegisterContextDarwin_arm::EXC))
    200 
    201 static RegisterInfo g_register_infos[] = {
    202 // General purpose registers
    203 //  NAME        ALT     SZ  OFFSET              ENCODING        FORMAT          COMPILER                DWARF               GENERIC                     GDB                     LLDB NATIVE   VALUE REGS    INVALIDATE REGS
    204 //  ======      ======= ==  =============       =============   ============    ===============         ===============     =========================   =====================   ============= ==========    ===============
    205 {   "r0",       NULL,   4,  GPR_OFFSET(0),      eEncodingUint,  eFormatHex,     { gcc_r0,               dwarf_r0,           LLDB_INVALID_REGNUM,        gdb_arm_r0,             gpr_r0      },      NULL,              NULL},
    206 {   "r1",       NULL,   4,  GPR_OFFSET(1),      eEncodingUint,  eFormatHex,     { gcc_r1,               dwarf_r1,           LLDB_INVALID_REGNUM,        gdb_arm_r1,             gpr_r1      },      NULL,              NULL},
    207 {   "r2",       NULL,   4,  GPR_OFFSET(2),      eEncodingUint,  eFormatHex,     { gcc_r2,               dwarf_r2,           LLDB_INVALID_REGNUM,        gdb_arm_r2,             gpr_r2      },      NULL,              NULL},
    208 {   "r3",       NULL,   4,  GPR_OFFSET(3),      eEncodingUint,  eFormatHex,     { gcc_r3,               dwarf_r3,           LLDB_INVALID_REGNUM,        gdb_arm_r3,             gpr_r3      },      NULL,              NULL},
    209 {   "r4",       NULL,   4,  GPR_OFFSET(4),      eEncodingUint,  eFormatHex,     { gcc_r4,               dwarf_r4,           LLDB_INVALID_REGNUM,        gdb_arm_r4,             gpr_r4      },      NULL,              NULL},
    210 {   "r5",       NULL,   4,  GPR_OFFSET(5),      eEncodingUint,  eFormatHex,     { gcc_r5,               dwarf_r5,           LLDB_INVALID_REGNUM,        gdb_arm_r5,             gpr_r5      },      NULL,              NULL},
    211 {   "r6",       NULL,   4,  GPR_OFFSET(6),      eEncodingUint,  eFormatHex,     { gcc_r6,               dwarf_r6,           LLDB_INVALID_REGNUM,        gdb_arm_r6,             gpr_r6      },      NULL,              NULL},
    212 {   "r7",       NULL,   4,  GPR_OFFSET(7),      eEncodingUint,  eFormatHex,     { gcc_r7,               dwarf_r7,           LLDB_REGNUM_GENERIC_FP,     gdb_arm_r7,             gpr_r7      },      NULL,              NULL},
    213 {   "r8",       NULL,   4,  GPR_OFFSET(8),      eEncodingUint,  eFormatHex,     { gcc_r8,               dwarf_r8,           LLDB_INVALID_REGNUM,        gdb_arm_r8,             gpr_r8      },      NULL,              NULL},
    214 {   "r9",       NULL,   4,  GPR_OFFSET(9),      eEncodingUint,  eFormatHex,     { gcc_r9,               dwarf_r9,           LLDB_INVALID_REGNUM,        gdb_arm_r9,             gpr_r9      },      NULL,              NULL},
    215 {   "r10",      NULL,   4,  GPR_OFFSET(10),     eEncodingUint,  eFormatHex,     { gcc_r10,              dwarf_r10,          LLDB_INVALID_REGNUM,        gdb_arm_r10,            gpr_r10     },      NULL,              NULL},
    216 {   "r11",      NULL,   4,  GPR_OFFSET(11),     eEncodingUint,  eFormatHex,     { gcc_r11,              dwarf_r11,          LLDB_INVALID_REGNUM,        gdb_arm_r11,            gpr_r11     },      NULL,              NULL},
    217 {   "r12",      NULL,   4,  GPR_OFFSET(12),     eEncodingUint,  eFormatHex,     { gcc_r12,              dwarf_r12,          LLDB_INVALID_REGNUM,        gdb_arm_r12,            gpr_r12     },      NULL,              NULL},
    218 {   "sp",       "r13",  4,  GPR_OFFSET(13),     eEncodingUint,  eFormatHex,     { gcc_sp,               dwarf_sp,           LLDB_REGNUM_GENERIC_SP,     gdb_arm_sp,             gpr_sp      },      NULL,              NULL},
    219 {   "lr",       "r14",  4,  GPR_OFFSET(14),     eEncodingUint,  eFormatHex,     { gcc_lr,               dwarf_lr,           LLDB_REGNUM_GENERIC_RA,     gdb_arm_lr,             gpr_lr      },      NULL,              NULL},
    220 {   "pc",       "r15",  4,  GPR_OFFSET(15),     eEncodingUint,  eFormatHex,     { gcc_pc,               dwarf_pc,           LLDB_REGNUM_GENERIC_PC,     gdb_arm_pc,             gpr_pc      },      NULL,              NULL},
    221 {   "cpsr",     "psr",  4,  GPR_OFFSET(16),     eEncodingUint,  eFormatHex,     { gcc_cpsr,             dwarf_cpsr,         LLDB_REGNUM_GENERIC_FLAGS,  gdb_arm_cpsr,           gpr_cpsr    },      NULL,              NULL},
    222 
    223 {   "s0",       NULL,   4,  FPU_OFFSET(0),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s0,           LLDB_INVALID_REGNUM,        gdb_arm_s0,             fpu_s0      },      NULL,              NULL},
    224 {   "s1",       NULL,   4,  FPU_OFFSET(1),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s1,           LLDB_INVALID_REGNUM,        gdb_arm_s1,             fpu_s1      },      NULL,              NULL},
    225 {   "s2",       NULL,   4,  FPU_OFFSET(2),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s2,           LLDB_INVALID_REGNUM,        gdb_arm_s2,             fpu_s2      },      NULL,              NULL},
    226 {   "s3",       NULL,   4,  FPU_OFFSET(3),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s3,           LLDB_INVALID_REGNUM,        gdb_arm_s3,             fpu_s3      },      NULL,              NULL},
    227 {   "s4",       NULL,   4,  FPU_OFFSET(4),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s4,           LLDB_INVALID_REGNUM,        gdb_arm_s4,             fpu_s4      },      NULL,              NULL},
    228 {   "s5",       NULL,   4,  FPU_OFFSET(5),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s5,           LLDB_INVALID_REGNUM,        gdb_arm_s5,             fpu_s5      },      NULL,              NULL},
    229 {   "s6",       NULL,   4,  FPU_OFFSET(6),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s6,           LLDB_INVALID_REGNUM,        gdb_arm_s6,             fpu_s6      },      NULL,              NULL},
    230 {   "s7",       NULL,   4,  FPU_OFFSET(7),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s7,           LLDB_INVALID_REGNUM,        gdb_arm_s7,             fpu_s7      },      NULL,              NULL},
    231 {   "s8",       NULL,   4,  FPU_OFFSET(8),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s8,           LLDB_INVALID_REGNUM,        gdb_arm_s8,             fpu_s8      },      NULL,              NULL},
    232 {   "s9",       NULL,   4,  FPU_OFFSET(9),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s9,           LLDB_INVALID_REGNUM,        gdb_arm_s9,             fpu_s9      },      NULL,              NULL},
    233 {   "s10",      NULL,   4,  FPU_OFFSET(10),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s10,          LLDB_INVALID_REGNUM,        gdb_arm_s10,            fpu_s10     },      NULL,              NULL},
    234 {   "s11",      NULL,   4,  FPU_OFFSET(11),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s11,          LLDB_INVALID_REGNUM,        gdb_arm_s11,            fpu_s11     },      NULL,              NULL},
    235 {   "s12",      NULL,   4,  FPU_OFFSET(12),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s12,          LLDB_INVALID_REGNUM,        gdb_arm_s12,            fpu_s12     },      NULL,              NULL},
    236 {   "s13",      NULL,   4,  FPU_OFFSET(13),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s13,          LLDB_INVALID_REGNUM,        gdb_arm_s13,            fpu_s13     },      NULL,              NULL},
    237 {   "s14",      NULL,   4,  FPU_OFFSET(14),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s14,          LLDB_INVALID_REGNUM,        gdb_arm_s14,            fpu_s14     },      NULL,              NULL},
    238 {   "s15",      NULL,   4,  FPU_OFFSET(15),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s15,          LLDB_INVALID_REGNUM,        gdb_arm_s15,            fpu_s15     },      NULL,              NULL},
    239 {   "s16",      NULL,   4,  FPU_OFFSET(16),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s16,          LLDB_INVALID_REGNUM,        gdb_arm_s16,            fpu_s16     },      NULL,              NULL},
    240 {   "s17",      NULL,   4,  FPU_OFFSET(17),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s17,          LLDB_INVALID_REGNUM,        gdb_arm_s17,            fpu_s17     },      NULL,              NULL},
    241 {   "s18",      NULL,   4,  FPU_OFFSET(18),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s18,          LLDB_INVALID_REGNUM,        gdb_arm_s18,            fpu_s18     },      NULL,              NULL},
    242 {   "s19",      NULL,   4,  FPU_OFFSET(19),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s19,          LLDB_INVALID_REGNUM,        gdb_arm_s19,            fpu_s19     },      NULL,              NULL},
    243 {   "s20",      NULL,   4,  FPU_OFFSET(20),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s20,          LLDB_INVALID_REGNUM,        gdb_arm_s20,            fpu_s20     },      NULL,              NULL},
    244 {   "s21",      NULL,   4,  FPU_OFFSET(21),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s21,          LLDB_INVALID_REGNUM,        gdb_arm_s21,            fpu_s21     },      NULL,              NULL},
    245 {   "s22",      NULL,   4,  FPU_OFFSET(22),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s22,          LLDB_INVALID_REGNUM,        gdb_arm_s22,            fpu_s22     },      NULL,              NULL},
    246 {   "s23",      NULL,   4,  FPU_OFFSET(23),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s23,          LLDB_INVALID_REGNUM,        gdb_arm_s23,            fpu_s23     },      NULL,              NULL},
    247 {   "s24",      NULL,   4,  FPU_OFFSET(24),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s24,          LLDB_INVALID_REGNUM,        gdb_arm_s24,            fpu_s24     },      NULL,              NULL},
    248 {   "s25",      NULL,   4,  FPU_OFFSET(25),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s25,          LLDB_INVALID_REGNUM,        gdb_arm_s25,            fpu_s25     },      NULL,              NULL},
    249 {   "s26",      NULL,   4,  FPU_OFFSET(26),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s26,          LLDB_INVALID_REGNUM,        gdb_arm_s26,            fpu_s26     },      NULL,              NULL},
    250 {   "s27",      NULL,   4,  FPU_OFFSET(27),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s27,          LLDB_INVALID_REGNUM,        gdb_arm_s27,            fpu_s27     },      NULL,              NULL},
    251 {   "s28",      NULL,   4,  FPU_OFFSET(28),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s28,          LLDB_INVALID_REGNUM,        gdb_arm_s28,            fpu_s28     },      NULL,              NULL},
    252 {   "s29",      NULL,   4,  FPU_OFFSET(29),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s29,          LLDB_INVALID_REGNUM,        gdb_arm_s29,            fpu_s29     },      NULL,              NULL},
    253 {   "s30",      NULL,   4,  FPU_OFFSET(30),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s30,          LLDB_INVALID_REGNUM,        gdb_arm_s30,            fpu_s30     },      NULL,              NULL},
    254 {   "s31",      NULL,   4,  FPU_OFFSET(31),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s31,          LLDB_INVALID_REGNUM,        gdb_arm_s31,            fpu_s31     },      NULL,              NULL},
    255 {   "fpscr",    NULL,   4,  FPU_OFFSET(32),     eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM,        gdb_arm_fpscr,          fpu_fpscr   },      NULL,              NULL},
    256 
    257 {   "exception",NULL,   4,  EXC_OFFSET(0),      eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    exc_exception },    NULL,              NULL},
    258 {   "fsr",      NULL,   4,  EXC_OFFSET(1),      eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    exc_fsr       },    NULL,              NULL},
    259 {   "far",      NULL,   4,  EXC_OFFSET(2),      eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    exc_far       },    NULL,              NULL},
    260 
    261 {   DEFINE_DBG (bvr, 0) },
    262 {   DEFINE_DBG (bvr, 1) },
    263 {   DEFINE_DBG (bvr, 2) },
    264 {   DEFINE_DBG (bvr, 3) },
    265 {   DEFINE_DBG (bvr, 4) },
    266 {   DEFINE_DBG (bvr, 5) },
    267 {   DEFINE_DBG (bvr, 6) },
    268 {   DEFINE_DBG (bvr, 7) },
    269 {   DEFINE_DBG (bvr, 8) },
    270 {   DEFINE_DBG (bvr, 9) },
    271 {   DEFINE_DBG (bvr, 10) },
    272 {   DEFINE_DBG (bvr, 11) },
    273 {   DEFINE_DBG (bvr, 12) },
    274 {   DEFINE_DBG (bvr, 13) },
    275 {   DEFINE_DBG (bvr, 14) },
    276 {   DEFINE_DBG (bvr, 15) },
    277 
    278 {   DEFINE_DBG (bcr, 0) },
    279 {   DEFINE_DBG (bcr, 1) },
    280 {   DEFINE_DBG (bcr, 2) },
    281 {   DEFINE_DBG (bcr, 3) },
    282 {   DEFINE_DBG (bcr, 4) },
    283 {   DEFINE_DBG (bcr, 5) },
    284 {   DEFINE_DBG (bcr, 6) },
    285 {   DEFINE_DBG (bcr, 7) },
    286 {   DEFINE_DBG (bcr, 8) },
    287 {   DEFINE_DBG (bcr, 9) },
    288 {   DEFINE_DBG (bcr, 10) },
    289 {   DEFINE_DBG (bcr, 11) },
    290 {   DEFINE_DBG (bcr, 12) },
    291 {   DEFINE_DBG (bcr, 13) },
    292 {   DEFINE_DBG (bcr, 14) },
    293 {   DEFINE_DBG (bcr, 15) },
    294 
    295 {   DEFINE_DBG (wvr, 0) },
    296 {   DEFINE_DBG (wvr, 1) },
    297 {   DEFINE_DBG (wvr, 2) },
    298 {   DEFINE_DBG (wvr, 3) },
    299 {   DEFINE_DBG (wvr, 4) },
    300 {   DEFINE_DBG (wvr, 5) },
    301 {   DEFINE_DBG (wvr, 6) },
    302 {   DEFINE_DBG (wvr, 7) },
    303 {   DEFINE_DBG (wvr, 8) },
    304 {   DEFINE_DBG (wvr, 9) },
    305 {   DEFINE_DBG (wvr, 10) },
    306 {   DEFINE_DBG (wvr, 11) },
    307 {   DEFINE_DBG (wvr, 12) },
    308 {   DEFINE_DBG (wvr, 13) },
    309 {   DEFINE_DBG (wvr, 14) },
    310 {   DEFINE_DBG (wvr, 15) },
    311 
    312 {   DEFINE_DBG (wcr, 0) },
    313 {   DEFINE_DBG (wcr, 1) },
    314 {   DEFINE_DBG (wcr, 2) },
    315 {   DEFINE_DBG (wcr, 3) },
    316 {   DEFINE_DBG (wcr, 4) },
    317 {   DEFINE_DBG (wcr, 5) },
    318 {   DEFINE_DBG (wcr, 6) },
    319 {   DEFINE_DBG (wcr, 7) },
    320 {   DEFINE_DBG (wcr, 8) },
    321 {   DEFINE_DBG (wcr, 9) },
    322 {   DEFINE_DBG (wcr, 10) },
    323 {   DEFINE_DBG (wcr, 11) },
    324 {   DEFINE_DBG (wcr, 12) },
    325 {   DEFINE_DBG (wcr, 13) },
    326 {   DEFINE_DBG (wcr, 14) },
    327 {   DEFINE_DBG (wcr, 15) }
    328 };
    329 
    330 // General purpose registers
    331 static uint32_t
    332 g_gpr_regnums[] =
    333 {
    334     gpr_r0,
    335     gpr_r1,
    336     gpr_r2,
    337     gpr_r3,
    338     gpr_r4,
    339     gpr_r5,
    340     gpr_r6,
    341     gpr_r7,
    342     gpr_r8,
    343     gpr_r9,
    344     gpr_r10,
    345     gpr_r11,
    346     gpr_r12,
    347     gpr_sp,
    348     gpr_lr,
    349     gpr_pc,
    350     gpr_cpsr
    351 };
    352 
    353 // Floating point registers
    354 static uint32_t
    355 g_fpu_regnums[] =
    356 {
    357     fpu_s0,
    358     fpu_s1,
    359     fpu_s2,
    360     fpu_s3,
    361     fpu_s4,
    362     fpu_s5,
    363     fpu_s6,
    364     fpu_s7,
    365     fpu_s8,
    366     fpu_s9,
    367     fpu_s10,
    368     fpu_s11,
    369     fpu_s12,
    370     fpu_s13,
    371     fpu_s14,
    372     fpu_s15,
    373     fpu_s16,
    374     fpu_s17,
    375     fpu_s18,
    376     fpu_s19,
    377     fpu_s20,
    378     fpu_s21,
    379     fpu_s22,
    380     fpu_s23,
    381     fpu_s24,
    382     fpu_s25,
    383     fpu_s26,
    384     fpu_s27,
    385     fpu_s28,
    386     fpu_s29,
    387     fpu_s30,
    388     fpu_s31,
    389     fpu_fpscr,
    390 };
    391 
    392 // Exception registers
    393 
    394 static uint32_t
    395 g_exc_regnums[] =
    396 {
    397     exc_exception,
    398     exc_fsr,
    399     exc_far,
    400 };
    401 
    402 static size_t k_num_register_infos = (sizeof(g_register_infos)/sizeof(RegisterInfo));
    403 
    404 void
    405 RegisterContextDarwin_arm::InvalidateAllRegisters ()
    406 {
    407     InvalidateAllRegisterStates();
    408 }
    409 
    410 
    411 size_t
    412 RegisterContextDarwin_arm::GetRegisterCount ()
    413 {
    414     assert(k_num_register_infos == k_num_registers);
    415     return k_num_registers;
    416 }
    417 
    418 const RegisterInfo *
    419 RegisterContextDarwin_arm::GetRegisterInfoAtIndex (size_t reg)
    420 {
    421     assert(k_num_register_infos == k_num_registers);
    422     if (reg < k_num_registers)
    423         return &g_register_infos[reg];
    424     return NULL;
    425 }
    426 
    427 size_t
    428 RegisterContextDarwin_arm::GetRegisterInfosCount ()
    429 {
    430     return k_num_register_infos;
    431 }
    432 
    433 const RegisterInfo *
    434 RegisterContextDarwin_arm::GetRegisterInfos ()
    435 {
    436     return g_register_infos;
    437 }
    438 
    439 
    440 // Number of registers in each register set
    441 const size_t k_num_gpr_registers = sizeof(g_gpr_regnums) / sizeof(uint32_t);
    442 const size_t k_num_fpu_registers = sizeof(g_fpu_regnums) / sizeof(uint32_t);
    443 const size_t k_num_exc_registers = sizeof(g_exc_regnums) / sizeof(uint32_t);
    444 
    445 //----------------------------------------------------------------------
    446 // Register set definitions. The first definitions at register set index
    447 // of zero is for all registers, followed by other registers sets. The
    448 // register information for the all register set need not be filled in.
    449 //----------------------------------------------------------------------
    450 static const RegisterSet g_reg_sets[] =
    451 {
    452     { "General Purpose Registers",  "gpr",  k_num_gpr_registers,    g_gpr_regnums,      },
    453     { "Floating Point Registers",   "fpu",  k_num_fpu_registers,    g_fpu_regnums       },
    454     { "Exception State Registers",  "exc",  k_num_exc_registers,    g_exc_regnums       }
    455 };
    456 
    457 const size_t k_num_regsets = sizeof(g_reg_sets) / sizeof(RegisterSet);
    458 
    459 
    460 size_t
    461 RegisterContextDarwin_arm::GetRegisterSetCount ()
    462 {
    463     return k_num_regsets;
    464 }
    465 
    466 const RegisterSet *
    467 RegisterContextDarwin_arm::GetRegisterSet (size_t reg_set)
    468 {
    469     if (reg_set < k_num_regsets)
    470         return &g_reg_sets[reg_set];
    471     return NULL;
    472 }
    473 
    474 
    475 //----------------------------------------------------------------------
    476 // Register information defintions for 32 bit i386.
    477 //----------------------------------------------------------------------
    478 int
    479 RegisterContextDarwin_arm::GetSetForNativeRegNum (int reg)
    480 {
    481     if (reg < fpu_s0)
    482         return GPRRegSet;
    483     else if (reg < exc_exception)
    484         return FPURegSet;
    485     else if (reg < k_num_registers)
    486         return EXCRegSet;
    487     return -1;
    488 }
    489 
    490 int
    491 RegisterContextDarwin_arm::ReadGPR (bool force)
    492 {
    493     int set = GPRRegSet;
    494     if (force || !RegisterSetIsCached(set))
    495     {
    496         SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
    497     }
    498     return GetError(GPRRegSet, Read);
    499 }
    500 
    501 int
    502 RegisterContextDarwin_arm::ReadFPU (bool force)
    503 {
    504     int set = FPURegSet;
    505     if (force || !RegisterSetIsCached(set))
    506     {
    507         SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
    508     }
    509     return GetError(FPURegSet, Read);
    510 }
    511 
    512 int
    513 RegisterContextDarwin_arm::ReadEXC (bool force)
    514 {
    515     int set = EXCRegSet;
    516     if (force || !RegisterSetIsCached(set))
    517     {
    518         SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
    519     }
    520     return GetError(EXCRegSet, Read);
    521 }
    522 
    523 int
    524 RegisterContextDarwin_arm::ReadDBG (bool force)
    525 {
    526     int set = DBGRegSet;
    527     if (force || !RegisterSetIsCached(set))
    528     {
    529         SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg));
    530     }
    531     return GetError(DBGRegSet, Read);
    532 }
    533 
    534 int
    535 RegisterContextDarwin_arm::WriteGPR ()
    536 {
    537     int set = GPRRegSet;
    538     if (!RegisterSetIsCached(set))
    539     {
    540         SetError (set, Write, -1);
    541         return KERN_INVALID_ARGUMENT;
    542     }
    543     SetError (set, Write, DoWriteGPR(GetThreadID(), set, gpr));
    544     SetError (set, Read, -1);
    545     return GetError(GPRRegSet, Write);
    546 }
    547 
    548 int
    549 RegisterContextDarwin_arm::WriteFPU ()
    550 {
    551     int set = FPURegSet;
    552     if (!RegisterSetIsCached(set))
    553     {
    554         SetError (set, Write, -1);
    555         return KERN_INVALID_ARGUMENT;
    556     }
    557     SetError (set, Write, DoWriteFPU(GetThreadID(), set, fpu));
    558     SetError (set, Read, -1);
    559     return GetError(FPURegSet, Write);
    560 }
    561 
    562 int
    563 RegisterContextDarwin_arm::WriteEXC ()
    564 {
    565     int set = EXCRegSet;
    566     if (!RegisterSetIsCached(set))
    567     {
    568         SetError (set, Write, -1);
    569         return KERN_INVALID_ARGUMENT;
    570     }
    571     SetError (set, Write, DoWriteEXC(GetThreadID(), set, exc));
    572     SetError (set, Read, -1);
    573     return GetError(EXCRegSet, Write);
    574 }
    575 
    576 int
    577 RegisterContextDarwin_arm::WriteDBG ()
    578 {
    579     int set = DBGRegSet;
    580     if (!RegisterSetIsCached(set))
    581     {
    582         SetError (set, Write, -1);
    583         return KERN_INVALID_ARGUMENT;
    584     }
    585     SetError (set, Write, DoWriteDBG(GetThreadID(), set, dbg));
    586     SetError (set, Read, -1);
    587     return GetError(DBGRegSet, Write);
    588 }
    589 
    590 
    591 int
    592 RegisterContextDarwin_arm::ReadRegisterSet (uint32_t set, bool force)
    593 {
    594     switch (set)
    595     {
    596     case GPRRegSet:    return ReadGPR(force);
    597     case FPURegSet:    return ReadFPU(force);
    598     case EXCRegSet:    return ReadEXC(force);
    599     case DBGRegSet:    return ReadDBG(force);
    600     default: break;
    601     }
    602     return KERN_INVALID_ARGUMENT;
    603 }
    604 
    605 int
    606 RegisterContextDarwin_arm::WriteRegisterSet (uint32_t set)
    607 {
    608     // Make sure we have a valid context to set.
    609     if (RegisterSetIsCached(set))
    610     {
    611         switch (set)
    612         {
    613         case GPRRegSet:    return WriteGPR();
    614         case FPURegSet:    return WriteFPU();
    615         case EXCRegSet:    return WriteEXC();
    616         case DBGRegSet:    return WriteDBG();
    617         default: break;
    618         }
    619     }
    620     return KERN_INVALID_ARGUMENT;
    621 }
    622 
    623 void
    624 RegisterContextDarwin_arm::LogDBGRegisters (Log *log, const DBG& dbg)
    625 {
    626     if (log)
    627     {
    628         for (uint32_t i=0; i<16; i++)
    629             log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { 0x%8.8x, 0x%8.8x }",
    630                 i, i, dbg.bvr[i], dbg.bcr[i],
    631                 i, i, dbg.wvr[i], dbg.wcr[i]);
    632     }
    633 }
    634 
    635 
    636 bool
    637 RegisterContextDarwin_arm::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value)
    638 {
    639     const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
    640     int set = RegisterContextDarwin_arm::GetSetForNativeRegNum (reg);
    641 
    642     if (set == -1)
    643         return false;
    644 
    645     if (ReadRegisterSet(set, false) != KERN_SUCCESS)
    646         return false;
    647 
    648     switch (reg)
    649     {
    650     case gpr_r0:
    651     case gpr_r1:
    652     case gpr_r2:
    653     case gpr_r3:
    654     case gpr_r4:
    655     case gpr_r5:
    656     case gpr_r6:
    657     case gpr_r7:
    658     case gpr_r8:
    659     case gpr_r9:
    660     case gpr_r10:
    661     case gpr_r11:
    662     case gpr_r12:
    663     case gpr_sp:
    664     case gpr_lr:
    665     case gpr_pc:
    666     case gpr_cpsr:
    667         value.SetUInt32 (gpr.r[reg - gpr_r0]);
    668         break;
    669 
    670     case fpu_s0:
    671     case fpu_s1:
    672     case fpu_s2:
    673     case fpu_s3:
    674     case fpu_s4:
    675     case fpu_s5:
    676     case fpu_s6:
    677     case fpu_s7:
    678     case fpu_s8:
    679     case fpu_s9:
    680     case fpu_s10:
    681     case fpu_s11:
    682     case fpu_s12:
    683     case fpu_s13:
    684     case fpu_s14:
    685     case fpu_s15:
    686     case fpu_s16:
    687     case fpu_s17:
    688     case fpu_s18:
    689     case fpu_s19:
    690     case fpu_s20:
    691     case fpu_s21:
    692     case fpu_s22:
    693     case fpu_s23:
    694     case fpu_s24:
    695     case fpu_s25:
    696     case fpu_s26:
    697     case fpu_s27:
    698     case fpu_s28:
    699     case fpu_s29:
    700     case fpu_s30:
    701     case fpu_s31:
    702         value.SetUInt32 (fpu.floats.s[reg], RegisterValue::eTypeFloat);
    703         break;
    704 
    705     case fpu_fpscr:
    706         value.SetUInt32 (fpu.fpscr);
    707         break;
    708 
    709     case exc_exception:
    710         value.SetUInt32 (exc.exception);
    711         break;
    712     case exc_fsr:
    713         value.SetUInt32 (exc.fsr);
    714         break;
    715     case exc_far:
    716         value.SetUInt32 (exc.far);
    717         break;
    718 
    719     default:
    720         value.SetValueToInvalid();
    721         return false;
    722 
    723     }
    724     return true;
    725 }
    726 
    727 
    728 bool
    729 RegisterContextDarwin_arm::WriteRegister (const RegisterInfo *reg_info,
    730                                         const RegisterValue &value)
    731 {
    732     const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
    733     int set = GetSetForNativeRegNum (reg);
    734 
    735     if (set == -1)
    736         return false;
    737 
    738     if (ReadRegisterSet(set, false) != KERN_SUCCESS)
    739         return false;
    740 
    741     switch (reg)
    742     {
    743     case gpr_r0:
    744     case gpr_r1:
    745     case gpr_r2:
    746     case gpr_r3:
    747     case gpr_r4:
    748     case gpr_r5:
    749     case gpr_r6:
    750     case gpr_r7:
    751     case gpr_r8:
    752     case gpr_r9:
    753     case gpr_r10:
    754     case gpr_r11:
    755     case gpr_r12:
    756     case gpr_sp:
    757     case gpr_lr:
    758     case gpr_pc:
    759     case gpr_cpsr:
    760             gpr.r[reg - gpr_r0] = value.GetAsUInt32();
    761         break;
    762 
    763     case fpu_s0:
    764     case fpu_s1:
    765     case fpu_s2:
    766     case fpu_s3:
    767     case fpu_s4:
    768     case fpu_s5:
    769     case fpu_s6:
    770     case fpu_s7:
    771     case fpu_s8:
    772     case fpu_s9:
    773     case fpu_s10:
    774     case fpu_s11:
    775     case fpu_s12:
    776     case fpu_s13:
    777     case fpu_s14:
    778     case fpu_s15:
    779     case fpu_s16:
    780     case fpu_s17:
    781     case fpu_s18:
    782     case fpu_s19:
    783     case fpu_s20:
    784     case fpu_s21:
    785     case fpu_s22:
    786     case fpu_s23:
    787     case fpu_s24:
    788     case fpu_s25:
    789     case fpu_s26:
    790     case fpu_s27:
    791     case fpu_s28:
    792     case fpu_s29:
    793     case fpu_s30:
    794     case fpu_s31:
    795         fpu.floats.s[reg] = value.GetAsUInt32();
    796         break;
    797 
    798     case fpu_fpscr:
    799         fpu.fpscr = value.GetAsUInt32();
    800         break;
    801 
    802     case exc_exception:
    803         exc.exception = value.GetAsUInt32();
    804         break;
    805     case exc_fsr:
    806         exc.fsr = value.GetAsUInt32();
    807         break;
    808     case exc_far:
    809         exc.far = value.GetAsUInt32();
    810         break;
    811 
    812     default:
    813         return false;
    814 
    815     }
    816     return WriteRegisterSet(set) == KERN_SUCCESS;
    817 }
    818 
    819 bool
    820 RegisterContextDarwin_arm::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
    821 {
    822     data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
    823     if (data_sp &&
    824         ReadGPR (false) == KERN_SUCCESS &&
    825         ReadFPU (false) == KERN_SUCCESS &&
    826         ReadEXC (false) == KERN_SUCCESS)
    827     {
    828         uint8_t *dst = data_sp->GetBytes();
    829         ::memcpy (dst, &gpr, sizeof(gpr));
    830         dst += sizeof(gpr);
    831 
    832         ::memcpy (dst, &fpu, sizeof(fpu));
    833         dst += sizeof(gpr);
    834 
    835         ::memcpy (dst, &exc, sizeof(exc));
    836         return true;
    837     }
    838     return false;
    839 }
    840 
    841 bool
    842 RegisterContextDarwin_arm::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
    843 {
    844     if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
    845     {
    846         const uint8_t *src = data_sp->GetBytes();
    847         ::memcpy (&gpr, src, sizeof(gpr));
    848         src += sizeof(gpr);
    849 
    850         ::memcpy (&fpu, src, sizeof(fpu));
    851         src += sizeof(gpr);
    852 
    853         ::memcpy (&exc, src, sizeof(exc));
    854         uint32_t success_count = 0;
    855         if (WriteGPR() == KERN_SUCCESS)
    856             ++success_count;
    857         if (WriteFPU() == KERN_SUCCESS)
    858             ++success_count;
    859         if (WriteEXC() == KERN_SUCCESS)
    860             ++success_count;
    861         return success_count == 3;
    862     }
    863     return false;
    864 }
    865 
    866 uint32_t
    867 RegisterContextDarwin_arm::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t reg)
    868 {
    869     if (kind == eRegisterKindGeneric)
    870     {
    871         switch (reg)
    872         {
    873         case LLDB_REGNUM_GENERIC_PC: return gpr_pc;
    874         case LLDB_REGNUM_GENERIC_SP: return gpr_sp;
    875         case LLDB_REGNUM_GENERIC_FP: return gpr_r7;
    876         case LLDB_REGNUM_GENERIC_RA: return gpr_lr;
    877         case LLDB_REGNUM_GENERIC_FLAGS: return gpr_cpsr;
    878         default:
    879             break;
    880         }
    881     }
    882     else if (kind == eRegisterKindDWARF)
    883     {
    884         switch (reg)
    885         {
    886         case dwarf_r0:  return gpr_r0;
    887         case dwarf_r1:  return gpr_r1;
    888         case dwarf_r2:  return gpr_r2;
    889         case dwarf_r3:  return gpr_r3;
    890         case dwarf_r4:  return gpr_r4;
    891         case dwarf_r5:  return gpr_r5;
    892         case dwarf_r6:  return gpr_r6;
    893         case dwarf_r7:  return gpr_r7;
    894         case dwarf_r8:  return gpr_r8;
    895         case dwarf_r9:  return gpr_r9;
    896         case dwarf_r10: return gpr_r10;
    897         case dwarf_r11: return gpr_r11;
    898         case dwarf_r12: return gpr_r12;
    899         case dwarf_sp:  return gpr_sp;
    900         case dwarf_lr:  return gpr_lr;
    901         case dwarf_pc:  return gpr_pc;
    902         case dwarf_spsr: return gpr_cpsr;
    903 
    904         case dwarf_s0:  return fpu_s0;
    905         case dwarf_s1:  return fpu_s1;
    906         case dwarf_s2:  return fpu_s2;
    907         case dwarf_s3:  return fpu_s3;
    908         case dwarf_s4:  return fpu_s4;
    909         case dwarf_s5:  return fpu_s5;
    910         case dwarf_s6:  return fpu_s6;
    911         case dwarf_s7:  return fpu_s7;
    912         case dwarf_s8:  return fpu_s8;
    913         case dwarf_s9:  return fpu_s9;
    914         case dwarf_s10: return fpu_s10;
    915         case dwarf_s11: return fpu_s11;
    916         case dwarf_s12: return fpu_s12;
    917         case dwarf_s13: return fpu_s13;
    918         case dwarf_s14: return fpu_s14;
    919         case dwarf_s15: return fpu_s15;
    920         case dwarf_s16: return fpu_s16;
    921         case dwarf_s17: return fpu_s17;
    922         case dwarf_s18: return fpu_s18;
    923         case dwarf_s19: return fpu_s19;
    924         case dwarf_s20: return fpu_s20;
    925         case dwarf_s21: return fpu_s21;
    926         case dwarf_s22: return fpu_s22;
    927         case dwarf_s23: return fpu_s23;
    928         case dwarf_s24: return fpu_s24;
    929         case dwarf_s25: return fpu_s25;
    930         case dwarf_s26: return fpu_s26;
    931         case dwarf_s27: return fpu_s27;
    932         case dwarf_s28: return fpu_s28;
    933         case dwarf_s29: return fpu_s29;
    934         case dwarf_s30: return fpu_s30;
    935         case dwarf_s31: return fpu_s31;
    936 
    937         default:
    938             break;
    939         }
    940     }
    941     else if (kind == eRegisterKindGCC)
    942     {
    943         switch (reg)
    944         {
    945         case gcc_r0:    return gpr_r0;
    946         case gcc_r1:    return gpr_r1;
    947         case gcc_r2:    return gpr_r2;
    948         case gcc_r3:    return gpr_r3;
    949         case gcc_r4:    return gpr_r4;
    950         case gcc_r5:    return gpr_r5;
    951         case gcc_r6:    return gpr_r6;
    952         case gcc_r7:    return gpr_r7;
    953         case gcc_r8:    return gpr_r8;
    954         case gcc_r9:    return gpr_r9;
    955         case gcc_r10:   return gpr_r10;
    956         case gcc_r11:   return gpr_r11;
    957         case gcc_r12:   return gpr_r12;
    958         case gcc_sp:    return gpr_sp;
    959         case gcc_lr:    return gpr_lr;
    960         case gcc_pc:    return gpr_pc;
    961         case gcc_cpsr:  return gpr_cpsr;
    962         }
    963     }
    964     else if (kind == eRegisterKindLLDB)
    965     {
    966         return reg;
    967     }
    968     return LLDB_INVALID_REGNUM;
    969 }
    970 
    971 
    972 uint32_t
    973 RegisterContextDarwin_arm::NumSupportedHardwareBreakpoints ()
    974 {
    975 #if defined (__arm__)
    976     // Set the init value to something that will let us know that we need to
    977     // autodetect how many breakpoints are supported dynamically...
    978     static uint32_t g_num_supported_hw_breakpoints = UINT32_MAX;
    979     if (g_num_supported_hw_breakpoints == UINT32_MAX)
    980     {
    981         // Set this to zero in case we can't tell if there are any HW breakpoints
    982         g_num_supported_hw_breakpoints = 0;
    983 
    984         uint32_t register_DBGDIDR;
    985 
    986         asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR));
    987         g_num_supported_hw_breakpoints = Bits32 (register_DBGDIDR, 27, 24);
    988         // Zero is reserved for the BRP count, so don't increment it if it is zero
    989         if (g_num_supported_hw_breakpoints > 0)
    990             g_num_supported_hw_breakpoints++;
    991 //        if (log) log->Printf ("DBGDIDR=0x%8.8x (number BRP pairs = %u)", register_DBGDIDR, g_num_supported_hw_breakpoints);
    992 
    993     }
    994     return g_num_supported_hw_breakpoints;
    995 #else
    996     // TODO: figure out remote case here!
    997     return 6;
    998 #endif
    999 }
   1000 
   1001 uint32_t
   1002 RegisterContextDarwin_arm::SetHardwareBreakpoint (lldb::addr_t addr, size_t size)
   1003 {
   1004     // Make sure our address isn't bogus
   1005     if (addr & 1)
   1006         return LLDB_INVALID_INDEX32;
   1007 
   1008     int kret = ReadDBG (false);
   1009 
   1010     if (kret == KERN_SUCCESS)
   1011     {
   1012         const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints();
   1013         uint32_t i;
   1014         for (i=0; i<num_hw_breakpoints; ++i)
   1015         {
   1016             if ((dbg.bcr[i] & BCR_ENABLE) == 0)
   1017                 break; // We found an available hw breakpoint slot (in i)
   1018         }
   1019 
   1020         // See if we found an available hw breakpoint slot above
   1021         if (i < num_hw_breakpoints)
   1022         {
   1023             // Make sure bits 1:0 are clear in our address
   1024             dbg.bvr[i] = addr & ~((lldb::addr_t)3);
   1025 
   1026             if (size == 2 || addr & 2)
   1027             {
   1028                 uint32_t byte_addr_select = (addr & 2) ? BAS_IMVA_2_3 : BAS_IMVA_0_1;
   1029 
   1030                 // We have a thumb breakpoint
   1031                 // We have an ARM breakpoint
   1032                 dbg.bcr[i] =  BCR_M_IMVA_MATCH |    // Stop on address mismatch
   1033                                         byte_addr_select |  // Set the correct byte address select so we only trigger on the correct opcode
   1034                                         S_USER |            // Which modes should this breakpoint stop in?
   1035                                         BCR_ENABLE;         // Enable this hardware breakpoint
   1036 //                if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint( addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x / 0x%8.8x (Thumb)",
   1037 //                        addr,
   1038 //                        size,
   1039 //                        i,
   1040 //                        i,
   1041 //                        dbg.bvr[i],
   1042 //                        dbg.bcr[i]);
   1043             }
   1044             else if (size == 4)
   1045             {
   1046                 // We have an ARM breakpoint
   1047                 dbg.bcr[i] =  BCR_M_IMVA_MATCH |    // Stop on address mismatch
   1048                                         BAS_IMVA_ALL |      // Stop on any of the four bytes following the IMVA
   1049                                         S_USER |            // Which modes should this breakpoint stop in?
   1050                                         BCR_ENABLE;         // Enable this hardware breakpoint
   1051 //                if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint( addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x / 0x%8.8x (ARM)",
   1052 //                        addr,
   1053 //                        size,
   1054 //                        i,
   1055 //                        i,
   1056 //                        dbg.bvr[i],
   1057 //                        dbg.bcr[i]);
   1058             }
   1059 
   1060             kret = WriteDBG();
   1061 //            if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint() WriteDBG() => 0x%8.8x.", kret);
   1062 
   1063             if (kret == KERN_SUCCESS)
   1064                 return i;
   1065         }
   1066 //        else
   1067 //        {
   1068 //            if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(addr = %8.8p, size = %u) => all hardware breakpoint resources are being used.", addr, size);
   1069 //        }
   1070     }
   1071 
   1072     return LLDB_INVALID_INDEX32;
   1073 }
   1074 
   1075 bool
   1076 RegisterContextDarwin_arm::ClearHardwareBreakpoint (uint32_t hw_index)
   1077 {
   1078     int kret = ReadDBG (false);
   1079 
   1080     const uint32_t num_hw_points = NumSupportedHardwareBreakpoints();
   1081     if (kret == KERN_SUCCESS)
   1082     {
   1083         if (hw_index < num_hw_points)
   1084         {
   1085             dbg.bcr[hw_index] = 0;
   1086 //            if (log) log->Printf ("RegisterContextDarwin_arm::SetHardwareBreakpoint( %u ) - BVR%u = 0x%8.8x  BCR%u = 0x%8.8x",
   1087 //                    hw_index,
   1088 //                    hw_index,
   1089 //                    dbg.bvr[hw_index],
   1090 //                    hw_index,
   1091 //                    dbg.bcr[hw_index]);
   1092 
   1093             kret = WriteDBG();
   1094 
   1095             if (kret == KERN_SUCCESS)
   1096                 return true;
   1097         }
   1098     }
   1099     return false;
   1100 }
   1101 
   1102 uint32_t
   1103 RegisterContextDarwin_arm::NumSupportedHardwareWatchpoints ()
   1104 {
   1105 #if defined (__arm__)
   1106     // Set the init value to something that will let us know that we need to
   1107     // autodetect how many watchpoints are supported dynamically...
   1108     static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX;
   1109     if (g_num_supported_hw_watchpoints == UINT32_MAX)
   1110     {
   1111         // Set this to zero in case we can't tell if there are any HW breakpoints
   1112         g_num_supported_hw_watchpoints = 0;
   1113 
   1114         uint32_t register_DBGDIDR;
   1115         asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR));
   1116         g_num_supported_hw_watchpoints = Bits32 (register_DBGDIDR, 31, 28) + 1;
   1117 //        if (log) log->Printf ("DBGDIDR=0x%8.8x (number WRP pairs = %u)", register_DBGDIDR, g_num_supported_hw_watchpoints);
   1118     }
   1119     return g_num_supported_hw_watchpoints;
   1120 #else
   1121     // TODO: figure out remote case here!
   1122     return 2;
   1123 #endif
   1124 }
   1125 
   1126 
   1127 uint32_t
   1128 RegisterContextDarwin_arm::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write)
   1129 {
   1130 //    if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(addr = %8.8p, size = %u, read = %u, write = %u)", addr, size, read, write);
   1131 
   1132     const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
   1133 
   1134     // Can't watch zero bytes
   1135     if (size == 0)
   1136         return LLDB_INVALID_INDEX32;
   1137 
   1138     // We must watch for either read or write
   1139     if (read == false && write == false)
   1140         return LLDB_INVALID_INDEX32;
   1141 
   1142     // Can't watch more than 4 bytes per WVR/WCR pair
   1143     if (size > 4)
   1144         return LLDB_INVALID_INDEX32;
   1145 
   1146     // We can only watch up to four bytes that follow a 4 byte aligned address
   1147     // per watchpoint register pair. Since we have at most so we can only watch
   1148     // until the next 4 byte boundary and we need to make sure we can properly
   1149     // encode this.
   1150     uint32_t addr_word_offset = addr % 4;
   1151 //    if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - addr_word_offset = 0x%8.8x", addr_word_offset);
   1152 
   1153     uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset;
   1154 //    if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - byte_mask = 0x%8.8x", byte_mask);
   1155     if (byte_mask > 0xfu)
   1156         return LLDB_INVALID_INDEX32;
   1157 
   1158     // Read the debug state
   1159     int kret = ReadDBG (false);
   1160 
   1161     if (kret == KERN_SUCCESS)
   1162     {
   1163         // Check to make sure we have the needed hardware support
   1164         uint32_t i = 0;
   1165 
   1166         for (i=0; i<num_hw_watchpoints; ++i)
   1167         {
   1168             if ((dbg.wcr[i] & WCR_ENABLE) == 0)
   1169                 break; // We found an available hw breakpoint slot (in i)
   1170         }
   1171 
   1172         // See if we found an available hw breakpoint slot above
   1173         if (i < num_hw_watchpoints)
   1174         {
   1175             // Make the byte_mask into a valid Byte Address Select mask
   1176             uint32_t byte_address_select = byte_mask << 5;
   1177             // Make sure bits 1:0 are clear in our address
   1178             dbg.wvr[i] = addr & ~((lldb::addr_t)3);
   1179             dbg.wcr[i] =  byte_address_select |       // Which bytes that follow the IMVA that we will watch
   1180                                     S_USER |                    // Stop only in user mode
   1181                                     (read ? WCR_LOAD : 0) |     // Stop on read access?
   1182                                     (write ? WCR_STORE : 0) |   // Stop on write access?
   1183                                     WCR_ENABLE;                 // Enable this watchpoint;
   1184 
   1185             kret = WriteDBG();
   1186 //            if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() WriteDBG() => 0x%8.8x.", kret);
   1187 
   1188             if (kret == KERN_SUCCESS)
   1189                 return i;
   1190         }
   1191         else
   1192         {
   1193 //            if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(): All hardware resources (%u) are in use.", num_hw_watchpoints);
   1194         }
   1195     }
   1196     return LLDB_INVALID_INDEX32;
   1197 }
   1198 
   1199 bool
   1200 RegisterContextDarwin_arm::ClearHardwareWatchpoint (uint32_t hw_index)
   1201 {
   1202     int kret = ReadDBG (false);
   1203 
   1204     const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
   1205     if (kret == KERN_SUCCESS)
   1206     {
   1207         if (hw_index < num_hw_points)
   1208         {
   1209             dbg.wcr[hw_index] = 0;
   1210 //            if (log) log->Printf ("RegisterContextDarwin_arm::ClearHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x  WCR%u = 0x%8.8x",
   1211 //                    hw_index,
   1212 //                    hw_index,
   1213 //                    dbg.wvr[hw_index],
   1214 //                    hw_index,
   1215 //                    dbg.wcr[hw_index]);
   1216 
   1217             kret = WriteDBG();
   1218 
   1219             if (kret == KERN_SUCCESS)
   1220                 return true;
   1221         }
   1222     }
   1223     return false;
   1224 }
   1225 
   1226 #endif
   1227