1 //===-- RegisterContextDarwin_arm64.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_arm64.h"
13 
14 // C Includes
15 #include <mach/mach_types.h>
16 #include <mach/thread_act.h>
17 #include <sys/sysctl.h>
18 
19 // C++ Includes
20 // Other libraries and framework includes
21 #include "lldb/Core/DataBufferHeap.h"
22 #include "lldb/Core/DataExtractor.h"
23 #include "lldb/Core/Log.h"
24 #include "lldb/Core/RegisterValue.h"
25 #include "lldb/Core/Scalar.h"
26 #include "lldb/Host/Endian.h"
27 #include "llvm/Support/Compiler.h"
28 
29 #include "Plugins/Process/Utility/InstructionUtils.h"
30 
31 // Support building against older versions of LLVM, this macro was added
32 // recently.
33 #ifndef LLVM_EXTENSION
34 #define LLVM_EXTENSION
35 #endif
36 
37 // Project includes
38 #include "ARM64_GCC_Registers.h"
39 #include "ARM64_DWARF_Registers.h"
40 
41 using namespace lldb;
42 using namespace lldb_private;
43 
44 enum
45 {
46     gpr_x0 = 0,
47     gpr_x1,
48     gpr_x2,
49     gpr_x3,
50     gpr_x4,
51     gpr_x5,
52     gpr_x6,
53     gpr_x7,
54     gpr_x8,
55     gpr_x9,
56     gpr_x10,
57     gpr_x11,
58     gpr_x12,
59     gpr_x13,
60     gpr_x14,
61     gpr_x15,
62     gpr_x16,
63     gpr_x17,
64     gpr_x18,
65     gpr_x19,
66     gpr_x20,
67     gpr_x21,
68     gpr_x22,
69     gpr_x23,
70     gpr_x24,
71     gpr_x25,
72     gpr_x26,
73     gpr_x27,
74     gpr_x28,
75     gpr_x29 = 29,  gpr_fp = gpr_x29,
76     gpr_x30 = 30,  gpr_lr = gpr_x30,  gpr_ra = gpr_x30,
77     gpr_x31 = 31,  gpr_sp = gpr_x31,
78     gpr_pc = 32,
79     gpr_cpsr,
80 
81     fpu_v0,
82     fpu_v1,
83     fpu_v2,
84     fpu_v3,
85     fpu_v4,
86     fpu_v5,
87     fpu_v6,
88     fpu_v7,
89     fpu_v8,
90     fpu_v9,
91     fpu_v10,
92     fpu_v11,
93     fpu_v12,
94     fpu_v13,
95     fpu_v14,
96     fpu_v15,
97     fpu_v16,
98     fpu_v17,
99     fpu_v18,
100     fpu_v19,
101     fpu_v20,
102     fpu_v21,
103     fpu_v22,
104     fpu_v23,
105     fpu_v24,
106     fpu_v25,
107     fpu_v26,
108     fpu_v27,
109     fpu_v28,
110     fpu_v29,
111     fpu_v30,
112     fpu_v31,
113 
114     fpu_fpsr,
115     fpu_fpcr,
116 
117     exc_far,
118     exc_esr,
119     exc_exception,
120 
121     dbg_bvr0,
122     dbg_bvr1,
123     dbg_bvr2,
124     dbg_bvr3,
125     dbg_bvr4,
126     dbg_bvr5,
127     dbg_bvr6,
128     dbg_bvr7,
129     dbg_bvr8,
130     dbg_bvr9,
131     dbg_bvr10,
132     dbg_bvr11,
133     dbg_bvr12,
134     dbg_bvr13,
135     dbg_bvr14,
136     dbg_bvr15,
137 
138     dbg_bcr0,
139     dbg_bcr1,
140     dbg_bcr2,
141     dbg_bcr3,
142     dbg_bcr4,
143     dbg_bcr5,
144     dbg_bcr6,
145     dbg_bcr7,
146     dbg_bcr8,
147     dbg_bcr9,
148     dbg_bcr10,
149     dbg_bcr11,
150     dbg_bcr12,
151     dbg_bcr13,
152     dbg_bcr14,
153     dbg_bcr15,
154 
155     dbg_wvr0,
156     dbg_wvr1,
157     dbg_wvr2,
158     dbg_wvr3,
159     dbg_wvr4,
160     dbg_wvr5,
161     dbg_wvr6,
162     dbg_wvr7,
163     dbg_wvr8,
164     dbg_wvr9,
165     dbg_wvr10,
166     dbg_wvr11,
167     dbg_wvr12,
168     dbg_wvr13,
169     dbg_wvr14,
170     dbg_wvr15,
171 
172     dbg_wcr0,
173     dbg_wcr1,
174     dbg_wcr2,
175     dbg_wcr3,
176     dbg_wcr4,
177     dbg_wcr5,
178     dbg_wcr6,
179     dbg_wcr7,
180     dbg_wcr8,
181     dbg_wcr9,
182     dbg_wcr10,
183     dbg_wcr11,
184     dbg_wcr12,
185     dbg_wcr13,
186     dbg_wcr14,
187     dbg_wcr15,
188 
189     k_num_registers
190 };
191 
192 
193 RegisterContextDarwin_arm64::RegisterContextDarwin_arm64(Thread &thread, uint32_t concrete_frame_idx) :
194     RegisterContext(thread, concrete_frame_idx),
195     gpr(),
196     fpu(),
197     exc()
198 {
199     uint32_t i;
200     for (i=0; i<kNumErrors; i++)
201     {
202         gpr_errs[i] = -1;
203         fpu_errs[i] = -1;
204         exc_errs[i] = -1;
205     }
206 }
207 
208 RegisterContextDarwin_arm64::~RegisterContextDarwin_arm64()
209 {
210 }
211 
212 
213 #define GPR_OFFSET(idx) ((idx) * 8)
214 #define GPR_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_arm64::GPR, reg))
215 
216 #define FPU_OFFSET(idx) ((idx) * 16 + sizeof (RegisterContextDarwin_arm64::GPR))
217 #define FPU_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_arm64::FPU, reg))
218 
219 #define EXC_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_arm64::EXC, reg) + sizeof (RegisterContextDarwin_arm64::GPR) + sizeof (RegisterContextDarwin_arm64::FPU))
220 #define DBG_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_arm64::DBG, reg) + sizeof (RegisterContextDarwin_arm64::GPR) + sizeof (RegisterContextDarwin_arm64::FPU) + sizeof (RegisterContextDarwin_arm64::EXC))
221 
222 #define DEFINE_DBG(reg, i)  #reg, NULL, sizeof(((RegisterContextDarwin_arm64::DBG *)NULL)->reg[i]), DBG_OFFSET_NAME(reg[i]), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, dbg_##reg##i }, NULL, NULL
223 #define REG_CONTEXT_SIZE (sizeof (RegisterContextDarwin_arm64::GPR) + sizeof (RegisterContextDarwin_arm64::FPU) + sizeof (RegisterContextDarwin_arm64::EXC))
224 
225 static RegisterInfo g_register_infos[] = {
226 // General purpose registers
227 //  NAME        ALT     SZ  OFFSET              ENCODING        FORMAT          COMPILER                DWARF               GENERIC                     GDB                     LLDB NATIVE   VALUE REGS    INVALIDATE REGS
228 //  ======      ======= ==  =============       =============   ============    ===============         ===============     =========================   =====================   ============= ==========    ===============
229 {   "x0",       NULL,   8,  GPR_OFFSET(0),      eEncodingUint,  eFormatHex,     { arm64_gcc::x0,               arm64_dwarf::x0,           LLDB_INVALID_REGNUM,        arm64_gcc::x0,             gpr_x0      },      NULL,              NULL},
230 {   "x1",       NULL,   8,  GPR_OFFSET(1),      eEncodingUint,  eFormatHex,     { arm64_gcc::x1,               arm64_dwarf::x1,           LLDB_INVALID_REGNUM,        arm64_gcc::x1,             gpr_x1      },      NULL,              NULL},
231 {   "x2",       NULL,   8,  GPR_OFFSET(2),      eEncodingUint,  eFormatHex,     { arm64_gcc::x2,               arm64_dwarf::x2,           LLDB_INVALID_REGNUM,        arm64_gcc::x2,             gpr_x2      },      NULL,              NULL},
232 {   "x3",       NULL,   8,  GPR_OFFSET(3),      eEncodingUint,  eFormatHex,     { arm64_gcc::x3,               arm64_dwarf::x3,           LLDB_INVALID_REGNUM,        arm64_gcc::x3,             gpr_x3      },      NULL,              NULL},
233 {   "x4",       NULL,   8,  GPR_OFFSET(4),      eEncodingUint,  eFormatHex,     { arm64_gcc::x4,               arm64_dwarf::x4,           LLDB_INVALID_REGNUM,        arm64_gcc::x4,             gpr_x4      },      NULL,              NULL},
234 {   "x5",       NULL,   8,  GPR_OFFSET(5),      eEncodingUint,  eFormatHex,     { arm64_gcc::x5,               arm64_dwarf::x5,           LLDB_INVALID_REGNUM,        arm64_gcc::x5,             gpr_x5      },      NULL,              NULL},
235 {   "x6",       NULL,   8,  GPR_OFFSET(6),      eEncodingUint,  eFormatHex,     { arm64_gcc::x6,               arm64_dwarf::x6,           LLDB_INVALID_REGNUM,        arm64_gcc::x6,             gpr_x6      },      NULL,              NULL},
236 {   "x7",       NULL,   8,  GPR_OFFSET(7),      eEncodingUint,  eFormatHex,     { arm64_gcc::x7,               arm64_dwarf::x7,           LLDB_INVALID_REGNUM,        arm64_gcc::x7,             gpr_x7      },      NULL,              NULL},
237 {   "x8",       NULL,   8,  GPR_OFFSET(8),      eEncodingUint,  eFormatHex,     { arm64_gcc::x8,               arm64_dwarf::x8,           LLDB_INVALID_REGNUM,        arm64_gcc::x8,             gpr_x8      },      NULL,              NULL},
238 {   "x9",       NULL,   8,  GPR_OFFSET(9),      eEncodingUint,  eFormatHex,     { arm64_gcc::x9,               arm64_dwarf::x9,           LLDB_INVALID_REGNUM,        arm64_gcc::x9,             gpr_x9      },      NULL,              NULL},
239 {   "x10",      NULL,   8,  GPR_OFFSET(10),     eEncodingUint,  eFormatHex,     { arm64_gcc::x10,              arm64_dwarf::x10,          LLDB_INVALID_REGNUM,        arm64_gcc::x10,            gpr_x10     },      NULL,              NULL},
240 {   "x11",      NULL,   8,  GPR_OFFSET(11),     eEncodingUint,  eFormatHex,     { arm64_gcc::x11,              arm64_dwarf::x11,          LLDB_INVALID_REGNUM,        arm64_gcc::x11,            gpr_x11     },      NULL,              NULL},
241 {   "x12",      NULL,   8,  GPR_OFFSET(12),     eEncodingUint,  eFormatHex,     { arm64_gcc::x12,              arm64_dwarf::x12,          LLDB_INVALID_REGNUM,        arm64_gcc::x12,            gpr_x12     },      NULL,              NULL},
242 {   "x13",      NULL,   8,  GPR_OFFSET(13),     eEncodingUint,  eFormatHex,     { arm64_gcc::x13,              arm64_dwarf::x13,          LLDB_INVALID_REGNUM,        arm64_gcc::x13,            gpr_x13     },      NULL,              NULL},
243 {   "x14",      NULL,   8,  GPR_OFFSET(14),     eEncodingUint,  eFormatHex,     { arm64_gcc::x14,              arm64_dwarf::x14,          LLDB_INVALID_REGNUM,        arm64_gcc::x14,            gpr_x14     },      NULL,              NULL},
244 {   "x15",      NULL,   8,  GPR_OFFSET(15),     eEncodingUint,  eFormatHex,     { arm64_gcc::x15,              arm64_dwarf::x15,          LLDB_INVALID_REGNUM,        arm64_gcc::x15,            gpr_x15     },      NULL,              NULL},
245 {   "x16",      NULL,   8,  GPR_OFFSET(16),     eEncodingUint,  eFormatHex,     { arm64_gcc::x16,              arm64_dwarf::x16,          LLDB_INVALID_REGNUM,        arm64_gcc::x16,            gpr_x16     },      NULL,              NULL},
246 {   "x17",      NULL,   8,  GPR_OFFSET(17),     eEncodingUint,  eFormatHex,     { arm64_gcc::x17,              arm64_dwarf::x17,          LLDB_INVALID_REGNUM,        arm64_gcc::x17,            gpr_x17     },      NULL,              NULL},
247 {   "x18",      NULL,   8,  GPR_OFFSET(18),     eEncodingUint,  eFormatHex,     { arm64_gcc::x18,              arm64_dwarf::x18,          LLDB_INVALID_REGNUM,        arm64_gcc::x18,            gpr_x18     },      NULL,              NULL},
248 {   "x19",      NULL,   8,  GPR_OFFSET(19),     eEncodingUint,  eFormatHex,     { arm64_gcc::x19,              arm64_dwarf::x19,          LLDB_INVALID_REGNUM,        arm64_gcc::x19,            gpr_x19     },      NULL,              NULL},
249 {   "x20",      NULL,   8,  GPR_OFFSET(20),     eEncodingUint,  eFormatHex,     { arm64_gcc::x20,              arm64_dwarf::x20,          LLDB_INVALID_REGNUM,        arm64_gcc::x20,            gpr_x20     },      NULL,              NULL},
250 {   "x21",      NULL,   8,  GPR_OFFSET(21),     eEncodingUint,  eFormatHex,     { arm64_gcc::x21,              arm64_dwarf::x21,          LLDB_INVALID_REGNUM,        arm64_gcc::x21,            gpr_x21     },      NULL,              NULL},
251 {   "x22",      NULL,   8,  GPR_OFFSET(22),     eEncodingUint,  eFormatHex,     { arm64_gcc::x22,              arm64_dwarf::x22,          LLDB_INVALID_REGNUM,        arm64_gcc::x22,            gpr_x22     },      NULL,              NULL},
252 {   "x23",      NULL,   8,  GPR_OFFSET(23),     eEncodingUint,  eFormatHex,     { arm64_gcc::x23,              arm64_dwarf::x23,          LLDB_INVALID_REGNUM,        arm64_gcc::x23,            gpr_x23     },      NULL,              NULL},
253 {   "x24",      NULL,   8,  GPR_OFFSET(24),     eEncodingUint,  eFormatHex,     { arm64_gcc::x24,              arm64_dwarf::x24,          LLDB_INVALID_REGNUM,        arm64_gcc::x24,            gpr_x24     },      NULL,              NULL},
254 {   "x25",      NULL,   8,  GPR_OFFSET(25),     eEncodingUint,  eFormatHex,     { arm64_gcc::x25,              arm64_dwarf::x25,          LLDB_INVALID_REGNUM,        arm64_gcc::x25,            gpr_x25     },      NULL,              NULL},
255 {   "x26",      NULL,   8,  GPR_OFFSET(26),     eEncodingUint,  eFormatHex,     { arm64_gcc::x26,              arm64_dwarf::x26,          LLDB_INVALID_REGNUM,        arm64_gcc::x26,            gpr_x26     },      NULL,              NULL},
256 {   "x27",      NULL,   8,  GPR_OFFSET(27),     eEncodingUint,  eFormatHex,     { arm64_gcc::x27,              arm64_dwarf::x27,          LLDB_INVALID_REGNUM,        arm64_gcc::x27,            gpr_x27     },      NULL,              NULL},
257 {   "x28",      NULL,   8,  GPR_OFFSET(28),     eEncodingUint,  eFormatHex,     { arm64_gcc::x28,              arm64_dwarf::x28,          LLDB_INVALID_REGNUM,        arm64_gcc::x28,            gpr_x28     },      NULL,              NULL},
258 
259 {   "fp",       "x29",  8,  GPR_OFFSET(29),     eEncodingUint,  eFormatHex,     { arm64_gcc::fp,               arm64_dwarf::fp,           LLDB_REGNUM_GENERIC_FP,     arm64_gcc::fp,             gpr_fp      },      NULL,              NULL},
260 {   "lr",       "x30",  8,  GPR_OFFSET(30),     eEncodingUint,  eFormatHex,     { arm64_gcc::lr,               arm64_dwarf::lr,           LLDB_REGNUM_GENERIC_RA,     arm64_gcc::lr,             gpr_lr      },      NULL,              NULL},
261 {   "sp",       "x31",  8,  GPR_OFFSET(31),     eEncodingUint,  eFormatHex,     { arm64_gcc::sp,               arm64_dwarf::sp,           LLDB_REGNUM_GENERIC_SP,     arm64_gcc::sp,             gpr_sp      },      NULL,              NULL},
262 {   "pc",       NULL,   8,  GPR_OFFSET(32),     eEncodingUint,  eFormatHex,     { arm64_gcc::pc,               arm64_dwarf::pc,           LLDB_REGNUM_GENERIC_PC,     arm64_gcc::pc,             gpr_pc      },      NULL,              NULL},
263 
264 {   "cpsr",     NULL,   4,  GPR_OFFSET_NAME(cpsr), eEncodingUint,  eFormatHex,  { arm64_gcc::cpsr,             arm64_dwarf::cpsr,         LLDB_REGNUM_GENERIC_FLAGS,  arm64_gcc::cpsr,           gpr_cpsr    },      NULL,              NULL},
265 
266 {   "v0",       NULL,  16,  FPU_OFFSET(0),      eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v0,           LLDB_INVALID_REGNUM,        arm64_gcc::v0,             fpu_v0      },      NULL,              NULL},
267 {   "v1",       NULL,  16,  FPU_OFFSET(1),      eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v1,           LLDB_INVALID_REGNUM,        arm64_gcc::v1,             fpu_v1      },      NULL,              NULL},
268 {   "v2",       NULL,  16,  FPU_OFFSET(2),      eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v2,           LLDB_INVALID_REGNUM,        arm64_gcc::v2,             fpu_v2      },      NULL,              NULL},
269 {   "v3",       NULL,  16,  FPU_OFFSET(3),      eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v3,           LLDB_INVALID_REGNUM,        arm64_gcc::v3,             fpu_v3      },      NULL,              NULL},
270 {   "v4",       NULL,  16,  FPU_OFFSET(4),      eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v4,           LLDB_INVALID_REGNUM,        arm64_gcc::v4,             fpu_v4      },      NULL,              NULL},
271 {   "v5",       NULL,  16,  FPU_OFFSET(5),      eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v5,           LLDB_INVALID_REGNUM,        arm64_gcc::v5,             fpu_v5      },      NULL,              NULL},
272 {   "v6",       NULL,  16,  FPU_OFFSET(6),      eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v6,           LLDB_INVALID_REGNUM,        arm64_gcc::v6,             fpu_v6      },      NULL,              NULL},
273 {   "v7",       NULL,  16,  FPU_OFFSET(7),      eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v7,           LLDB_INVALID_REGNUM,        arm64_gcc::v7,             fpu_v7      },      NULL,              NULL},
274 {   "v8",       NULL,  16,  FPU_OFFSET(8),      eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v8,           LLDB_INVALID_REGNUM,        arm64_gcc::v8,             fpu_v8      },      NULL,              NULL},
275 {   "v9",       NULL,  16,  FPU_OFFSET(9),      eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v9,           LLDB_INVALID_REGNUM,        arm64_gcc::v9,             fpu_v9      },      NULL,              NULL},
276 {   "v10",      NULL,  16,  FPU_OFFSET(10),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v10,          LLDB_INVALID_REGNUM,        arm64_gcc::v10,            fpu_v10     },      NULL,              NULL},
277 {   "v11",      NULL,  16,  FPU_OFFSET(11),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v11,          LLDB_INVALID_REGNUM,        arm64_gcc::v11,            fpu_v11     },      NULL,              NULL},
278 {   "v12",      NULL,  16,  FPU_OFFSET(12),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v12,          LLDB_INVALID_REGNUM,        arm64_gcc::v12,            fpu_v12     },      NULL,              NULL},
279 {   "v13",      NULL,  16,  FPU_OFFSET(13),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v13,          LLDB_INVALID_REGNUM,        arm64_gcc::v13,            fpu_v13     },      NULL,              NULL},
280 {   "v14",      NULL,  16,  FPU_OFFSET(14),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v14,          LLDB_INVALID_REGNUM,        arm64_gcc::v14,            fpu_v14     },      NULL,              NULL},
281 {   "v15",      NULL,  16,  FPU_OFFSET(15),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v15,          LLDB_INVALID_REGNUM,        arm64_gcc::v15,            fpu_v15     },      NULL,              NULL},
282 {   "v16",      NULL,  16,  FPU_OFFSET(16),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v16,          LLDB_INVALID_REGNUM,        arm64_gcc::v16,            fpu_v16     },      NULL,              NULL},
283 {   "v17",      NULL,  16,  FPU_OFFSET(17),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v17,          LLDB_INVALID_REGNUM,        arm64_gcc::v17,            fpu_v17     },      NULL,              NULL},
284 {   "v18",      NULL,  16,  FPU_OFFSET(18),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v18,          LLDB_INVALID_REGNUM,        arm64_gcc::v18,            fpu_v18     },      NULL,              NULL},
285 {   "v19",      NULL,  16,  FPU_OFFSET(19),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v19,          LLDB_INVALID_REGNUM,        arm64_gcc::v19,            fpu_v19     },      NULL,              NULL},
286 {   "v20",      NULL,  16,  FPU_OFFSET(20),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v20,          LLDB_INVALID_REGNUM,        arm64_gcc::v20,            fpu_v20     },      NULL,              NULL},
287 {   "v21",      NULL,  16,  FPU_OFFSET(21),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v21,          LLDB_INVALID_REGNUM,        arm64_gcc::v21,            fpu_v21     },      NULL,              NULL},
288 {   "v22",      NULL,  16,  FPU_OFFSET(22),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v22,          LLDB_INVALID_REGNUM,        arm64_gcc::v22,            fpu_v22     },      NULL,              NULL},
289 {   "v23",      NULL,  16,  FPU_OFFSET(23),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v23,          LLDB_INVALID_REGNUM,        arm64_gcc::v23,            fpu_v23     },      NULL,              NULL},
290 {   "v24",      NULL,  16,  FPU_OFFSET(24),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v24,          LLDB_INVALID_REGNUM,        arm64_gcc::v24,            fpu_v24     },      NULL,              NULL},
291 {   "v25",      NULL,  16,  FPU_OFFSET(25),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v25,          LLDB_INVALID_REGNUM,        arm64_gcc::v25,            fpu_v25     },      NULL,              NULL},
292 {   "v26",      NULL,  16,  FPU_OFFSET(26),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v26,          LLDB_INVALID_REGNUM,        arm64_gcc::v26,            fpu_v26     },      NULL,              NULL},
293 {   "v27",      NULL,  16,  FPU_OFFSET(27),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v27,          LLDB_INVALID_REGNUM,        arm64_gcc::v27,            fpu_v27     },      NULL,              NULL},
294 {   "v28",      NULL,  16,  FPU_OFFSET(28),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v28,          LLDB_INVALID_REGNUM,        arm64_gcc::v28,            fpu_v28     },      NULL,              NULL},
295 {   "v29",      NULL,  16,  FPU_OFFSET(29),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v29,          LLDB_INVALID_REGNUM,        arm64_gcc::v29,            fpu_v29     },      NULL,              NULL},
296 {   "v30",      NULL,  16,  FPU_OFFSET(30),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v30,          LLDB_INVALID_REGNUM,        arm64_gcc::v30,            fpu_v30     },      NULL,              NULL},
297 {   "v31",      NULL,  16,  FPU_OFFSET(31),     eEncodingVector, eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM,  arm64_dwarf::v31,          LLDB_INVALID_REGNUM,        arm64_gcc::v31,            fpu_v31     },      NULL,              NULL},
298 
299 {   "fpsr",    NULL,   4,  FPU_OFFSET_NAME(fpsr),     eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  fpu_fpsr   },      NULL,              NULL},
300 {   "fpcr",    NULL,   4,  FPU_OFFSET_NAME(fpcr),     eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  fpu_fpcr   },      NULL,              NULL},
301 
302 {   "far",      NULL,   8,  EXC_OFFSET_NAME(far),       eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    exc_far       },    NULL,              NULL},
303 {   "esr",      NULL,   4,  EXC_OFFSET_NAME(esr),       eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    exc_esr       },    NULL,              NULL},
304 {   "exception",NULL,   4,  EXC_OFFSET_NAME(exception), eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    exc_exception },    NULL,              NULL},
305 
306 {   DEFINE_DBG (bvr, 0) },
307 {   DEFINE_DBG (bvr, 1) },
308 {   DEFINE_DBG (bvr, 2) },
309 {   DEFINE_DBG (bvr, 3) },
310 {   DEFINE_DBG (bvr, 4) },
311 {   DEFINE_DBG (bvr, 5) },
312 {   DEFINE_DBG (bvr, 6) },
313 {   DEFINE_DBG (bvr, 7) },
314 {   DEFINE_DBG (bvr, 8) },
315 {   DEFINE_DBG (bvr, 9) },
316 {   DEFINE_DBG (bvr, 10) },
317 {   DEFINE_DBG (bvr, 11) },
318 {   DEFINE_DBG (bvr, 12) },
319 {   DEFINE_DBG (bvr, 13) },
320 {   DEFINE_DBG (bvr, 14) },
321 {   DEFINE_DBG (bvr, 15) },
322 
323 {   DEFINE_DBG (bcr, 0) },
324 {   DEFINE_DBG (bcr, 1) },
325 {   DEFINE_DBG (bcr, 2) },
326 {   DEFINE_DBG (bcr, 3) },
327 {   DEFINE_DBG (bcr, 4) },
328 {   DEFINE_DBG (bcr, 5) },
329 {   DEFINE_DBG (bcr, 6) },
330 {   DEFINE_DBG (bcr, 7) },
331 {   DEFINE_DBG (bcr, 8) },
332 {   DEFINE_DBG (bcr, 9) },
333 {   DEFINE_DBG (bcr, 10) },
334 {   DEFINE_DBG (bcr, 11) },
335 {   DEFINE_DBG (bcr, 12) },
336 {   DEFINE_DBG (bcr, 13) },
337 {   DEFINE_DBG (bcr, 14) },
338 {   DEFINE_DBG (bcr, 15) },
339 
340 {   DEFINE_DBG (wvr, 0) },
341 {   DEFINE_DBG (wvr, 1) },
342 {   DEFINE_DBG (wvr, 2) },
343 {   DEFINE_DBG (wvr, 3) },
344 {   DEFINE_DBG (wvr, 4) },
345 {   DEFINE_DBG (wvr, 5) },
346 {   DEFINE_DBG (wvr, 6) },
347 {   DEFINE_DBG (wvr, 7) },
348 {   DEFINE_DBG (wvr, 8) },
349 {   DEFINE_DBG (wvr, 9) },
350 {   DEFINE_DBG (wvr, 10) },
351 {   DEFINE_DBG (wvr, 11) },
352 {   DEFINE_DBG (wvr, 12) },
353 {   DEFINE_DBG (wvr, 13) },
354 {   DEFINE_DBG (wvr, 14) },
355 {   DEFINE_DBG (wvr, 15) },
356 
357 {   DEFINE_DBG (wcr, 0) },
358 {   DEFINE_DBG (wcr, 1) },
359 {   DEFINE_DBG (wcr, 2) },
360 {   DEFINE_DBG (wcr, 3) },
361 {   DEFINE_DBG (wcr, 4) },
362 {   DEFINE_DBG (wcr, 5) },
363 {   DEFINE_DBG (wcr, 6) },
364 {   DEFINE_DBG (wcr, 7) },
365 {   DEFINE_DBG (wcr, 8) },
366 {   DEFINE_DBG (wcr, 9) },
367 {   DEFINE_DBG (wcr, 10) },
368 {   DEFINE_DBG (wcr, 11) },
369 {   DEFINE_DBG (wcr, 12) },
370 {   DEFINE_DBG (wcr, 13) },
371 {   DEFINE_DBG (wcr, 14) },
372 {   DEFINE_DBG (wcr, 15) }
373 };
374 
375 // General purpose registers
376 static uint32_t
377 g_gpr_regnums[] =
378 {
379     gpr_x0,
380     gpr_x1,
381     gpr_x2,
382     gpr_x3,
383     gpr_x4,
384     gpr_x5,
385     gpr_x6,
386     gpr_x7,
387     gpr_x8,
388     gpr_x9,
389     gpr_x10,
390     gpr_x11,
391     gpr_x12,
392     gpr_x13,
393     gpr_x14,
394     gpr_x15,
395     gpr_x16,
396     gpr_x17,
397     gpr_x18,
398     gpr_x19,
399     gpr_x20,
400     gpr_x21,
401     gpr_x22,
402     gpr_x23,
403     gpr_x24,
404     gpr_x25,
405     gpr_x26,
406     gpr_x27,
407     gpr_x28,
408     gpr_fp,
409     gpr_lr,
410     gpr_sp,
411     gpr_pc,
412     gpr_cpsr
413 };
414 
415 // Floating point registers
416 static uint32_t
417 g_fpu_regnums[] =
418 {
419     fpu_v0,
420     fpu_v1,
421     fpu_v2,
422     fpu_v3,
423     fpu_v4,
424     fpu_v5,
425     fpu_v6,
426     fpu_v7,
427     fpu_v8,
428     fpu_v9,
429     fpu_v10,
430     fpu_v11,
431     fpu_v12,
432     fpu_v13,
433     fpu_v14,
434     fpu_v15,
435     fpu_v16,
436     fpu_v17,
437     fpu_v18,
438     fpu_v19,
439     fpu_v20,
440     fpu_v21,
441     fpu_v22,
442     fpu_v23,
443     fpu_v24,
444     fpu_v25,
445     fpu_v26,
446     fpu_v27,
447     fpu_v28,
448     fpu_v29,
449     fpu_v30,
450     fpu_v31,
451     fpu_fpsr,
452     fpu_fpcr
453 };
454 
455 // Exception registers
456 
457 static uint32_t
458 g_exc_regnums[] =
459 {
460     exc_far,
461     exc_esr,
462     exc_exception
463 };
464 
465 static size_t k_num_register_infos = (sizeof(g_register_infos)/sizeof(RegisterInfo));
466 
467 void
468 RegisterContextDarwin_arm64::InvalidateAllRegisters ()
469 {
470     InvalidateAllRegisterStates();
471 }
472 
473 
474 size_t
475 RegisterContextDarwin_arm64::GetRegisterCount ()
476 {
477     assert(k_num_register_infos == k_num_registers);
478     return k_num_registers;
479 }
480 
481 const RegisterInfo *
482 RegisterContextDarwin_arm64::GetRegisterInfoAtIndex (size_t reg)
483 {
484     assert(k_num_register_infos == k_num_registers);
485     if (reg < k_num_registers)
486         return &g_register_infos[reg];
487     return NULL;
488 }
489 
490 size_t
491 RegisterContextDarwin_arm64::GetRegisterInfosCount ()
492 {
493     return k_num_register_infos;
494 }
495 
496 const RegisterInfo *
497 RegisterContextDarwin_arm64::GetRegisterInfos ()
498 {
499     return g_register_infos;
500 }
501 
502 
503 // Number of registers in each register set
504 const size_t k_num_gpr_registers = sizeof(g_gpr_regnums) / sizeof(uint32_t);
505 const size_t k_num_fpu_registers = sizeof(g_fpu_regnums) / sizeof(uint32_t);
506 const size_t k_num_exc_registers = sizeof(g_exc_regnums) / sizeof(uint32_t);
507 
508 //----------------------------------------------------------------------
509 // Register set definitions. The first definitions at register set index
510 // of zero is for all registers, followed by other registers sets. The
511 // register information for the all register set need not be filled in.
512 //----------------------------------------------------------------------
513 static const RegisterSet g_reg_sets[] =
514 {
515     { "General Purpose Registers",  "gpr",  k_num_gpr_registers,    g_gpr_regnums,      },
516     { "Floating Point Registers",   "fpu",  k_num_fpu_registers,    g_fpu_regnums       },
517     { "Exception State Registers",  "exc",  k_num_exc_registers,    g_exc_regnums       }
518 };
519 
520 const size_t k_num_regsets = sizeof(g_reg_sets) / sizeof(RegisterSet);
521 
522 
523 size_t
524 RegisterContextDarwin_arm64::GetRegisterSetCount ()
525 {
526     return k_num_regsets;
527 }
528 
529 const RegisterSet *
530 RegisterContextDarwin_arm64::GetRegisterSet (size_t reg_set)
531 {
532     if (reg_set < k_num_regsets)
533         return &g_reg_sets[reg_set];
534     return NULL;
535 }
536 
537 
538 //----------------------------------------------------------------------
539 // Register information defintions for arm64
540 //----------------------------------------------------------------------
541 int
542 RegisterContextDarwin_arm64::GetSetForNativeRegNum (int reg)
543 {
544     if (reg < fpu_v0)
545         return GPRRegSet;
546     else if (reg < exc_far)
547         return FPURegSet;
548     else if (reg < k_num_registers)
549         return EXCRegSet;
550     return -1;
551 }
552 
553 int
554 RegisterContextDarwin_arm64::ReadGPR (bool force)
555 {
556     int set = GPRRegSet;
557     if (force || !RegisterSetIsCached(set))
558     {
559         SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
560     }
561     return GetError(GPRRegSet, Read);
562 }
563 
564 int
565 RegisterContextDarwin_arm64::ReadFPU (bool force)
566 {
567     int set = FPURegSet;
568     if (force || !RegisterSetIsCached(set))
569     {
570         SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
571     }
572     return GetError(FPURegSet, Read);
573 }
574 
575 int
576 RegisterContextDarwin_arm64::ReadEXC (bool force)
577 {
578     int set = EXCRegSet;
579     if (force || !RegisterSetIsCached(set))
580     {
581         SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
582     }
583     return GetError(EXCRegSet, Read);
584 }
585 
586 int
587 RegisterContextDarwin_arm64::ReadDBG (bool force)
588 {
589     int set = DBGRegSet;
590     if (force || !RegisterSetIsCached(set))
591     {
592         SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg));
593     }
594     return GetError(DBGRegSet, Read);
595 }
596 
597 int
598 RegisterContextDarwin_arm64::WriteGPR ()
599 {
600     int set = GPRRegSet;
601     if (!RegisterSetIsCached(set))
602     {
603         SetError (set, Write, -1);
604         return KERN_INVALID_ARGUMENT;
605     }
606     SetError (set, Write, DoWriteGPR(GetThreadID(), set, gpr));
607     SetError (set, Read, -1);
608     return GetError(GPRRegSet, Write);
609 }
610 
611 int
612 RegisterContextDarwin_arm64::WriteFPU ()
613 {
614     int set = FPURegSet;
615     if (!RegisterSetIsCached(set))
616     {
617         SetError (set, Write, -1);
618         return KERN_INVALID_ARGUMENT;
619     }
620     SetError (set, Write, DoWriteFPU(GetThreadID(), set, fpu));
621     SetError (set, Read, -1);
622     return GetError(FPURegSet, Write);
623 }
624 
625 int
626 RegisterContextDarwin_arm64::WriteEXC ()
627 {
628     int set = EXCRegSet;
629     if (!RegisterSetIsCached(set))
630     {
631         SetError (set, Write, -1);
632         return KERN_INVALID_ARGUMENT;
633     }
634     SetError (set, Write, DoWriteEXC(GetThreadID(), set, exc));
635     SetError (set, Read, -1);
636     return GetError(EXCRegSet, Write);
637 }
638 
639 int
640 RegisterContextDarwin_arm64::WriteDBG ()
641 {
642     int set = DBGRegSet;
643     if (!RegisterSetIsCached(set))
644     {
645         SetError (set, Write, -1);
646         return KERN_INVALID_ARGUMENT;
647     }
648     SetError (set, Write, DoWriteDBG(GetThreadID(), set, dbg));
649     SetError (set, Read, -1);
650     return GetError(DBGRegSet, Write);
651 }
652 
653 
654 int
655 RegisterContextDarwin_arm64::ReadRegisterSet (uint32_t set, bool force)
656 {
657     switch (set)
658     {
659     case GPRRegSet:    return ReadGPR(force);
660     case FPURegSet:    return ReadFPU(force);
661     case EXCRegSet:    return ReadEXC(force);
662     case DBGRegSet:    return ReadDBG(force);
663     default: break;
664     }
665     return KERN_INVALID_ARGUMENT;
666 }
667 
668 int
669 RegisterContextDarwin_arm64::WriteRegisterSet (uint32_t set)
670 {
671     // Make sure we have a valid context to set.
672     if (RegisterSetIsCached(set))
673     {
674         switch (set)
675         {
676         case GPRRegSet:    return WriteGPR();
677         case FPURegSet:    return WriteFPU();
678         case EXCRegSet:    return WriteEXC();
679         case DBGRegSet:    return WriteDBG();
680         default: break;
681         }
682     }
683     return KERN_INVALID_ARGUMENT;
684 }
685 
686 void
687 RegisterContextDarwin_arm64::LogDBGRegisters (Log *log, const DBG& dbg)
688 {
689     if (log)
690     {
691         for (uint32_t i=0; i<16; i++)
692             log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8llx, 0x%8.8llx } WVR%-2u/WCR%-2u = { 0x%8.8llx, 0x%8.8llx }",
693                 i, i, dbg.bvr[i], dbg.bcr[i],
694                 i, i, dbg.wvr[i], dbg.wcr[i]);
695     }
696 }
697 
698 
699 bool
700 RegisterContextDarwin_arm64::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value)
701 {
702     const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
703     int set = RegisterContextDarwin_arm64::GetSetForNativeRegNum (reg);
704 
705     if (set == -1)
706         return false;
707 
708     if (ReadRegisterSet(set, false) != KERN_SUCCESS)
709         return false;
710 
711     switch (reg)
712     {
713     case gpr_x0:
714     case gpr_x1:
715     case gpr_x2:
716     case gpr_x3:
717     case gpr_x4:
718     case gpr_x5:
719     case gpr_x6:
720     case gpr_x7:
721     case gpr_x8:
722     case gpr_x9:
723     case gpr_x10:
724     case gpr_x11:
725     case gpr_x12:
726     case gpr_x13:
727     case gpr_x14:
728     case gpr_x15:
729     case gpr_x16:
730     case gpr_x17:
731     case gpr_x18:
732     case gpr_x19:
733     case gpr_x20:
734     case gpr_x21:
735     case gpr_x22:
736     case gpr_x23:
737     case gpr_x24:
738     case gpr_x25:
739     case gpr_x26:
740     case gpr_x27:
741     case gpr_x28:
742     case gpr_fp:
743     case gpr_sp:
744     case gpr_lr:
745     case gpr_pc:
746     case gpr_cpsr:
747         value.SetUInt64 (gpr.x[reg - gpr_x0]);
748         break;
749 
750     case fpu_v0:
751     case fpu_v1:
752     case fpu_v2:
753     case fpu_v3:
754     case fpu_v4:
755     case fpu_v5:
756     case fpu_v6:
757     case fpu_v7:
758     case fpu_v8:
759     case fpu_v9:
760     case fpu_v10:
761     case fpu_v11:
762     case fpu_v12:
763     case fpu_v13:
764     case fpu_v14:
765     case fpu_v15:
766     case fpu_v16:
767     case fpu_v17:
768     case fpu_v18:
769     case fpu_v19:
770     case fpu_v20:
771     case fpu_v21:
772     case fpu_v22:
773     case fpu_v23:
774     case fpu_v24:
775     case fpu_v25:
776     case fpu_v26:
777     case fpu_v27:
778     case fpu_v28:
779     case fpu_v29:
780     case fpu_v30:
781     case fpu_v31:
782         value.SetBytes(fpu.v[reg].bytes, reg_info->byte_size, lldb::endian::InlHostByteOrder());
783         break;
784 
785     case fpu_fpsr:
786         value.SetUInt32 (fpu.fpsr);
787         break;
788 
789     case fpu_fpcr:
790         value.SetUInt32 (fpu.fpcr);
791         break;
792 
793     case exc_exception:
794         value.SetUInt32 (exc.exception);
795         break;
796     case exc_esr:
797         value.SetUInt32 (exc.esr);
798         break;
799     case exc_far:
800         value.SetUInt64 (exc.far);
801         break;
802 
803     default:
804         value.SetValueToInvalid();
805         return false;
806 
807     }
808     return true;
809 }
810 
811 
812 bool
813 RegisterContextDarwin_arm64::WriteRegister (const RegisterInfo *reg_info,
814                                         const RegisterValue &value)
815 {
816     const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
817     int set = GetSetForNativeRegNum (reg);
818 
819     if (set == -1)
820         return false;
821 
822     if (ReadRegisterSet(set, false) != KERN_SUCCESS)
823         return false;
824 
825     switch (reg)
826     {
827     case gpr_x0:
828     case gpr_x1:
829     case gpr_x2:
830     case gpr_x3:
831     case gpr_x4:
832     case gpr_x5:
833     case gpr_x6:
834     case gpr_x7:
835     case gpr_x8:
836     case gpr_x9:
837     case gpr_x10:
838     case gpr_x11:
839     case gpr_x12:
840     case gpr_x13:
841     case gpr_x14:
842     case gpr_x15:
843     case gpr_x16:
844     case gpr_x17:
845     case gpr_x18:
846     case gpr_x19:
847     case gpr_x20:
848     case gpr_x21:
849     case gpr_x22:
850     case gpr_x23:
851     case gpr_x24:
852     case gpr_x25:
853     case gpr_x26:
854     case gpr_x27:
855     case gpr_x28:
856     case gpr_fp:
857     case gpr_sp:
858     case gpr_lr:
859     case gpr_pc:
860     case gpr_cpsr:
861             gpr.x[reg - gpr_x0] = value.GetAsUInt64();
862         break;
863 
864     case fpu_v0:
865     case fpu_v1:
866     case fpu_v2:
867     case fpu_v3:
868     case fpu_v4:
869     case fpu_v5:
870     case fpu_v6:
871     case fpu_v7:
872     case fpu_v8:
873     case fpu_v9:
874     case fpu_v10:
875     case fpu_v11:
876     case fpu_v12:
877     case fpu_v13:
878     case fpu_v14:
879     case fpu_v15:
880     case fpu_v16:
881     case fpu_v17:
882     case fpu_v18:
883     case fpu_v19:
884     case fpu_v20:
885     case fpu_v21:
886     case fpu_v22:
887     case fpu_v23:
888     case fpu_v24:
889     case fpu_v25:
890     case fpu_v26:
891     case fpu_v27:
892     case fpu_v28:
893     case fpu_v29:
894     case fpu_v30:
895     case fpu_v31:
896         ::memcpy (fpu.v[reg].bytes, value.GetBytes(), value.GetByteSize());
897         break;
898 
899     case fpu_fpsr:
900         fpu.fpsr = value.GetAsUInt32();
901         break;
902 
903     case fpu_fpcr:
904         fpu.fpcr = value.GetAsUInt32();
905         break;
906 
907     case exc_exception:
908         exc.exception = value.GetAsUInt32();
909         break;
910     case exc_esr:
911         exc.esr = value.GetAsUInt32();
912         break;
913     case exc_far:
914         exc.far = value.GetAsUInt64();
915         break;
916 
917     default:
918         return false;
919 
920     }
921     return WriteRegisterSet(set) == KERN_SUCCESS;
922 }
923 
924 bool
925 RegisterContextDarwin_arm64::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
926 {
927     data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
928     if (data_sp &&
929         ReadGPR (false) == KERN_SUCCESS &&
930         ReadFPU (false) == KERN_SUCCESS &&
931         ReadEXC (false) == KERN_SUCCESS)
932     {
933         uint8_t *dst = data_sp->GetBytes();
934         ::memcpy (dst, &gpr, sizeof(gpr));
935         dst += sizeof(gpr);
936 
937         ::memcpy (dst, &fpu, sizeof(fpu));
938         dst += sizeof(gpr);
939 
940         ::memcpy (dst, &exc, sizeof(exc));
941         return true;
942     }
943     return false;
944 }
945 
946 bool
947 RegisterContextDarwin_arm64::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
948 {
949     if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
950     {
951         const uint8_t *src = data_sp->GetBytes();
952         ::memcpy (&gpr, src, sizeof(gpr));
953         src += sizeof(gpr);
954 
955         ::memcpy (&fpu, src, sizeof(fpu));
956         src += sizeof(gpr);
957 
958         ::memcpy (&exc, src, sizeof(exc));
959         uint32_t success_count = 0;
960         if (WriteGPR() == KERN_SUCCESS)
961             ++success_count;
962         if (WriteFPU() == KERN_SUCCESS)
963             ++success_count;
964         if (WriteEXC() == KERN_SUCCESS)
965             ++success_count;
966         return success_count == 3;
967     }
968     return false;
969 }
970 
971 uint32_t
972 RegisterContextDarwin_arm64::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t reg)
973 {
974     if (kind == eRegisterKindGeneric)
975     {
976         switch (reg)
977         {
978         case LLDB_REGNUM_GENERIC_PC: return gpr_pc;
979         case LLDB_REGNUM_GENERIC_SP: return gpr_sp;
980         case LLDB_REGNUM_GENERIC_FP: return gpr_fp;
981         case LLDB_REGNUM_GENERIC_RA: return gpr_lr;
982         case LLDB_REGNUM_GENERIC_FLAGS: return gpr_cpsr;
983         default:
984             break;
985         }
986     }
987     else if (kind == eRegisterKindDWARF)
988     {
989         switch (reg)
990         {
991         case arm64_dwarf::x0:  return gpr_x0;
992         case arm64_dwarf::x1:  return gpr_x1;
993         case arm64_dwarf::x2:  return gpr_x2;
994         case arm64_dwarf::x3:  return gpr_x3;
995         case arm64_dwarf::x4:  return gpr_x4;
996         case arm64_dwarf::x5:  return gpr_x5;
997         case arm64_dwarf::x6:  return gpr_x6;
998         case arm64_dwarf::x7:  return gpr_x7;
999         case arm64_dwarf::x8:  return gpr_x8;
1000         case arm64_dwarf::x9:  return gpr_x9;
1001         case arm64_dwarf::x10: return gpr_x10;
1002         case arm64_dwarf::x11: return gpr_x11;
1003         case arm64_dwarf::x12: return gpr_x12;
1004         case arm64_dwarf::x13: return gpr_x13;
1005         case arm64_dwarf::x14: return gpr_x14;
1006         case arm64_dwarf::x15: return gpr_x15;
1007         case arm64_dwarf::x16: return gpr_x16;
1008         case arm64_dwarf::x17: return gpr_x17;
1009         case arm64_dwarf::x18: return gpr_x18;
1010         case arm64_dwarf::x19: return gpr_x19;
1011         case arm64_dwarf::x20: return gpr_x20;
1012         case arm64_dwarf::x21: return gpr_x21;
1013         case arm64_dwarf::x22: return gpr_x22;
1014         case arm64_dwarf::x23: return gpr_x23;
1015         case arm64_dwarf::x24: return gpr_x24;
1016         case arm64_dwarf::x25: return gpr_x25;
1017         case arm64_dwarf::x26: return gpr_x26;
1018         case arm64_dwarf::x27: return gpr_x27;
1019         case arm64_dwarf::x28: return gpr_x28;
1020 
1021         case arm64_dwarf::fp:  return gpr_fp;
1022         case arm64_dwarf::sp:  return gpr_sp;
1023         case arm64_dwarf::lr:  return gpr_lr;
1024         case arm64_dwarf::pc:  return gpr_pc;
1025         case arm64_dwarf::cpsr: return gpr_cpsr;
1026 
1027         case arm64_dwarf::v0:  return fpu_v0;
1028         case arm64_dwarf::v1:  return fpu_v1;
1029         case arm64_dwarf::v2:  return fpu_v2;
1030         case arm64_dwarf::v3:  return fpu_v3;
1031         case arm64_dwarf::v4:  return fpu_v4;
1032         case arm64_dwarf::v5:  return fpu_v5;
1033         case arm64_dwarf::v6:  return fpu_v6;
1034         case arm64_dwarf::v7:  return fpu_v7;
1035         case arm64_dwarf::v8:  return fpu_v8;
1036         case arm64_dwarf::v9:  return fpu_v9;
1037         case arm64_dwarf::v10: return fpu_v10;
1038         case arm64_dwarf::v11: return fpu_v11;
1039         case arm64_dwarf::v12: return fpu_v12;
1040         case arm64_dwarf::v13: return fpu_v13;
1041         case arm64_dwarf::v14: return fpu_v14;
1042         case arm64_dwarf::v15: return fpu_v15;
1043         case arm64_dwarf::v16: return fpu_v16;
1044         case arm64_dwarf::v17: return fpu_v17;
1045         case arm64_dwarf::v18: return fpu_v18;
1046         case arm64_dwarf::v19: return fpu_v19;
1047         case arm64_dwarf::v20: return fpu_v20;
1048         case arm64_dwarf::v21: return fpu_v21;
1049         case arm64_dwarf::v22: return fpu_v22;
1050         case arm64_dwarf::v23: return fpu_v23;
1051         case arm64_dwarf::v24: return fpu_v24;
1052         case arm64_dwarf::v25: return fpu_v25;
1053         case arm64_dwarf::v26: return fpu_v26;
1054         case arm64_dwarf::v27: return fpu_v27;
1055         case arm64_dwarf::v28: return fpu_v28;
1056         case arm64_dwarf::v29: return fpu_v29;
1057         case arm64_dwarf::v30: return fpu_v30;
1058         case arm64_dwarf::v31: return fpu_v31;
1059 
1060         default:
1061             break;
1062         }
1063     }
1064     else if (kind == eRegisterKindGCC)
1065     {
1066         switch (reg)
1067         {
1068         case arm64_gcc::x0:  return gpr_x0;
1069         case arm64_gcc::x1:  return gpr_x1;
1070         case arm64_gcc::x2:  return gpr_x2;
1071         case arm64_gcc::x3:  return gpr_x3;
1072         case arm64_gcc::x4:  return gpr_x4;
1073         case arm64_gcc::x5:  return gpr_x5;
1074         case arm64_gcc::x6:  return gpr_x6;
1075         case arm64_gcc::x7:  return gpr_x7;
1076         case arm64_gcc::x8:  return gpr_x8;
1077         case arm64_gcc::x9:  return gpr_x9;
1078         case arm64_gcc::x10: return gpr_x10;
1079         case arm64_gcc::x11: return gpr_x11;
1080         case arm64_gcc::x12: return gpr_x12;
1081         case arm64_gcc::x13: return gpr_x13;
1082         case arm64_gcc::x14: return gpr_x14;
1083         case arm64_gcc::x15: return gpr_x15;
1084         case arm64_gcc::x16: return gpr_x16;
1085         case arm64_gcc::x17: return gpr_x17;
1086         case arm64_gcc::x18: return gpr_x18;
1087         case arm64_gcc::x19: return gpr_x19;
1088         case arm64_gcc::x20: return gpr_x20;
1089         case arm64_gcc::x21: return gpr_x21;
1090         case arm64_gcc::x22: return gpr_x22;
1091         case arm64_gcc::x23: return gpr_x23;
1092         case arm64_gcc::x24: return gpr_x24;
1093         case arm64_gcc::x25: return gpr_x25;
1094         case arm64_gcc::x26: return gpr_x26;
1095         case arm64_gcc::x27: return gpr_x27;
1096         case arm64_gcc::x28: return gpr_x28;
1097         case arm64_gcc::fp:   return gpr_fp;
1098         case arm64_gcc::sp:   return gpr_sp;
1099         case arm64_gcc::lr:   return gpr_lr;
1100         case arm64_gcc::pc:   return gpr_pc;
1101         case arm64_gcc::cpsr: return gpr_cpsr;
1102         }
1103     }
1104     else if (kind == eRegisterKindLLDB)
1105     {
1106         return reg;
1107     }
1108     return LLDB_INVALID_REGNUM;
1109 }
1110 
1111 
1112 uint32_t
1113 RegisterContextDarwin_arm64::NumSupportedHardwareWatchpoints ()
1114 {
1115 #if defined (__arm64__)
1116     // autodetect how many watchpoints are supported dynamically...
1117     static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX;
1118     if (g_num_supported_hw_watchpoints == UINT32_MAX)
1119     {
1120         size_t len;
1121         uint32_t n = 0;
1122         len = sizeof (n);
1123         if (::sysctlbyname("hw.optional.watchpoint", &n, &len, NULL, 0) == 0)
1124         {
1125             g_num_supported_hw_watchpoints = n;
1126         }
1127     }
1128     return g_num_supported_hw_watchpoints;
1129 #else
1130     // TODO: figure out remote case here!
1131     return 2;
1132 #endif
1133 }
1134 
1135 
1136 uint32_t
1137 RegisterContextDarwin_arm64::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write)
1138 {
1139 //    if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint(addr = %8.8p, size = %u, read = %u, write = %u)", addr, size, read, write);
1140 
1141     const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
1142 
1143     // Can't watch zero bytes
1144     if (size == 0)
1145         return LLDB_INVALID_INDEX32;
1146 
1147     // We must watch for either read or write
1148     if (read == false && write == false)
1149         return LLDB_INVALID_INDEX32;
1150 
1151     // Can't watch more than 4 bytes per WVR/WCR pair
1152     if (size > 4)
1153         return LLDB_INVALID_INDEX32;
1154 
1155     // We can only watch up to four bytes that follow a 4 byte aligned address
1156     // per watchpoint register pair. Since we have at most so we can only watch
1157     // until the next 4 byte boundary and we need to make sure we can properly
1158     // encode this.
1159     uint32_t addr_word_offset = addr % 4;
1160 //    if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() - addr_word_offset = 0x%8.8x", addr_word_offset);
1161 
1162     uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset;
1163 //    if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() - byte_mask = 0x%8.8x", byte_mask);
1164     if (byte_mask > 0xfu)
1165         return LLDB_INVALID_INDEX32;
1166 
1167     // Read the debug state
1168     int kret = ReadDBG (false);
1169 
1170     if (kret == KERN_SUCCESS)
1171     {
1172         // Check to make sure we have the needed hardware support
1173         uint32_t i = 0;
1174 
1175         for (i=0; i<num_hw_watchpoints; ++i)
1176         {
1177             if ((dbg.wcr[i] & WCR_ENABLE) == 0)
1178                 break; // We found an available hw breakpoint slot (in i)
1179         }
1180 
1181         // See if we found an available hw breakpoint slot above
1182         if (i < num_hw_watchpoints)
1183         {
1184             // Make the byte_mask into a valid Byte Address Select mask
1185             uint32_t byte_address_select = byte_mask << 5;
1186             // Make sure bits 1:0 are clear in our address
1187             dbg.wvr[i] = addr & ~((lldb::addr_t)3);
1188             dbg.wcr[i] =  byte_address_select |       // Which bytes that follow the IMVA that we will watch
1189                                     S_USER |                    // Stop only in user mode
1190                                     (read ? WCR_LOAD : 0) |     // Stop on read access?
1191                                     (write ? WCR_STORE : 0) |   // Stop on write access?
1192                                     WCR_ENABLE;                 // Enable this watchpoint;
1193 
1194             kret = WriteDBG();
1195 //            if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() WriteDBG() => 0x%8.8x.", kret);
1196 
1197             if (kret == KERN_SUCCESS)
1198                 return i;
1199         }
1200         else
1201         {
1202 //            if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint(): All hardware resources (%u) are in use.", num_hw_watchpoints);
1203         }
1204     }
1205     return LLDB_INVALID_INDEX32;
1206 }
1207 
1208 bool
1209 RegisterContextDarwin_arm64::ClearHardwareWatchpoint (uint32_t hw_index)
1210 {
1211     int kret = ReadDBG (false);
1212 
1213     const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
1214     if (kret == KERN_SUCCESS)
1215     {
1216         if (hw_index < num_hw_points)
1217         {
1218             dbg.wcr[hw_index] = 0;
1219 //            if (log) log->Printf ("RegisterContextDarwin_arm64::ClearHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x  WCR%u = 0x%8.8x",
1220 //                    hw_index,
1221 //                    hw_index,
1222 //                    dbg.wvr[hw_index],
1223 //                    hw_index,
1224 //                    dbg.wcr[hw_index]);
1225 
1226             kret = WriteDBG();
1227 
1228             if (kret == KERN_SUCCESS)
1229                 return true;
1230         }
1231     }
1232     return false;
1233 }
1234 
1235 #endif
1236