1//===-- ABIMacOSX_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 "ABIMacOSX_arm.h"
10
11#include <optional>
12#include <vector>
13
14#include "llvm/ADT/STLExtras.h"
15#include "llvm/TargetParser/Triple.h"
16
17#include "lldb/Core/Module.h"
18#include "lldb/Core/PluginManager.h"
19#include "lldb/Core/Value.h"
20#include "lldb/Core/ValueObjectConstResult.h"
21#include "lldb/Symbol/UnwindPlan.h"
22#include "lldb/Target/Process.h"
23#include "lldb/Target/RegisterContext.h"
24#include "lldb/Target/Target.h"
25#include "lldb/Target/Thread.h"
26#include "lldb/Utility/ConstString.h"
27#include "lldb/Utility/RegisterValue.h"
28#include "lldb/Utility/Scalar.h"
29#include "lldb/Utility/Status.h"
30
31#include "Plugins/Process/Utility/ARMDefines.h"
32#include "Utility/ARM_DWARF_Registers.h"
33#include "Utility/ARM_ehframe_Registers.h"
34
35using namespace lldb;
36using namespace lldb_private;
37
38static const RegisterInfo g_register_infos[] = {
39 // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME
40 // DWARF GENERIC PROCESS PLUGIN
41 // LLDB NATIVE
42 // ========== ======= == === ============= ============
43 // ======================= =================== ===========================
44 // ======================= ======================
45 {.name: "r0",
46 .alt_name: nullptr,
47 .byte_size: 4,
48 .byte_offset: 0,
49 .encoding: eEncodingUint,
50 .format: eFormatHex,
51 .kinds: {ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM,
52 LLDB_INVALID_REGNUM},
53 .value_regs: nullptr,
54 .invalidate_regs: nullptr,
55 .flags_type: nullptr,
56 },
57 {.name: "r1",
58 .alt_name: nullptr,
59 .byte_size: 4,
60 .byte_offset: 0,
61 .encoding: eEncodingUint,
62 .format: eFormatHex,
63 .kinds: {ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM,
64 LLDB_INVALID_REGNUM},
65 .value_regs: nullptr,
66 .invalidate_regs: nullptr,
67 .flags_type: nullptr,
68 },
69 {.name: "r2",
70 .alt_name: nullptr,
71 .byte_size: 4,
72 .byte_offset: 0,
73 .encoding: eEncodingUint,
74 .format: eFormatHex,
75 .kinds: {ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM,
76 LLDB_INVALID_REGNUM},
77 .value_regs: nullptr,
78 .invalidate_regs: nullptr,
79 .flags_type: nullptr,
80 },
81 {.name: "r3",
82 .alt_name: nullptr,
83 .byte_size: 4,
84 .byte_offset: 0,
85 .encoding: eEncodingUint,
86 .format: eFormatHex,
87 .kinds: {ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM,
88 LLDB_INVALID_REGNUM},
89 .value_regs: nullptr,
90 .invalidate_regs: nullptr,
91 .flags_type: nullptr,
92 },
93 {.name: "r4",
94 .alt_name: nullptr,
95 .byte_size: 4,
96 .byte_offset: 0,
97 .encoding: eEncodingUint,
98 .format: eFormatHex,
99 .kinds: {ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
100 LLDB_INVALID_REGNUM},
101 .value_regs: nullptr,
102 .invalidate_regs: nullptr,
103 .flags_type: nullptr,
104 },
105 {.name: "r5",
106 .alt_name: nullptr,
107 .byte_size: 4,
108 .byte_offset: 0,
109 .encoding: eEncodingUint,
110 .format: eFormatHex,
111 .kinds: {ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
112 LLDB_INVALID_REGNUM},
113 .value_regs: nullptr,
114 .invalidate_regs: nullptr,
115 .flags_type: nullptr,
116 },
117 {.name: "r6",
118 .alt_name: nullptr,
119 .byte_size: 4,
120 .byte_offset: 0,
121 .encoding: eEncodingUint,
122 .format: eFormatHex,
123 .kinds: {ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
124 LLDB_INVALID_REGNUM},
125 .value_regs: nullptr,
126 .invalidate_regs: nullptr,
127 .flags_type: nullptr,
128 },
129 {.name: "r7",
130 .alt_name: nullptr,
131 .byte_size: 4,
132 .byte_offset: 0,
133 .encoding: eEncodingUint,
134 .format: eFormatHex,
135 .kinds: {ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
136 LLDB_INVALID_REGNUM},
137 .value_regs: nullptr,
138 .invalidate_regs: nullptr,
139 .flags_type: nullptr,
140 },
141 {.name: "r8",
142 .alt_name: nullptr,
143 .byte_size: 4,
144 .byte_offset: 0,
145 .encoding: eEncodingUint,
146 .format: eFormatHex,
147 .kinds: {ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
148 LLDB_INVALID_REGNUM},
149 .value_regs: nullptr,
150 .invalidate_regs: nullptr,
151 .flags_type: nullptr,
152 },
153 {.name: "r9",
154 .alt_name: nullptr,
155 .byte_size: 4,
156 .byte_offset: 0,
157 .encoding: eEncodingUint,
158 .format: eFormatHex,
159 .kinds: {ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
160 LLDB_INVALID_REGNUM},
161 .value_regs: nullptr,
162 .invalidate_regs: nullptr,
163 .flags_type: nullptr,
164 },
165 {.name: "r10",
166 .alt_name: nullptr,
167 .byte_size: 4,
168 .byte_offset: 0,
169 .encoding: eEncodingUint,
170 .format: eFormatHex,
171 .kinds: {ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
172 LLDB_INVALID_REGNUM},
173 .value_regs: nullptr,
174 .invalidate_regs: nullptr,
175 .flags_type: nullptr,
176 },
177 {.name: "r11",
178 .alt_name: nullptr,
179 .byte_size: 4,
180 .byte_offset: 0,
181 .encoding: eEncodingUint,
182 .format: eFormatHex,
183 .kinds: {ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
184 LLDB_INVALID_REGNUM},
185 .value_regs: nullptr,
186 .invalidate_regs: nullptr,
187 .flags_type: nullptr,
188 },
189 {.name: "r12",
190 .alt_name: nullptr,
191 .byte_size: 4,
192 .byte_offset: 0,
193 .encoding: eEncodingUint,
194 .format: eFormatHex,
195 .kinds: {ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
196 LLDB_INVALID_REGNUM},
197 .value_regs: nullptr,
198 .invalidate_regs: nullptr,
199 .flags_type: nullptr,
200 },
201 {.name: "sp",
202 .alt_name: "r13",
203 .byte_size: 4,
204 .byte_offset: 0,
205 .encoding: eEncodingUint,
206 .format: eFormatHex,
207 .kinds: {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
208 LLDB_INVALID_REGNUM},
209 .value_regs: nullptr,
210 .invalidate_regs: nullptr,
211 .flags_type: nullptr,
212 },
213 {.name: "lr",
214 .alt_name: "r14",
215 .byte_size: 4,
216 .byte_offset: 0,
217 .encoding: eEncodingUint,
218 .format: eFormatHex,
219 .kinds: {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM,
220 LLDB_INVALID_REGNUM},
221 .value_regs: nullptr,
222 .invalidate_regs: nullptr,
223 .flags_type: nullptr,
224 },
225 {.name: "pc",
226 .alt_name: "r15",
227 .byte_size: 4,
228 .byte_offset: 0,
229 .encoding: eEncodingUint,
230 .format: eFormatHex,
231 .kinds: {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
232 LLDB_INVALID_REGNUM},
233 .value_regs: nullptr,
234 .invalidate_regs: nullptr,
235 .flags_type: nullptr,
236 },
237 {.name: "cpsr",
238 .alt_name: "psr",
239 .byte_size: 4,
240 .byte_offset: 0,
241 .encoding: eEncodingUint,
242 .format: eFormatHex,
243 .kinds: {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM,
244 LLDB_INVALID_REGNUM},
245 .value_regs: nullptr,
246 .invalidate_regs: nullptr,
247 .flags_type: nullptr,
248 },
249 {.name: "s0",
250 .alt_name: nullptr,
251 .byte_size: 4,
252 .byte_offset: 0,
253 .encoding: eEncodingIEEE754,
254 .format: eFormatFloat,
255 .kinds: {LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
256 LLDB_INVALID_REGNUM},
257 .value_regs: nullptr,
258 .invalidate_regs: nullptr,
259 .flags_type: nullptr,
260 },
261 {.name: "s1",
262 .alt_name: nullptr,
263 .byte_size: 4,
264 .byte_offset: 0,
265 .encoding: eEncodingIEEE754,
266 .format: eFormatFloat,
267 .kinds: {LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
268 LLDB_INVALID_REGNUM},
269 .value_regs: nullptr,
270 .invalidate_regs: nullptr,
271 .flags_type: nullptr,
272 },
273 {.name: "s2",
274 .alt_name: nullptr,
275 .byte_size: 4,
276 .byte_offset: 0,
277 .encoding: eEncodingIEEE754,
278 .format: eFormatFloat,
279 .kinds: {LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
280 LLDB_INVALID_REGNUM},
281 .value_regs: nullptr,
282 .invalidate_regs: nullptr,
283 .flags_type: nullptr,
284 },
285 {.name: "s3",
286 .alt_name: nullptr,
287 .byte_size: 4,
288 .byte_offset: 0,
289 .encoding: eEncodingIEEE754,
290 .format: eFormatFloat,
291 .kinds: {LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
292 LLDB_INVALID_REGNUM},
293 .value_regs: nullptr,
294 .invalidate_regs: nullptr,
295 .flags_type: nullptr,
296 },
297 {.name: "s4",
298 .alt_name: nullptr,
299 .byte_size: 4,
300 .byte_offset: 0,
301 .encoding: eEncodingIEEE754,
302 .format: eFormatFloat,
303 .kinds: {LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
304 LLDB_INVALID_REGNUM},
305 .value_regs: nullptr,
306 .invalidate_regs: nullptr,
307 .flags_type: nullptr,
308 },
309 {.name: "s5",
310 .alt_name: nullptr,
311 .byte_size: 4,
312 .byte_offset: 0,
313 .encoding: eEncodingIEEE754,
314 .format: eFormatFloat,
315 .kinds: {LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
316 LLDB_INVALID_REGNUM},
317 .value_regs: nullptr,
318 .invalidate_regs: nullptr,
319 .flags_type: nullptr,
320 },
321 {.name: "s6",
322 .alt_name: nullptr,
323 .byte_size: 4,
324 .byte_offset: 0,
325 .encoding: eEncodingIEEE754,
326 .format: eFormatFloat,
327 .kinds: {LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
328 LLDB_INVALID_REGNUM},
329 .value_regs: nullptr,
330 .invalidate_regs: nullptr,
331 .flags_type: nullptr,
332 },
333 {.name: "s7",
334 .alt_name: nullptr,
335 .byte_size: 4,
336 .byte_offset: 0,
337 .encoding: eEncodingIEEE754,
338 .format: eFormatFloat,
339 .kinds: {LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
340 LLDB_INVALID_REGNUM},
341 .value_regs: nullptr,
342 .invalidate_regs: nullptr,
343 .flags_type: nullptr,
344 },
345 {.name: "s8",
346 .alt_name: nullptr,
347 .byte_size: 4,
348 .byte_offset: 0,
349 .encoding: eEncodingIEEE754,
350 .format: eFormatFloat,
351 .kinds: {LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
352 LLDB_INVALID_REGNUM},
353 .value_regs: nullptr,
354 .invalidate_regs: nullptr,
355 .flags_type: nullptr,
356 },
357 {.name: "s9",
358 .alt_name: nullptr,
359 .byte_size: 4,
360 .byte_offset: 0,
361 .encoding: eEncodingIEEE754,
362 .format: eFormatFloat,
363 .kinds: {LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
364 LLDB_INVALID_REGNUM},
365 .value_regs: nullptr,
366 .invalidate_regs: nullptr,
367 .flags_type: nullptr,
368 },
369 {.name: "s10",
370 .alt_name: nullptr,
371 .byte_size: 4,
372 .byte_offset: 0,
373 .encoding: eEncodingIEEE754,
374 .format: eFormatFloat,
375 .kinds: {LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
376 LLDB_INVALID_REGNUM},
377 .value_regs: nullptr,
378 .invalidate_regs: nullptr,
379 .flags_type: nullptr,
380 },
381 {.name: "s11",
382 .alt_name: nullptr,
383 .byte_size: 4,
384 .byte_offset: 0,
385 .encoding: eEncodingIEEE754,
386 .format: eFormatFloat,
387 .kinds: {LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
388 LLDB_INVALID_REGNUM},
389 .value_regs: nullptr,
390 .invalidate_regs: nullptr,
391 .flags_type: nullptr,
392 },
393 {.name: "s12",
394 .alt_name: nullptr,
395 .byte_size: 4,
396 .byte_offset: 0,
397 .encoding: eEncodingIEEE754,
398 .format: eFormatFloat,
399 .kinds: {LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
400 LLDB_INVALID_REGNUM},
401 .value_regs: nullptr,
402 .invalidate_regs: nullptr,
403 .flags_type: nullptr,
404 },
405 {.name: "s13",
406 .alt_name: nullptr,
407 .byte_size: 4,
408 .byte_offset: 0,
409 .encoding: eEncodingIEEE754,
410 .format: eFormatFloat,
411 .kinds: {LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
412 LLDB_INVALID_REGNUM},
413 .value_regs: nullptr,
414 .invalidate_regs: nullptr,
415 .flags_type: nullptr,
416 },
417 {.name: "s14",
418 .alt_name: nullptr,
419 .byte_size: 4,
420 .byte_offset: 0,
421 .encoding: eEncodingIEEE754,
422 .format: eFormatFloat,
423 .kinds: {LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
424 LLDB_INVALID_REGNUM},
425 .value_regs: nullptr,
426 .invalidate_regs: nullptr,
427 .flags_type: nullptr,
428 },
429 {.name: "s15",
430 .alt_name: nullptr,
431 .byte_size: 4,
432 .byte_offset: 0,
433 .encoding: eEncodingIEEE754,
434 .format: eFormatFloat,
435 .kinds: {LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
436 LLDB_INVALID_REGNUM},
437 .value_regs: nullptr,
438 .invalidate_regs: nullptr,
439 .flags_type: nullptr,
440 },
441 {.name: "s16",
442 .alt_name: nullptr,
443 .byte_size: 4,
444 .byte_offset: 0,
445 .encoding: eEncodingIEEE754,
446 .format: eFormatFloat,
447 .kinds: {LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
448 LLDB_INVALID_REGNUM},
449 .value_regs: nullptr,
450 .invalidate_regs: nullptr,
451 .flags_type: nullptr,
452 },
453 {.name: "s17",
454 .alt_name: nullptr,
455 .byte_size: 4,
456 .byte_offset: 0,
457 .encoding: eEncodingIEEE754,
458 .format: eFormatFloat,
459 .kinds: {LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
460 LLDB_INVALID_REGNUM},
461 .value_regs: nullptr,
462 .invalidate_regs: nullptr,
463 .flags_type: nullptr,
464 },
465 {.name: "s18",
466 .alt_name: nullptr,
467 .byte_size: 4,
468 .byte_offset: 0,
469 .encoding: eEncodingIEEE754,
470 .format: eFormatFloat,
471 .kinds: {LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
472 LLDB_INVALID_REGNUM},
473 .value_regs: nullptr,
474 .invalidate_regs: nullptr,
475 .flags_type: nullptr,
476 },
477 {.name: "s19",
478 .alt_name: nullptr,
479 .byte_size: 4,
480 .byte_offset: 0,
481 .encoding: eEncodingIEEE754,
482 .format: eFormatFloat,
483 .kinds: {LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
484 LLDB_INVALID_REGNUM},
485 .value_regs: nullptr,
486 .invalidate_regs: nullptr,
487 .flags_type: nullptr,
488 },
489 {.name: "s20",
490 .alt_name: nullptr,
491 .byte_size: 4,
492 .byte_offset: 0,
493 .encoding: eEncodingIEEE754,
494 .format: eFormatFloat,
495 .kinds: {LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
496 LLDB_INVALID_REGNUM},
497 .value_regs: nullptr,
498 .invalidate_regs: nullptr,
499 .flags_type: nullptr,
500 },
501 {.name: "s21",
502 .alt_name: nullptr,
503 .byte_size: 4,
504 .byte_offset: 0,
505 .encoding: eEncodingIEEE754,
506 .format: eFormatFloat,
507 .kinds: {LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
508 LLDB_INVALID_REGNUM},
509 .value_regs: nullptr,
510 .invalidate_regs: nullptr,
511 .flags_type: nullptr,
512 },
513 {.name: "s22",
514 .alt_name: nullptr,
515 .byte_size: 4,
516 .byte_offset: 0,
517 .encoding: eEncodingIEEE754,
518 .format: eFormatFloat,
519 .kinds: {LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
520 LLDB_INVALID_REGNUM},
521 .value_regs: nullptr,
522 .invalidate_regs: nullptr,
523 .flags_type: nullptr,
524 },
525 {.name: "s23",
526 .alt_name: nullptr,
527 .byte_size: 4,
528 .byte_offset: 0,
529 .encoding: eEncodingIEEE754,
530 .format: eFormatFloat,
531 .kinds: {LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
532 LLDB_INVALID_REGNUM},
533 .value_regs: nullptr,
534 .invalidate_regs: nullptr,
535 .flags_type: nullptr,
536 },
537 {.name: "s24",
538 .alt_name: nullptr,
539 .byte_size: 4,
540 .byte_offset: 0,
541 .encoding: eEncodingIEEE754,
542 .format: eFormatFloat,
543 .kinds: {LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
544 LLDB_INVALID_REGNUM},
545 .value_regs: nullptr,
546 .invalidate_regs: nullptr,
547 .flags_type: nullptr,
548 },
549 {.name: "s25",
550 .alt_name: nullptr,
551 .byte_size: 4,
552 .byte_offset: 0,
553 .encoding: eEncodingIEEE754,
554 .format: eFormatFloat,
555 .kinds: {LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
556 LLDB_INVALID_REGNUM},
557 .value_regs: nullptr,
558 .invalidate_regs: nullptr,
559 .flags_type: nullptr,
560 },
561 {.name: "s26",
562 .alt_name: nullptr,
563 .byte_size: 4,
564 .byte_offset: 0,
565 .encoding: eEncodingIEEE754,
566 .format: eFormatFloat,
567 .kinds: {LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
568 LLDB_INVALID_REGNUM},
569 .value_regs: nullptr,
570 .invalidate_regs: nullptr,
571 .flags_type: nullptr,
572 },
573 {.name: "s27",
574 .alt_name: nullptr,
575 .byte_size: 4,
576 .byte_offset: 0,
577 .encoding: eEncodingIEEE754,
578 .format: eFormatFloat,
579 .kinds: {LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
580 LLDB_INVALID_REGNUM},
581 .value_regs: nullptr,
582 .invalidate_regs: nullptr,
583 .flags_type: nullptr,
584 },
585 {.name: "s28",
586 .alt_name: nullptr,
587 .byte_size: 4,
588 .byte_offset: 0,
589 .encoding: eEncodingIEEE754,
590 .format: eFormatFloat,
591 .kinds: {LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
592 LLDB_INVALID_REGNUM},
593 .value_regs: nullptr,
594 .invalidate_regs: nullptr,
595 .flags_type: nullptr,
596 },
597 {.name: "s29",
598 .alt_name: nullptr,
599 .byte_size: 4,
600 .byte_offset: 0,
601 .encoding: eEncodingIEEE754,
602 .format: eFormatFloat,
603 .kinds: {LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
604 LLDB_INVALID_REGNUM},
605 .value_regs: nullptr,
606 .invalidate_regs: nullptr,
607 .flags_type: nullptr,
608 },
609 {.name: "s30",
610 .alt_name: nullptr,
611 .byte_size: 4,
612 .byte_offset: 0,
613 .encoding: eEncodingIEEE754,
614 .format: eFormatFloat,
615 .kinds: {LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
616 LLDB_INVALID_REGNUM},
617 .value_regs: nullptr,
618 .invalidate_regs: nullptr,
619 .flags_type: nullptr,
620 },
621 {.name: "s31",
622 .alt_name: nullptr,
623 .byte_size: 4,
624 .byte_offset: 0,
625 .encoding: eEncodingIEEE754,
626 .format: eFormatFloat,
627 .kinds: {LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
628 LLDB_INVALID_REGNUM},
629 .value_regs: nullptr,
630 .invalidate_regs: nullptr,
631 .flags_type: nullptr,
632 },
633 {.name: "fpscr",
634 .alt_name: nullptr,
635 .byte_size: 4,
636 .byte_offset: 0,
637 .encoding: eEncodingUint,
638 .format: eFormatHex,
639 .kinds: {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
640 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
641 .value_regs: nullptr,
642 .invalidate_regs: nullptr,
643 .flags_type: nullptr,
644 },
645 {.name: "d0",
646 .alt_name: nullptr,
647 .byte_size: 8,
648 .byte_offset: 0,
649 .encoding: eEncodingIEEE754,
650 .format: eFormatFloat,
651 .kinds: {LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
652 LLDB_INVALID_REGNUM},
653 .value_regs: nullptr,
654 .invalidate_regs: nullptr,
655 .flags_type: nullptr,
656 },
657 {.name: "d1",
658 .alt_name: nullptr,
659 .byte_size: 8,
660 .byte_offset: 0,
661 .encoding: eEncodingIEEE754,
662 .format: eFormatFloat,
663 .kinds: {LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
664 LLDB_INVALID_REGNUM},
665 .value_regs: nullptr,
666 .invalidate_regs: nullptr,
667 .flags_type: nullptr,
668 },
669 {.name: "d2",
670 .alt_name: nullptr,
671 .byte_size: 8,
672 .byte_offset: 0,
673 .encoding: eEncodingIEEE754,
674 .format: eFormatFloat,
675 .kinds: {LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
676 LLDB_INVALID_REGNUM},
677 .value_regs: nullptr,
678 .invalidate_regs: nullptr,
679 .flags_type: nullptr,
680 },
681 {.name: "d3",
682 .alt_name: nullptr,
683 .byte_size: 8,
684 .byte_offset: 0,
685 .encoding: eEncodingIEEE754,
686 .format: eFormatFloat,
687 .kinds: {LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
688 LLDB_INVALID_REGNUM},
689 .value_regs: nullptr,
690 .invalidate_regs: nullptr,
691 .flags_type: nullptr,
692 },
693 {.name: "d4",
694 .alt_name: nullptr,
695 .byte_size: 8,
696 .byte_offset: 0,
697 .encoding: eEncodingIEEE754,
698 .format: eFormatFloat,
699 .kinds: {LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
700 LLDB_INVALID_REGNUM},
701 .value_regs: nullptr,
702 .invalidate_regs: nullptr,
703 .flags_type: nullptr,
704 },
705 {.name: "d5",
706 .alt_name: nullptr,
707 .byte_size: 8,
708 .byte_offset: 0,
709 .encoding: eEncodingIEEE754,
710 .format: eFormatFloat,
711 .kinds: {LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
712 LLDB_INVALID_REGNUM},
713 .value_regs: nullptr,
714 .invalidate_regs: nullptr,
715 .flags_type: nullptr,
716 },
717 {.name: "d6",
718 .alt_name: nullptr,
719 .byte_size: 8,
720 .byte_offset: 0,
721 .encoding: eEncodingIEEE754,
722 .format: eFormatFloat,
723 .kinds: {LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
724 LLDB_INVALID_REGNUM},
725 .value_regs: nullptr,
726 .invalidate_regs: nullptr,
727 .flags_type: nullptr,
728 },
729 {.name: "d7",
730 .alt_name: nullptr,
731 .byte_size: 8,
732 .byte_offset: 0,
733 .encoding: eEncodingIEEE754,
734 .format: eFormatFloat,
735 .kinds: {LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
736 LLDB_INVALID_REGNUM},
737 .value_regs: nullptr,
738 .invalidate_regs: nullptr,
739 .flags_type: nullptr,
740 },
741 {.name: "d8",
742 .alt_name: nullptr,
743 .byte_size: 8,
744 .byte_offset: 0,
745 .encoding: eEncodingIEEE754,
746 .format: eFormatFloat,
747 .kinds: {LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
748 LLDB_INVALID_REGNUM},
749 .value_regs: nullptr,
750 .invalidate_regs: nullptr,
751 .flags_type: nullptr,
752 },
753 {.name: "d9",
754 .alt_name: nullptr,
755 .byte_size: 8,
756 .byte_offset: 0,
757 .encoding: eEncodingIEEE754,
758 .format: eFormatFloat,
759 .kinds: {LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
760 LLDB_INVALID_REGNUM},
761 .value_regs: nullptr,
762 .invalidate_regs: nullptr,
763 .flags_type: nullptr,
764 },
765 {.name: "d10",
766 .alt_name: nullptr,
767 .byte_size: 8,
768 .byte_offset: 0,
769 .encoding: eEncodingIEEE754,
770 .format: eFormatFloat,
771 .kinds: {LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
772 LLDB_INVALID_REGNUM},
773 .value_regs: nullptr,
774 .invalidate_regs: nullptr,
775 .flags_type: nullptr,
776 },
777 {.name: "d11",
778 .alt_name: nullptr,
779 .byte_size: 8,
780 .byte_offset: 0,
781 .encoding: eEncodingIEEE754,
782 .format: eFormatFloat,
783 .kinds: {LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
784 LLDB_INVALID_REGNUM},
785 .value_regs: nullptr,
786 .invalidate_regs: nullptr,
787 .flags_type: nullptr,
788 },
789 {.name: "d12",
790 .alt_name: nullptr,
791 .byte_size: 8,
792 .byte_offset: 0,
793 .encoding: eEncodingIEEE754,
794 .format: eFormatFloat,
795 .kinds: {LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
796 LLDB_INVALID_REGNUM},
797 .value_regs: nullptr,
798 .invalidate_regs: nullptr,
799 .flags_type: nullptr,
800 },
801 {.name: "d13",
802 .alt_name: nullptr,
803 .byte_size: 8,
804 .byte_offset: 0,
805 .encoding: eEncodingIEEE754,
806 .format: eFormatFloat,
807 .kinds: {LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
808 LLDB_INVALID_REGNUM},
809 .value_regs: nullptr,
810 .invalidate_regs: nullptr,
811 .flags_type: nullptr,
812 },
813 {.name: "d14",
814 .alt_name: nullptr,
815 .byte_size: 8,
816 .byte_offset: 0,
817 .encoding: eEncodingIEEE754,
818 .format: eFormatFloat,
819 .kinds: {LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
820 LLDB_INVALID_REGNUM},
821 .value_regs: nullptr,
822 .invalidate_regs: nullptr,
823 .flags_type: nullptr,
824 },
825 {.name: "d15",
826 .alt_name: nullptr,
827 .byte_size: 8,
828 .byte_offset: 0,
829 .encoding: eEncodingIEEE754,
830 .format: eFormatFloat,
831 .kinds: {LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
832 LLDB_INVALID_REGNUM},
833 .value_regs: nullptr,
834 .invalidate_regs: nullptr,
835 .flags_type: nullptr,
836 },
837 {.name: "d16",
838 .alt_name: nullptr,
839 .byte_size: 8,
840 .byte_offset: 0,
841 .encoding: eEncodingIEEE754,
842 .format: eFormatFloat,
843 .kinds: {LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
844 LLDB_INVALID_REGNUM},
845 .value_regs: nullptr,
846 .invalidate_regs: nullptr,
847 .flags_type: nullptr,
848 },
849 {.name: "d17",
850 .alt_name: nullptr,
851 .byte_size: 8,
852 .byte_offset: 0,
853 .encoding: eEncodingIEEE754,
854 .format: eFormatFloat,
855 .kinds: {LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
856 LLDB_INVALID_REGNUM},
857 .value_regs: nullptr,
858 .invalidate_regs: nullptr,
859 .flags_type: nullptr,
860 },
861 {.name: "d18",
862 .alt_name: nullptr,
863 .byte_size: 8,
864 .byte_offset: 0,
865 .encoding: eEncodingIEEE754,
866 .format: eFormatFloat,
867 .kinds: {LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
868 LLDB_INVALID_REGNUM},
869 .value_regs: nullptr,
870 .invalidate_regs: nullptr,
871 .flags_type: nullptr,
872 },
873 {.name: "d19",
874 .alt_name: nullptr,
875 .byte_size: 8,
876 .byte_offset: 0,
877 .encoding: eEncodingIEEE754,
878 .format: eFormatFloat,
879 .kinds: {LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
880 LLDB_INVALID_REGNUM},
881 .value_regs: nullptr,
882 .invalidate_regs: nullptr,
883 .flags_type: nullptr,
884 },
885 {.name: "d20",
886 .alt_name: nullptr,
887 .byte_size: 8,
888 .byte_offset: 0,
889 .encoding: eEncodingIEEE754,
890 .format: eFormatFloat,
891 .kinds: {LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
892 LLDB_INVALID_REGNUM},
893 .value_regs: nullptr,
894 .invalidate_regs: nullptr,
895 .flags_type: nullptr,
896 },
897 {.name: "d21",
898 .alt_name: nullptr,
899 .byte_size: 8,
900 .byte_offset: 0,
901 .encoding: eEncodingIEEE754,
902 .format: eFormatFloat,
903 .kinds: {LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
904 LLDB_INVALID_REGNUM},
905 .value_regs: nullptr,
906 .invalidate_regs: nullptr,
907 .flags_type: nullptr,
908 },
909 {.name: "d22",
910 .alt_name: nullptr,
911 .byte_size: 8,
912 .byte_offset: 0,
913 .encoding: eEncodingIEEE754,
914 .format: eFormatFloat,
915 .kinds: {LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
916 LLDB_INVALID_REGNUM},
917 .value_regs: nullptr,
918 .invalidate_regs: nullptr,
919 .flags_type: nullptr,
920 },
921 {.name: "d23",
922 .alt_name: nullptr,
923 .byte_size: 8,
924 .byte_offset: 0,
925 .encoding: eEncodingIEEE754,
926 .format: eFormatFloat,
927 .kinds: {LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
928 LLDB_INVALID_REGNUM},
929 .value_regs: nullptr,
930 .invalidate_regs: nullptr,
931 .flags_type: nullptr,
932 },
933 {.name: "d24",
934 .alt_name: nullptr,
935 .byte_size: 8,
936 .byte_offset: 0,
937 .encoding: eEncodingIEEE754,
938 .format: eFormatFloat,
939 .kinds: {LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
940 LLDB_INVALID_REGNUM},
941 .value_regs: nullptr,
942 .invalidate_regs: nullptr,
943 .flags_type: nullptr,
944 },
945 {.name: "d25",
946 .alt_name: nullptr,
947 .byte_size: 8,
948 .byte_offset: 0,
949 .encoding: eEncodingIEEE754,
950 .format: eFormatFloat,
951 .kinds: {LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
952 LLDB_INVALID_REGNUM},
953 .value_regs: nullptr,
954 .invalidate_regs: nullptr,
955 .flags_type: nullptr,
956 },
957 {.name: "d26",
958 .alt_name: nullptr,
959 .byte_size: 8,
960 .byte_offset: 0,
961 .encoding: eEncodingIEEE754,
962 .format: eFormatFloat,
963 .kinds: {LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
964 LLDB_INVALID_REGNUM},
965 .value_regs: nullptr,
966 .invalidate_regs: nullptr,
967 .flags_type: nullptr,
968 },
969 {.name: "d27",
970 .alt_name: nullptr,
971 .byte_size: 8,
972 .byte_offset: 0,
973 .encoding: eEncodingIEEE754,
974 .format: eFormatFloat,
975 .kinds: {LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
976 LLDB_INVALID_REGNUM},
977 .value_regs: nullptr,
978 .invalidate_regs: nullptr,
979 .flags_type: nullptr,
980 },
981 {.name: "d28",
982 .alt_name: nullptr,
983 .byte_size: 8,
984 .byte_offset: 0,
985 .encoding: eEncodingIEEE754,
986 .format: eFormatFloat,
987 .kinds: {LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
988 LLDB_INVALID_REGNUM},
989 .value_regs: nullptr,
990 .invalidate_regs: nullptr,
991 .flags_type: nullptr,
992 },
993 {.name: "d29",
994 .alt_name: nullptr,
995 .byte_size: 8,
996 .byte_offset: 0,
997 .encoding: eEncodingIEEE754,
998 .format: eFormatFloat,
999 .kinds: {LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1000 LLDB_INVALID_REGNUM},
1001 .value_regs: nullptr,
1002 .invalidate_regs: nullptr,
1003 .flags_type: nullptr,
1004 },
1005 {.name: "d30",
1006 .alt_name: nullptr,
1007 .byte_size: 8,
1008 .byte_offset: 0,
1009 .encoding: eEncodingIEEE754,
1010 .format: eFormatFloat,
1011 .kinds: {LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1012 LLDB_INVALID_REGNUM},
1013 .value_regs: nullptr,
1014 .invalidate_regs: nullptr,
1015 .flags_type: nullptr,
1016 },
1017 {.name: "d31",
1018 .alt_name: nullptr,
1019 .byte_size: 8,
1020 .byte_offset: 0,
1021 .encoding: eEncodingIEEE754,
1022 .format: eFormatFloat,
1023 .kinds: {LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1024 LLDB_INVALID_REGNUM},
1025 .value_regs: nullptr,
1026 .invalidate_regs: nullptr,
1027 .flags_type: nullptr,
1028 },
1029 {.name: "r8_usr",
1030 .alt_name: nullptr,
1031 .byte_size: 4,
1032 .byte_offset: 0,
1033 .encoding: eEncodingUint,
1034 .format: eFormatHex,
1035 .kinds: {LLDB_INVALID_REGNUM, dwarf_r8_usr, LLDB_INVALID_REGNUM,
1036 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1037 .value_regs: nullptr,
1038 .invalidate_regs: nullptr,
1039 .flags_type: nullptr,
1040 },
1041 {.name: "r9_usr",
1042 .alt_name: nullptr,
1043 .byte_size: 4,
1044 .byte_offset: 0,
1045 .encoding: eEncodingUint,
1046 .format: eFormatHex,
1047 .kinds: {LLDB_INVALID_REGNUM, dwarf_r9_usr, LLDB_INVALID_REGNUM,
1048 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1049 .value_regs: nullptr,
1050 .invalidate_regs: nullptr,
1051 .flags_type: nullptr,
1052 },
1053 {.name: "r10_usr",
1054 .alt_name: nullptr,
1055 .byte_size: 4,
1056 .byte_offset: 0,
1057 .encoding: eEncodingUint,
1058 .format: eFormatHex,
1059 .kinds: {LLDB_INVALID_REGNUM, dwarf_r10_usr, LLDB_INVALID_REGNUM,
1060 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1061 .value_regs: nullptr,
1062 .invalidate_regs: nullptr,
1063 .flags_type: nullptr,
1064 },
1065 {.name: "r11_usr",
1066 .alt_name: nullptr,
1067 .byte_size: 4,
1068 .byte_offset: 0,
1069 .encoding: eEncodingUint,
1070 .format: eFormatHex,
1071 .kinds: {LLDB_INVALID_REGNUM, dwarf_r11_usr, LLDB_INVALID_REGNUM,
1072 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1073 .value_regs: nullptr,
1074 .invalidate_regs: nullptr,
1075 .flags_type: nullptr,
1076 },
1077 {.name: "r12_usr",
1078 .alt_name: nullptr,
1079 .byte_size: 4,
1080 .byte_offset: 0,
1081 .encoding: eEncodingUint,
1082 .format: eFormatHex,
1083 .kinds: {LLDB_INVALID_REGNUM, dwarf_r12_usr, LLDB_INVALID_REGNUM,
1084 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1085 .value_regs: nullptr,
1086 .invalidate_regs: nullptr,
1087 .flags_type: nullptr,
1088 },
1089 {.name: "r13_usr",
1090 .alt_name: "sp_usr",
1091 .byte_size: 4,
1092 .byte_offset: 0,
1093 .encoding: eEncodingUint,
1094 .format: eFormatHex,
1095 .kinds: {LLDB_INVALID_REGNUM, dwarf_r13_usr, LLDB_INVALID_REGNUM,
1096 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1097 .value_regs: nullptr,
1098 .invalidate_regs: nullptr,
1099 .flags_type: nullptr,
1100 },
1101 {.name: "r14_usr",
1102 .alt_name: "lr_usr",
1103 .byte_size: 4,
1104 .byte_offset: 0,
1105 .encoding: eEncodingUint,
1106 .format: eFormatHex,
1107 .kinds: {LLDB_INVALID_REGNUM, dwarf_r14_usr, LLDB_INVALID_REGNUM,
1108 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1109 .value_regs: nullptr,
1110 .invalidate_regs: nullptr,
1111 .flags_type: nullptr,
1112 },
1113 {.name: "r8_fiq",
1114 .alt_name: nullptr,
1115 .byte_size: 4,
1116 .byte_offset: 0,
1117 .encoding: eEncodingUint,
1118 .format: eFormatHex,
1119 .kinds: {LLDB_INVALID_REGNUM, dwarf_r8_fiq, LLDB_INVALID_REGNUM,
1120 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1121 .value_regs: nullptr,
1122 .invalidate_regs: nullptr,
1123 .flags_type: nullptr,
1124 },
1125 {.name: "r9_fiq",
1126 .alt_name: nullptr,
1127 .byte_size: 4,
1128 .byte_offset: 0,
1129 .encoding: eEncodingUint,
1130 .format: eFormatHex,
1131 .kinds: {LLDB_INVALID_REGNUM, dwarf_r9_fiq, LLDB_INVALID_REGNUM,
1132 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1133 .value_regs: nullptr,
1134 .invalidate_regs: nullptr,
1135 .flags_type: nullptr,
1136 },
1137 {.name: "r10_fiq",
1138 .alt_name: nullptr,
1139 .byte_size: 4,
1140 .byte_offset: 0,
1141 .encoding: eEncodingUint,
1142 .format: eFormatHex,
1143 .kinds: {LLDB_INVALID_REGNUM, dwarf_r10_fiq, LLDB_INVALID_REGNUM,
1144 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1145 .value_regs: nullptr,
1146 .invalidate_regs: nullptr,
1147 .flags_type: nullptr,
1148 },
1149 {.name: "r11_fiq",
1150 .alt_name: nullptr,
1151 .byte_size: 4,
1152 .byte_offset: 0,
1153 .encoding: eEncodingUint,
1154 .format: eFormatHex,
1155 .kinds: {LLDB_INVALID_REGNUM, dwarf_r11_fiq, LLDB_INVALID_REGNUM,
1156 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1157 .value_regs: nullptr,
1158 .invalidate_regs: nullptr,
1159 .flags_type: nullptr,
1160 },
1161 {.name: "r12_fiq",
1162 .alt_name: nullptr,
1163 .byte_size: 4,
1164 .byte_offset: 0,
1165 .encoding: eEncodingUint,
1166 .format: eFormatHex,
1167 .kinds: {LLDB_INVALID_REGNUM, dwarf_r12_fiq, LLDB_INVALID_REGNUM,
1168 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1169 .value_regs: nullptr,
1170 .invalidate_regs: nullptr,
1171 .flags_type: nullptr,
1172 },
1173 {.name: "r13_fiq",
1174 .alt_name: "sp_fiq",
1175 .byte_size: 4,
1176 .byte_offset: 0,
1177 .encoding: eEncodingUint,
1178 .format: eFormatHex,
1179 .kinds: {LLDB_INVALID_REGNUM, dwarf_r13_fiq, LLDB_INVALID_REGNUM,
1180 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1181 .value_regs: nullptr,
1182 .invalidate_regs: nullptr,
1183 .flags_type: nullptr,
1184 },
1185 {.name: "r14_fiq",
1186 .alt_name: "lr_fiq",
1187 .byte_size: 4,
1188 .byte_offset: 0,
1189 .encoding: eEncodingUint,
1190 .format: eFormatHex,
1191 .kinds: {LLDB_INVALID_REGNUM, dwarf_r14_fiq, LLDB_INVALID_REGNUM,
1192 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1193 .value_regs: nullptr,
1194 .invalidate_regs: nullptr,
1195 .flags_type: nullptr,
1196 },
1197 {.name: "r13_irq",
1198 .alt_name: "sp_irq",
1199 .byte_size: 4,
1200 .byte_offset: 0,
1201 .encoding: eEncodingUint,
1202 .format: eFormatHex,
1203 .kinds: {LLDB_INVALID_REGNUM, dwarf_r13_irq, LLDB_INVALID_REGNUM,
1204 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1205 .value_regs: nullptr,
1206 .invalidate_regs: nullptr,
1207 .flags_type: nullptr,
1208 },
1209 {.name: "r14_irq",
1210 .alt_name: "lr_irq",
1211 .byte_size: 4,
1212 .byte_offset: 0,
1213 .encoding: eEncodingUint,
1214 .format: eFormatHex,
1215 .kinds: {LLDB_INVALID_REGNUM, dwarf_r14_irq, LLDB_INVALID_REGNUM,
1216 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1217 .value_regs: nullptr,
1218 .invalidate_regs: nullptr,
1219 .flags_type: nullptr,
1220 },
1221 {.name: "r13_abt",
1222 .alt_name: "sp_abt",
1223 .byte_size: 4,
1224 .byte_offset: 0,
1225 .encoding: eEncodingUint,
1226 .format: eFormatHex,
1227 .kinds: {LLDB_INVALID_REGNUM, dwarf_r13_abt, LLDB_INVALID_REGNUM,
1228 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1229 .value_regs: nullptr,
1230 .invalidate_regs: nullptr,
1231 .flags_type: nullptr,
1232 },
1233 {.name: "r14_abt",
1234 .alt_name: "lr_abt",
1235 .byte_size: 4,
1236 .byte_offset: 0,
1237 .encoding: eEncodingUint,
1238 .format: eFormatHex,
1239 .kinds: {LLDB_INVALID_REGNUM, dwarf_r14_abt, LLDB_INVALID_REGNUM,
1240 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1241 .value_regs: nullptr,
1242 .invalidate_regs: nullptr,
1243 .flags_type: nullptr,
1244 },
1245 {.name: "r13_und",
1246 .alt_name: "sp_und",
1247 .byte_size: 4,
1248 .byte_offset: 0,
1249 .encoding: eEncodingUint,
1250 .format: eFormatHex,
1251 .kinds: {LLDB_INVALID_REGNUM, dwarf_r13_und, LLDB_INVALID_REGNUM,
1252 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1253 .value_regs: nullptr,
1254 .invalidate_regs: nullptr,
1255 .flags_type: nullptr,
1256 },
1257 {.name: "r14_und",
1258 .alt_name: "lr_und",
1259 .byte_size: 4,
1260 .byte_offset: 0,
1261 .encoding: eEncodingUint,
1262 .format: eFormatHex,
1263 .kinds: {LLDB_INVALID_REGNUM, dwarf_r14_und, LLDB_INVALID_REGNUM,
1264 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1265 .value_regs: nullptr,
1266 .invalidate_regs: nullptr,
1267 .flags_type: nullptr,
1268 },
1269 {.name: "r13_svc",
1270 .alt_name: "sp_svc",
1271 .byte_size: 4,
1272 .byte_offset: 0,
1273 .encoding: eEncodingUint,
1274 .format: eFormatHex,
1275 .kinds: {LLDB_INVALID_REGNUM, dwarf_r13_svc, LLDB_INVALID_REGNUM,
1276 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1277 .value_regs: nullptr,
1278 .invalidate_regs: nullptr,
1279 .flags_type: nullptr,
1280 },
1281 {.name: "r14_svc",
1282 .alt_name: "lr_svc",
1283 .byte_size: 4,
1284 .byte_offset: 0,
1285 .encoding: eEncodingUint,
1286 .format: eFormatHex,
1287 .kinds: {LLDB_INVALID_REGNUM, dwarf_r14_svc, LLDB_INVALID_REGNUM,
1288 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1289 .value_regs: nullptr,
1290 .invalidate_regs: nullptr,
1291 .flags_type: nullptr,
1292 }};
1293
1294static const uint32_t k_num_register_infos = std::size(g_register_infos);
1295
1296const lldb_private::RegisterInfo *
1297ABIMacOSX_arm::GetRegisterInfoArray(uint32_t &count) {
1298 count = k_num_register_infos;
1299 return g_register_infos;
1300}
1301
1302size_t ABIMacOSX_arm::GetRedZoneSize() const { return 0; }
1303
1304// Static Functions
1305
1306ABISP
1307ABIMacOSX_arm::CreateInstance(ProcessSP process_sp, const ArchSpec &arch) {
1308 const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
1309 const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor();
1310
1311 if (vendor_type == llvm::Triple::Apple) {
1312 if ((arch_type == llvm::Triple::arm) ||
1313 (arch_type == llvm::Triple::thumb)) {
1314 return ABISP(
1315 new ABIMacOSX_arm(std::move(process_sp), MakeMCRegisterInfo(arch)));
1316 }
1317 }
1318
1319 return ABISP();
1320}
1321
1322bool ABIMacOSX_arm::PrepareTrivialCall(Thread &thread, addr_t sp,
1323 addr_t function_addr, addr_t return_addr,
1324 llvm::ArrayRef<addr_t> args) const {
1325 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1326 if (!reg_ctx)
1327 return false;
1328
1329 const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1330 kind: eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
1331 const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1332 kind: eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
1333 const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1334 kind: eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
1335
1336 RegisterValue reg_value;
1337
1338 const char *reg_names[] = {"r0", "r1", "r2", "r3"};
1339
1340 llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end();
1341
1342 for (size_t i = 0; i < std::size(reg_names); ++i) {
1343 if (ai == ae)
1344 break;
1345
1346 reg_value.SetUInt32(uint: *ai);
1347 if (!reg_ctx->WriteRegister(reg_info: reg_ctx->GetRegisterInfoByName(reg_name: reg_names[i]),
1348 reg_value))
1349 return false;
1350
1351 ++ai;
1352 }
1353
1354 if (ai != ae) {
1355 // Spill onto the stack
1356 size_t num_stack_regs = ae - ai;
1357
1358 sp -= (num_stack_regs * 4);
1359 // Keep the stack 16 byte aligned
1360 sp &= ~(16ull - 1ull);
1361
1362 // just using arg1 to get the right size
1363 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
1364 reg_kind: eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
1365
1366 addr_t arg_pos = sp;
1367
1368 for (; ai != ae; ++ai) {
1369 reg_value.SetUInt32(uint: *ai);
1370 if (reg_ctx
1371 ->WriteRegisterValueToMemory(reg_info, dst_addr: arg_pos,
1372 dst_len: reg_info->byte_size, reg_value)
1373 .Fail())
1374 return false;
1375 arg_pos += reg_info->byte_size;
1376 }
1377 }
1378
1379 TargetSP target_sp(thread.CalculateTarget());
1380 Address so_addr;
1381
1382 // Figure out if our return address is ARM or Thumb by using the
1383 // Address::GetCallableLoadAddress(Target*) which will figure out the ARM
1384 // thumb-ness and set the correct address bits for us.
1385 so_addr.SetLoadAddress(load_addr: return_addr, target: target_sp.get());
1386 return_addr = so_addr.GetCallableLoadAddress(target: target_sp.get());
1387
1388 // Set "lr" to the return address
1389 if (!reg_ctx->WriteRegisterFromUnsigned(reg: ra_reg_num, uval: return_addr))
1390 return false;
1391
1392 // If bit zero or 1 is set, this must be a thumb function, no need to figure
1393 // this out from the symbols.
1394 so_addr.SetLoadAddress(load_addr: function_addr, target: target_sp.get());
1395 function_addr = so_addr.GetCallableLoadAddress(target: target_sp.get());
1396
1397 const RegisterInfo *cpsr_reg_info = reg_ctx->GetRegisterInfoByName(reg_name: "cpsr");
1398 const uint32_t curr_cpsr = reg_ctx->ReadRegisterAsUnsigned(reg_info: cpsr_reg_info, fail_value: 0);
1399
1400 // Make a new CPSR and mask out any Thumb IT (if/then) bits
1401 uint32_t new_cpsr = curr_cpsr & ~MASK_CPSR_IT_MASK;
1402 // If bit zero or 1 is set, this must be thumb...
1403 if (function_addr & 1ull)
1404 new_cpsr |= MASK_CPSR_T; // Set T bit in CPSR
1405 else
1406 new_cpsr &= ~MASK_CPSR_T; // Clear T bit in CPSR
1407
1408 if (new_cpsr != curr_cpsr) {
1409 if (!reg_ctx->WriteRegisterFromUnsigned(reg_info: cpsr_reg_info, uval: new_cpsr))
1410 return false;
1411 }
1412
1413 function_addr &=
1414 ~1ull; // clear bit zero since the CPSR will take care of the mode for us
1415
1416 // Update the sp - stack pointer - to be aligned to 16-bytes
1417 sp &= ~(0xfull);
1418 if (!reg_ctx->WriteRegisterFromUnsigned(reg: sp_reg_num, uval: sp))
1419 return false;
1420
1421 // Set "pc" to the address requested
1422 if (!reg_ctx->WriteRegisterFromUnsigned(reg: pc_reg_num, uval: function_addr))
1423 return false;
1424
1425 return true;
1426}
1427
1428bool ABIMacOSX_arm::GetArgumentValues(Thread &thread, ValueList &values) const {
1429 uint32_t num_values = values.GetSize();
1430
1431 ExecutionContext exe_ctx(thread.shared_from_this());
1432 // For now, assume that the types in the AST values come from the Target's
1433 // scratch AST.
1434
1435 // Extract the register context so we can read arguments from registers
1436
1437 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1438
1439 if (!reg_ctx)
1440 return false;
1441
1442 addr_t sp = 0;
1443
1444 for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) {
1445 // We currently only support extracting values with Clang QualTypes. Do we
1446 // care about others?
1447 Value *value = values.GetValueAtIndex(idx: value_idx);
1448
1449 if (!value)
1450 return false;
1451
1452 CompilerType compiler_type = value->GetCompilerType();
1453 if (compiler_type) {
1454 bool is_signed = false;
1455 size_t bit_width = 0;
1456 std::optional<uint64_t> bit_size = compiler_type.GetBitSize(exe_scope: &thread);
1457 if (!bit_size)
1458 return false;
1459 if (compiler_type.IsIntegerOrEnumerationType(is_signed))
1460 bit_width = *bit_size;
1461 else if (compiler_type.IsPointerOrReferenceType())
1462 bit_width = *bit_size;
1463 else
1464 // We only handle integer, pointer and reference types currently...
1465 return false;
1466
1467 if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) {
1468 if (value_idx < 4) {
1469 // Arguments 1-4 are in r0-r3...
1470 const RegisterInfo *arg_reg_info = nullptr;
1471 // Search by generic ID first, then fall back to by name
1472 uint32_t arg_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1473 kind: eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
1474 if (arg_reg_num != LLDB_INVALID_REGNUM) {
1475 arg_reg_info = reg_ctx->GetRegisterInfoAtIndex(reg: arg_reg_num);
1476 } else {
1477 switch (value_idx) {
1478 case 0:
1479 arg_reg_info = reg_ctx->GetRegisterInfoByName(reg_name: "r0");
1480 break;
1481 case 1:
1482 arg_reg_info = reg_ctx->GetRegisterInfoByName(reg_name: "r1");
1483 break;
1484 case 2:
1485 arg_reg_info = reg_ctx->GetRegisterInfoByName(reg_name: "r2");
1486 break;
1487 case 3:
1488 arg_reg_info = reg_ctx->GetRegisterInfoByName(reg_name: "r3");
1489 break;
1490 }
1491 }
1492
1493 if (arg_reg_info) {
1494 RegisterValue reg_value;
1495
1496 if (reg_ctx->ReadRegister(reg_info: arg_reg_info, reg_value)) {
1497 if (is_signed)
1498 reg_value.SignExtend(sign_bitpos: bit_width);
1499 if (!reg_value.GetScalarValue(scalar&: value->GetScalar()))
1500 return false;
1501 continue;
1502 }
1503 }
1504 return false;
1505 } else {
1506 if (sp == 0) {
1507 // Read the stack pointer if it already hasn't been read
1508 sp = reg_ctx->GetSP(fail_value: 0);
1509 if (sp == 0)
1510 return false;
1511 }
1512
1513 // Arguments 5 on up are on the stack
1514 const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8;
1515 Status error;
1516 if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory(
1517 addr: sp, byte_size: arg_byte_size, is_signed, scalar&: value->GetScalar(), error))
1518 return false;
1519
1520 sp += arg_byte_size;
1521 }
1522 }
1523 }
1524 }
1525 return true;
1526}
1527
1528bool ABIMacOSX_arm::IsArmv7kProcess() const {
1529 bool is_armv7k = false;
1530 ProcessSP process_sp(GetProcessSP());
1531 if (process_sp) {
1532 const ArchSpec &arch(process_sp->GetTarget().GetArchitecture());
1533 const ArchSpec::Core system_core = arch.GetCore();
1534 if (system_core == ArchSpec::eCore_arm_armv7k) {
1535 is_armv7k = true;
1536 }
1537 }
1538 return is_armv7k;
1539}
1540
1541ValueObjectSP ABIMacOSX_arm::GetReturnValueObjectImpl(
1542 Thread &thread, lldb_private::CompilerType &compiler_type) const {
1543 Value value;
1544 ValueObjectSP return_valobj_sp;
1545
1546 if (!compiler_type)
1547 return return_valobj_sp;
1548
1549 value.SetCompilerType(compiler_type);
1550
1551 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1552 if (!reg_ctx)
1553 return return_valobj_sp;
1554
1555 bool is_signed;
1556
1557 // Get the pointer to the first stack argument so we have a place to start
1558 // when reading data
1559
1560 const RegisterInfo *r0_reg_info = reg_ctx->GetRegisterInfoByName(reg_name: "r0", start_idx: 0);
1561 if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
1562 std::optional<uint64_t> bit_width = compiler_type.GetBitSize(exe_scope: &thread);
1563 if (!bit_width)
1564 return return_valobj_sp;
1565
1566 switch (*bit_width) {
1567 default:
1568 return return_valobj_sp;
1569 case 128:
1570 if (IsArmv7kProcess()) {
1571 // "A composite type not larger than 16 bytes is returned in r0-r3. The
1572 // format is as if the result had been stored in memory at a word-
1573 // aligned address and then loaded into r0-r3 with an ldm instruction"
1574 {
1575 const RegisterInfo *r1_reg_info =
1576 reg_ctx->GetRegisterInfoByName(reg_name: "r1", start_idx: 0);
1577 const RegisterInfo *r2_reg_info =
1578 reg_ctx->GetRegisterInfoByName(reg_name: "r2", start_idx: 0);
1579 const RegisterInfo *r3_reg_info =
1580 reg_ctx->GetRegisterInfoByName(reg_name: "r3", start_idx: 0);
1581 if (r1_reg_info && r2_reg_info && r3_reg_info) {
1582 std::optional<uint64_t> byte_size =
1583 compiler_type.GetByteSize(exe_scope: &thread);
1584 if (!byte_size)
1585 return return_valobj_sp;
1586 ProcessSP process_sp(thread.GetProcess());
1587 if (*byte_size <= r0_reg_info->byte_size + r1_reg_info->byte_size +
1588 r2_reg_info->byte_size +
1589 r3_reg_info->byte_size &&
1590 process_sp) {
1591 std::unique_ptr<DataBufferHeap> heap_data_up(
1592 new DataBufferHeap(*byte_size, 0));
1593 const ByteOrder byte_order = process_sp->GetByteOrder();
1594 RegisterValue r0_reg_value;
1595 RegisterValue r1_reg_value;
1596 RegisterValue r2_reg_value;
1597 RegisterValue r3_reg_value;
1598 if (reg_ctx->ReadRegister(reg_info: r0_reg_info, reg_value&: r0_reg_value) &&
1599 reg_ctx->ReadRegister(reg_info: r1_reg_info, reg_value&: r1_reg_value) &&
1600 reg_ctx->ReadRegister(reg_info: r2_reg_info, reg_value&: r2_reg_value) &&
1601 reg_ctx->ReadRegister(reg_info: r3_reg_info, reg_value&: r3_reg_value)) {
1602 Status error;
1603 if (r0_reg_value.GetAsMemoryData(reg_info: *r0_reg_info,
1604 dst: heap_data_up->GetBytes() + 0,
1605 dst_len: 4, dst_byte_order: byte_order, error) &&
1606 r1_reg_value.GetAsMemoryData(reg_info: *r1_reg_info,
1607 dst: heap_data_up->GetBytes() + 4,
1608 dst_len: 4, dst_byte_order: byte_order, error) &&
1609 r2_reg_value.GetAsMemoryData(reg_info: *r2_reg_info,
1610 dst: heap_data_up->GetBytes() + 8,
1611 dst_len: 4, dst_byte_order: byte_order, error) &&
1612 r3_reg_value.GetAsMemoryData(reg_info: *r3_reg_info,
1613 dst: heap_data_up->GetBytes() + 12,
1614 dst_len: 4, dst_byte_order: byte_order, error)) {
1615 DataExtractor data(DataBufferSP(heap_data_up.release()),
1616 byte_order,
1617 process_sp->GetAddressByteSize());
1618
1619 return_valobj_sp = ValueObjectConstResult::Create(
1620 exe_scope: &thread, compiler_type, name: ConstString(""), data);
1621 return return_valobj_sp;
1622 }
1623 }
1624 }
1625 }
1626 }
1627 } else {
1628 return return_valobj_sp;
1629 }
1630 break;
1631 case 64: {
1632 const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfoByName(reg_name: "r1", start_idx: 0);
1633 uint64_t raw_value;
1634 raw_value = reg_ctx->ReadRegisterAsUnsigned(reg_info: r0_reg_info, fail_value: 0) & UINT32_MAX;
1635 raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(reg_info: r1_reg_info, fail_value: 0) &
1636 UINT32_MAX))
1637 << 32;
1638 if (is_signed)
1639 value.GetScalar() = (int64_t)raw_value;
1640 else
1641 value.GetScalar() = (uint64_t)raw_value;
1642 } break;
1643 case 32:
1644 if (is_signed)
1645 value.GetScalar() = (int32_t)(
1646 reg_ctx->ReadRegisterAsUnsigned(reg_info: r0_reg_info, fail_value: 0) & UINT32_MAX);
1647 else
1648 value.GetScalar() = (uint32_t)(
1649 reg_ctx->ReadRegisterAsUnsigned(reg_info: r0_reg_info, fail_value: 0) & UINT32_MAX);
1650 break;
1651 case 16:
1652 if (is_signed)
1653 value.GetScalar() = (int16_t)(
1654 reg_ctx->ReadRegisterAsUnsigned(reg_info: r0_reg_info, fail_value: 0) & UINT16_MAX);
1655 else
1656 value.GetScalar() = (uint16_t)(
1657 reg_ctx->ReadRegisterAsUnsigned(reg_info: r0_reg_info, fail_value: 0) & UINT16_MAX);
1658 break;
1659 case 8:
1660 if (is_signed)
1661 value.GetScalar() = (int8_t)(
1662 reg_ctx->ReadRegisterAsUnsigned(reg_info: r0_reg_info, fail_value: 0) & UINT8_MAX);
1663 else
1664 value.GetScalar() = (uint8_t)(
1665 reg_ctx->ReadRegisterAsUnsigned(reg_info: r0_reg_info, fail_value: 0) & UINT8_MAX);
1666 break;
1667 }
1668 } else if (compiler_type.IsPointerType()) {
1669 uint32_t ptr =
1670 thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_info: r0_reg_info, fail_value: 0) &
1671 UINT32_MAX;
1672 value.GetScalar() = ptr;
1673 } else {
1674 // not handled yet
1675 return return_valobj_sp;
1676 }
1677
1678 // If we get here, we have a valid Value, so make our ValueObject out of it:
1679
1680 return_valobj_sp = ValueObjectConstResult::Create(
1681 exe_scope: thread.GetStackFrameAtIndex(idx: 0).get(), value, name: ConstString(""));
1682 return return_valobj_sp;
1683}
1684
1685Status ABIMacOSX_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
1686 lldb::ValueObjectSP &new_value_sp) {
1687 Status error;
1688 if (!new_value_sp) {
1689 error.SetErrorString("Empty value object for return value.");
1690 return error;
1691 }
1692
1693 CompilerType compiler_type = new_value_sp->GetCompilerType();
1694 if (!compiler_type) {
1695 error.SetErrorString("Null clang type for return value.");
1696 return error;
1697 }
1698
1699 Thread *thread = frame_sp->GetThread().get();
1700
1701 bool is_signed;
1702 uint32_t count;
1703 bool is_complex;
1704
1705 RegisterContext *reg_ctx = thread->GetRegisterContext().get();
1706
1707 bool set_it_simple = false;
1708 if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1709 compiler_type.IsPointerType()) {
1710 DataExtractor data;
1711 Status data_error;
1712 size_t num_bytes = new_value_sp->GetData(data, error&: data_error);
1713 if (data_error.Fail()) {
1714 error.SetErrorStringWithFormat(
1715 "Couldn't convert return value to raw data: %s",
1716 data_error.AsCString());
1717 return error;
1718 }
1719 lldb::offset_t offset = 0;
1720 if (num_bytes <= 8) {
1721 const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName(reg_name: "r0", start_idx: 0);
1722 if (num_bytes <= 4) {
1723 uint32_t raw_value = data.GetMaxU32(offset_ptr: &offset, byte_size: num_bytes);
1724
1725 if (reg_ctx->WriteRegisterFromUnsigned(reg_info: r0_info, uval: raw_value))
1726 set_it_simple = true;
1727 } else {
1728 uint32_t raw_value = data.GetMaxU32(offset_ptr: &offset, byte_size: 4);
1729
1730 if (reg_ctx->WriteRegisterFromUnsigned(reg_info: r0_info, uval: raw_value)) {
1731 const RegisterInfo *r1_info = reg_ctx->GetRegisterInfoByName(reg_name: "r1", start_idx: 0);
1732 uint32_t raw_value = data.GetMaxU32(offset_ptr: &offset, byte_size: num_bytes - offset);
1733
1734 if (reg_ctx->WriteRegisterFromUnsigned(reg_info: r1_info, uval: raw_value))
1735 set_it_simple = true;
1736 }
1737 }
1738 } else if (num_bytes <= 16 && IsArmv7kProcess()) {
1739 // "A composite type not larger than 16 bytes is returned in r0-r3. The
1740 // format is as if the result had been stored in memory at a word-aligned
1741 // address and then loaded into r0-r3 with an ldm instruction"
1742
1743 const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName(reg_name: "r0", start_idx: 0);
1744 const RegisterInfo *r1_info = reg_ctx->GetRegisterInfoByName(reg_name: "r1", start_idx: 0);
1745 const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName(reg_name: "r2", start_idx: 0);
1746 const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName(reg_name: "r3", start_idx: 0);
1747 lldb::offset_t offset = 0;
1748 uint32_t bytes_written = 4;
1749 uint32_t raw_value = data.GetMaxU64(offset_ptr: &offset, byte_size: 4);
1750 if (reg_ctx->WriteRegisterFromUnsigned(reg_info: r0_info, uval: raw_value) &&
1751 bytes_written <= num_bytes) {
1752 bytes_written += 4;
1753 raw_value = data.GetMaxU64(offset_ptr: &offset, byte_size: 4);
1754 if (bytes_written <= num_bytes &&
1755 reg_ctx->WriteRegisterFromUnsigned(reg_info: r1_info, uval: raw_value)) {
1756 bytes_written += 4;
1757 raw_value = data.GetMaxU64(offset_ptr: &offset, byte_size: 4);
1758 if (bytes_written <= num_bytes &&
1759 reg_ctx->WriteRegisterFromUnsigned(reg_info: r2_info, uval: raw_value)) {
1760 bytes_written += 4;
1761 raw_value = data.GetMaxU64(offset_ptr: &offset, byte_size: 4);
1762 if (bytes_written <= num_bytes &&
1763 reg_ctx->WriteRegisterFromUnsigned(reg_info: r3_info, uval: raw_value)) {
1764 set_it_simple = true;
1765 }
1766 }
1767 }
1768 }
1769 } else {
1770 error.SetErrorString("We don't support returning longer than 64 bit "
1771 "integer values at present.");
1772 }
1773 } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
1774 if (is_complex)
1775 error.SetErrorString(
1776 "We don't support returning complex values at present");
1777 else
1778 error.SetErrorString(
1779 "We don't support returning float values at present");
1780 }
1781
1782 if (!set_it_simple)
1783 error.SetErrorString(
1784 "We only support setting simple integer return types at present.");
1785
1786 return error;
1787}
1788
1789bool ABIMacOSX_arm::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
1790 unwind_plan.Clear();
1791 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1792
1793 uint32_t lr_reg_num = dwarf_lr;
1794 uint32_t sp_reg_num = dwarf_sp;
1795 uint32_t pc_reg_num = dwarf_pc;
1796
1797 UnwindPlan::RowSP row(new UnwindPlan::Row);
1798
1799 // Our Call Frame Address is the stack pointer value
1800 row->GetCFAValue().SetIsRegisterPlusOffset(reg_num: sp_reg_num, offset: 0);
1801
1802 // The previous PC is in the LR
1803 row->SetRegisterLocationToRegister(reg_num: pc_reg_num, other_reg_num: lr_reg_num, can_replace: true);
1804 unwind_plan.AppendRow(row_sp: row);
1805
1806 // All other registers are the same.
1807
1808 unwind_plan.SetSourceName("arm at-func-entry default");
1809 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1810
1811 return true;
1812}
1813
1814bool ABIMacOSX_arm::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
1815 unwind_plan.Clear();
1816 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1817
1818 uint32_t fp_reg_num =
1819 dwarf_r7; // apple uses r7 for all frames. Normal arm uses r11
1820 uint32_t pc_reg_num = dwarf_pc;
1821
1822 UnwindPlan::RowSP row(new UnwindPlan::Row);
1823 const int32_t ptr_size = 4;
1824
1825 row->GetCFAValue().SetIsRegisterPlusOffset(reg_num: fp_reg_num, offset: 2 * ptr_size);
1826 row->SetOffset(0);
1827 row->SetUnspecifiedRegistersAreUndefined(true);
1828
1829 row->SetRegisterLocationToAtCFAPlusOffset(reg_num: fp_reg_num, offset: ptr_size * -2, can_replace: true);
1830 row->SetRegisterLocationToAtCFAPlusOffset(reg_num: pc_reg_num, offset: ptr_size * -1, can_replace: true);
1831
1832 unwind_plan.AppendRow(row_sp: row);
1833 unwind_plan.SetSourceName("arm-apple-ios default unwind plan");
1834 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1835 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1836 unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
1837
1838 return true;
1839}
1840
1841// cf. "ARMv6 Function Calling Conventions"
1842// https://developer.apple.com/library/ios/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARMv6FunctionCallingConventions.html
1843// and "ARMv7 Function Calling Conventions"
1844// https://developer.apple.com/library/ios/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARMv7FunctionCallingConventions.html
1845
1846// ARMv7 on iOS general purpose reg rules:
1847// r0-r3 not preserved (used for argument passing)
1848// r4-r6 preserved
1849// r7 preserved (frame pointer)
1850// r8 preserved
1851// r9 not preserved (usable as volatile scratch register with iOS 3.x and
1852// later)
1853// r10-r11 preserved
1854// r12 not presrved
1855// r13 preserved (stack pointer)
1856// r14 not preserved (link register)
1857// r15 preserved (pc)
1858// cpsr not preserved (different rules for different bits)
1859
1860// ARMv7 on iOS floating point rules:
1861// d0-d7 not preserved (aka s0-s15, q0-q3)
1862// d8-d15 preserved (aka s16-s31, q4-q7)
1863// d16-d31 not preserved (aka q8-q15)
1864
1865bool ABIMacOSX_arm::RegisterIsVolatile(const RegisterInfo *reg_info) {
1866 if (reg_info) {
1867 // Volatile registers are: r0, r1, r2, r3, r9, r12, r13 (aka sp)
1868 const char *name = reg_info->name;
1869 if (name[0] == 'r') {
1870 switch (name[1]) {
1871 case '0':
1872 return name[2] == '\0'; // r0
1873 case '1':
1874 switch (name[2]) {
1875 case '\0':
1876 return true; // r1
1877 case '2':
1878 case '3':
1879 return name[3] == '\0'; // r12, r13 (sp)
1880 default:
1881 break;
1882 }
1883 break;
1884
1885 case '2':
1886 return name[2] == '\0'; // r2
1887 case '3':
1888 return name[2] == '\0'; // r3
1889 case '9':
1890 return name[2] == '\0'; // r9 (apple-ios only...)
1891
1892 break;
1893 }
1894 } else if (name[0] == 'd') {
1895 switch (name[1]) {
1896 case '0':
1897 return name[2] == '\0'; // d0 is volatile
1898
1899 case '1':
1900 switch (name[2]) {
1901 case '\0':
1902 return true; // d1 is volatile
1903 case '6':
1904 case '7':
1905 case '8':
1906 case '9':
1907 return name[3] == '\0'; // d16 - d19 are volatile
1908 default:
1909 break;
1910 }
1911 break;
1912
1913 case '2':
1914 switch (name[2]) {
1915 case '\0':
1916 return true; // d2 is volatile
1917 case '0':
1918 case '1':
1919 case '2':
1920 case '3':
1921 case '4':
1922 case '5':
1923 case '6':
1924 case '7':
1925 case '8':
1926 case '9':
1927 return name[3] == '\0'; // d20 - d29 are volatile
1928 default:
1929 break;
1930 }
1931 break;
1932
1933 case '3':
1934 switch (name[2]) {
1935 case '\0':
1936 return true; // d3 is volatile
1937 case '0':
1938 case '1':
1939 return name[3] == '\0'; // d30 - d31 are volatile
1940 default:
1941 break;
1942 }
1943 break;
1944 case '4':
1945 case '5':
1946 case '6':
1947 case '7':
1948 return name[2] == '\0'; // d4 - d7 are volatile
1949
1950 default:
1951 break;
1952 }
1953 } else if (name[0] == 's') {
1954 switch (name[1]) {
1955 case '0':
1956 return name[2] == '\0'; // s0 is volatile
1957
1958 case '1':
1959 switch (name[2]) {
1960 case '\0':
1961 return true; // s1 is volatile
1962 case '0':
1963 case '1':
1964 case '2':
1965 case '3':
1966 case '4':
1967 case '5':
1968 return name[3] == '\0'; // s10 - s15 are volatile
1969 default:
1970 break;
1971 }
1972 break;
1973
1974 case '2':
1975 case '3':
1976 case '4':
1977 case '5':
1978 case '6':
1979 case '7':
1980 case '8':
1981 case '9':
1982 return name[2] == '\0'; // s2 - s9 are volatile
1983
1984 default:
1985 break;
1986 }
1987 } else if (name[0] == 'q') {
1988 switch (name[1]) {
1989 case '1':
1990 switch (name[2]) {
1991 case '\0':
1992 return true; // q1 is volatile
1993 case '0':
1994 case '1':
1995 case '2':
1996 case '3':
1997 case '4':
1998 case '5':
1999 return true; // q10-q15 are volatile
2000 default:
2001 break;
2002 };
2003 break;
2004 case '0':
2005 case '2':
2006 case '3':
2007 return name[2] == '\0'; // q0-q3 are volatile
2008 case '8':
2009 case '9':
2010 return name[2] == '\0'; // q8-q9 are volatile
2011 default:
2012 break;
2013 }
2014 } else if (name[0] == 's' && name[1] == 'p' && name[2] == '\0')
2015 return true;
2016 }
2017 return false;
2018}
2019
2020void ABIMacOSX_arm::Initialize() {
2021 PluginManager::RegisterPlugin(name: GetPluginNameStatic(),
2022 description: "Mac OS X ABI for arm targets", create_callback: CreateInstance);
2023}
2024
2025void ABIMacOSX_arm::Terminate() {
2026 PluginManager::UnregisterPlugin(create_callback: CreateInstance);
2027}
2028

source code of lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp