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