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

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

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