1//===-- RegisterContextDarwin_arm.cpp -------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "RegisterContextDarwin_arm.h"
10#include "RegisterContextDarwinConstants.h"
11
12#include "lldb/Utility/DataBufferHeap.h"
13#include "lldb/Utility/DataExtractor.h"
14#include "lldb/Utility/Endian.h"
15#include "lldb/Utility/Log.h"
16#include "lldb/Utility/RegisterValue.h"
17#include "lldb/Utility/Scalar.h"
18#include "llvm/Support/Compiler.h"
19
20#include "Plugins/Process/Utility/InstructionUtils.h"
21
22#include <memory>
23
24#include "Utility/ARM_DWARF_Registers.h"
25#include "Utility/ARM_ehframe_Registers.h"
26
27#include "llvm/ADT/STLExtras.h"
28
29using namespace lldb;
30using namespace lldb_private;
31
32enum {
33 gpr_r0 = 0,
34 gpr_r1,
35 gpr_r2,
36 gpr_r3,
37 gpr_r4,
38 gpr_r5,
39 gpr_r6,
40 gpr_r7,
41 gpr_r8,
42 gpr_r9,
43 gpr_r10,
44 gpr_r11,
45 gpr_r12,
46 gpr_r13,
47 gpr_sp = gpr_r13,
48 gpr_r14,
49 gpr_lr = gpr_r14,
50 gpr_r15,
51 gpr_pc = gpr_r15,
52 gpr_cpsr,
53
54 fpu_s0,
55 fpu_s1,
56 fpu_s2,
57 fpu_s3,
58 fpu_s4,
59 fpu_s5,
60 fpu_s6,
61 fpu_s7,
62 fpu_s8,
63 fpu_s9,
64 fpu_s10,
65 fpu_s11,
66 fpu_s12,
67 fpu_s13,
68 fpu_s14,
69 fpu_s15,
70 fpu_s16,
71 fpu_s17,
72 fpu_s18,
73 fpu_s19,
74 fpu_s20,
75 fpu_s21,
76 fpu_s22,
77 fpu_s23,
78 fpu_s24,
79 fpu_s25,
80 fpu_s26,
81 fpu_s27,
82 fpu_s28,
83 fpu_s29,
84 fpu_s30,
85 fpu_s31,
86 fpu_fpscr,
87
88 exc_exception,
89 exc_fsr,
90 exc_far,
91
92 dbg_bvr0,
93 dbg_bvr1,
94 dbg_bvr2,
95 dbg_bvr3,
96 dbg_bvr4,
97 dbg_bvr5,
98 dbg_bvr6,
99 dbg_bvr7,
100 dbg_bvr8,
101 dbg_bvr9,
102 dbg_bvr10,
103 dbg_bvr11,
104 dbg_bvr12,
105 dbg_bvr13,
106 dbg_bvr14,
107 dbg_bvr15,
108
109 dbg_bcr0,
110 dbg_bcr1,
111 dbg_bcr2,
112 dbg_bcr3,
113 dbg_bcr4,
114 dbg_bcr5,
115 dbg_bcr6,
116 dbg_bcr7,
117 dbg_bcr8,
118 dbg_bcr9,
119 dbg_bcr10,
120 dbg_bcr11,
121 dbg_bcr12,
122 dbg_bcr13,
123 dbg_bcr14,
124 dbg_bcr15,
125
126 dbg_wvr0,
127 dbg_wvr1,
128 dbg_wvr2,
129 dbg_wvr3,
130 dbg_wvr4,
131 dbg_wvr5,
132 dbg_wvr6,
133 dbg_wvr7,
134 dbg_wvr8,
135 dbg_wvr9,
136 dbg_wvr10,
137 dbg_wvr11,
138 dbg_wvr12,
139 dbg_wvr13,
140 dbg_wvr14,
141 dbg_wvr15,
142
143 dbg_wcr0,
144 dbg_wcr1,
145 dbg_wcr2,
146 dbg_wcr3,
147 dbg_wcr4,
148 dbg_wcr5,
149 dbg_wcr6,
150 dbg_wcr7,
151 dbg_wcr8,
152 dbg_wcr9,
153 dbg_wcr10,
154 dbg_wcr11,
155 dbg_wcr12,
156 dbg_wcr13,
157 dbg_wcr14,
158 dbg_wcr15,
159
160 k_num_registers
161};
162
163#define GPR_OFFSET(idx) ((idx)*4)
164#define FPU_OFFSET(idx) ((idx)*4 + sizeof(RegisterContextDarwin_arm::GPR))
165#define EXC_OFFSET(idx) \
166 ((idx)*4 + sizeof(RegisterContextDarwin_arm::GPR) + \
167 sizeof(RegisterContextDarwin_arm::FPU))
168#define DBG_OFFSET(reg) \
169 ((LLVM_EXTENSION offsetof(RegisterContextDarwin_arm::DBG, reg) + \
170 sizeof(RegisterContextDarwin_arm::GPR) + \
171 sizeof(RegisterContextDarwin_arm::FPU) + \
172 sizeof(RegisterContextDarwin_arm::EXC)))
173
174#define DEFINE_DBG(reg, i) \
175 #reg, NULL, sizeof(((RegisterContextDarwin_arm::DBG *) NULL)->reg[i]), \
176 DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, \
177 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
178 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
179 LLDB_INVALID_REGNUM }, \
180 nullptr, nullptr, nullptr,
181#define REG_CONTEXT_SIZE \
182 (sizeof(RegisterContextDarwin_arm::GPR) + \
183 sizeof(RegisterContextDarwin_arm::FPU) + \
184 sizeof(RegisterContextDarwin_arm::EXC))
185
186static RegisterInfo g_register_infos[] = {
187 // General purpose registers
188 // NAME ALT SZ OFFSET ENCODING FORMAT
189 // EH_FRAME DWARF GENERIC
190 // PROCESS PLUGIN LLDB NATIVE
191 // ====== ======= == ============= ============= ============
192 // =============== =============== =========================
193 // ===================== =============
194 {.name: "r0",
195 .alt_name: nullptr,
196 .byte_size: 4,
197 GPR_OFFSET(0),
198 .encoding: eEncodingUint,
199 .format: eFormatHex,
200 .kinds: {ehframe_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r0},
201 .value_regs: nullptr,
202 .invalidate_regs: nullptr,
203 .flags_type: nullptr,
204 },
205 {.name: "r1",
206 .alt_name: nullptr,
207 .byte_size: 4,
208 GPR_OFFSET(1),
209 .encoding: eEncodingUint,
210 .format: eFormatHex,
211 .kinds: {ehframe_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r1},
212 .value_regs: nullptr,
213 .invalidate_regs: nullptr,
214 .flags_type: nullptr,
215 },
216 {.name: "r2",
217 .alt_name: nullptr,
218 .byte_size: 4,
219 GPR_OFFSET(2),
220 .encoding: eEncodingUint,
221 .format: eFormatHex,
222 .kinds: {ehframe_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r2},
223 .value_regs: nullptr,
224 .invalidate_regs: nullptr,
225 .flags_type: nullptr,
226 },
227 {.name: "r3",
228 .alt_name: nullptr,
229 .byte_size: 4,
230 GPR_OFFSET(3),
231 .encoding: eEncodingUint,
232 .format: eFormatHex,
233 .kinds: {ehframe_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r3},
234 .value_regs: nullptr,
235 .invalidate_regs: nullptr,
236 .flags_type: nullptr,
237 },
238 {.name: "r4",
239 .alt_name: nullptr,
240 .byte_size: 4,
241 GPR_OFFSET(4),
242 .encoding: eEncodingUint,
243 .format: eFormatHex,
244 .kinds: {ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r4},
245 .value_regs: nullptr,
246 .invalidate_regs: nullptr,
247 .flags_type: nullptr,
248 },
249 {.name: "r5",
250 .alt_name: nullptr,
251 .byte_size: 4,
252 GPR_OFFSET(5),
253 .encoding: eEncodingUint,
254 .format: eFormatHex,
255 .kinds: {ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r5},
256 .value_regs: nullptr,
257 .invalidate_regs: nullptr,
258 .flags_type: nullptr,
259 },
260 {.name: "r6",
261 .alt_name: nullptr,
262 .byte_size: 4,
263 GPR_OFFSET(6),
264 .encoding: eEncodingUint,
265 .format: eFormatHex,
266 .kinds: {ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r6},
267 .value_regs: nullptr,
268 .invalidate_regs: nullptr,
269 .flags_type: nullptr,
270 },
271 {.name: "r7",
272 .alt_name: nullptr,
273 .byte_size: 4,
274 GPR_OFFSET(7),
275 .encoding: eEncodingUint,
276 .format: eFormatHex,
277 .kinds: {ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
278 gpr_r7},
279 .value_regs: nullptr,
280 .invalidate_regs: nullptr,
281 .flags_type: nullptr,
282 },
283 {.name: "r8",
284 .alt_name: nullptr,
285 .byte_size: 4,
286 GPR_OFFSET(8),
287 .encoding: eEncodingUint,
288 .format: eFormatHex,
289 .kinds: {ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r8},
290 .value_regs: nullptr,
291 .invalidate_regs: nullptr,
292 .flags_type: nullptr,
293 },
294 {.name: "r9",
295 .alt_name: nullptr,
296 .byte_size: 4,
297 GPR_OFFSET(9),
298 .encoding: eEncodingUint,
299 .format: eFormatHex,
300 .kinds: {ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r9},
301 .value_regs: nullptr,
302 .invalidate_regs: nullptr,
303 .flags_type: nullptr,
304 },
305 {.name: "r10",
306 .alt_name: nullptr,
307 .byte_size: 4,
308 GPR_OFFSET(10),
309 .encoding: eEncodingUint,
310 .format: eFormatHex,
311 .kinds: {ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
312 gpr_r10},
313 .value_regs: nullptr,
314 .invalidate_regs: nullptr,
315 .flags_type: nullptr,
316 },
317 {.name: "r11",
318 .alt_name: nullptr,
319 .byte_size: 4,
320 GPR_OFFSET(11),
321 .encoding: eEncodingUint,
322 .format: eFormatHex,
323 .kinds: {ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
324 gpr_r11},
325 .value_regs: nullptr,
326 .invalidate_regs: nullptr,
327 .flags_type: nullptr,
328 },
329 {.name: "r12",
330 .alt_name: nullptr,
331 .byte_size: 4,
332 GPR_OFFSET(12),
333 .encoding: eEncodingUint,
334 .format: eFormatHex,
335 .kinds: {ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
336 gpr_r12},
337 .value_regs: nullptr,
338 .invalidate_regs: nullptr,
339 .flags_type: nullptr,
340 },
341 {.name: "sp",
342 .alt_name: "r13",
343 .byte_size: 4,
344 GPR_OFFSET(13),
345 .encoding: eEncodingUint,
346 .format: eFormatHex,
347 .kinds: {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
348 gpr_sp},
349 .value_regs: nullptr,
350 .invalidate_regs: nullptr,
351 .flags_type: nullptr,
352 },
353 {.name: "lr",
354 .alt_name: "r14",
355 .byte_size: 4,
356 GPR_OFFSET(14),
357 .encoding: eEncodingUint,
358 .format: eFormatHex,
359 .kinds: {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM,
360 gpr_lr},
361 .value_regs: nullptr,
362 .invalidate_regs: nullptr,
363 .flags_type: nullptr,
364 },
365 {.name: "pc",
366 .alt_name: "r15",
367 .byte_size: 4,
368 GPR_OFFSET(15),
369 .encoding: eEncodingUint,
370 .format: eFormatHex,
371 .kinds: {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
372 gpr_pc},
373 .value_regs: nullptr,
374 .invalidate_regs: nullptr,
375 .flags_type: nullptr,
376 },
377 {.name: "cpsr",
378 .alt_name: "psr",
379 .byte_size: 4,
380 GPR_OFFSET(16),
381 .encoding: eEncodingUint,
382 .format: eFormatHex,
383 .kinds: {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM,
384 gpr_cpsr},
385 .value_regs: nullptr,
386 .invalidate_regs: nullptr,
387 .flags_type: nullptr,
388 },
389
390 {.name: "s0",
391 .alt_name: nullptr,
392 .byte_size: 4,
393 FPU_OFFSET(0),
394 .encoding: eEncodingIEEE754,
395 .format: eFormatFloat,
396 .kinds: {LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
397 fpu_s0},
398 .value_regs: nullptr,
399 .invalidate_regs: nullptr,
400 .flags_type: nullptr,
401 },
402 {.name: "s1",
403 .alt_name: nullptr,
404 .byte_size: 4,
405 FPU_OFFSET(1),
406 .encoding: eEncodingIEEE754,
407 .format: eFormatFloat,
408 .kinds: {LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
409 fpu_s1},
410 .value_regs: nullptr,
411 .invalidate_regs: nullptr,
412 .flags_type: nullptr,
413 },
414 {.name: "s2",
415 .alt_name: nullptr,
416 .byte_size: 4,
417 FPU_OFFSET(2),
418 .encoding: eEncodingIEEE754,
419 .format: eFormatFloat,
420 .kinds: {LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
421 fpu_s2},
422 .value_regs: nullptr,
423 .invalidate_regs: nullptr,
424 .flags_type: nullptr,
425 },
426 {.name: "s3",
427 .alt_name: nullptr,
428 .byte_size: 4,
429 FPU_OFFSET(3),
430 .encoding: eEncodingIEEE754,
431 .format: eFormatFloat,
432 .kinds: {LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
433 fpu_s3},
434 .value_regs: nullptr,
435 .invalidate_regs: nullptr,
436 .flags_type: nullptr,
437 },
438 {.name: "s4",
439 .alt_name: nullptr,
440 .byte_size: 4,
441 FPU_OFFSET(4),
442 .encoding: eEncodingIEEE754,
443 .format: eFormatFloat,
444 .kinds: {LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
445 fpu_s4},
446 .value_regs: nullptr,
447 .invalidate_regs: nullptr,
448 .flags_type: nullptr,
449 },
450 {.name: "s5",
451 .alt_name: nullptr,
452 .byte_size: 4,
453 FPU_OFFSET(5),
454 .encoding: eEncodingIEEE754,
455 .format: eFormatFloat,
456 .kinds: {LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
457 fpu_s5},
458 .value_regs: nullptr,
459 .invalidate_regs: nullptr,
460 .flags_type: nullptr,
461 },
462 {.name: "s6",
463 .alt_name: nullptr,
464 .byte_size: 4,
465 FPU_OFFSET(6),
466 .encoding: eEncodingIEEE754,
467 .format: eFormatFloat,
468 .kinds: {LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
469 fpu_s6},
470 .value_regs: nullptr,
471 .invalidate_regs: nullptr,
472 .flags_type: nullptr,
473 },
474 {.name: "s7",
475 .alt_name: nullptr,
476 .byte_size: 4,
477 FPU_OFFSET(7),
478 .encoding: eEncodingIEEE754,
479 .format: eFormatFloat,
480 .kinds: {LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
481 fpu_s7},
482 .value_regs: nullptr,
483 .invalidate_regs: nullptr,
484 .flags_type: nullptr,
485 },
486 {.name: "s8",
487 .alt_name: nullptr,
488 .byte_size: 4,
489 FPU_OFFSET(8),
490 .encoding: eEncodingIEEE754,
491 .format: eFormatFloat,
492 .kinds: {LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
493 fpu_s8},
494 .value_regs: nullptr,
495 .invalidate_regs: nullptr,
496 .flags_type: nullptr,
497 },
498 {.name: "s9",
499 .alt_name: nullptr,
500 .byte_size: 4,
501 FPU_OFFSET(9),
502 .encoding: eEncodingIEEE754,
503 .format: eFormatFloat,
504 .kinds: {LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
505 fpu_s9},
506 .value_regs: nullptr,
507 .invalidate_regs: nullptr,
508 .flags_type: nullptr,
509 },
510 {.name: "s10",
511 .alt_name: nullptr,
512 .byte_size: 4,
513 FPU_OFFSET(10),
514 .encoding: eEncodingIEEE754,
515 .format: eFormatFloat,
516 .kinds: {LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
517 fpu_s10},
518 .value_regs: nullptr,
519 .invalidate_regs: nullptr,
520 .flags_type: nullptr,
521 },
522 {.name: "s11",
523 .alt_name: nullptr,
524 .byte_size: 4,
525 FPU_OFFSET(11),
526 .encoding: eEncodingIEEE754,
527 .format: eFormatFloat,
528 .kinds: {LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
529 fpu_s11},
530 .value_regs: nullptr,
531 .invalidate_regs: nullptr,
532 .flags_type: nullptr,
533 },
534 {.name: "s12",
535 .alt_name: nullptr,
536 .byte_size: 4,
537 FPU_OFFSET(12),
538 .encoding: eEncodingIEEE754,
539 .format: eFormatFloat,
540 .kinds: {LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
541 fpu_s12},
542 .value_regs: nullptr,
543 .invalidate_regs: nullptr,
544 .flags_type: nullptr,
545 },
546 {.name: "s13",
547 .alt_name: nullptr,
548 .byte_size: 4,
549 FPU_OFFSET(13),
550 .encoding: eEncodingIEEE754,
551 .format: eFormatFloat,
552 .kinds: {LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
553 fpu_s13},
554 .value_regs: nullptr,
555 .invalidate_regs: nullptr,
556 .flags_type: nullptr,
557 },
558 {.name: "s14",
559 .alt_name: nullptr,
560 .byte_size: 4,
561 FPU_OFFSET(14),
562 .encoding: eEncodingIEEE754,
563 .format: eFormatFloat,
564 .kinds: {LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
565 fpu_s14},
566 .value_regs: nullptr,
567 .invalidate_regs: nullptr,
568 .flags_type: nullptr,
569 },
570 {.name: "s15",
571 .alt_name: nullptr,
572 .byte_size: 4,
573 FPU_OFFSET(15),
574 .encoding: eEncodingIEEE754,
575 .format: eFormatFloat,
576 .kinds: {LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
577 fpu_s15},
578 .value_regs: nullptr,
579 .invalidate_regs: nullptr,
580 .flags_type: nullptr,
581 },
582 {.name: "s16",
583 .alt_name: nullptr,
584 .byte_size: 4,
585 FPU_OFFSET(16),
586 .encoding: eEncodingIEEE754,
587 .format: eFormatFloat,
588 .kinds: {LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
589 fpu_s16},
590 .value_regs: nullptr,
591 .invalidate_regs: nullptr,
592 .flags_type: nullptr,
593 },
594 {.name: "s17",
595 .alt_name: nullptr,
596 .byte_size: 4,
597 FPU_OFFSET(17),
598 .encoding: eEncodingIEEE754,
599 .format: eFormatFloat,
600 .kinds: {LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
601 fpu_s17},
602 .value_regs: nullptr,
603 .invalidate_regs: nullptr,
604 .flags_type: nullptr,
605 },
606 {.name: "s18",
607 .alt_name: nullptr,
608 .byte_size: 4,
609 FPU_OFFSET(18),
610 .encoding: eEncodingIEEE754,
611 .format: eFormatFloat,
612 .kinds: {LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
613 fpu_s18},
614 .value_regs: nullptr,
615 .invalidate_regs: nullptr,
616 .flags_type: nullptr,
617 },
618 {.name: "s19",
619 .alt_name: nullptr,
620 .byte_size: 4,
621 FPU_OFFSET(19),
622 .encoding: eEncodingIEEE754,
623 .format: eFormatFloat,
624 .kinds: {LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
625 fpu_s19},
626 .value_regs: nullptr,
627 .invalidate_regs: nullptr,
628 .flags_type: nullptr,
629 },
630 {.name: "s20",
631 .alt_name: nullptr,
632 .byte_size: 4,
633 FPU_OFFSET(20),
634 .encoding: eEncodingIEEE754,
635 .format: eFormatFloat,
636 .kinds: {LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
637 fpu_s20},
638 .value_regs: nullptr,
639 .invalidate_regs: nullptr,
640 .flags_type: nullptr,
641 },
642 {.name: "s21",
643 .alt_name: nullptr,
644 .byte_size: 4,
645 FPU_OFFSET(21),
646 .encoding: eEncodingIEEE754,
647 .format: eFormatFloat,
648 .kinds: {LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
649 fpu_s21},
650 .value_regs: nullptr,
651 .invalidate_regs: nullptr,
652 .flags_type: nullptr,
653 },
654 {.name: "s22",
655 .alt_name: nullptr,
656 .byte_size: 4,
657 FPU_OFFSET(22),
658 .encoding: eEncodingIEEE754,
659 .format: eFormatFloat,
660 .kinds: {LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
661 fpu_s22},
662 .value_regs: nullptr,
663 .invalidate_regs: nullptr,
664 .flags_type: nullptr,
665 },
666 {.name: "s23",
667 .alt_name: nullptr,
668 .byte_size: 4,
669 FPU_OFFSET(23),
670 .encoding: eEncodingIEEE754,
671 .format: eFormatFloat,
672 .kinds: {LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
673 fpu_s23},
674 .value_regs: nullptr,
675 .invalidate_regs: nullptr,
676 .flags_type: nullptr,
677 },
678 {.name: "s24",
679 .alt_name: nullptr,
680 .byte_size: 4,
681 FPU_OFFSET(24),
682 .encoding: eEncodingIEEE754,
683 .format: eFormatFloat,
684 .kinds: {LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
685 fpu_s24},
686 .value_regs: nullptr,
687 .invalidate_regs: nullptr,
688 .flags_type: nullptr,
689 },
690 {.name: "s25",
691 .alt_name: nullptr,
692 .byte_size: 4,
693 FPU_OFFSET(25),
694 .encoding: eEncodingIEEE754,
695 .format: eFormatFloat,
696 .kinds: {LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
697 fpu_s25},
698 .value_regs: nullptr,
699 .invalidate_regs: nullptr,
700 .flags_type: nullptr,
701 },
702 {.name: "s26",
703 .alt_name: nullptr,
704 .byte_size: 4,
705 FPU_OFFSET(26),
706 .encoding: eEncodingIEEE754,
707 .format: eFormatFloat,
708 .kinds: {LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
709 fpu_s26},
710 .value_regs: nullptr,
711 .invalidate_regs: nullptr,
712 .flags_type: nullptr,
713 },
714 {.name: "s27",
715 .alt_name: nullptr,
716 .byte_size: 4,
717 FPU_OFFSET(27),
718 .encoding: eEncodingIEEE754,
719 .format: eFormatFloat,
720 .kinds: {LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
721 fpu_s27},
722 .value_regs: nullptr,
723 .invalidate_regs: nullptr,
724 .flags_type: nullptr,
725 },
726 {.name: "s28",
727 .alt_name: nullptr,
728 .byte_size: 4,
729 FPU_OFFSET(28),
730 .encoding: eEncodingIEEE754,
731 .format: eFormatFloat,
732 .kinds: {LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
733 fpu_s28},
734 .value_regs: nullptr,
735 .invalidate_regs: nullptr,
736 .flags_type: nullptr,
737 },
738 {.name: "s29",
739 .alt_name: nullptr,
740 .byte_size: 4,
741 FPU_OFFSET(29),
742 .encoding: eEncodingIEEE754,
743 .format: eFormatFloat,
744 .kinds: {LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
745 fpu_s29},
746 .value_regs: nullptr,
747 .invalidate_regs: nullptr,
748 .flags_type: nullptr,
749 },
750 {.name: "s30",
751 .alt_name: nullptr,
752 .byte_size: 4,
753 FPU_OFFSET(30),
754 .encoding: eEncodingIEEE754,
755 .format: eFormatFloat,
756 .kinds: {LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
757 fpu_s30},
758 .value_regs: nullptr,
759 .invalidate_regs: nullptr,
760 .flags_type: nullptr,
761 },
762 {.name: "s31",
763 .alt_name: nullptr,
764 .byte_size: 4,
765 FPU_OFFSET(31),
766 .encoding: eEncodingIEEE754,
767 .format: eFormatFloat,
768 .kinds: {LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
769 fpu_s31},
770 .value_regs: nullptr,
771 .invalidate_regs: nullptr,
772 .flags_type: nullptr,
773 },
774 {.name: "fpscr",
775 .alt_name: nullptr,
776 .byte_size: 4,
777 FPU_OFFSET(32),
778 .encoding: eEncodingUint,
779 .format: eFormatHex,
780 .kinds: {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
781 LLDB_INVALID_REGNUM, fpu_fpscr},
782 .value_regs: nullptr,
783 .invalidate_regs: nullptr,
784 .flags_type: nullptr,
785 },
786
787 {.name: "exception",
788 .alt_name: nullptr,
789 .byte_size: 4,
790 EXC_OFFSET(0),
791 .encoding: eEncodingUint,
792 .format: eFormatHex,
793 .kinds: {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
794 LLDB_INVALID_REGNUM, exc_exception},
795 .value_regs: nullptr,
796 .invalidate_regs: nullptr,
797 .flags_type: nullptr,
798 },
799 {.name: "fsr",
800 .alt_name: nullptr,
801 .byte_size: 4,
802 EXC_OFFSET(1),
803 .encoding: eEncodingUint,
804 .format: eFormatHex,
805 .kinds: {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
806 LLDB_INVALID_REGNUM, exc_fsr},
807 .value_regs: nullptr,
808 .invalidate_regs: nullptr,
809 .flags_type: nullptr,
810 },
811 {.name: "far",
812 .alt_name: nullptr,
813 .byte_size: 4,
814 EXC_OFFSET(2),
815 .encoding: eEncodingUint,
816 .format: eFormatHex,
817 .kinds: {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
818 LLDB_INVALID_REGNUM, exc_far},
819 .value_regs: nullptr,
820 .invalidate_regs: nullptr,
821 .flags_type: nullptr,
822 },
823
824 {DEFINE_DBG(bvr, 0)},
825 {DEFINE_DBG(bvr, 1)},
826 {DEFINE_DBG(bvr, 2)},
827 {DEFINE_DBG(bvr, 3)},
828 {DEFINE_DBG(bvr, 4)},
829 {DEFINE_DBG(bvr, 5)},
830 {DEFINE_DBG(bvr, 6)},
831 {DEFINE_DBG(bvr, 7)},
832 {DEFINE_DBG(bvr, 8)},
833 {DEFINE_DBG(bvr, 9)},
834 {DEFINE_DBG(bvr, 10)},
835 {DEFINE_DBG(bvr, 11)},
836 {DEFINE_DBG(bvr, 12)},
837 {DEFINE_DBG(bvr, 13)},
838 {DEFINE_DBG(bvr, 14)},
839 {DEFINE_DBG(bvr, 15)},
840
841 {DEFINE_DBG(bcr, 0)},
842 {DEFINE_DBG(bcr, 1)},
843 {DEFINE_DBG(bcr, 2)},
844 {DEFINE_DBG(bcr, 3)},
845 {DEFINE_DBG(bcr, 4)},
846 {DEFINE_DBG(bcr, 5)},
847 {DEFINE_DBG(bcr, 6)},
848 {DEFINE_DBG(bcr, 7)},
849 {DEFINE_DBG(bcr, 8)},
850 {DEFINE_DBG(bcr, 9)},
851 {DEFINE_DBG(bcr, 10)},
852 {DEFINE_DBG(bcr, 11)},
853 {DEFINE_DBG(bcr, 12)},
854 {DEFINE_DBG(bcr, 13)},
855 {DEFINE_DBG(bcr, 14)},
856 {DEFINE_DBG(bcr, 15)},
857
858 {DEFINE_DBG(wvr, 0)},
859 {DEFINE_DBG(wvr, 1)},
860 {DEFINE_DBG(wvr, 2)},
861 {DEFINE_DBG(wvr, 3)},
862 {DEFINE_DBG(wvr, 4)},
863 {DEFINE_DBG(wvr, 5)},
864 {DEFINE_DBG(wvr, 6)},
865 {DEFINE_DBG(wvr, 7)},
866 {DEFINE_DBG(wvr, 8)},
867 {DEFINE_DBG(wvr, 9)},
868 {DEFINE_DBG(wvr, 10)},
869 {DEFINE_DBG(wvr, 11)},
870 {DEFINE_DBG(wvr, 12)},
871 {DEFINE_DBG(wvr, 13)},
872 {DEFINE_DBG(wvr, 14)},
873 {DEFINE_DBG(wvr, 15)},
874
875 {DEFINE_DBG(wcr, 0)},
876 {DEFINE_DBG(wcr, 1)},
877 {DEFINE_DBG(wcr, 2)},
878 {DEFINE_DBG(wcr, 3)},
879 {DEFINE_DBG(wcr, 4)},
880 {DEFINE_DBG(wcr, 5)},
881 {DEFINE_DBG(wcr, 6)},
882 {DEFINE_DBG(wcr, 7)},
883 {DEFINE_DBG(wcr, 8)},
884 {DEFINE_DBG(wcr, 9)},
885 {DEFINE_DBG(wcr, 10)},
886 {DEFINE_DBG(wcr, 11)},
887 {DEFINE_DBG(wcr, 12)},
888 {DEFINE_DBG(wcr, 13)},
889 {DEFINE_DBG(wcr, 14)},
890 {DEFINE_DBG(wcr, 15)}};
891
892// General purpose registers
893static uint32_t g_gpr_regnums[] = {
894 gpr_r0, gpr_r1, gpr_r2, gpr_r3, gpr_r4, gpr_r5, gpr_r6, gpr_r7, gpr_r8,
895 gpr_r9, gpr_r10, gpr_r11, gpr_r12, gpr_sp, gpr_lr, gpr_pc, gpr_cpsr};
896
897// Floating point registers
898static uint32_t g_fpu_regnums[] = {
899 fpu_s0, fpu_s1, fpu_s2, fpu_s3, fpu_s4, fpu_s5, fpu_s6,
900 fpu_s7, fpu_s8, fpu_s9, fpu_s10, fpu_s11, fpu_s12, fpu_s13,
901 fpu_s14, fpu_s15, fpu_s16, fpu_s17, fpu_s18, fpu_s19, fpu_s20,
902 fpu_s21, fpu_s22, fpu_s23, fpu_s24, fpu_s25, fpu_s26, fpu_s27,
903 fpu_s28, fpu_s29, fpu_s30, fpu_s31, fpu_fpscr,
904};
905
906// Exception registers
907
908static uint32_t g_exc_regnums[] = {
909 exc_exception, exc_fsr, exc_far,
910};
911
912static size_t k_num_register_infos = std::size(g_register_infos);
913
914RegisterContextDarwin_arm::RegisterContextDarwin_arm(
915 Thread &thread, uint32_t concrete_frame_idx)
916 : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() {
917 uint32_t i;
918 for (i = 0; i < kNumErrors; i++) {
919 gpr_errs[i] = -1;
920 fpu_errs[i] = -1;
921 exc_errs[i] = -1;
922 }
923}
924
925RegisterContextDarwin_arm::~RegisterContextDarwin_arm() = default;
926
927void RegisterContextDarwin_arm::InvalidateAllRegisters() {
928 InvalidateAllRegisterStates();
929}
930
931size_t RegisterContextDarwin_arm::GetRegisterCount() {
932 assert(k_num_register_infos == k_num_registers);
933 return k_num_registers;
934}
935
936const RegisterInfo *
937RegisterContextDarwin_arm::GetRegisterInfoAtIndex(size_t reg) {
938 assert(k_num_register_infos == k_num_registers);
939 if (reg < k_num_registers)
940 return &g_register_infos[reg];
941 return nullptr;
942}
943
944size_t RegisterContextDarwin_arm::GetRegisterInfosCount() {
945 return k_num_register_infos;
946}
947
948const RegisterInfo *RegisterContextDarwin_arm::GetRegisterInfos() {
949 return g_register_infos;
950}
951
952// Number of registers in each register set
953const size_t k_num_gpr_registers = std::size(g_gpr_regnums);
954const size_t k_num_fpu_registers = std::size(g_fpu_regnums);
955const size_t k_num_exc_registers = std::size(g_exc_regnums);
956
957// Register set definitions. The first definitions at register set index of
958// zero is for all registers, followed by other registers sets. The register
959// information for the all register set need not be filled in.
960static const RegisterSet g_reg_sets[] = {
961 {
962 .name: "General Purpose Registers", .short_name: "gpr", .num_registers: k_num_gpr_registers, .registers: g_gpr_regnums,
963 },
964 {.name: "Floating Point Registers", .short_name: "fpu", .num_registers: k_num_fpu_registers, .registers: g_fpu_regnums},
965 {.name: "Exception State Registers", .short_name: "exc", .num_registers: k_num_exc_registers, .registers: g_exc_regnums}};
966
967const size_t k_num_regsets = std::size(g_reg_sets);
968
969size_t RegisterContextDarwin_arm::GetRegisterSetCount() {
970 return k_num_regsets;
971}
972
973const RegisterSet *RegisterContextDarwin_arm::GetRegisterSet(size_t reg_set) {
974 if (reg_set < k_num_regsets)
975 return &g_reg_sets[reg_set];
976 return nullptr;
977}
978
979// Register information definitions for 32 bit i386.
980int RegisterContextDarwin_arm::GetSetForNativeRegNum(int reg) {
981 if (reg < fpu_s0)
982 return GPRRegSet;
983 else if (reg < exc_exception)
984 return FPURegSet;
985 else if (reg < k_num_registers)
986 return EXCRegSet;
987 return -1;
988}
989
990int RegisterContextDarwin_arm::ReadGPR(bool force) {
991 int set = GPRRegSet;
992 if (force || !RegisterSetIsCached(set)) {
993 SetError(flavor: set, err_idx: Read, err: DoReadGPR(tid: GetThreadID(), flavor: set, gpr));
994 }
995 return GetError(flavor: GPRRegSet, err_idx: Read);
996}
997
998int RegisterContextDarwin_arm::ReadFPU(bool force) {
999 int set = FPURegSet;
1000 if (force || !RegisterSetIsCached(set)) {
1001 SetError(flavor: set, err_idx: Read, err: DoReadFPU(tid: GetThreadID(), flavor: set, fpu));
1002 }
1003 return GetError(flavor: FPURegSet, err_idx: Read);
1004}
1005
1006int RegisterContextDarwin_arm::ReadEXC(bool force) {
1007 int set = EXCRegSet;
1008 if (force || !RegisterSetIsCached(set)) {
1009 SetError(flavor: set, err_idx: Read, err: DoReadEXC(tid: GetThreadID(), flavor: set, exc));
1010 }
1011 return GetError(flavor: EXCRegSet, err_idx: Read);
1012}
1013
1014int RegisterContextDarwin_arm::ReadDBG(bool force) {
1015 int set = DBGRegSet;
1016 if (force || !RegisterSetIsCached(set)) {
1017 SetError(flavor: set, err_idx: Read, err: DoReadDBG(tid: GetThreadID(), flavor: set, dbg));
1018 }
1019 return GetError(flavor: DBGRegSet, err_idx: Read);
1020}
1021
1022int RegisterContextDarwin_arm::WriteGPR() {
1023 int set = GPRRegSet;
1024 if (!RegisterSetIsCached(set)) {
1025 SetError(flavor: set, err_idx: Write, err: -1);
1026 return KERN_INVALID_ARGUMENT;
1027 }
1028 SetError(flavor: set, err_idx: Write, err: DoWriteGPR(tid: GetThreadID(), flavor: set, gpr));
1029 SetError(flavor: set, err_idx: Read, err: -1);
1030 return GetError(flavor: GPRRegSet, err_idx: Write);
1031}
1032
1033int RegisterContextDarwin_arm::WriteFPU() {
1034 int set = FPURegSet;
1035 if (!RegisterSetIsCached(set)) {
1036 SetError(flavor: set, err_idx: Write, err: -1);
1037 return KERN_INVALID_ARGUMENT;
1038 }
1039 SetError(flavor: set, err_idx: Write, err: DoWriteFPU(tid: GetThreadID(), flavor: set, fpu));
1040 SetError(flavor: set, err_idx: Read, err: -1);
1041 return GetError(flavor: FPURegSet, err_idx: Write);
1042}
1043
1044int RegisterContextDarwin_arm::WriteEXC() {
1045 int set = EXCRegSet;
1046 if (!RegisterSetIsCached(set)) {
1047 SetError(flavor: set, err_idx: Write, err: -1);
1048 return KERN_INVALID_ARGUMENT;
1049 }
1050 SetError(flavor: set, err_idx: Write, err: DoWriteEXC(tid: GetThreadID(), flavor: set, exc));
1051 SetError(flavor: set, err_idx: Read, err: -1);
1052 return GetError(flavor: EXCRegSet, err_idx: Write);
1053}
1054
1055int RegisterContextDarwin_arm::WriteDBG() {
1056 int set = DBGRegSet;
1057 if (!RegisterSetIsCached(set)) {
1058 SetError(flavor: set, err_idx: Write, err: -1);
1059 return KERN_INVALID_ARGUMENT;
1060 }
1061 SetError(flavor: set, err_idx: Write, err: DoWriteDBG(tid: GetThreadID(), flavor: set, dbg));
1062 SetError(flavor: set, err_idx: Read, err: -1);
1063 return GetError(flavor: DBGRegSet, err_idx: Write);
1064}
1065
1066int RegisterContextDarwin_arm::ReadRegisterSet(uint32_t set, bool force) {
1067 switch (set) {
1068 case GPRRegSet:
1069 return ReadGPR(force);
1070 case GPRAltRegSet:
1071 return ReadGPR(force);
1072 case FPURegSet:
1073 return ReadFPU(force);
1074 case EXCRegSet:
1075 return ReadEXC(force);
1076 case DBGRegSet:
1077 return ReadDBG(force);
1078 default:
1079 break;
1080 }
1081 return KERN_INVALID_ARGUMENT;
1082}
1083
1084int RegisterContextDarwin_arm::WriteRegisterSet(uint32_t set) {
1085 // Make sure we have a valid context to set.
1086 if (RegisterSetIsCached(set)) {
1087 switch (set) {
1088 case GPRRegSet:
1089 return WriteGPR();
1090 case GPRAltRegSet:
1091 return WriteGPR();
1092 case FPURegSet:
1093 return WriteFPU();
1094 case EXCRegSet:
1095 return WriteEXC();
1096 case DBGRegSet:
1097 return WriteDBG();
1098 default:
1099 break;
1100 }
1101 }
1102 return KERN_INVALID_ARGUMENT;
1103}
1104
1105void RegisterContextDarwin_arm::LogDBGRegisters(Log *log, const DBG &dbg) {
1106 if (log) {
1107 for (uint32_t i = 0; i < 16; i++)
1108 LLDB_LOGF(log,
1109 "BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { "
1110 "0x%8.8x, 0x%8.8x }",
1111 i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]);
1112 }
1113}
1114
1115bool RegisterContextDarwin_arm::ReadRegister(const RegisterInfo *reg_info,
1116 RegisterValue &value) {
1117 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
1118 int set = RegisterContextDarwin_arm::GetSetForNativeRegNum(reg);
1119
1120 if (set == -1)
1121 return false;
1122
1123 if (ReadRegisterSet(set, force: false) != KERN_SUCCESS)
1124 return false;
1125
1126 switch (reg) {
1127 case gpr_r0:
1128 case gpr_r1:
1129 case gpr_r2:
1130 case gpr_r3:
1131 case gpr_r4:
1132 case gpr_r5:
1133 case gpr_r6:
1134 case gpr_r7:
1135 case gpr_r8:
1136 case gpr_r9:
1137 case gpr_r10:
1138 case gpr_r11:
1139 case gpr_r12:
1140 case gpr_sp:
1141 case gpr_lr:
1142 case gpr_pc:
1143 value.SetUInt32(uint: gpr.r[reg - gpr_r0]);
1144 break;
1145 case gpr_cpsr:
1146 value.SetUInt32(uint: gpr.cpsr);
1147 break;
1148 case fpu_s0:
1149 case fpu_s1:
1150 case fpu_s2:
1151 case fpu_s3:
1152 case fpu_s4:
1153 case fpu_s5:
1154 case fpu_s6:
1155 case fpu_s7:
1156 case fpu_s8:
1157 case fpu_s9:
1158 case fpu_s10:
1159 case fpu_s11:
1160 case fpu_s12:
1161 case fpu_s13:
1162 case fpu_s14:
1163 case fpu_s15:
1164 case fpu_s16:
1165 case fpu_s17:
1166 case fpu_s18:
1167 case fpu_s19:
1168 case fpu_s20:
1169 case fpu_s21:
1170 case fpu_s22:
1171 case fpu_s23:
1172 case fpu_s24:
1173 case fpu_s25:
1174 case fpu_s26:
1175 case fpu_s27:
1176 case fpu_s28:
1177 case fpu_s29:
1178 case fpu_s30:
1179 case fpu_s31:
1180 value.SetUInt32(uint: fpu.floats.s[reg], t: RegisterValue::eTypeFloat);
1181 break;
1182
1183 case fpu_fpscr:
1184 value.SetUInt32(uint: fpu.fpscr);
1185 break;
1186
1187 case exc_exception:
1188 value.SetUInt32(uint: exc.exception);
1189 break;
1190 case exc_fsr:
1191 value.SetUInt32(uint: exc.fsr);
1192 break;
1193 case exc_far:
1194 value.SetUInt32(uint: exc.far);
1195 break;
1196
1197 default:
1198 value.SetValueToInvalid();
1199 return false;
1200 }
1201 return true;
1202}
1203
1204bool RegisterContextDarwin_arm::WriteRegister(const RegisterInfo *reg_info,
1205 const RegisterValue &value) {
1206 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
1207 int set = GetSetForNativeRegNum(reg);
1208
1209 if (set == -1)
1210 return false;
1211
1212 if (ReadRegisterSet(set, force: false) != KERN_SUCCESS)
1213 return false;
1214
1215 switch (reg) {
1216 case gpr_r0:
1217 case gpr_r1:
1218 case gpr_r2:
1219 case gpr_r3:
1220 case gpr_r4:
1221 case gpr_r5:
1222 case gpr_r6:
1223 case gpr_r7:
1224 case gpr_r8:
1225 case gpr_r9:
1226 case gpr_r10:
1227 case gpr_r11:
1228 case gpr_r12:
1229 case gpr_sp:
1230 case gpr_lr:
1231 case gpr_pc:
1232 case gpr_cpsr:
1233 gpr.r[reg - gpr_r0] = value.GetAsUInt32();
1234 break;
1235
1236 case fpu_s0:
1237 case fpu_s1:
1238 case fpu_s2:
1239 case fpu_s3:
1240 case fpu_s4:
1241 case fpu_s5:
1242 case fpu_s6:
1243 case fpu_s7:
1244 case fpu_s8:
1245 case fpu_s9:
1246 case fpu_s10:
1247 case fpu_s11:
1248 case fpu_s12:
1249 case fpu_s13:
1250 case fpu_s14:
1251 case fpu_s15:
1252 case fpu_s16:
1253 case fpu_s17:
1254 case fpu_s18:
1255 case fpu_s19:
1256 case fpu_s20:
1257 case fpu_s21:
1258 case fpu_s22:
1259 case fpu_s23:
1260 case fpu_s24:
1261 case fpu_s25:
1262 case fpu_s26:
1263 case fpu_s27:
1264 case fpu_s28:
1265 case fpu_s29:
1266 case fpu_s30:
1267 case fpu_s31:
1268 fpu.floats.s[reg] = value.GetAsUInt32();
1269 break;
1270
1271 case fpu_fpscr:
1272 fpu.fpscr = value.GetAsUInt32();
1273 break;
1274
1275 case exc_exception:
1276 exc.exception = value.GetAsUInt32();
1277 break;
1278 case exc_fsr:
1279 exc.fsr = value.GetAsUInt32();
1280 break;
1281 case exc_far:
1282 exc.far = value.GetAsUInt32();
1283 break;
1284
1285 default:
1286 return false;
1287 }
1288 return WriteRegisterSet(set) == KERN_SUCCESS;
1289}
1290
1291bool RegisterContextDarwin_arm::ReadAllRegisterValues(
1292 lldb::WritableDataBufferSP &data_sp) {
1293 data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, args: 0);
1294 if (data_sp && ReadGPR(force: false) == KERN_SUCCESS &&
1295 ReadFPU(force: false) == KERN_SUCCESS && ReadEXC(force: false) == KERN_SUCCESS) {
1296 uint8_t *dst = data_sp->GetBytes();
1297 ::memcpy(dest: dst, src: &gpr, n: sizeof(gpr));
1298 dst += sizeof(gpr);
1299
1300 ::memcpy(dest: dst, src: &fpu, n: sizeof(fpu));
1301 dst += sizeof(gpr);
1302
1303 ::memcpy(dest: dst, src: &exc, n: sizeof(exc));
1304 return true;
1305 }
1306 return false;
1307}
1308
1309bool RegisterContextDarwin_arm::WriteAllRegisterValues(
1310 const lldb::DataBufferSP &data_sp) {
1311 if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
1312 const uint8_t *src = data_sp->GetBytes();
1313 ::memcpy(dest: &gpr, src: src, n: sizeof(gpr));
1314 src += sizeof(gpr);
1315
1316 ::memcpy(dest: &fpu, src: src, n: sizeof(fpu));
1317 src += sizeof(gpr);
1318
1319 ::memcpy(dest: &exc, src: src, n: sizeof(exc));
1320 uint32_t success_count = 0;
1321 if (WriteGPR() == KERN_SUCCESS)
1322 ++success_count;
1323 if (WriteFPU() == KERN_SUCCESS)
1324 ++success_count;
1325 if (WriteEXC() == KERN_SUCCESS)
1326 ++success_count;
1327 return success_count == 3;
1328 }
1329 return false;
1330}
1331
1332uint32_t RegisterContextDarwin_arm::ConvertRegisterKindToRegisterNumber(
1333 lldb::RegisterKind kind, uint32_t reg) {
1334 if (kind == eRegisterKindGeneric) {
1335 switch (reg) {
1336 case LLDB_REGNUM_GENERIC_PC:
1337 return gpr_pc;
1338 case LLDB_REGNUM_GENERIC_SP:
1339 return gpr_sp;
1340 case LLDB_REGNUM_GENERIC_FP:
1341 return gpr_r7;
1342 case LLDB_REGNUM_GENERIC_RA:
1343 return gpr_lr;
1344 case LLDB_REGNUM_GENERIC_FLAGS:
1345 return gpr_cpsr;
1346 default:
1347 break;
1348 }
1349 } else if (kind == eRegisterKindDWARF) {
1350 switch (reg) {
1351 case dwarf_r0:
1352 return gpr_r0;
1353 case dwarf_r1:
1354 return gpr_r1;
1355 case dwarf_r2:
1356 return gpr_r2;
1357 case dwarf_r3:
1358 return gpr_r3;
1359 case dwarf_r4:
1360 return gpr_r4;
1361 case dwarf_r5:
1362 return gpr_r5;
1363 case dwarf_r6:
1364 return gpr_r6;
1365 case dwarf_r7:
1366 return gpr_r7;
1367 case dwarf_r8:
1368 return gpr_r8;
1369 case dwarf_r9:
1370 return gpr_r9;
1371 case dwarf_r10:
1372 return gpr_r10;
1373 case dwarf_r11:
1374 return gpr_r11;
1375 case dwarf_r12:
1376 return gpr_r12;
1377 case dwarf_sp:
1378 return gpr_sp;
1379 case dwarf_lr:
1380 return gpr_lr;
1381 case dwarf_pc:
1382 return gpr_pc;
1383 case dwarf_spsr:
1384 return gpr_cpsr;
1385
1386 case dwarf_s0:
1387 return fpu_s0;
1388 case dwarf_s1:
1389 return fpu_s1;
1390 case dwarf_s2:
1391 return fpu_s2;
1392 case dwarf_s3:
1393 return fpu_s3;
1394 case dwarf_s4:
1395 return fpu_s4;
1396 case dwarf_s5:
1397 return fpu_s5;
1398 case dwarf_s6:
1399 return fpu_s6;
1400 case dwarf_s7:
1401 return fpu_s7;
1402 case dwarf_s8:
1403 return fpu_s8;
1404 case dwarf_s9:
1405 return fpu_s9;
1406 case dwarf_s10:
1407 return fpu_s10;
1408 case dwarf_s11:
1409 return fpu_s11;
1410 case dwarf_s12:
1411 return fpu_s12;
1412 case dwarf_s13:
1413 return fpu_s13;
1414 case dwarf_s14:
1415 return fpu_s14;
1416 case dwarf_s15:
1417 return fpu_s15;
1418 case dwarf_s16:
1419 return fpu_s16;
1420 case dwarf_s17:
1421 return fpu_s17;
1422 case dwarf_s18:
1423 return fpu_s18;
1424 case dwarf_s19:
1425 return fpu_s19;
1426 case dwarf_s20:
1427 return fpu_s20;
1428 case dwarf_s21:
1429 return fpu_s21;
1430 case dwarf_s22:
1431 return fpu_s22;
1432 case dwarf_s23:
1433 return fpu_s23;
1434 case dwarf_s24:
1435 return fpu_s24;
1436 case dwarf_s25:
1437 return fpu_s25;
1438 case dwarf_s26:
1439 return fpu_s26;
1440 case dwarf_s27:
1441 return fpu_s27;
1442 case dwarf_s28:
1443 return fpu_s28;
1444 case dwarf_s29:
1445 return fpu_s29;
1446 case dwarf_s30:
1447 return fpu_s30;
1448 case dwarf_s31:
1449 return fpu_s31;
1450
1451 default:
1452 break;
1453 }
1454 } else if (kind == eRegisterKindEHFrame) {
1455 switch (reg) {
1456 case ehframe_r0:
1457 return gpr_r0;
1458 case ehframe_r1:
1459 return gpr_r1;
1460 case ehframe_r2:
1461 return gpr_r2;
1462 case ehframe_r3:
1463 return gpr_r3;
1464 case ehframe_r4:
1465 return gpr_r4;
1466 case ehframe_r5:
1467 return gpr_r5;
1468 case ehframe_r6:
1469 return gpr_r6;
1470 case ehframe_r7:
1471 return gpr_r7;
1472 case ehframe_r8:
1473 return gpr_r8;
1474 case ehframe_r9:
1475 return gpr_r9;
1476 case ehframe_r10:
1477 return gpr_r10;
1478 case ehframe_r11:
1479 return gpr_r11;
1480 case ehframe_r12:
1481 return gpr_r12;
1482 case ehframe_sp:
1483 return gpr_sp;
1484 case ehframe_lr:
1485 return gpr_lr;
1486 case ehframe_pc:
1487 return gpr_pc;
1488 case ehframe_cpsr:
1489 return gpr_cpsr;
1490 }
1491 } else if (kind == eRegisterKindLLDB) {
1492 return reg;
1493 }
1494 return LLDB_INVALID_REGNUM;
1495}
1496
1497uint32_t RegisterContextDarwin_arm::NumSupportedHardwareBreakpoints() {
1498#if defined(__APPLE__) && defined(__arm__)
1499 // Set the init value to something that will let us know that we need to
1500 // autodetect how many breakpoints are supported dynamically...
1501 static uint32_t g_num_supported_hw_breakpoints = UINT32_MAX;
1502 if (g_num_supported_hw_breakpoints == UINT32_MAX) {
1503 // Set this to zero in case we can't tell if there are any HW breakpoints
1504 g_num_supported_hw_breakpoints = 0;
1505
1506 uint32_t register_DBGDIDR;
1507
1508 asm("mrc p14, 0, %0, c0, c0, 0" : "=r"(register_DBGDIDR));
1509 g_num_supported_hw_breakpoints = Bits32(register_DBGDIDR, 27, 24);
1510 // Zero is reserved for the BRP count, so don't increment it if it is zero
1511 if (g_num_supported_hw_breakpoints > 0)
1512 g_num_supported_hw_breakpoints++;
1513 }
1514 return g_num_supported_hw_breakpoints;
1515#else
1516 // TODO: figure out remote case here!
1517 return 6;
1518#endif
1519}
1520
1521uint32_t RegisterContextDarwin_arm::SetHardwareBreakpoint(lldb::addr_t addr,
1522 size_t size) {
1523 // Make sure our address isn't bogus
1524 if (addr & 1)
1525 return LLDB_INVALID_INDEX32;
1526
1527 int kret = ReadDBG(force: false);
1528
1529 if (kret == KERN_SUCCESS) {
1530 const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints();
1531 uint32_t i;
1532 for (i = 0; i < num_hw_breakpoints; ++i) {
1533 if ((dbg.bcr[i] & BCR_ENABLE) == 0)
1534 break; // We found an available hw breakpoint slot (in i)
1535 }
1536
1537 // See if we found an available hw breakpoint slot above
1538 if (i < num_hw_breakpoints) {
1539 // Make sure bits 1:0 are clear in our address
1540 dbg.bvr[i] = addr & ~((lldb::addr_t)3);
1541
1542 if (size == 2 || addr & 2) {
1543 uint32_t byte_addr_select = (addr & 2) ? BAS_IMVA_2_3 : BAS_IMVA_0_1;
1544
1545 // We have a thumb breakpoint
1546 // We have an ARM breakpoint
1547 dbg.bcr[i] = BCR_M_IMVA_MATCH | // Stop on address match
1548 byte_addr_select | // Set the correct byte address select
1549 // so we only trigger on the correct
1550 // opcode
1551 S_USER | // Which modes should this breakpoint stop in?
1552 BCR_ENABLE; // Enable this hardware breakpoint
1553 // if (log) log->Printf
1554 // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(
1555 // addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x /
1556 // 0x%8.8x (Thumb)",
1557 // addr,
1558 // size,
1559 // i,
1560 // i,
1561 // dbg.bvr[i],
1562 // dbg.bcr[i]);
1563 } else if (size == 4) {
1564 // We have an ARM breakpoint
1565 dbg.bcr[i] =
1566 BCR_M_IMVA_MATCH | // Stop on address match
1567 BAS_IMVA_ALL | // Stop on any of the four bytes following the IMVA
1568 S_USER | // Which modes should this breakpoint stop in?
1569 BCR_ENABLE; // Enable this hardware breakpoint
1570 // if (log) log->Printf
1571 // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(
1572 // addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x /
1573 // 0x%8.8x (ARM)",
1574 // addr,
1575 // size,
1576 // i,
1577 // i,
1578 // dbg.bvr[i],
1579 // dbg.bcr[i]);
1580 }
1581
1582 kret = WriteDBG();
1583 // if (log) log->Printf
1584 // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint()
1585 // WriteDBG() => 0x%8.8x.", kret);
1586
1587 if (kret == KERN_SUCCESS)
1588 return i;
1589 }
1590 // else
1591 // {
1592 // if (log) log->Printf
1593 // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(addr =
1594 // %8.8p, size = %u) => all hardware breakpoint resources are
1595 // being used.", addr, size);
1596 // }
1597 }
1598
1599 return LLDB_INVALID_INDEX32;
1600}
1601
1602bool RegisterContextDarwin_arm::ClearHardwareBreakpoint(uint32_t hw_index) {
1603 int kret = ReadDBG(force: false);
1604
1605 const uint32_t num_hw_points = NumSupportedHardwareBreakpoints();
1606 if (kret == KERN_SUCCESS) {
1607 if (hw_index < num_hw_points) {
1608 dbg.bcr[hw_index] = 0;
1609 // if (log) log->Printf
1610 // ("RegisterContextDarwin_arm::SetHardwareBreakpoint( %u ) -
1611 // BVR%u = 0x%8.8x BCR%u = 0x%8.8x",
1612 // hw_index,
1613 // hw_index,
1614 // dbg.bvr[hw_index],
1615 // hw_index,
1616 // dbg.bcr[hw_index]);
1617
1618 kret = WriteDBG();
1619
1620 if (kret == KERN_SUCCESS)
1621 return true;
1622 }
1623 }
1624 return false;
1625}
1626
1627uint32_t RegisterContextDarwin_arm::NumSupportedHardwareWatchpoints() {
1628#if defined(__APPLE__) && defined(__arm__)
1629 // Set the init value to something that will let us know that we need to
1630 // autodetect how many watchpoints are supported dynamically...
1631 static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX;
1632 if (g_num_supported_hw_watchpoints == UINT32_MAX) {
1633 // Set this to zero in case we can't tell if there are any HW breakpoints
1634 g_num_supported_hw_watchpoints = 0;
1635
1636 uint32_t register_DBGDIDR;
1637 asm("mrc p14, 0, %0, c0, c0, 0" : "=r"(register_DBGDIDR));
1638 g_num_supported_hw_watchpoints = Bits32(register_DBGDIDR, 31, 28) + 1;
1639 }
1640 return g_num_supported_hw_watchpoints;
1641#else
1642 // TODO: figure out remote case here!
1643 return 2;
1644#endif
1645}
1646
1647uint32_t RegisterContextDarwin_arm::SetHardwareWatchpoint(lldb::addr_t addr,
1648 size_t size,
1649 bool read,
1650 bool write) {
1651 const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
1652
1653 // Can't watch zero bytes
1654 if (size == 0)
1655 return LLDB_INVALID_INDEX32;
1656
1657 // We must watch for either read or write
1658 if (!read && !write)
1659 return LLDB_INVALID_INDEX32;
1660
1661 // Can't watch more than 4 bytes per WVR/WCR pair
1662 if (size > 4)
1663 return LLDB_INVALID_INDEX32;
1664
1665 // We can only watch up to four bytes that follow a 4 byte aligned address
1666 // per watchpoint register pair. Since we have at most so we can only watch
1667 // until the next 4 byte boundary and we need to make sure we can properly
1668 // encode this.
1669 uint32_t addr_word_offset = addr % 4;
1670 // if (log) log->Printf
1671 // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() -
1672 // addr_word_offset = 0x%8.8x", addr_word_offset);
1673
1674 uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset;
1675 // if (log) log->Printf
1676 // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - byte_mask =
1677 // 0x%8.8x", byte_mask);
1678 if (byte_mask > 0xfu)
1679 return LLDB_INVALID_INDEX32;
1680
1681 // Read the debug state
1682 int kret = ReadDBG(force: false);
1683
1684 if (kret == KERN_SUCCESS) {
1685 // Check to make sure we have the needed hardware support
1686 uint32_t i = 0;
1687
1688 for (i = 0; i < num_hw_watchpoints; ++i) {
1689 if ((dbg.wcr[i] & WCR_ENABLE) == 0)
1690 break; // We found an available hw breakpoint slot (in i)
1691 }
1692
1693 // See if we found an available hw breakpoint slot above
1694 if (i < num_hw_watchpoints) {
1695 // Make the byte_mask into a valid Byte Address Select mask
1696 uint32_t byte_address_select = byte_mask << 5;
1697 // Make sure bits 1:0 are clear in our address
1698 dbg.wvr[i] = addr & ~((lldb::addr_t)3);
1699 dbg.wcr[i] = byte_address_select | // Which bytes that follow the IMVA
1700 // that we will watch
1701 S_USER | // Stop only in user mode
1702 (read ? WCR_LOAD : 0) | // Stop on read access?
1703 (write ? WCR_STORE : 0) | // Stop on write access?
1704 WCR_ENABLE; // Enable this watchpoint;
1705
1706 kret = WriteDBG();
1707 // if (log) log->Printf
1708 // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint()
1709 // WriteDBG() => 0x%8.8x.", kret);
1710
1711 if (kret == KERN_SUCCESS)
1712 return i;
1713 } else {
1714 // if (log) log->Printf
1715 // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(): All
1716 // hardware resources (%u) are in use.", num_hw_watchpoints);
1717 }
1718 }
1719 return LLDB_INVALID_INDEX32;
1720}
1721
1722bool RegisterContextDarwin_arm::ClearHardwareWatchpoint(uint32_t hw_index) {
1723 int kret = ReadDBG(force: false);
1724
1725 const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
1726 if (kret == KERN_SUCCESS) {
1727 if (hw_index < num_hw_points) {
1728 dbg.wcr[hw_index] = 0;
1729 // if (log) log->Printf
1730 // ("RegisterContextDarwin_arm::ClearHardwareWatchpoint( %u ) -
1731 // WVR%u = 0x%8.8x WCR%u = 0x%8.8x",
1732 // hw_index,
1733 // hw_index,
1734 // dbg.wvr[hw_index],
1735 // hw_index,
1736 // dbg.wcr[hw_index]);
1737
1738 kret = WriteDBG();
1739
1740 if (kret == KERN_SUCCESS)
1741 return true;
1742 }
1743 }
1744 return false;
1745}
1746

source code of lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp