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