1 //===-- ABISysV_hexagon.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_hexagon.h"
10
11 #include "llvm/ADT/Triple.h"
12 #include "llvm/IR/DerivedTypes.h"
13
14 #include "lldb/Core/Module.h"
15 #include "lldb/Core/PluginManager.h"
16 #include "lldb/Core/Value.h"
17 #include "lldb/Core/ValueObjectConstResult.h"
18 #include "lldb/Core/ValueObjectMemory.h"
19 #include "lldb/Core/ValueObjectRegister.h"
20 #include "lldb/Symbol/UnwindPlan.h"
21 #include "lldb/Target/Process.h"
22 #include "lldb/Target/RegisterContext.h"
23 #include "lldb/Target/StackFrame.h"
24 #include "lldb/Target/Target.h"
25 #include "lldb/Target/Thread.h"
26 #include "lldb/Utility/ConstString.h"
27 #include "lldb/Utility/DataExtractor.h"
28 #include "lldb/Utility/Log.h"
29 #include "lldb/Utility/RegisterValue.h"
30 #include "lldb/Utility/Status.h"
31
32 using namespace lldb;
33 using namespace lldb_private;
34
35 LLDB_PLUGIN_DEFINE_ADV(ABISysV_hexagon, ABIHexagon)
36
37 static const RegisterInfo g_register_infos[] = {
38 // hexagon-core.xml
39 {"r00",
40 "",
41 4,
42 0,
43 eEncodingUint,
44 eFormatAddressInfo,
45 {0, 0, LLDB_INVALID_REGNUM, 0, 0},
46 nullptr,
47 nullptr,
48 nullptr,
49 0},
50 {"r01",
51 "",
52 4,
53 0,
54 eEncodingUint,
55 eFormatAddressInfo,
56 {1, 1, LLDB_INVALID_REGNUM, 1, 1},
57 nullptr,
58 nullptr,
59 nullptr,
60 0},
61 {"r02",
62 "",
63 4,
64 0,
65 eEncodingUint,
66 eFormatAddressInfo,
67 {2, 2, LLDB_INVALID_REGNUM, 2, 2},
68 nullptr,
69 nullptr,
70 nullptr,
71 0},
72 {"r03",
73 "",
74 4,
75 0,
76 eEncodingUint,
77 eFormatAddressInfo,
78 {3, 3, LLDB_INVALID_REGNUM, 3, 3},
79 nullptr,
80 nullptr,
81 nullptr,
82 0},
83 {"r04",
84 "",
85 4,
86 0,
87 eEncodingUint,
88 eFormatAddressInfo,
89 {4, 4, LLDB_INVALID_REGNUM, 4, 4},
90 nullptr,
91 nullptr,
92 nullptr,
93 0},
94 {"r05",
95 "",
96 4,
97 0,
98 eEncodingUint,
99 eFormatAddressInfo,
100 {5, 5, LLDB_INVALID_REGNUM, 5, 5},
101 nullptr,
102 nullptr,
103 nullptr,
104 0},
105 {"r06",
106 "",
107 4,
108 0,
109 eEncodingUint,
110 eFormatAddressInfo,
111 {6, 6, LLDB_INVALID_REGNUM, 6, 6},
112 nullptr,
113 nullptr,
114 nullptr,
115 0},
116 {"r07",
117 "",
118 4,
119 0,
120 eEncodingUint,
121 eFormatAddressInfo,
122 {7, 7, LLDB_INVALID_REGNUM, 7, 7},
123 nullptr,
124 nullptr,
125 nullptr,
126 0},
127 {"r08",
128 "",
129 4,
130 0,
131 eEncodingUint,
132 eFormatAddressInfo,
133 {8, 8, LLDB_INVALID_REGNUM, 8, 8},
134 nullptr,
135 nullptr,
136 nullptr,
137 0},
138 {"r09",
139 "",
140 4,
141 0,
142 eEncodingUint,
143 eFormatAddressInfo,
144 {9, 9, LLDB_INVALID_REGNUM, 9, 9},
145 nullptr,
146 nullptr,
147 nullptr,
148 0},
149 {"r10",
150 "",
151 4,
152 0,
153 eEncodingUint,
154 eFormatAddressInfo,
155 {10, 10, LLDB_INVALID_REGNUM, 10, 10},
156 nullptr,
157 nullptr,
158 nullptr,
159 0},
160 {"r11",
161 "",
162 4,
163 0,
164 eEncodingUint,
165 eFormatAddressInfo,
166 {11, 11, LLDB_INVALID_REGNUM, 11, 11},
167 nullptr,
168 nullptr,
169 nullptr,
170 0},
171 {"r12",
172 "",
173 4,
174 0,
175 eEncodingUint,
176 eFormatAddressInfo,
177 {12, 12, LLDB_INVALID_REGNUM, 12, 12},
178 nullptr,
179 nullptr,
180 nullptr,
181 0},
182 {"r13",
183 "",
184 4,
185 0,
186 eEncodingUint,
187 eFormatAddressInfo,
188 {13, 13, LLDB_INVALID_REGNUM, 13, 13},
189 nullptr,
190 nullptr,
191 nullptr,
192 0},
193 {"r14",
194 "",
195 4,
196 0,
197 eEncodingUint,
198 eFormatAddressInfo,
199 {14, 14, LLDB_INVALID_REGNUM, 14, 14},
200 nullptr,
201 nullptr,
202 nullptr,
203 0},
204 {"r15",
205 "",
206 4,
207 0,
208 eEncodingUint,
209 eFormatAddressInfo,
210 {15, 15, LLDB_INVALID_REGNUM, 15, 15},
211 nullptr,
212 nullptr,
213 nullptr,
214 0},
215 {"r16",
216 "",
217 4,
218 0,
219 eEncodingUint,
220 eFormatAddressInfo,
221 {16, 16, LLDB_INVALID_REGNUM, 16, 16},
222 nullptr,
223 nullptr,
224 nullptr,
225 0},
226 {"r17",
227 "",
228 4,
229 0,
230 eEncodingUint,
231 eFormatAddressInfo,
232 {17, 17, LLDB_INVALID_REGNUM, 17, 17},
233 nullptr,
234 nullptr,
235 nullptr,
236 0},
237 {"r18",
238 "",
239 4,
240 0,
241 eEncodingUint,
242 eFormatAddressInfo,
243 {18, 18, LLDB_INVALID_REGNUM, 18, 18},
244 nullptr,
245 nullptr,
246 nullptr,
247 0},
248 {"r19",
249 "",
250 4,
251 0,
252 eEncodingUint,
253 eFormatAddressInfo,
254 {19, 19, LLDB_INVALID_REGNUM, 19, 19},
255 nullptr,
256 nullptr,
257 nullptr,
258 0},
259 {"r20",
260 "",
261 4,
262 0,
263 eEncodingUint,
264 eFormatAddressInfo,
265 {20, 20, LLDB_INVALID_REGNUM, 20, 20},
266 nullptr,
267 nullptr,
268 nullptr,
269 0},
270 {"r21",
271 "",
272 4,
273 0,
274 eEncodingUint,
275 eFormatAddressInfo,
276 {21, 21, LLDB_INVALID_REGNUM, 21, 21},
277 nullptr,
278 nullptr,
279 nullptr,
280 0},
281 {"r22",
282 "",
283 4,
284 0,
285 eEncodingUint,
286 eFormatAddressInfo,
287 {22, 22, LLDB_INVALID_REGNUM, 22, 22},
288 nullptr,
289 nullptr,
290 nullptr,
291 0},
292 {"r23",
293 "",
294 4,
295 0,
296 eEncodingUint,
297 eFormatAddressInfo,
298 {23, 23, LLDB_INVALID_REGNUM, 23, 23},
299 nullptr,
300 nullptr,
301 nullptr,
302 0},
303 {"r24",
304 "",
305 4,
306 0,
307 eEncodingUint,
308 eFormatAddressInfo,
309 {24, 24, LLDB_INVALID_REGNUM, 24, 24},
310 nullptr,
311 nullptr,
312 nullptr,
313 0},
314 {"r25",
315 "",
316 4,
317 0,
318 eEncodingUint,
319 eFormatAddressInfo,
320 {25, 25, LLDB_INVALID_REGNUM, 25, 25},
321 nullptr,
322 nullptr,
323 nullptr,
324 0},
325 {"r26",
326 "",
327 4,
328 0,
329 eEncodingUint,
330 eFormatAddressInfo,
331 {26, 26, LLDB_INVALID_REGNUM, 26, 26},
332 nullptr,
333 nullptr,
334 nullptr,
335 0},
336 {"r27",
337 "",
338 4,
339 0,
340 eEncodingUint,
341 eFormatAddressInfo,
342 {27, 27, LLDB_INVALID_REGNUM, 27, 27},
343 nullptr,
344 nullptr,
345 nullptr,
346 0},
347 {"r28",
348 "",
349 4,
350 0,
351 eEncodingUint,
352 eFormatAddressInfo,
353 {28, 28, LLDB_INVALID_REGNUM, 28, 28},
354 nullptr,
355 nullptr,
356 nullptr,
357 0},
358 {"sp",
359 "r29",
360 4,
361 0,
362 eEncodingUint,
363 eFormatAddressInfo,
364 {29, 29, LLDB_REGNUM_GENERIC_SP, 29, 29},
365 nullptr,
366 nullptr,
367 nullptr,
368 0},
369 {"fp",
370 "r30",
371 4,
372 0,
373 eEncodingUint,
374 eFormatAddressInfo,
375 {30, 30, LLDB_REGNUM_GENERIC_FP, 30, 30},
376 nullptr,
377 nullptr,
378 nullptr,
379 0},
380 {"lr",
381 "r31",
382 4,
383 0,
384 eEncodingUint,
385 eFormatAddressInfo,
386 {31, 31, LLDB_REGNUM_GENERIC_RA, 31, 31},
387 nullptr,
388 nullptr,
389 nullptr,
390 0},
391 {"sa0",
392 "",
393 4,
394 0,
395 eEncodingUint,
396 eFormatAddressInfo,
397 {32, 32, LLDB_INVALID_REGNUM, 32, 32},
398 nullptr,
399 nullptr,
400 nullptr,
401 0},
402 {"lc0",
403 "",
404 4,
405 0,
406 eEncodingUint,
407 eFormatAddressInfo,
408 {33, 33, LLDB_INVALID_REGNUM, 33, 33},
409 nullptr,
410 nullptr,
411 nullptr,
412 0},
413 {"sa1",
414 "",
415 4,
416 0,
417 eEncodingUint,
418 eFormatAddressInfo,
419 {34, 34, LLDB_INVALID_REGNUM, 34, 34},
420 nullptr,
421 nullptr,
422 nullptr,
423 0},
424 {"lc1",
425 "",
426 4,
427 0,
428 eEncodingUint,
429 eFormatAddressInfo,
430 {35, 35, LLDB_INVALID_REGNUM, 35, 35},
431 nullptr,
432 nullptr,
433 nullptr,
434 0},
435 // --> hexagon-v4/5/55/56-sim.xml
436 {"p3_0",
437 "",
438 4,
439 0,
440 eEncodingUint,
441 eFormatAddressInfo,
442 {36, 36, LLDB_INVALID_REGNUM, 36, 36},
443 nullptr,
444 nullptr,
445 nullptr,
446 0},
447 // PADDING {
448 {"p00",
449 "",
450 4,
451 0,
452 eEncodingInvalid,
453 eFormatInvalid,
454 {37, 37, LLDB_INVALID_REGNUM, 37, 37},
455 nullptr,
456 nullptr,
457 nullptr,
458 0},
459 // }
460 {"m0",
461 "",
462 4,
463 0,
464 eEncodingUint,
465 eFormatAddressInfo,
466 {38, 38, LLDB_INVALID_REGNUM, 38, 38},
467 nullptr,
468 nullptr,
469 nullptr,
470 0},
471 {"m1",
472 "",
473 4,
474 0,
475 eEncodingUint,
476 eFormatAddressInfo,
477 {39, 39, LLDB_INVALID_REGNUM, 39, 39},
478 nullptr,
479 nullptr,
480 nullptr,
481 0},
482 {"usr",
483 "",
484 4,
485 0,
486 eEncodingUint,
487 eFormatAddressInfo,
488 {40, 40, LLDB_INVALID_REGNUM, 40, 40},
489 nullptr,
490 nullptr,
491 nullptr,
492 0},
493 {"pc",
494 "",
495 4,
496 0,
497 eEncodingUint,
498 eFormatAddressInfo,
499 {41, 41, LLDB_REGNUM_GENERIC_PC, 41, 41},
500 nullptr,
501 nullptr,
502 nullptr,
503 0},
504 {"ugp",
505 "",
506 4,
507 0,
508 eEncodingUint,
509 eFormatAddressInfo,
510 {42, 42, LLDB_INVALID_REGNUM, 42, 42},
511 nullptr,
512 nullptr,
513 nullptr,
514 0},
515 {"gp",
516 "",
517 4,
518 0,
519 eEncodingUint,
520 eFormatAddressInfo,
521 {43, 43, LLDB_INVALID_REGNUM, 43, 43},
522 nullptr,
523 nullptr,
524 nullptr,
525 0},
526 {"cs0",
527 "",
528 4,
529 0,
530 eEncodingUint,
531 eFormatAddressInfo,
532 {44, 44, LLDB_INVALID_REGNUM, 44, 44},
533 nullptr,
534 nullptr,
535 nullptr,
536 0},
537 {"cs1",
538 "",
539 4,
540 0,
541 eEncodingUint,
542 eFormatAddressInfo,
543 {45, 45, LLDB_INVALID_REGNUM, 45, 45},
544 nullptr,
545 nullptr,
546 nullptr,
547 0},
548 // PADDING {
549 {"p01",
550 "",
551 4,
552 0,
553 eEncodingInvalid,
554 eFormatInvalid,
555 {46, 46, LLDB_INVALID_REGNUM, 46, 46},
556 nullptr,
557 nullptr,
558 nullptr,
559 0},
560 {"p02",
561 "",
562 4,
563 0,
564 eEncodingInvalid,
565 eFormatInvalid,
566 {47, 47, LLDB_INVALID_REGNUM, 47, 47},
567 nullptr,
568 nullptr,
569 nullptr,
570 0},
571 {"p03",
572 "",
573 4,
574 0,
575 eEncodingInvalid,
576 eFormatInvalid,
577 {48, 48, LLDB_INVALID_REGNUM, 48, 48},
578 nullptr,
579 nullptr,
580 nullptr,
581 0},
582 {"p04",
583 "",
584 4,
585 0,
586 eEncodingInvalid,
587 eFormatInvalid,
588 {49, 49, LLDB_INVALID_REGNUM, 49, 49},
589 nullptr,
590 nullptr,
591 nullptr,
592 0},
593 {"p05",
594 "",
595 4,
596 0,
597 eEncodingInvalid,
598 eFormatInvalid,
599 {50, 50, LLDB_INVALID_REGNUM, 50, 50},
600 nullptr,
601 nullptr,
602 nullptr,
603 0},
604 {"p06",
605 "",
606 4,
607 0,
608 eEncodingInvalid,
609 eFormatInvalid,
610 {51, 51, LLDB_INVALID_REGNUM, 51, 51},
611 nullptr,
612 nullptr,
613 nullptr,
614 0},
615 {"p07",
616 "",
617 4,
618 0,
619 eEncodingInvalid,
620 eFormatInvalid,
621 {52, 52, LLDB_INVALID_REGNUM, 52, 52},
622 nullptr,
623 nullptr,
624 nullptr,
625 0},
626 {"p08",
627 "",
628 4,
629 0,
630 eEncodingInvalid,
631 eFormatInvalid,
632 {53, 53, LLDB_INVALID_REGNUM, 53, 53},
633 nullptr,
634 nullptr,
635 nullptr,
636 0},
637 {"p09",
638 "",
639 4,
640 0,
641 eEncodingInvalid,
642 eFormatInvalid,
643 {54, 54, LLDB_INVALID_REGNUM, 54, 54},
644 nullptr,
645 nullptr,
646 nullptr,
647 0},
648 {"p10",
649 "",
650 4,
651 0,
652 eEncodingInvalid,
653 eFormatInvalid,
654 {55, 55, LLDB_INVALID_REGNUM, 55, 55},
655 nullptr,
656 nullptr,
657 nullptr,
658 0},
659 {"p11",
660 "",
661 4,
662 0,
663 eEncodingInvalid,
664 eFormatInvalid,
665 {56, 56, LLDB_INVALID_REGNUM, 56, 56},
666 nullptr,
667 nullptr,
668 nullptr,
669 0},
670 {"p12",
671 "",
672 4,
673 0,
674 eEncodingInvalid,
675 eFormatInvalid,
676 {57, 57, LLDB_INVALID_REGNUM, 57, 57},
677 nullptr,
678 nullptr,
679 nullptr,
680 0},
681 {"p13",
682 "",
683 4,
684 0,
685 eEncodingInvalid,
686 eFormatInvalid,
687 {58, 58, LLDB_INVALID_REGNUM, 58, 58},
688 nullptr,
689 nullptr,
690 nullptr,
691 0},
692 {"p14",
693 "",
694 4,
695 0,
696 eEncodingInvalid,
697 eFormatInvalid,
698 {59, 59, LLDB_INVALID_REGNUM, 59, 59},
699 nullptr,
700 nullptr,
701 nullptr,
702 0},
703 {"p15",
704 "",
705 4,
706 0,
707 eEncodingInvalid,
708 eFormatInvalid,
709 {60, 60, LLDB_INVALID_REGNUM, 60, 60},
710 nullptr,
711 nullptr,
712 nullptr,
713 0},
714 {"p16",
715 "",
716 4,
717 0,
718 eEncodingInvalid,
719 eFormatInvalid,
720 {61, 61, LLDB_INVALID_REGNUM, 61, 61},
721 nullptr,
722 nullptr,
723 nullptr,
724 0},
725 {"p17",
726 "",
727 4,
728 0,
729 eEncodingInvalid,
730 eFormatInvalid,
731 {62, 62, LLDB_INVALID_REGNUM, 62, 62},
732 nullptr,
733 nullptr,
734 nullptr,
735 0},
736 {"p18",
737 "",
738 4,
739 0,
740 eEncodingInvalid,
741 eFormatInvalid,
742 {63, 63, LLDB_INVALID_REGNUM, 63, 63},
743 nullptr,
744 nullptr,
745 nullptr,
746 0},
747 // }
748 {"sgp0",
749 "",
750 4,
751 0,
752 eEncodingUint,
753 eFormatAddressInfo,
754 {64, 64, LLDB_INVALID_REGNUM, 64, 64},
755 nullptr,
756 nullptr,
757 nullptr,
758 0},
759 // PADDING {
760 {"p19",
761 "",
762 4,
763 0,
764 eEncodingInvalid,
765 eFormatInvalid,
766 {65, 65, LLDB_INVALID_REGNUM, 65, 65},
767 nullptr,
768 nullptr,
769 nullptr,
770 0},
771 // }
772 {"stid",
773 "",
774 4,
775 0,
776 eEncodingUint,
777 eFormatAddressInfo,
778 {66, 66, LLDB_INVALID_REGNUM, 66, 66},
779 nullptr,
780 nullptr,
781 nullptr,
782 0},
783 {"elr",
784 "",
785 4,
786 0,
787 eEncodingUint,
788 eFormatAddressInfo,
789 {67, 67, LLDB_INVALID_REGNUM, 67, 67},
790 nullptr,
791 nullptr,
792 nullptr,
793 0},
794 {"badva0",
795 "",
796 4,
797 0,
798 eEncodingUint,
799 eFormatAddressInfo,
800 {68, 68, LLDB_INVALID_REGNUM, 68, 68},
801 nullptr,
802 nullptr,
803 nullptr,
804 0},
805 {"badva1",
806 "",
807 4,
808 0,
809 eEncodingUint,
810 eFormatAddressInfo,
811 {69, 69, LLDB_INVALID_REGNUM, 69, 69},
812 nullptr,
813 nullptr,
814 nullptr,
815 0},
816 {"ssr",
817 "",
818 4,
819 0,
820 eEncodingUint,
821 eFormatAddressInfo,
822 {70, 70, LLDB_INVALID_REGNUM, 70, 70},
823 nullptr,
824 nullptr,
825 nullptr,
826 0},
827 {"ccr",
828 "",
829 4,
830 0,
831 eEncodingUint,
832 eFormatAddressInfo,
833 {71, 71, LLDB_INVALID_REGNUM, 71, 71},
834 nullptr,
835 nullptr,
836 nullptr,
837 0},
838 {"htid",
839 "",
840 4,
841 0,
842 eEncodingUint,
843 eFormatAddressInfo,
844 {72, 72, LLDB_INVALID_REGNUM, 72, 72},
845 nullptr,
846 nullptr,
847 nullptr,
848 0},
849 // PADDING {
850 {"p20",
851 "",
852 4,
853 0,
854 eEncodingInvalid,
855 eFormatInvalid,
856 {73, 73, LLDB_INVALID_REGNUM, 73, 73},
857 nullptr,
858 nullptr,
859 nullptr,
860 0},
861 // }
862 {"imask",
863 "",
864 4,
865 0,
866 eEncodingUint,
867 eFormatAddressInfo,
868 {74, 74, LLDB_INVALID_REGNUM, 74, 74},
869 nullptr,
870 nullptr,
871 nullptr,
872 0},
873 // PADDING {
874 {"p21",
875 "",
876 4,
877 0,
878 eEncodingInvalid,
879 eFormatInvalid,
880 {75, 75, LLDB_INVALID_REGNUM, 75, 75},
881 nullptr,
882 nullptr,
883 nullptr,
884 0},
885 {"p22",
886 "",
887 4,
888 0,
889 eEncodingInvalid,
890 eFormatInvalid,
891 {76, 76, LLDB_INVALID_REGNUM, 76, 76},
892 nullptr,
893 nullptr,
894 nullptr,
895 0},
896 {"p23",
897 "",
898 4,
899 0,
900 eEncodingInvalid,
901 eFormatInvalid,
902 {77, 77, LLDB_INVALID_REGNUM, 77, 77},
903 nullptr,
904 nullptr,
905 nullptr,
906 0},
907 {"p24",
908 "",
909 4,
910 0,
911 eEncodingInvalid,
912 eFormatInvalid,
913 {78, 78, LLDB_INVALID_REGNUM, 78, 78},
914 nullptr,
915 nullptr,
916 nullptr,
917 0},
918 {"p25",
919 "",
920 4,
921 0,
922 eEncodingInvalid,
923 eFormatInvalid,
924 {79, 79, LLDB_INVALID_REGNUM, 79, 79},
925 nullptr,
926 nullptr,
927 nullptr,
928 0},
929 // }
930 {"g0",
931 "",
932 4,
933 0,
934 eEncodingUint,
935 eFormatAddressInfo,
936 {80, 80, LLDB_INVALID_REGNUM, 80, 80},
937 nullptr,
938 nullptr,
939 nullptr,
940 0},
941 {"g1",
942 "",
943 4,
944 0,
945 eEncodingUint,
946 eFormatAddressInfo,
947 {81, 81, LLDB_INVALID_REGNUM, 81, 81},
948 nullptr,
949 nullptr,
950 nullptr,
951 0},
952 {"g2",
953 "",
954 4,
955 0,
956 eEncodingUint,
957 eFormatAddressInfo,
958 {82, 82, LLDB_INVALID_REGNUM, 82, 82},
959 nullptr,
960 nullptr,
961 nullptr,
962 0},
963 {"g3",
964 "",
965 4,
966 0,
967 eEncodingUint,
968 eFormatAddressInfo,
969 {83, 83, LLDB_INVALID_REGNUM, 83, 83},
970 nullptr,
971 nullptr,
972 nullptr,
973 0}};
974
975 static const uint32_t k_num_register_infos =
976 sizeof(g_register_infos) / sizeof(RegisterInfo);
977
978 const lldb_private::RegisterInfo *
GetRegisterInfoArray(uint32_t & count)979 ABISysV_hexagon::GetRegisterInfoArray(uint32_t &count) {
980 count = k_num_register_infos;
981 return g_register_infos;
982 }
983
984 /*
985 http://en.wikipedia.org/wiki/Red_zone_%28computing%29
986
987 In computing, a red zone is a fixed size area in memory beyond the stack
988 pointer that has not been
989 "allocated". This region of memory is not to be modified by
990 interrupt/exception/signal handlers.
991 This allows the space to be used for temporary data without the extra
992 overhead of modifying the
993 stack pointer. The x86-64 ABI mandates a 128 byte red zone.[1] The OpenRISC
994 toolchain assumes a
995 128 byte red zone though it is not documented.
996 */
GetRedZoneSize() const997 size_t ABISysV_hexagon::GetRedZoneSize() const { return 0; }
998
999 // Static Functions
1000
1001 ABISP
CreateInstance(lldb::ProcessSP process_sp,const ArchSpec & arch)1002 ABISysV_hexagon::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
1003 if (arch.GetTriple().getArch() == llvm::Triple::hexagon) {
1004 return ABISP(
1005 new ABISysV_hexagon(std::move(process_sp), MakeMCRegisterInfo(arch)));
1006 }
1007 return ABISP();
1008 }
1009
PrepareTrivialCall(Thread & thread,lldb::addr_t sp,lldb::addr_t pc,lldb::addr_t ra,llvm::ArrayRef<addr_t> args) const1010 bool ABISysV_hexagon::PrepareTrivialCall(Thread &thread, lldb::addr_t sp,
1011 lldb::addr_t pc, lldb::addr_t ra,
1012 llvm::ArrayRef<addr_t> args) const {
1013 // we don't use the traditional trivial call specialized for jit
1014 return false;
1015 }
1016
1017 /*
1018
1019 // AD:
1020 // . safeguard the current stack
1021 // . how can we know that the called function will create its own frame
1022 properly?
1023 // . we could manually make a new stack first:
1024 // 2. push RA
1025 // 3. push FP
1026 // 4. FP = SP
1027 // 5. SP = SP ( since no locals in our temp frame )
1028
1029 // AD 6/05/2014
1030 // . variable argument list parameters are not passed via registers, they are
1031 passed on
1032 // the stack. This presents us with a problem, since we need to know when
1033 the valist
1034 // starts. Currently I can find out if a function is varg, but not how many
1035 // real parameters it takes. Thus I don't know when to start spilling the
1036 vargs. For
1037 // the time being, to progress, I will assume that it takes on real parameter
1038 before
1039 // the vargs list starts.
1040
1041 // AD 06/05/2014
1042 // . how do we adhere to the stack alignment requirements
1043
1044 // AD 06/05/2014
1045 // . handle 64bit values and their register / stack requirements
1046
1047 */
1048 #define HEX_ABI_DEBUG 0
PrepareTrivialCall(Thread & thread,lldb::addr_t sp,lldb::addr_t pc,lldb::addr_t ra,llvm::Type & prototype,llvm::ArrayRef<ABI::CallArgument> args) const1049 bool ABISysV_hexagon::PrepareTrivialCall(
1050 Thread &thread, lldb::addr_t sp, lldb::addr_t pc, lldb::addr_t ra,
1051 llvm::Type &prototype, llvm::ArrayRef<ABI::CallArgument> args) const {
1052 // default number of register passed arguments for varg functions
1053 const int nVArgRegParams = 1;
1054 Status error;
1055
1056 // grab the process so we have access to the memory for spilling
1057 lldb::ProcessSP proc = thread.GetProcess();
1058
1059 // get the register context for modifying all of the registers
1060 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1061 if (!reg_ctx)
1062 return false;
1063
1064 uint32_t pc_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
1065 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
1066 if (pc_reg == LLDB_INVALID_REGNUM)
1067 return false;
1068
1069 uint32_t ra_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
1070 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
1071 if (ra_reg == LLDB_INVALID_REGNUM)
1072 return false;
1073
1074 uint32_t sp_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
1075 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
1076 if (sp_reg == LLDB_INVALID_REGNUM)
1077 return false;
1078
1079 // push host data onto target
1080 for (size_t i = 0; i < args.size(); i++) {
1081 const ABI::CallArgument &arg = args[i];
1082 // skip over target values
1083 if (arg.type == ABI::CallArgument::TargetValue)
1084 continue;
1085 // round up to 8 byte multiple
1086 size_t argSize = (arg.size | 0x7) + 1;
1087
1088 // create space on the stack for this data
1089 sp -= argSize;
1090
1091 // write this argument onto the stack of the host process
1092 proc->WriteMemory(sp, arg.data_up.get(), arg.size, error);
1093 if (error.Fail())
1094 return false;
1095
1096 // update the argument with the target pointer
1097 // XXX: This is a gross hack for getting around the const
1098 *const_cast<lldb::addr_t *>(&arg.value) = sp;
1099 }
1100
1101 #if HEX_ABI_DEBUG
1102 // print the original stack pointer
1103 printf("sp : %04" PRIx64 " \n", sp);
1104 #endif
1105
1106 // make sure number of parameters matches prototype
1107 assert(prototype.getFunctionNumParams() == args.size());
1108
1109 // check if this is a variable argument function
1110 bool isVArg = prototype.isFunctionVarArg();
1111
1112 // number of arguments passed by register
1113 int nRegArgs = nVArgRegParams;
1114 if (!isVArg) {
1115 // number of arguments is limited by [R0 : R5] space
1116 nRegArgs = args.size();
1117 if (nRegArgs > 6)
1118 nRegArgs = 6;
1119 }
1120
1121 // pass arguments that are passed via registers
1122 for (int i = 0; i < nRegArgs; i++) {
1123 // get the parameter as a u32
1124 uint32_t param = (uint32_t)args[i].value;
1125 // write argument into register
1126 if (!reg_ctx->WriteRegisterFromUnsigned(i, param))
1127 return false;
1128 }
1129
1130 // number of arguments to spill onto stack
1131 int nSpillArgs = args.size() - nRegArgs;
1132 // make space on the stack for arguments
1133 sp -= 4 * nSpillArgs;
1134 // align stack on an 8 byte boundary
1135 if (sp & 7)
1136 sp -= 4;
1137
1138 // arguments that are passed on the stack
1139 for (size_t i = nRegArgs, offs = 0; i < args.size(); i++) {
1140 // get the parameter as a u32
1141 uint32_t param = (uint32_t)args[i].value;
1142 // write argument to stack
1143 proc->WriteMemory(sp + offs, (void *)¶m, sizeof(param), error);
1144 if (!error.Success())
1145 return false;
1146 //
1147 offs += 4;
1148 }
1149
1150 // update registers with current function call state
1151 reg_ctx->WriteRegisterFromUnsigned(pc_reg, pc);
1152 reg_ctx->WriteRegisterFromUnsigned(ra_reg, ra);
1153 reg_ctx->WriteRegisterFromUnsigned(sp_reg, sp);
1154
1155 #if HEX_ABI_DEBUG
1156 // quick and dirty stack dumper for debugging
1157 for (int i = -8; i < 8; i++) {
1158 uint32_t data = 0;
1159 lldb::addr_t addr = sp + i * 4;
1160 proc->ReadMemory(addr, (void *)&data, sizeof(data), error);
1161 printf("\n0x%04" PRIx64 " 0x%08x ", addr, data);
1162 if (i == 0)
1163 printf("<<-- sp");
1164 }
1165 printf("\n");
1166 #endif
1167
1168 return true;
1169 }
1170
GetArgumentValues(Thread & thread,ValueList & values) const1171 bool ABISysV_hexagon::GetArgumentValues(Thread &thread,
1172 ValueList &values) const {
1173 return false;
1174 }
1175
1176 Status
SetReturnValueObject(lldb::StackFrameSP & frame_sp,lldb::ValueObjectSP & new_value_sp)1177 ABISysV_hexagon::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
1178 lldb::ValueObjectSP &new_value_sp) {
1179 Status error;
1180 return error;
1181 }
1182
GetReturnValueObjectSimple(Thread & thread,CompilerType & return_compiler_type) const1183 ValueObjectSP ABISysV_hexagon::GetReturnValueObjectSimple(
1184 Thread &thread, CompilerType &return_compiler_type) const {
1185 ValueObjectSP return_valobj_sp;
1186 return return_valobj_sp;
1187 }
1188
GetReturnValueObjectImpl(Thread & thread,CompilerType & return_compiler_type) const1189 ValueObjectSP ABISysV_hexagon::GetReturnValueObjectImpl(
1190 Thread &thread, CompilerType &return_compiler_type) const {
1191 ValueObjectSP return_valobj_sp;
1192 return return_valobj_sp;
1193 }
1194
1195 // called when we are on the first instruction of a new function for hexagon
1196 // the return address is in RA (R31)
CreateFunctionEntryUnwindPlan(UnwindPlan & unwind_plan)1197 bool ABISysV_hexagon::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
1198 unwind_plan.Clear();
1199 unwind_plan.SetRegisterKind(eRegisterKindGeneric);
1200 unwind_plan.SetReturnAddressRegister(LLDB_REGNUM_GENERIC_RA);
1201
1202 UnwindPlan::RowSP row(new UnwindPlan::Row);
1203
1204 // Our Call Frame Address is the stack pointer value
1205 row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_SP, 4);
1206 row->SetOffset(0);
1207
1208 // The previous PC is in the LR
1209 row->SetRegisterLocationToRegister(LLDB_REGNUM_GENERIC_PC,
1210 LLDB_REGNUM_GENERIC_RA, true);
1211 unwind_plan.AppendRow(row);
1212
1213 unwind_plan.SetSourceName("hexagon at-func-entry default");
1214 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1215 return true;
1216 }
1217
CreateDefaultUnwindPlan(UnwindPlan & unwind_plan)1218 bool ABISysV_hexagon::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
1219 unwind_plan.Clear();
1220 unwind_plan.SetRegisterKind(eRegisterKindGeneric);
1221
1222 uint32_t fp_reg_num = LLDB_REGNUM_GENERIC_FP;
1223 uint32_t sp_reg_num = LLDB_REGNUM_GENERIC_SP;
1224 uint32_t pc_reg_num = LLDB_REGNUM_GENERIC_PC;
1225
1226 UnwindPlan::RowSP row(new UnwindPlan::Row);
1227
1228 row->SetUnspecifiedRegistersAreUndefined(true);
1229 row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_FP, 8);
1230
1231 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, -8, true);
1232 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, true);
1233 row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
1234
1235 unwind_plan.AppendRow(row);
1236 unwind_plan.SetSourceName("hexagon default unwind plan");
1237 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1238 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1239 unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
1240 return true;
1241 }
1242
1243 /*
1244 Register Usage Saved By
1245
1246 R0 - R5 parameters(a) -
1247 R6 - R15 Scratch(b) Caller
1248 R16 - R27 Scratch Callee
1249 R28 Scratch(b) Caller
1250 R29 - R31 Stack Frames Callee(c)
1251 P3:0 Processor State Caller
1252
1253 a = the caller can change parameter values
1254 b = R14 - R15 and R28 are used by the procedure linkage table
1255 c = R29 - R31 are saved and restored by allocframe() and deallocframe()
1256 */
RegisterIsVolatile(const RegisterInfo * reg_info)1257 bool ABISysV_hexagon::RegisterIsVolatile(const RegisterInfo *reg_info) {
1258 return !RegisterIsCalleeSaved(reg_info);
1259 }
1260
RegisterIsCalleeSaved(const RegisterInfo * reg_info)1261 bool ABISysV_hexagon::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
1262 int reg = ((reg_info->byte_offset) / 4);
1263
1264 bool save = (reg >= 16) && (reg <= 27);
1265 save |= (reg >= 29) && (reg <= 32);
1266
1267 return save;
1268 }
1269
Initialize()1270 void ABISysV_hexagon::Initialize() {
1271 PluginManager::RegisterPlugin(GetPluginNameStatic(),
1272 "System V ABI for hexagon targets",
1273 CreateInstance);
1274 }
1275
Terminate()1276 void ABISysV_hexagon::Terminate() {
1277 PluginManager::UnregisterPlugin(CreateInstance);
1278 }
1279
GetPluginNameStatic()1280 lldb_private::ConstString ABISysV_hexagon::GetPluginNameStatic() {
1281 static ConstString g_name("sysv-hexagon");
1282 return g_name;
1283 }
1284
1285 // PluginInterface protocol
1286
GetPluginName()1287 lldb_private::ConstString ABISysV_hexagon::GetPluginName() {
1288 return GetPluginNameStatic();
1289 }
1290
GetPluginVersion()1291 uint32_t ABISysV_hexagon::GetPluginVersion() { return 1; }
1292
1293 // get value object specialized to work with llvm IR types
1294 lldb::ValueObjectSP
GetReturnValueObjectImpl(lldb_private::Thread & thread,llvm::Type & retType) const1295 ABISysV_hexagon::GetReturnValueObjectImpl(lldb_private::Thread &thread,
1296 llvm::Type &retType) const {
1297 Value value;
1298 ValueObjectSP vObjSP;
1299
1300 // get the current register context
1301 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1302 if (!reg_ctx)
1303 return vObjSP;
1304
1305 // for now just pop R0 to find the return value
1306 const lldb_private::RegisterInfo *r0_info =
1307 reg_ctx->GetRegisterInfoAtIndex(0);
1308 if (r0_info == nullptr)
1309 return vObjSP;
1310
1311 // void return type
1312 if (retType.isVoidTy()) {
1313 value.GetScalar() = 0;
1314 }
1315 // integer / pointer return type
1316 else if (retType.isIntegerTy() || retType.isPointerTy()) {
1317 // read r0 register value
1318 lldb_private::RegisterValue r0_value;
1319 if (!reg_ctx->ReadRegister(r0_info, r0_value))
1320 return vObjSP;
1321
1322 // push r0 into value
1323 uint32_t r0_u32 = r0_value.GetAsUInt32();
1324
1325 // account for integer size
1326 if (retType.isIntegerTy() && retType.isSized()) {
1327 uint64_t size = retType.getScalarSizeInBits();
1328 uint64_t mask = (1ull << size) - 1;
1329 // mask out higher order bits then the type we expect
1330 r0_u32 &= mask;
1331 }
1332
1333 value.GetScalar() = r0_u32;
1334 }
1335 // unsupported return type
1336 else
1337 return vObjSP;
1338
1339 // pack the value into a ValueObjectSP
1340 vObjSP = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
1341 value, ConstString(""));
1342 return vObjSP;
1343 }
1344