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/IR/DerivedTypes.h"
12 #include "llvm/TargetParser/Triple.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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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
447 },
448 // PADDING {
449 {"p00",
450 "",
451 4,
452 0,
453 eEncodingInvalid,
454 eFormatInvalid,
455 {37, 37, LLDB_INVALID_REGNUM, 37, 37},
456 nullptr,
457 nullptr,
458 nullptr,
459 },
460 // }
461 {"m0",
462 "",
463 4,
464 0,
465 eEncodingUint,
466 eFormatAddressInfo,
467 {38, 38, LLDB_INVALID_REGNUM, 38, 38},
468 nullptr,
469 nullptr,
470 nullptr,
471 },
472 {"m1",
473 "",
474 4,
475 0,
476 eEncodingUint,
477 eFormatAddressInfo,
478 {39, 39, LLDB_INVALID_REGNUM, 39, 39},
479 nullptr,
480 nullptr,
481 nullptr,
482 },
483 {"usr",
484 "",
485 4,
486 0,
487 eEncodingUint,
488 eFormatAddressInfo,
489 {40, 40, LLDB_INVALID_REGNUM, 40, 40},
490 nullptr,
491 nullptr,
492 nullptr,
493 },
494 {"pc",
495 "",
496 4,
497 0,
498 eEncodingUint,
499 eFormatAddressInfo,
500 {41, 41, LLDB_REGNUM_GENERIC_PC, 41, 41},
501 nullptr,
502 nullptr,
503 nullptr,
504 },
505 {"ugp",
506 "",
507 4,
508 0,
509 eEncodingUint,
510 eFormatAddressInfo,
511 {42, 42, LLDB_INVALID_REGNUM, 42, 42},
512 nullptr,
513 nullptr,
514 nullptr,
515 },
516 {"gp",
517 "",
518 4,
519 0,
520 eEncodingUint,
521 eFormatAddressInfo,
522 {43, 43, LLDB_INVALID_REGNUM, 43, 43},
523 nullptr,
524 nullptr,
525 nullptr,
526 },
527 {"cs0",
528 "",
529 4,
530 0,
531 eEncodingUint,
532 eFormatAddressInfo,
533 {44, 44, LLDB_INVALID_REGNUM, 44, 44},
534 nullptr,
535 nullptr,
536 nullptr,
537 },
538 {"cs1",
539 "",
540 4,
541 0,
542 eEncodingUint,
543 eFormatAddressInfo,
544 {45, 45, LLDB_INVALID_REGNUM, 45, 45},
545 nullptr,
546 nullptr,
547 nullptr,
548 },
549 // PADDING {
550 {"p01",
551 "",
552 4,
553 0,
554 eEncodingInvalid,
555 eFormatInvalid,
556 {46, 46, LLDB_INVALID_REGNUM, 46, 46},
557 nullptr,
558 nullptr,
559 nullptr,
560 },
561 {"p02",
562 "",
563 4,
564 0,
565 eEncodingInvalid,
566 eFormatInvalid,
567 {47, 47, LLDB_INVALID_REGNUM, 47, 47},
568 nullptr,
569 nullptr,
570 nullptr,
571 },
572 {"p03",
573 "",
574 4,
575 0,
576 eEncodingInvalid,
577 eFormatInvalid,
578 {48, 48, LLDB_INVALID_REGNUM, 48, 48},
579 nullptr,
580 nullptr,
581 nullptr,
582 },
583 {"p04",
584 "",
585 4,
586 0,
587 eEncodingInvalid,
588 eFormatInvalid,
589 {49, 49, LLDB_INVALID_REGNUM, 49, 49},
590 nullptr,
591 nullptr,
592 nullptr,
593 },
594 {"p05",
595 "",
596 4,
597 0,
598 eEncodingInvalid,
599 eFormatInvalid,
600 {50, 50, LLDB_INVALID_REGNUM, 50, 50},
601 nullptr,
602 nullptr,
603 nullptr,
604 },
605 {"p06",
606 "",
607 4,
608 0,
609 eEncodingInvalid,
610 eFormatInvalid,
611 {51, 51, LLDB_INVALID_REGNUM, 51, 51},
612 nullptr,
613 nullptr,
614 nullptr,
615 },
616 {"p07",
617 "",
618 4,
619 0,
620 eEncodingInvalid,
621 eFormatInvalid,
622 {52, 52, LLDB_INVALID_REGNUM, 52, 52},
623 nullptr,
624 nullptr,
625 nullptr,
626 },
627 {"p08",
628 "",
629 4,
630 0,
631 eEncodingInvalid,
632 eFormatInvalid,
633 {53, 53, LLDB_INVALID_REGNUM, 53, 53},
634 nullptr,
635 nullptr,
636 nullptr,
637 },
638 {"p09",
639 "",
640 4,
641 0,
642 eEncodingInvalid,
643 eFormatInvalid,
644 {54, 54, LLDB_INVALID_REGNUM, 54, 54},
645 nullptr,
646 nullptr,
647 nullptr,
648 },
649 {"p10",
650 "",
651 4,
652 0,
653 eEncodingInvalid,
654 eFormatInvalid,
655 {55, 55, LLDB_INVALID_REGNUM, 55, 55},
656 nullptr,
657 nullptr,
658 nullptr,
659 },
660 {"p11",
661 "",
662 4,
663 0,
664 eEncodingInvalid,
665 eFormatInvalid,
666 {56, 56, LLDB_INVALID_REGNUM, 56, 56},
667 nullptr,
668 nullptr,
669 nullptr,
670 },
671 {"p12",
672 "",
673 4,
674 0,
675 eEncodingInvalid,
676 eFormatInvalid,
677 {57, 57, LLDB_INVALID_REGNUM, 57, 57},
678 nullptr,
679 nullptr,
680 nullptr,
681 },
682 {"p13",
683 "",
684 4,
685 0,
686 eEncodingInvalid,
687 eFormatInvalid,
688 {58, 58, LLDB_INVALID_REGNUM, 58, 58},
689 nullptr,
690 nullptr,
691 nullptr,
692 },
693 {"p14",
694 "",
695 4,
696 0,
697 eEncodingInvalid,
698 eFormatInvalid,
699 {59, 59, LLDB_INVALID_REGNUM, 59, 59},
700 nullptr,
701 nullptr,
702 nullptr,
703 },
704 {"p15",
705 "",
706 4,
707 0,
708 eEncodingInvalid,
709 eFormatInvalid,
710 {60, 60, LLDB_INVALID_REGNUM, 60, 60},
711 nullptr,
712 nullptr,
713 nullptr,
714 },
715 {"p16",
716 "",
717 4,
718 0,
719 eEncodingInvalid,
720 eFormatInvalid,
721 {61, 61, LLDB_INVALID_REGNUM, 61, 61},
722 nullptr,
723 nullptr,
724 nullptr,
725 },
726 {"p17",
727 "",
728 4,
729 0,
730 eEncodingInvalid,
731 eFormatInvalid,
732 {62, 62, LLDB_INVALID_REGNUM, 62, 62},
733 nullptr,
734 nullptr,
735 nullptr,
736 },
737 {"p18",
738 "",
739 4,
740 0,
741 eEncodingInvalid,
742 eFormatInvalid,
743 {63, 63, LLDB_INVALID_REGNUM, 63, 63},
744 nullptr,
745 nullptr,
746 nullptr,
747 },
748 // }
749 {"sgp0",
750 "",
751 4,
752 0,
753 eEncodingUint,
754 eFormatAddressInfo,
755 {64, 64, LLDB_INVALID_REGNUM, 64, 64},
756 nullptr,
757 nullptr,
758 nullptr,
759 },
760 // PADDING {
761 {"p19",
762 "",
763 4,
764 0,
765 eEncodingInvalid,
766 eFormatInvalid,
767 {65, 65, LLDB_INVALID_REGNUM, 65, 65},
768 nullptr,
769 nullptr,
770 nullptr,
771 },
772 // }
773 {"stid",
774 "",
775 4,
776 0,
777 eEncodingUint,
778 eFormatAddressInfo,
779 {66, 66, LLDB_INVALID_REGNUM, 66, 66},
780 nullptr,
781 nullptr,
782 nullptr,
783 },
784 {"elr",
785 "",
786 4,
787 0,
788 eEncodingUint,
789 eFormatAddressInfo,
790 {67, 67, LLDB_INVALID_REGNUM, 67, 67},
791 nullptr,
792 nullptr,
793 nullptr,
794 },
795 {"badva0",
796 "",
797 4,
798 0,
799 eEncodingUint,
800 eFormatAddressInfo,
801 {68, 68, LLDB_INVALID_REGNUM, 68, 68},
802 nullptr,
803 nullptr,
804 nullptr,
805 },
806 {"badva1",
807 "",
808 4,
809 0,
810 eEncodingUint,
811 eFormatAddressInfo,
812 {69, 69, LLDB_INVALID_REGNUM, 69, 69},
813 nullptr,
814 nullptr,
815 nullptr,
816 },
817 {"ssr",
818 "",
819 4,
820 0,
821 eEncodingUint,
822 eFormatAddressInfo,
823 {70, 70, LLDB_INVALID_REGNUM, 70, 70},
824 nullptr,
825 nullptr,
826 nullptr,
827 },
828 {"ccr",
829 "",
830 4,
831 0,
832 eEncodingUint,
833 eFormatAddressInfo,
834 {71, 71, LLDB_INVALID_REGNUM, 71, 71},
835 nullptr,
836 nullptr,
837 nullptr,
838 },
839 {"htid",
840 "",
841 4,
842 0,
843 eEncodingUint,
844 eFormatAddressInfo,
845 {72, 72, LLDB_INVALID_REGNUM, 72, 72},
846 nullptr,
847 nullptr,
848 nullptr,
849 },
850 // PADDING {
851 {"p20",
852 "",
853 4,
854 0,
855 eEncodingInvalid,
856 eFormatInvalid,
857 {73, 73, LLDB_INVALID_REGNUM, 73, 73},
858 nullptr,
859 nullptr,
860 nullptr,
861 },
862 // }
863 {"imask",
864 "",
865 4,
866 0,
867 eEncodingUint,
868 eFormatAddressInfo,
869 {74, 74, LLDB_INVALID_REGNUM, 74, 74},
870 nullptr,
871 nullptr,
872 nullptr,
873 },
874 // PADDING {
875 {"p21",
876 "",
877 4,
878 0,
879 eEncodingInvalid,
880 eFormatInvalid,
881 {75, 75, LLDB_INVALID_REGNUM, 75, 75},
882 nullptr,
883 nullptr,
884 nullptr,
885 },
886 {"p22",
887 "",
888 4,
889 0,
890 eEncodingInvalid,
891 eFormatInvalid,
892 {76, 76, LLDB_INVALID_REGNUM, 76, 76},
893 nullptr,
894 nullptr,
895 nullptr,
896 },
897 {"p23",
898 "",
899 4,
900 0,
901 eEncodingInvalid,
902 eFormatInvalid,
903 {77, 77, LLDB_INVALID_REGNUM, 77, 77},
904 nullptr,
905 nullptr,
906 nullptr,
907 },
908 {"p24",
909 "",
910 4,
911 0,
912 eEncodingInvalid,
913 eFormatInvalid,
914 {78, 78, LLDB_INVALID_REGNUM, 78, 78},
915 nullptr,
916 nullptr,
917 nullptr,
918 },
919 {"p25",
920 "",
921 4,
922 0,
923 eEncodingInvalid,
924 eFormatInvalid,
925 {79, 79, LLDB_INVALID_REGNUM, 79, 79},
926 nullptr,
927 nullptr,
928 nullptr,
929 },
930 // }
931 {"g0",
932 "",
933 4,
934 0,
935 eEncodingUint,
936 eFormatAddressInfo,
937 {80, 80, LLDB_INVALID_REGNUM, 80, 80},
938 nullptr,
939 nullptr,
940 nullptr,
941 },
942 {"g1",
943 "",
944 4,
945 0,
946 eEncodingUint,
947 eFormatAddressInfo,
948 {81, 81, LLDB_INVALID_REGNUM, 81, 81},
949 nullptr,
950 nullptr,
951 nullptr,
952 },
953 {"g2",
954 "",
955 4,
956 0,
957 eEncodingUint,
958 eFormatAddressInfo,
959 {82, 82, LLDB_INVALID_REGNUM, 82, 82},
960 nullptr,
961 nullptr,
962 nullptr,
963 },
964 {"g3",
965 "",
966 4,
967 0,
968 eEncodingUint,
969 eFormatAddressInfo,
970 {83, 83, LLDB_INVALID_REGNUM, 83, 83},
971 nullptr,
972 nullptr,
973 nullptr,
974 }};
975
976 static const uint32_t k_num_register_infos =
977 sizeof(g_register_infos) / sizeof(RegisterInfo);
978
979 const lldb_private::RegisterInfo *
GetRegisterInfoArray(uint32_t & count)980 ABISysV_hexagon::GetRegisterInfoArray(uint32_t &count) {
981 count = k_num_register_infos;
982 return g_register_infos;
983 }
984
985 /*
986 http://en.wikipedia.org/wiki/Red_zone_%28computing%29
987
988 In computing, a red zone is a fixed size area in memory beyond the stack
989 pointer that has not been
990 "allocated". This region of memory is not to be modified by
991 interrupt/exception/signal handlers.
992 This allows the space to be used for temporary data without the extra
993 overhead of modifying the
994 stack pointer. The x86-64 ABI mandates a 128 byte red zone.[1] The OpenRISC
995 toolchain assumes a
996 128 byte red zone though it is not documented.
997 */
GetRedZoneSize() const998 size_t ABISysV_hexagon::GetRedZoneSize() const { return 0; }
999
1000 // Static Functions
1001
1002 ABISP
CreateInstance(lldb::ProcessSP process_sp,const ArchSpec & arch)1003 ABISysV_hexagon::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
1004 if (arch.GetTriple().getArch() == llvm::Triple::hexagon) {
1005 return ABISP(
1006 new ABISysV_hexagon(std::move(process_sp), MakeMCRegisterInfo(arch)));
1007 }
1008 return ABISP();
1009 }
1010
PrepareTrivialCall(Thread & thread,lldb::addr_t sp,lldb::addr_t pc,lldb::addr_t ra,llvm::ArrayRef<addr_t> args) const1011 bool ABISysV_hexagon::PrepareTrivialCall(Thread &thread, lldb::addr_t sp,
1012 lldb::addr_t pc, lldb::addr_t ra,
1013 llvm::ArrayRef<addr_t> args) const {
1014 // we don't use the traditional trivial call specialized for jit
1015 return false;
1016 }
1017
1018 /*
1019
1020 // AD:
1021 // . safeguard the current stack
1022 // . how can we know that the called function will create its own frame
1023 properly?
1024 // . we could manually make a new stack first:
1025 // 2. push RA
1026 // 3. push FP
1027 // 4. FP = SP
1028 // 5. SP = SP ( since no locals in our temp frame )
1029
1030 // AD 6/05/2014
1031 // . variable argument list parameters are not passed via registers, they are
1032 passed on
1033 // the stack. This presents us with a problem, since we need to know when
1034 the valist
1035 // starts. Currently I can find out if a function is varg, but not how many
1036 // real parameters it takes. Thus I don't know when to start spilling the
1037 vargs. For
1038 // the time being, to progress, I will assume that it takes on real parameter
1039 before
1040 // the vargs list starts.
1041
1042 // AD 06/05/2014
1043 // . how do we adhere to the stack alignment requirements
1044
1045 // AD 06/05/2014
1046 // . handle 64bit values and their register / stack requirements
1047
1048 */
1049 #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) const1050 bool ABISysV_hexagon::PrepareTrivialCall(
1051 Thread &thread, lldb::addr_t sp, lldb::addr_t pc, lldb::addr_t ra,
1052 llvm::Type &prototype, llvm::ArrayRef<ABI::CallArgument> args) const {
1053 // default number of register passed arguments for varg functions
1054 const int nVArgRegParams = 1;
1055 Status error;
1056
1057 // grab the process so we have access to the memory for spilling
1058 lldb::ProcessSP proc = thread.GetProcess();
1059
1060 // get the register context for modifying all of the registers
1061 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1062 if (!reg_ctx)
1063 return false;
1064
1065 uint32_t pc_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
1066 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
1067 if (pc_reg == LLDB_INVALID_REGNUM)
1068 return false;
1069
1070 uint32_t ra_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
1071 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
1072 if (ra_reg == LLDB_INVALID_REGNUM)
1073 return false;
1074
1075 uint32_t sp_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
1076 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
1077 if (sp_reg == LLDB_INVALID_REGNUM)
1078 return false;
1079
1080 // push host data onto target
1081 for (size_t i = 0; i < args.size(); i++) {
1082 const ABI::CallArgument &arg = args[i];
1083 // skip over target values
1084 if (arg.type == ABI::CallArgument::TargetValue)
1085 continue;
1086 // round up to 8 byte multiple
1087 size_t argSize = (arg.size | 0x7) + 1;
1088
1089 // create space on the stack for this data
1090 sp -= argSize;
1091
1092 // write this argument onto the stack of the host process
1093 proc->WriteMemory(sp, arg.data_up.get(), arg.size, error);
1094 if (error.Fail())
1095 return false;
1096
1097 // update the argument with the target pointer
1098 // XXX: This is a gross hack for getting around the const
1099 *const_cast<lldb::addr_t *>(&arg.value) = sp;
1100 }
1101
1102 #if HEX_ABI_DEBUG
1103 // print the original stack pointer
1104 printf("sp : %04" PRIx64 " \n", sp);
1105 #endif
1106
1107 // make sure number of parameters matches prototype
1108 assert(prototype.getFunctionNumParams() == args.size());
1109
1110 // check if this is a variable argument function
1111 bool isVArg = prototype.isFunctionVarArg();
1112
1113 // number of arguments passed by register
1114 int nRegArgs = nVArgRegParams;
1115 if (!isVArg) {
1116 // number of arguments is limited by [R0 : R5] space
1117 nRegArgs = args.size();
1118 if (nRegArgs > 6)
1119 nRegArgs = 6;
1120 }
1121
1122 // pass arguments that are passed via registers
1123 for (int i = 0; i < nRegArgs; i++) {
1124 // get the parameter as a u32
1125 uint32_t param = (uint32_t)args[i].value;
1126 // write argument into register
1127 if (!reg_ctx->WriteRegisterFromUnsigned(i, param))
1128 return false;
1129 }
1130
1131 // number of arguments to spill onto stack
1132 int nSpillArgs = args.size() - nRegArgs;
1133 // make space on the stack for arguments
1134 sp -= 4 * nSpillArgs;
1135 // align stack on an 8 byte boundary
1136 if (sp & 7)
1137 sp -= 4;
1138
1139 // arguments that are passed on the stack
1140 for (size_t i = nRegArgs, offs = 0; i < args.size(); i++) {
1141 // get the parameter as a u32
1142 uint32_t param = (uint32_t)args[i].value;
1143 // write argument to stack
1144 proc->WriteMemory(sp + offs, (void *)¶m, sizeof(param), error);
1145 if (!error.Success())
1146 return false;
1147 //
1148 offs += 4;
1149 }
1150
1151 // update registers with current function call state
1152 reg_ctx->WriteRegisterFromUnsigned(pc_reg, pc);
1153 reg_ctx->WriteRegisterFromUnsigned(ra_reg, ra);
1154 reg_ctx->WriteRegisterFromUnsigned(sp_reg, sp);
1155
1156 #if HEX_ABI_DEBUG
1157 // quick and dirty stack dumper for debugging
1158 for (int i = -8; i < 8; i++) {
1159 uint32_t data = 0;
1160 lldb::addr_t addr = sp + i * 4;
1161 proc->ReadMemory(addr, (void *)&data, sizeof(data), error);
1162 printf("\n0x%04" PRIx64 " 0x%08x ", addr, data);
1163 if (i == 0)
1164 printf("<<-- sp");
1165 }
1166 printf("\n");
1167 #endif
1168
1169 return true;
1170 }
1171
GetArgumentValues(Thread & thread,ValueList & values) const1172 bool ABISysV_hexagon::GetArgumentValues(Thread &thread,
1173 ValueList &values) const {
1174 return false;
1175 }
1176
1177 Status
SetReturnValueObject(lldb::StackFrameSP & frame_sp,lldb::ValueObjectSP & new_value_sp)1178 ABISysV_hexagon::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
1179 lldb::ValueObjectSP &new_value_sp) {
1180 Status error;
1181 return error;
1182 }
1183
GetReturnValueObjectSimple(Thread & thread,CompilerType & return_compiler_type) const1184 ValueObjectSP ABISysV_hexagon::GetReturnValueObjectSimple(
1185 Thread &thread, CompilerType &return_compiler_type) const {
1186 ValueObjectSP return_valobj_sp;
1187 return return_valobj_sp;
1188 }
1189
GetReturnValueObjectImpl(Thread & thread,CompilerType & return_compiler_type) const1190 ValueObjectSP ABISysV_hexagon::GetReturnValueObjectImpl(
1191 Thread &thread, CompilerType &return_compiler_type) const {
1192 ValueObjectSP return_valobj_sp;
1193 return return_valobj_sp;
1194 }
1195
1196 // called when we are on the first instruction of a new function for hexagon
1197 // the return address is in RA (R31)
CreateFunctionEntryUnwindPlan(UnwindPlan & unwind_plan)1198 bool ABISysV_hexagon::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
1199 unwind_plan.Clear();
1200 unwind_plan.SetRegisterKind(eRegisterKindGeneric);
1201 unwind_plan.SetReturnAddressRegister(LLDB_REGNUM_GENERIC_RA);
1202
1203 UnwindPlan::RowSP row(new UnwindPlan::Row);
1204
1205 // Our Call Frame Address is the stack pointer value
1206 row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_SP, 4);
1207 row->SetOffset(0);
1208
1209 // The previous PC is in the LR
1210 row->SetRegisterLocationToRegister(LLDB_REGNUM_GENERIC_PC,
1211 LLDB_REGNUM_GENERIC_RA, true);
1212 unwind_plan.AppendRow(row);
1213
1214 unwind_plan.SetSourceName("hexagon at-func-entry default");
1215 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1216 return true;
1217 }
1218
CreateDefaultUnwindPlan(UnwindPlan & unwind_plan)1219 bool ABISysV_hexagon::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
1220 unwind_plan.Clear();
1221 unwind_plan.SetRegisterKind(eRegisterKindGeneric);
1222
1223 uint32_t fp_reg_num = LLDB_REGNUM_GENERIC_FP;
1224 uint32_t sp_reg_num = LLDB_REGNUM_GENERIC_SP;
1225 uint32_t pc_reg_num = LLDB_REGNUM_GENERIC_PC;
1226
1227 UnwindPlan::RowSP row(new UnwindPlan::Row);
1228
1229 row->SetUnspecifiedRegistersAreUndefined(true);
1230 row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_FP, 8);
1231
1232 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, -8, true);
1233 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, true);
1234 row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
1235
1236 unwind_plan.AppendRow(row);
1237 unwind_plan.SetSourceName("hexagon default unwind plan");
1238 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1239 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1240 unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
1241 return true;
1242 }
1243
1244 /*
1245 Register Usage Saved By
1246
1247 R0 - R5 parameters(a) -
1248 R6 - R15 Scratch(b) Caller
1249 R16 - R27 Scratch Callee
1250 R28 Scratch(b) Caller
1251 R29 - R31 Stack Frames Callee(c)
1252 P3:0 Processor State Caller
1253
1254 a = the caller can change parameter values
1255 b = R14 - R15 and R28 are used by the procedure linkage table
1256 c = R29 - R31 are saved and restored by allocframe() and deallocframe()
1257 */
RegisterIsVolatile(const RegisterInfo * reg_info)1258 bool ABISysV_hexagon::RegisterIsVolatile(const RegisterInfo *reg_info) {
1259 return !RegisterIsCalleeSaved(reg_info);
1260 }
1261
RegisterIsCalleeSaved(const RegisterInfo * reg_info)1262 bool ABISysV_hexagon::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
1263 int reg = ((reg_info->byte_offset) / 4);
1264
1265 bool save = (reg >= 16) && (reg <= 27);
1266 save |= (reg >= 29) && (reg <= 32);
1267
1268 return save;
1269 }
1270
Initialize()1271 void ABISysV_hexagon::Initialize() {
1272 PluginManager::RegisterPlugin(GetPluginNameStatic(),
1273 "System V ABI for hexagon targets",
1274 CreateInstance);
1275 }
1276
Terminate()1277 void ABISysV_hexagon::Terminate() {
1278 PluginManager::UnregisterPlugin(CreateInstance);
1279 }
1280
1281 // get value object specialized to work with llvm IR types
1282 lldb::ValueObjectSP
GetReturnValueObjectImpl(lldb_private::Thread & thread,llvm::Type & retType) const1283 ABISysV_hexagon::GetReturnValueObjectImpl(lldb_private::Thread &thread,
1284 llvm::Type &retType) const {
1285 Value value;
1286 ValueObjectSP vObjSP;
1287
1288 // get the current register context
1289 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1290 if (!reg_ctx)
1291 return vObjSP;
1292
1293 // for now just pop R0 to find the return value
1294 const lldb_private::RegisterInfo *r0_info =
1295 reg_ctx->GetRegisterInfoAtIndex(0);
1296 if (r0_info == nullptr)
1297 return vObjSP;
1298
1299 // void return type
1300 if (retType.isVoidTy()) {
1301 value.GetScalar() = 0;
1302 }
1303 // integer / pointer return type
1304 else if (retType.isIntegerTy() || retType.isPointerTy()) {
1305 // read r0 register value
1306 lldb_private::RegisterValue r0_value;
1307 if (!reg_ctx->ReadRegister(r0_info, r0_value))
1308 return vObjSP;
1309
1310 // push r0 into value
1311 uint32_t r0_u32 = r0_value.GetAsUInt32();
1312
1313 // account for integer size
1314 if (retType.isIntegerTy() && retType.isSized()) {
1315 uint64_t size = retType.getScalarSizeInBits();
1316 uint64_t mask = (1ull << size) - 1;
1317 // mask out higher order bits then the type we expect
1318 r0_u32 &= mask;
1319 }
1320
1321 value.GetScalar() = r0_u32;
1322 }
1323 // unsupported return type
1324 else
1325 return vObjSP;
1326
1327 // pack the value into a ValueObjectSP
1328 vObjSP = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
1329 value, ConstString(""));
1330 return vObjSP;
1331 }
1332