[AMDGPU] Mark AGPR tuple implicit in the first instr of AGPR spills. (#115285)
[llvm-project.git] / lldb / source / Plugins / ABI / ARM / ABISysV_arm.cpp
blobd67591ffa109bc45846c65a56f9ebfa28742a97c
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 //===----------------------------------------------------------------------===//
9 #include "ABISysV_arm.h"
11 #include <optional>
12 #include <vector>
14 #include "llvm/ADT/STLExtras.h"
15 #include "llvm/TargetParser/Triple.h"
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"
31 #include "Plugins/Process/Utility/ARMDefines.h"
32 #include "Utility/ARM_DWARF_Registers.h"
33 #include "Utility/ARM_ehframe_Registers.h"
35 using namespace lldb;
36 using namespace lldb_private;
38 LLDB_PLUGIN_DEFINE(ABISysV_arm)
40 static const RegisterInfo g_register_infos[] = {
41 {"r0",
42 nullptr,
45 eEncodingUint,
46 eFormatHex,
47 {ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM,
48 LLDB_INVALID_REGNUM},
49 nullptr,
50 nullptr,
51 nullptr,
53 {"r1",
54 nullptr,
57 eEncodingUint,
58 eFormatHex,
59 {ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM,
60 LLDB_INVALID_REGNUM},
61 nullptr,
62 nullptr,
63 nullptr,
65 {"r2",
66 nullptr,
69 eEncodingUint,
70 eFormatHex,
71 {ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM,
72 LLDB_INVALID_REGNUM},
73 nullptr,
74 nullptr,
75 nullptr,
77 {"r3",
78 nullptr,
81 eEncodingUint,
82 eFormatHex,
83 {ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM,
84 LLDB_INVALID_REGNUM},
85 nullptr,
86 nullptr,
87 nullptr,
89 {"r4",
90 nullptr,
93 eEncodingUint,
94 eFormatHex,
95 {ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
96 LLDB_INVALID_REGNUM},
97 nullptr,
98 nullptr,
99 nullptr,
101 {"r5",
102 nullptr,
105 eEncodingUint,
106 eFormatHex,
107 {ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
108 LLDB_INVALID_REGNUM},
109 nullptr,
110 nullptr,
111 nullptr,
113 {"r6",
114 nullptr,
117 eEncodingUint,
118 eFormatHex,
119 {ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
120 LLDB_INVALID_REGNUM},
121 nullptr,
122 nullptr,
123 nullptr,
125 {"r7",
126 nullptr,
129 eEncodingUint,
130 eFormatHex,
131 {ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
132 LLDB_INVALID_REGNUM},
133 nullptr,
134 nullptr,
135 nullptr,
137 {"r8",
138 nullptr,
141 eEncodingUint,
142 eFormatHex,
143 {ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
144 LLDB_INVALID_REGNUM},
145 nullptr,
146 nullptr,
147 nullptr,
149 {"r9",
150 nullptr,
153 eEncodingUint,
154 eFormatHex,
155 {ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
156 LLDB_INVALID_REGNUM},
157 nullptr,
158 nullptr,
159 nullptr,
161 {"r10",
162 nullptr,
165 eEncodingUint,
166 eFormatHex,
167 {ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
168 LLDB_INVALID_REGNUM},
169 nullptr,
170 nullptr,
171 nullptr,
173 {"r11",
174 nullptr,
177 eEncodingUint,
178 eFormatHex,
179 {ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
180 LLDB_INVALID_REGNUM},
181 nullptr,
182 nullptr,
183 nullptr,
185 {"r12",
186 nullptr,
189 eEncodingUint,
190 eFormatHex,
191 {ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
192 LLDB_INVALID_REGNUM},
193 nullptr,
194 nullptr,
195 nullptr,
197 {"sp",
198 "r13",
201 eEncodingUint,
202 eFormatHex,
203 {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
204 LLDB_INVALID_REGNUM},
205 nullptr,
206 nullptr,
207 nullptr,
209 {"lr",
210 "r14",
213 eEncodingUint,
214 eFormatHex,
215 {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM,
216 LLDB_INVALID_REGNUM},
217 nullptr,
218 nullptr,
219 nullptr,
221 {"pc",
222 "r15",
225 eEncodingUint,
226 eFormatHex,
227 {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
228 LLDB_INVALID_REGNUM},
229 nullptr,
230 nullptr,
231 nullptr,
233 {"cpsr",
234 "psr",
237 eEncodingUint,
238 eFormatHex,
239 {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM,
240 LLDB_INVALID_REGNUM},
241 nullptr,
242 nullptr,
243 nullptr,
245 {"s0",
246 nullptr,
249 eEncodingIEEE754,
250 eFormatFloat,
251 {LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
252 LLDB_INVALID_REGNUM},
253 nullptr,
254 nullptr,
255 nullptr,
257 {"s1",
258 nullptr,
261 eEncodingIEEE754,
262 eFormatFloat,
263 {LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
264 LLDB_INVALID_REGNUM},
265 nullptr,
266 nullptr,
267 nullptr,
269 {"s2",
270 nullptr,
273 eEncodingIEEE754,
274 eFormatFloat,
275 {LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
276 LLDB_INVALID_REGNUM},
277 nullptr,
278 nullptr,
279 nullptr,
281 {"s3",
282 nullptr,
285 eEncodingIEEE754,
286 eFormatFloat,
287 {LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
288 LLDB_INVALID_REGNUM},
289 nullptr,
290 nullptr,
291 nullptr,
293 {"s4",
294 nullptr,
297 eEncodingIEEE754,
298 eFormatFloat,
299 {LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
300 LLDB_INVALID_REGNUM},
301 nullptr,
302 nullptr,
303 nullptr,
305 {"s5",
306 nullptr,
309 eEncodingIEEE754,
310 eFormatFloat,
311 {LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
312 LLDB_INVALID_REGNUM},
313 nullptr,
314 nullptr,
315 nullptr,
317 {"s6",
318 nullptr,
321 eEncodingIEEE754,
322 eFormatFloat,
323 {LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
324 LLDB_INVALID_REGNUM},
325 nullptr,
326 nullptr,
327 nullptr,
329 {"s7",
330 nullptr,
333 eEncodingIEEE754,
334 eFormatFloat,
335 {LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
336 LLDB_INVALID_REGNUM},
337 nullptr,
338 nullptr,
339 nullptr,
341 {"s8",
342 nullptr,
345 eEncodingIEEE754,
346 eFormatFloat,
347 {LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
348 LLDB_INVALID_REGNUM},
349 nullptr,
350 nullptr,
351 nullptr,
353 {"s9",
354 nullptr,
357 eEncodingIEEE754,
358 eFormatFloat,
359 {LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
360 LLDB_INVALID_REGNUM},
361 nullptr,
362 nullptr,
363 nullptr,
365 {"s10",
366 nullptr,
369 eEncodingIEEE754,
370 eFormatFloat,
371 {LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
372 LLDB_INVALID_REGNUM},
373 nullptr,
374 nullptr,
375 nullptr,
377 {"s11",
378 nullptr,
381 eEncodingIEEE754,
382 eFormatFloat,
383 {LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
384 LLDB_INVALID_REGNUM},
385 nullptr,
386 nullptr,
387 nullptr,
389 {"s12",
390 nullptr,
393 eEncodingIEEE754,
394 eFormatFloat,
395 {LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
396 LLDB_INVALID_REGNUM},
397 nullptr,
398 nullptr,
399 nullptr,
401 {"s13",
402 nullptr,
405 eEncodingIEEE754,
406 eFormatFloat,
407 {LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
408 LLDB_INVALID_REGNUM},
409 nullptr,
410 nullptr,
411 nullptr,
413 {"s14",
414 nullptr,
417 eEncodingIEEE754,
418 eFormatFloat,
419 {LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
420 LLDB_INVALID_REGNUM},
421 nullptr,
422 nullptr,
423 nullptr,
425 {"s15",
426 nullptr,
429 eEncodingIEEE754,
430 eFormatFloat,
431 {LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
432 LLDB_INVALID_REGNUM},
433 nullptr,
434 nullptr,
435 nullptr,
437 {"s16",
438 nullptr,
441 eEncodingIEEE754,
442 eFormatFloat,
443 {LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
444 LLDB_INVALID_REGNUM},
445 nullptr,
446 nullptr,
447 nullptr,
449 {"s17",
450 nullptr,
453 eEncodingIEEE754,
454 eFormatFloat,
455 {LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
456 LLDB_INVALID_REGNUM},
457 nullptr,
458 nullptr,
459 nullptr,
461 {"s18",
462 nullptr,
465 eEncodingIEEE754,
466 eFormatFloat,
467 {LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
468 LLDB_INVALID_REGNUM},
469 nullptr,
470 nullptr,
471 nullptr,
473 {"s19",
474 nullptr,
477 eEncodingIEEE754,
478 eFormatFloat,
479 {LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
480 LLDB_INVALID_REGNUM},
481 nullptr,
482 nullptr,
483 nullptr,
485 {"s20",
486 nullptr,
489 eEncodingIEEE754,
490 eFormatFloat,
491 {LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
492 LLDB_INVALID_REGNUM},
493 nullptr,
494 nullptr,
495 nullptr,
497 {"s21",
498 nullptr,
501 eEncodingIEEE754,
502 eFormatFloat,
503 {LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
504 LLDB_INVALID_REGNUM},
505 nullptr,
506 nullptr,
507 nullptr,
509 {"s22",
510 nullptr,
513 eEncodingIEEE754,
514 eFormatFloat,
515 {LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
516 LLDB_INVALID_REGNUM},
517 nullptr,
518 nullptr,
519 nullptr,
521 {"s23",
522 nullptr,
525 eEncodingIEEE754,
526 eFormatFloat,
527 {LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
528 LLDB_INVALID_REGNUM},
529 nullptr,
530 nullptr,
531 nullptr,
533 {"s24",
534 nullptr,
537 eEncodingIEEE754,
538 eFormatFloat,
539 {LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
540 LLDB_INVALID_REGNUM},
541 nullptr,
542 nullptr,
543 nullptr,
545 {"s25",
546 nullptr,
549 eEncodingIEEE754,
550 eFormatFloat,
551 {LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
552 LLDB_INVALID_REGNUM},
553 nullptr,
554 nullptr,
555 nullptr,
557 {"s26",
558 nullptr,
561 eEncodingIEEE754,
562 eFormatFloat,
563 {LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
564 LLDB_INVALID_REGNUM},
565 nullptr,
566 nullptr,
567 nullptr,
569 {"s27",
570 nullptr,
573 eEncodingIEEE754,
574 eFormatFloat,
575 {LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
576 LLDB_INVALID_REGNUM},
577 nullptr,
578 nullptr,
579 nullptr,
581 {"s28",
582 nullptr,
585 eEncodingIEEE754,
586 eFormatFloat,
587 {LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
588 LLDB_INVALID_REGNUM},
589 nullptr,
590 nullptr,
591 nullptr,
593 {"s29",
594 nullptr,
597 eEncodingIEEE754,
598 eFormatFloat,
599 {LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
600 LLDB_INVALID_REGNUM},
601 nullptr,
602 nullptr,
603 nullptr,
605 {"s30",
606 nullptr,
609 eEncodingIEEE754,
610 eFormatFloat,
611 {LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
612 LLDB_INVALID_REGNUM},
613 nullptr,
614 nullptr,
615 nullptr,
617 {"s31",
618 nullptr,
621 eEncodingIEEE754,
622 eFormatFloat,
623 {LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
624 LLDB_INVALID_REGNUM},
625 nullptr,
626 nullptr,
627 nullptr,
629 {"fpscr",
630 nullptr,
633 eEncodingUint,
634 eFormatHex,
635 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
636 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
637 nullptr,
638 nullptr,
639 nullptr,
641 {"d0",
642 nullptr,
645 eEncodingIEEE754,
646 eFormatFloat,
647 {LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
648 LLDB_INVALID_REGNUM},
649 nullptr,
650 nullptr,
651 nullptr,
653 {"d1",
654 nullptr,
657 eEncodingIEEE754,
658 eFormatFloat,
659 {LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
660 LLDB_INVALID_REGNUM},
661 nullptr,
662 nullptr,
663 nullptr,
665 {"d2",
666 nullptr,
669 eEncodingIEEE754,
670 eFormatFloat,
671 {LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
672 LLDB_INVALID_REGNUM},
673 nullptr,
674 nullptr,
675 nullptr,
677 {"d3",
678 nullptr,
681 eEncodingIEEE754,
682 eFormatFloat,
683 {LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
684 LLDB_INVALID_REGNUM},
685 nullptr,
686 nullptr,
687 nullptr,
689 {"d4",
690 nullptr,
693 eEncodingIEEE754,
694 eFormatFloat,
695 {LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
696 LLDB_INVALID_REGNUM},
697 nullptr,
698 nullptr,
699 nullptr,
701 {"d5",
702 nullptr,
705 eEncodingIEEE754,
706 eFormatFloat,
707 {LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
708 LLDB_INVALID_REGNUM},
709 nullptr,
710 nullptr,
711 nullptr,
713 {"d6",
714 nullptr,
717 eEncodingIEEE754,
718 eFormatFloat,
719 {LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
720 LLDB_INVALID_REGNUM},
721 nullptr,
722 nullptr,
723 nullptr,
725 {"d7",
726 nullptr,
729 eEncodingIEEE754,
730 eFormatFloat,
731 {LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
732 LLDB_INVALID_REGNUM},
733 nullptr,
734 nullptr,
735 nullptr,
737 {"d8",
738 nullptr,
741 eEncodingIEEE754,
742 eFormatFloat,
743 {LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
744 LLDB_INVALID_REGNUM},
745 nullptr,
746 nullptr,
747 nullptr,
749 {"d9",
750 nullptr,
753 eEncodingIEEE754,
754 eFormatFloat,
755 {LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
756 LLDB_INVALID_REGNUM},
757 nullptr,
758 nullptr,
759 nullptr,
761 {"d10",
762 nullptr,
765 eEncodingIEEE754,
766 eFormatFloat,
767 {LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
768 LLDB_INVALID_REGNUM},
769 nullptr,
770 nullptr,
771 nullptr,
773 {"d11",
774 nullptr,
777 eEncodingIEEE754,
778 eFormatFloat,
779 {LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
780 LLDB_INVALID_REGNUM},
781 nullptr,
782 nullptr,
783 nullptr,
785 {"d12",
786 nullptr,
789 eEncodingIEEE754,
790 eFormatFloat,
791 {LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
792 LLDB_INVALID_REGNUM},
793 nullptr,
794 nullptr,
795 nullptr,
797 {"d13",
798 nullptr,
801 eEncodingIEEE754,
802 eFormatFloat,
803 {LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
804 LLDB_INVALID_REGNUM},
805 nullptr,
806 nullptr,
807 nullptr,
809 {"d14",
810 nullptr,
813 eEncodingIEEE754,
814 eFormatFloat,
815 {LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
816 LLDB_INVALID_REGNUM},
817 nullptr,
818 nullptr,
819 nullptr,
821 {"d15",
822 nullptr,
825 eEncodingIEEE754,
826 eFormatFloat,
827 {LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
828 LLDB_INVALID_REGNUM},
829 nullptr,
830 nullptr,
831 nullptr,
833 {"d16",
834 nullptr,
837 eEncodingIEEE754,
838 eFormatFloat,
839 {LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
840 LLDB_INVALID_REGNUM},
841 nullptr,
842 nullptr,
843 nullptr,
845 {"d17",
846 nullptr,
849 eEncodingIEEE754,
850 eFormatFloat,
851 {LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
852 LLDB_INVALID_REGNUM},
853 nullptr,
854 nullptr,
855 nullptr,
857 {"d18",
858 nullptr,
861 eEncodingIEEE754,
862 eFormatFloat,
863 {LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
864 LLDB_INVALID_REGNUM},
865 nullptr,
866 nullptr,
867 nullptr,
869 {"d19",
870 nullptr,
873 eEncodingIEEE754,
874 eFormatFloat,
875 {LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
876 LLDB_INVALID_REGNUM},
877 nullptr,
878 nullptr,
879 nullptr,
881 {"d20",
882 nullptr,
885 eEncodingIEEE754,
886 eFormatFloat,
887 {LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
888 LLDB_INVALID_REGNUM},
889 nullptr,
890 nullptr,
891 nullptr,
893 {"d21",
894 nullptr,
897 eEncodingIEEE754,
898 eFormatFloat,
899 {LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
900 LLDB_INVALID_REGNUM},
901 nullptr,
902 nullptr,
903 nullptr,
905 {"d22",
906 nullptr,
909 eEncodingIEEE754,
910 eFormatFloat,
911 {LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
912 LLDB_INVALID_REGNUM},
913 nullptr,
914 nullptr,
915 nullptr,
917 {"d23",
918 nullptr,
921 eEncodingIEEE754,
922 eFormatFloat,
923 {LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
924 LLDB_INVALID_REGNUM},
925 nullptr,
926 nullptr,
927 nullptr,
929 {"d24",
930 nullptr,
933 eEncodingIEEE754,
934 eFormatFloat,
935 {LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
936 LLDB_INVALID_REGNUM},
937 nullptr,
938 nullptr,
939 nullptr,
941 {"d25",
942 nullptr,
945 eEncodingIEEE754,
946 eFormatFloat,
947 {LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
948 LLDB_INVALID_REGNUM},
949 nullptr,
950 nullptr,
951 nullptr,
953 {"d26",
954 nullptr,
957 eEncodingIEEE754,
958 eFormatFloat,
959 {LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
960 LLDB_INVALID_REGNUM},
961 nullptr,
962 nullptr,
963 nullptr,
965 {"d27",
966 nullptr,
969 eEncodingIEEE754,
970 eFormatFloat,
971 {LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
972 LLDB_INVALID_REGNUM},
973 nullptr,
974 nullptr,
975 nullptr,
977 {"d28",
978 nullptr,
981 eEncodingIEEE754,
982 eFormatFloat,
983 {LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
984 LLDB_INVALID_REGNUM},
985 nullptr,
986 nullptr,
987 nullptr,
989 {"d29",
990 nullptr,
993 eEncodingIEEE754,
994 eFormatFloat,
995 {LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
996 LLDB_INVALID_REGNUM},
997 nullptr,
998 nullptr,
999 nullptr,
1001 {"d30",
1002 nullptr,
1005 eEncodingIEEE754,
1006 eFormatFloat,
1007 {LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1008 LLDB_INVALID_REGNUM},
1009 nullptr,
1010 nullptr,
1011 nullptr,
1013 {"d31",
1014 nullptr,
1017 eEncodingIEEE754,
1018 eFormatFloat,
1019 {LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1020 LLDB_INVALID_REGNUM},
1021 nullptr,
1022 nullptr,
1023 nullptr,
1025 {"r8_usr",
1026 nullptr,
1029 eEncodingUint,
1030 eFormatHex,
1031 {LLDB_INVALID_REGNUM, dwarf_r8_usr, LLDB_INVALID_REGNUM,
1032 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1033 nullptr,
1034 nullptr,
1035 nullptr,
1037 {"r9_usr",
1038 nullptr,
1041 eEncodingUint,
1042 eFormatHex,
1043 {LLDB_INVALID_REGNUM, dwarf_r9_usr, LLDB_INVALID_REGNUM,
1044 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1045 nullptr,
1046 nullptr,
1047 nullptr,
1049 {"r10_usr",
1050 nullptr,
1053 eEncodingUint,
1054 eFormatHex,
1055 {LLDB_INVALID_REGNUM, dwarf_r10_usr, LLDB_INVALID_REGNUM,
1056 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1057 nullptr,
1058 nullptr,
1059 nullptr,
1061 {"r11_usr",
1062 nullptr,
1065 eEncodingUint,
1066 eFormatHex,
1067 {LLDB_INVALID_REGNUM, dwarf_r11_usr, LLDB_INVALID_REGNUM,
1068 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1069 nullptr,
1070 nullptr,
1071 nullptr,
1073 {"r12_usr",
1074 nullptr,
1077 eEncodingUint,
1078 eFormatHex,
1079 {LLDB_INVALID_REGNUM, dwarf_r12_usr, LLDB_INVALID_REGNUM,
1080 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1081 nullptr,
1082 nullptr,
1083 nullptr,
1085 {"r13_usr",
1086 "sp_usr",
1089 eEncodingUint,
1090 eFormatHex,
1091 {LLDB_INVALID_REGNUM, dwarf_r13_usr, LLDB_INVALID_REGNUM,
1092 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1093 nullptr,
1094 nullptr,
1095 nullptr,
1097 {"r14_usr",
1098 "lr_usr",
1101 eEncodingUint,
1102 eFormatHex,
1103 {LLDB_INVALID_REGNUM, dwarf_r14_usr, LLDB_INVALID_REGNUM,
1104 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1105 nullptr,
1106 nullptr,
1107 nullptr,
1109 {"r8_fiq",
1110 nullptr,
1113 eEncodingUint,
1114 eFormatHex,
1115 {LLDB_INVALID_REGNUM, dwarf_r8_fiq, LLDB_INVALID_REGNUM,
1116 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1117 nullptr,
1118 nullptr,
1119 nullptr,
1121 {"r9_fiq",
1122 nullptr,
1125 eEncodingUint,
1126 eFormatHex,
1127 {LLDB_INVALID_REGNUM, dwarf_r9_fiq, LLDB_INVALID_REGNUM,
1128 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1129 nullptr,
1130 nullptr,
1131 nullptr,
1133 {"r10_fiq",
1134 nullptr,
1137 eEncodingUint,
1138 eFormatHex,
1139 {LLDB_INVALID_REGNUM, dwarf_r10_fiq, LLDB_INVALID_REGNUM,
1140 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1141 nullptr,
1142 nullptr,
1143 nullptr,
1145 {"r11_fiq",
1146 nullptr,
1149 eEncodingUint,
1150 eFormatHex,
1151 {LLDB_INVALID_REGNUM, dwarf_r11_fiq, LLDB_INVALID_REGNUM,
1152 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1153 nullptr,
1154 nullptr,
1155 nullptr,
1157 {"r12_fiq",
1158 nullptr,
1161 eEncodingUint,
1162 eFormatHex,
1163 {LLDB_INVALID_REGNUM, dwarf_r12_fiq, LLDB_INVALID_REGNUM,
1164 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1165 nullptr,
1166 nullptr,
1167 nullptr,
1169 {"r13_fiq",
1170 "sp_fiq",
1173 eEncodingUint,
1174 eFormatHex,
1175 {LLDB_INVALID_REGNUM, dwarf_r13_fiq, LLDB_INVALID_REGNUM,
1176 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1177 nullptr,
1178 nullptr,
1179 nullptr,
1181 {"r14_fiq",
1182 "lr_fiq",
1185 eEncodingUint,
1186 eFormatHex,
1187 {LLDB_INVALID_REGNUM, dwarf_r14_fiq, LLDB_INVALID_REGNUM,
1188 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1189 nullptr,
1190 nullptr,
1191 nullptr,
1193 {"r13_irq",
1194 "sp_irq",
1197 eEncodingUint,
1198 eFormatHex,
1199 {LLDB_INVALID_REGNUM, dwarf_r13_irq, LLDB_INVALID_REGNUM,
1200 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1201 nullptr,
1202 nullptr,
1203 nullptr,
1205 {"r14_irq",
1206 "lr_irq",
1209 eEncodingUint,
1210 eFormatHex,
1211 {LLDB_INVALID_REGNUM, dwarf_r14_irq, LLDB_INVALID_REGNUM,
1212 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1213 nullptr,
1214 nullptr,
1215 nullptr,
1217 {"r13_abt",
1218 "sp_abt",
1221 eEncodingUint,
1222 eFormatHex,
1223 {LLDB_INVALID_REGNUM, dwarf_r13_abt, LLDB_INVALID_REGNUM,
1224 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1225 nullptr,
1226 nullptr,
1227 nullptr,
1229 {"r14_abt",
1230 "lr_abt",
1233 eEncodingUint,
1234 eFormatHex,
1235 {LLDB_INVALID_REGNUM, dwarf_r14_abt, LLDB_INVALID_REGNUM,
1236 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1237 nullptr,
1238 nullptr,
1239 nullptr,
1241 {"r13_und",
1242 "sp_und",
1245 eEncodingUint,
1246 eFormatHex,
1247 {LLDB_INVALID_REGNUM, dwarf_r13_und, LLDB_INVALID_REGNUM,
1248 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1249 nullptr,
1250 nullptr,
1251 nullptr,
1253 {"r14_und",
1254 "lr_und",
1257 eEncodingUint,
1258 eFormatHex,
1259 {LLDB_INVALID_REGNUM, dwarf_r14_und, LLDB_INVALID_REGNUM,
1260 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1261 nullptr,
1262 nullptr,
1263 nullptr,
1266 {"r13_svc",
1267 "sp_svc",
1270 eEncodingUint,
1271 eFormatHex,
1272 {LLDB_INVALID_REGNUM, dwarf_r13_svc, LLDB_INVALID_REGNUM,
1273 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1274 nullptr,
1275 nullptr,
1276 nullptr,
1278 {"r14_svc",
1279 "lr_svc",
1282 eEncodingUint,
1283 eFormatHex,
1284 {LLDB_INVALID_REGNUM, dwarf_r14_svc, LLDB_INVALID_REGNUM,
1285 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1286 nullptr,
1287 nullptr,
1288 nullptr,
1291 static const uint32_t k_num_register_infos = std::size(g_register_infos);
1293 const lldb_private::RegisterInfo *
1294 ABISysV_arm::GetRegisterInfoArray(uint32_t &count) {
1295 count = k_num_register_infos;
1296 return g_register_infos;
1299 size_t ABISysV_arm::GetRedZoneSize() const { return 0; }
1301 // Static Functions
1303 ABISP
1304 ABISysV_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();
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)));
1316 return ABISP();
1319 bool 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;
1326 const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1327 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
1328 const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1329 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
1330 const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1331 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
1333 RegisterValue reg_value;
1335 const uint8_t reg_names[] = {
1336 LLDB_REGNUM_GENERIC_ARG1, LLDB_REGNUM_GENERIC_ARG2,
1337 LLDB_REGNUM_GENERIC_ARG3, LLDB_REGNUM_GENERIC_ARG4};
1339 llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end();
1341 for (size_t i = 0; i < std::size(reg_names); ++i) {
1342 if (ai == ae)
1343 break;
1345 reg_value.SetUInt32(*ai);
1346 if (!reg_ctx->WriteRegister(
1347 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, reg_names[i]),
1348 reg_value))
1349 return false;
1351 ++ai;
1354 if (ai != ae) {
1355 // Spill onto the stack
1356 size_t num_stack_regs = ae - ai;
1358 sp -= (num_stack_regs * 4);
1359 // Keep the stack 8 byte aligned, not that we need to
1360 sp &= ~(8ull - 1ull);
1362 // just using arg1 to get the right size
1363 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
1364 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
1366 addr_t arg_pos = sp;
1368 for (; ai != ae; ++ai) {
1369 reg_value.SetUInt32(*ai);
1370 if (reg_ctx
1371 ->WriteRegisterValueToMemory(reg_info, arg_pos,
1372 reg_info->byte_size, reg_value)
1373 .Fail())
1374 return false;
1375 arg_pos += reg_info->byte_size;
1379 TargetSP target_sp(thread.CalculateTarget());
1380 Address so_addr;
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(return_addr, target_sp.get());
1386 return_addr = so_addr.GetCallableLoadAddress(target_sp.get());
1388 // Set "lr" to the return address
1389 if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_num, return_addr))
1390 return false;
1392 // Set "sp" to the requested value
1393 if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_num, sp))
1394 return false;
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(function_addr, target_sp.get());
1399 function_addr = so_addr.GetCallableLoadAddress(target_sp.get());
1401 const RegisterInfo *cpsr_reg_info =
1402 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
1403 const uint32_t curr_cpsr = reg_ctx->ReadRegisterAsUnsigned(cpsr_reg_info, 0);
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
1413 if (new_cpsr != curr_cpsr) {
1414 if (!reg_ctx->WriteRegisterFromUnsigned(cpsr_reg_info, new_cpsr))
1415 return false;
1418 function_addr &=
1419 ~1ull; // clear bit zero since the CPSR will take care of the mode for us
1421 // Set "pc" to the address requested
1422 return reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, function_addr);
1425 bool ABISysV_arm::GetArgumentValues(Thread &thread, ValueList &values) const {
1426 uint32_t num_values = values.GetSize();
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.
1432 // Extract the register context so we can read arguments from registers
1434 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1436 if (!reg_ctx)
1437 return false;
1439 addr_t sp = 0;
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(value_idx);
1446 if (!value)
1447 return false;
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 = compiler_type.GetBitSize(&thread))
1456 bit_width = *size;
1457 } else {
1458 // We only handle integer, pointer and reference types currently...
1459 return false;
1462 if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) {
1463 if (value_idx < 4) {
1464 // Arguments 1-4 are in r0-r3...
1465 const RegisterInfo *arg_reg_info = nullptr;
1466 arg_reg_info = reg_ctx->GetRegisterInfo(
1467 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
1468 if (arg_reg_info) {
1469 RegisterValue reg_value;
1471 if (reg_ctx->ReadRegister(arg_reg_info, reg_value)) {
1472 if (is_signed)
1473 reg_value.SignExtend(bit_width);
1474 if (!reg_value.GetScalarValue(value->GetScalar()))
1475 return false;
1476 continue;
1479 return false;
1480 } else {
1481 if (sp == 0) {
1482 // Read the stack pointer if it already hasn't been read
1483 sp = reg_ctx->GetSP(0);
1484 if (sp == 0)
1485 return false;
1488 // Arguments 5 on up are on the stack
1489 const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8;
1490 Status error;
1491 if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory(
1492 sp, arg_byte_size, is_signed, value->GetScalar(), error))
1493 return false;
1495 sp += arg_byte_size;
1500 return true;
1503 static bool GetReturnValuePassedInMemory(Thread &thread,
1504 RegisterContext *reg_ctx,
1505 size_t byte_size, Value &value) {
1506 Status error;
1507 DataBufferHeap buffer(byte_size, 0);
1509 const RegisterInfo *r0_reg_info =
1510 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
1511 uint32_t address =
1512 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1513 thread.GetProcess()->ReadMemory(address, buffer.GetBytes(),
1514 buffer.GetByteSize(), error);
1516 if (error.Fail())
1517 return false;
1519 value.SetBytes(buffer.GetBytes(), buffer.GetByteSize());
1520 return true;
1523 bool ABISysV_arm::IsArmHardFloat(Thread &thread) const {
1524 ProcessSP process_sp(thread.GetProcess());
1525 if (process_sp) {
1526 const ArchSpec &arch(process_sp->GetTarget().GetArchitecture());
1528 return (arch.GetFlags() & ArchSpec::eARM_abi_hard_float) != 0;
1531 return false;
1534 ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl(
1535 Thread &thread, lldb_private::CompilerType &compiler_type) const {
1536 Value value;
1537 ValueObjectSP return_valobj_sp;
1539 if (!compiler_type)
1540 return return_valobj_sp;
1542 // value.SetContext (Value::eContextTypeClangType,
1543 // compiler_type.GetOpaqueQualType());
1544 value.SetCompilerType(compiler_type);
1546 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1547 if (!reg_ctx)
1548 return return_valobj_sp;
1550 bool is_signed;
1551 bool is_complex;
1552 uint32_t float_count;
1553 bool is_vfp_candidate = false;
1554 uint8_t vfp_count = 0;
1555 uint8_t vfp_byte_size = 0;
1557 // Get the pointer to the first stack argument so we have a place to start
1558 // when reading data
1560 const RegisterInfo *r0_reg_info =
1561 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
1562 std::optional<uint64_t> bit_width = compiler_type.GetBitSize(&thread);
1563 std::optional<uint64_t> byte_size = compiler_type.GetByteSize(&thread);
1564 if (!bit_width || !byte_size)
1565 return return_valobj_sp;
1567 if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
1568 switch (*bit_width) {
1569 default:
1570 return return_valobj_sp;
1571 case 64: {
1572 const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo(
1573 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
1574 uint64_t raw_value;
1575 raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1576 raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) &
1577 UINT32_MAX))
1578 << 32;
1579 if (is_signed)
1580 value.GetScalar() = (int64_t)raw_value;
1581 else
1582 value.GetScalar() = (uint64_t)raw_value;
1583 } break;
1584 case 32:
1585 if (is_signed)
1586 value.GetScalar() = (int32_t)(
1587 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
1588 else
1589 value.GetScalar() = (uint32_t)(
1590 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
1591 break;
1592 case 16:
1593 if (is_signed)
1594 value.GetScalar() = (int16_t)(
1595 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
1596 else
1597 value.GetScalar() = (uint16_t)(
1598 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
1599 break;
1600 case 8:
1601 if (is_signed)
1602 value.GetScalar() = (int8_t)(
1603 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
1604 else
1605 value.GetScalar() = (uint8_t)(
1606 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
1607 break;
1609 } else if (compiler_type.IsPointerType()) {
1610 uint32_t ptr =
1611 thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) &
1612 UINT32_MAX;
1613 value.GetScalar() = ptr;
1614 } else if (compiler_type.IsVectorType()) {
1615 if (IsArmHardFloat(thread) && (*byte_size == 8 || *byte_size == 16)) {
1616 is_vfp_candidate = true;
1617 vfp_byte_size = 8;
1618 vfp_count = (*byte_size == 8 ? 1 : 2);
1619 } else if (*byte_size <= 16) {
1620 DataBufferHeap buffer(16, 0);
1621 uint32_t *buffer_ptr = (uint32_t *)buffer.GetBytes();
1623 for (uint32_t i = 0; 4 * i < *byte_size; ++i) {
1624 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
1625 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
1626 buffer_ptr[i] =
1627 reg_ctx->ReadRegisterAsUnsigned(reg_info, 0) & UINT32_MAX;
1629 value.SetBytes(buffer.GetBytes(), *byte_size);
1630 } else {
1631 if (!GetReturnValuePassedInMemory(thread, reg_ctx, *byte_size, value))
1632 return return_valobj_sp;
1634 } else if (compiler_type.IsFloatingPointType(float_count, is_complex)) {
1635 if (float_count == 1 && !is_complex) {
1636 switch (*bit_width) {
1637 default:
1638 return return_valobj_sp;
1639 case 64: {
1640 static_assert(sizeof(double) == sizeof(uint64_t));
1642 if (IsArmHardFloat(thread)) {
1643 RegisterValue reg_value;
1644 const RegisterInfo *d0_reg_info =
1645 reg_ctx->GetRegisterInfoByName("d0", 0);
1646 reg_ctx->ReadRegister(d0_reg_info, reg_value);
1647 value.GetScalar() = reg_value.GetAsDouble();
1648 } else {
1649 uint64_t raw_value;
1650 const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo(
1651 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
1652 raw_value =
1653 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1654 raw_value |=
1655 ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) &
1656 UINT32_MAX))
1657 << 32;
1658 value.GetScalar() = *reinterpret_cast<double *>(&raw_value);
1660 break;
1662 case 16: // Half precision returned after a conversion to single precision
1663 case 32: {
1664 static_assert(sizeof(float) == sizeof(uint32_t));
1666 if (IsArmHardFloat(thread)) {
1667 RegisterValue reg_value;
1668 const RegisterInfo *s0_reg_info =
1669 reg_ctx->GetRegisterInfoByName("s0", 0);
1670 reg_ctx->ReadRegister(s0_reg_info, reg_value);
1671 value.GetScalar() = reg_value.GetAsFloat();
1672 } else {
1673 uint32_t raw_value;
1674 raw_value =
1675 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1676 value.GetScalar() = *reinterpret_cast<float *>(&raw_value);
1678 break;
1681 } else if (is_complex && float_count == 2) {
1682 if (IsArmHardFloat(thread)) {
1683 is_vfp_candidate = true;
1684 vfp_byte_size = *byte_size / 2;
1685 vfp_count = 2;
1686 } else if (!GetReturnValuePassedInMemory(thread, reg_ctx, *bit_width / 8,
1687 value))
1688 return return_valobj_sp;
1689 } else
1690 // not handled yet
1691 return return_valobj_sp;
1692 } else if (compiler_type.IsAggregateType()) {
1693 if (IsArmHardFloat(thread)) {
1694 CompilerType base_type;
1695 const uint32_t homogeneous_count =
1696 compiler_type.IsHomogeneousAggregate(&base_type);
1698 if (homogeneous_count > 0 && homogeneous_count <= 4) {
1699 std::optional<uint64_t> base_byte_size = base_type.GetByteSize(&thread);
1700 if (base_type.IsVectorType()) {
1701 if (base_byte_size &&
1702 (*base_byte_size == 8 || *base_byte_size == 16)) {
1703 is_vfp_candidate = true;
1704 vfp_byte_size = 8;
1705 vfp_count = (*base_byte_size == 8 ? homogeneous_count
1706 : homogeneous_count * 2);
1708 } else if (base_type.IsFloatingPointType(float_count, is_complex)) {
1709 if (float_count == 1 && !is_complex) {
1710 is_vfp_candidate = true;
1711 if (base_byte_size)
1712 vfp_byte_size = *base_byte_size;
1713 vfp_count = homogeneous_count;
1716 } else if (homogeneous_count == 0) {
1717 const uint32_t num_children = compiler_type.GetNumFields();
1719 if (num_children > 0 && num_children <= 2) {
1720 uint32_t index = 0;
1721 for (index = 0; index < num_children; index++) {
1722 std::string name;
1723 base_type = compiler_type.GetFieldAtIndex(index, name, nullptr,
1724 nullptr, nullptr);
1726 if (base_type.IsFloatingPointType(float_count, is_complex)) {
1727 std::optional<uint64_t> base_byte_size =
1728 base_type.GetByteSize(&thread);
1729 if (float_count == 2 && is_complex) {
1730 if (index != 0 && base_byte_size &&
1731 vfp_byte_size != *base_byte_size)
1732 break;
1733 else if (base_byte_size)
1734 vfp_byte_size = *base_byte_size;
1735 } else
1736 break;
1737 } else
1738 break;
1741 if (index == num_children) {
1742 is_vfp_candidate = true;
1743 vfp_byte_size = (vfp_byte_size >> 1);
1744 vfp_count = (num_children << 1);
1750 if (*byte_size <= 4) {
1751 RegisterValue r0_reg_value;
1752 uint32_t raw_value =
1753 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1754 value.SetBytes(&raw_value, *byte_size);
1755 } else if (!is_vfp_candidate) {
1756 if (!GetReturnValuePassedInMemory(thread, reg_ctx, *byte_size, value))
1757 return return_valobj_sp;
1759 } else {
1760 // not handled yet
1761 return return_valobj_sp;
1764 if (is_vfp_candidate) {
1765 ProcessSP process_sp(thread.GetProcess());
1766 ByteOrder byte_order = process_sp->GetByteOrder();
1768 WritableDataBufferSP data_sp(new DataBufferHeap(*byte_size, 0));
1769 uint32_t data_offset = 0;
1771 for (uint32_t reg_index = 0; reg_index < vfp_count; reg_index++) {
1772 uint32_t regnum = 0;
1774 if (vfp_byte_size == 4)
1775 regnum = dwarf_s0 + reg_index;
1776 else if (vfp_byte_size == 8)
1777 regnum = dwarf_d0 + reg_index;
1778 else
1779 break;
1781 const RegisterInfo *reg_info =
1782 reg_ctx->GetRegisterInfo(eRegisterKindDWARF, regnum);
1783 if (reg_info == nullptr)
1784 break;
1786 RegisterValue reg_value;
1787 if (!reg_ctx->ReadRegister(reg_info, reg_value))
1788 break;
1790 // Make sure we have enough room in "data_sp"
1791 if ((data_offset + vfp_byte_size) <= data_sp->GetByteSize()) {
1792 Status error;
1793 const size_t bytes_copied = reg_value.GetAsMemoryData(
1794 *reg_info, data_sp->GetBytes() + data_offset, vfp_byte_size,
1795 byte_order, error);
1796 if (bytes_copied != vfp_byte_size)
1797 break;
1799 data_offset += bytes_copied;
1803 if (data_offset == *byte_size) {
1804 DataExtractor data;
1805 data.SetByteOrder(byte_order);
1806 data.SetAddressByteSize(process_sp->GetAddressByteSize());
1807 data.SetData(data_sp);
1809 return ValueObjectConstResult::Create(&thread, compiler_type,
1810 ConstString(""), data);
1811 } else { // Some error occurred while getting values from registers
1812 return return_valobj_sp;
1816 // If we get here, we have a valid Value, so make our ValueObject out of it:
1818 return_valobj_sp = ValueObjectConstResult::Create(
1819 thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
1820 return return_valobj_sp;
1823 Status ABISysV_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
1824 lldb::ValueObjectSP &new_value_sp) {
1825 Status error;
1826 if (!new_value_sp) {
1827 error = Status::FromErrorString("Empty value object for return value.");
1828 return error;
1831 CompilerType compiler_type = new_value_sp->GetCompilerType();
1832 if (!compiler_type) {
1833 error = Status::FromErrorString("Null clang type for return value.");
1834 return error;
1837 Thread *thread = frame_sp->GetThread().get();
1839 bool is_signed;
1840 uint32_t count;
1841 bool is_complex;
1843 RegisterContext *reg_ctx = thread->GetRegisterContext().get();
1845 bool set_it_simple = false;
1846 if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1847 compiler_type.IsPointerType()) {
1848 DataExtractor data;
1849 Status data_error;
1850 size_t num_bytes = new_value_sp->GetData(data, data_error);
1851 if (data_error.Fail()) {
1852 error = Status::FromErrorStringWithFormat(
1853 "Couldn't convert return value to raw data: %s",
1854 data_error.AsCString());
1855 return error;
1857 lldb::offset_t offset = 0;
1858 if (num_bytes <= 8) {
1859 const RegisterInfo *r0_info = reg_ctx->GetRegisterInfo(
1860 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
1861 if (num_bytes <= 4) {
1862 uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
1864 if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value))
1865 set_it_simple = true;
1866 } else {
1867 uint32_t raw_value = data.GetMaxU32(&offset, 4);
1869 if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value)) {
1870 const RegisterInfo *r1_info = reg_ctx->GetRegisterInfo(
1871 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
1872 uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
1874 if (reg_ctx->WriteRegisterFromUnsigned(r1_info, raw_value))
1875 set_it_simple = true;
1878 } else {
1879 error = Status::FromErrorString(
1880 "We don't support returning longer than 64 bit "
1881 "integer values at present.");
1883 } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
1884 if (is_complex)
1885 error = Status::FromErrorString(
1886 "We don't support returning complex values at present");
1887 else
1888 error = Status::FromErrorString(
1889 "We don't support returning float values at present");
1892 if (!set_it_simple)
1893 error = Status::FromErrorString(
1894 "We only support setting simple integer return types at present.");
1896 return error;
1899 bool ABISysV_arm::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
1900 unwind_plan.Clear();
1901 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1903 uint32_t lr_reg_num = dwarf_lr;
1904 uint32_t sp_reg_num = dwarf_sp;
1905 uint32_t pc_reg_num = dwarf_pc;
1907 UnwindPlan::RowSP row(new UnwindPlan::Row);
1909 // Our Call Frame Address is the stack pointer value
1910 row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
1912 // The previous PC is in the LR
1913 row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
1914 unwind_plan.AppendRow(row);
1916 // All other registers are the same.
1918 unwind_plan.SetSourceName("arm at-func-entry default");
1919 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1921 return true;
1924 bool ABISysV_arm::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
1925 unwind_plan.Clear();
1926 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1928 // TODO: Handle thumb
1929 uint32_t fp_reg_num = dwarf_r11;
1930 uint32_t pc_reg_num = dwarf_pc;
1932 UnwindPlan::RowSP row(new UnwindPlan::Row);
1933 const int32_t ptr_size = 4;
1935 row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
1936 row->SetOffset(0);
1937 row->SetUnspecifiedRegistersAreUndefined(true);
1939 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
1940 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
1942 unwind_plan.AppendRow(row);
1943 unwind_plan.SetSourceName("arm default unwind plan");
1944 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1945 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1946 unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
1948 return true;
1951 // cf. "ARMv6 Function Calling Conventions"
1953 // ARMv7 on GNU/Linux general purpose reg rules:
1954 // r0-r3 not preserved (used for argument passing)
1955 // r4-r11 preserved (v1-v8)
1956 // r12 not presrved
1957 // r13 preserved (stack pointer)
1958 // r14 preserved (link register)
1959 // r15 preserved (pc)
1960 // cpsr not preserved (different rules for different bits)
1962 // ARMv7 VFP register rules:
1963 // d0-d7 not preserved (aka s0-s15, q0-q3)
1964 // d8-d15 preserved (aka s16-s31, q4-q7)
1965 // d16-d31 not preserved (aka q8-q15)
1967 bool ABISysV_arm::RegisterIsVolatile(const RegisterInfo *reg_info) {
1968 if (reg_info) {
1969 // Volatile registers are: r0, r1, r2, r3, r9, r12, r13 (aka sp)
1970 const char *name = reg_info->name;
1971 if (name[0] == 'r') {
1972 switch (name[1]) {
1973 case '0':
1974 return name[2] == '\0'; // r0
1975 case '1':
1976 switch (name[2]) {
1977 case '\0':
1978 return true; // r1
1979 case '2':
1980 return name[3] == '\0'; // r12
1981 default:
1982 break;
1984 break;
1986 case '2':
1987 return name[2] == '\0'; // r2
1988 case '3':
1989 return name[2] == '\0'; // r3
1990 default:
1991 break;
1993 } else if (name[0] == 'd') {
1994 switch (name[1]) {
1995 case '0':
1996 return name[2] == '\0'; // d0 is volatile
1998 case '1':
1999 switch (name[2]) {
2000 case '\0':
2001 return true; // d1 is volatile
2002 case '6':
2003 case '7':
2004 case '8':
2005 case '9':
2006 return name[3] == '\0'; // d16 - d19 are volatile
2007 default:
2008 break;
2010 break;
2012 case '2':
2013 switch (name[2]) {
2014 case '\0':
2015 return true; // d2 is volatile
2016 case '0':
2017 case '1':
2018 case '2':
2019 case '3':
2020 case '4':
2021 case '5':
2022 case '6':
2023 case '7':
2024 case '8':
2025 case '9':
2026 return name[3] == '\0'; // d20 - d29 are volatile
2027 default:
2028 break;
2030 break;
2032 case '3':
2033 switch (name[2]) {
2034 case '\0':
2035 return true; // d3 is volatile
2036 case '0':
2037 case '1':
2038 return name[3] == '\0'; // d30 - d31 are volatile
2039 default:
2040 break;
2042 break;
2043 case '4':
2044 case '5':
2045 case '6':
2046 case '7':
2047 return name[2] == '\0'; // d4 - d7 are volatile
2049 default:
2050 break;
2052 } else if (name[0] == 's') {
2053 switch (name[1]) {
2054 case '0':
2055 return name[2] == '\0'; // s0 is volatile
2057 case '1':
2058 switch (name[2]) {
2059 case '\0':
2060 return true; // s1 is volatile
2061 case '0':
2062 case '1':
2063 case '2':
2064 case '3':
2065 case '4':
2066 case '5':
2067 return name[3] == '\0'; // s10 - s15 are volatile
2068 default:
2069 break;
2071 break;
2073 case '2':
2074 case '3':
2075 case '4':
2076 case '5':
2077 case '6':
2078 case '7':
2079 case '8':
2080 case '9':
2081 return name[2] == '\0'; // s2 - s9 are volatile
2083 default:
2084 break;
2086 } else if (name[0] == 'q') {
2087 switch (name[1]) {
2088 case '1':
2089 switch (name[2]) {
2090 case '\0':
2091 return true; // q1 is volatile
2092 case '0':
2093 case '1':
2094 case '2':
2095 case '3':
2096 case '4':
2097 case '5':
2098 return true; // q10-q15 are volatile
2099 default:
2100 return false;
2102 break;
2104 case '0':
2105 case '2':
2106 case '3':
2107 return name[2] == '\0'; // q0-q3 are volatile
2108 case '8':
2109 case '9':
2110 return name[2] == '\0'; // q8-q9 are volatile
2111 default:
2112 break;
2114 } else if (name[0] == 's' && name[1] == 'p' && name[2] == '\0')
2115 return true;
2117 return false;
2120 void ABISysV_arm::Initialize() {
2121 PluginManager::RegisterPlugin(GetPluginNameStatic(),
2122 "SysV ABI for arm targets", CreateInstance);
2125 void ABISysV_arm::Terminate() {
2126 PluginManager::UnregisterPlugin(CreateInstance);