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

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