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

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

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