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

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