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 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 static bool g_register_info_names_constified = false;
978 
979 const lldb_private::RegisterInfo *
980 ABISysV_hexagon::GetRegisterInfoArray(uint32_t &count) {
981   // Make the C-string names and alt_names for the register infos into const
982   // C-string values by having the ConstString unique the names in the global
983   // constant C-string pool.
984   if (!g_register_info_names_constified) {
985     g_register_info_names_constified = true;
986     for (uint32_t i = 0; i < k_num_register_infos; ++i) {
987       if (g_register_infos[i].name)
988         g_register_infos[i].name =
989             ConstString(g_register_infos[i].name).GetCString();
990       if (g_register_infos[i].alt_name)
991         g_register_infos[i].alt_name =
992             ConstString(g_register_infos[i].alt_name).GetCString();
993     }
994   }
995   count = k_num_register_infos;
996   return g_register_infos;
997 }
998 
999 /*
1000     http://en.wikipedia.org/wiki/Red_zone_%28computing%29
1001 
1002     In computing, a red zone is a fixed size area in memory beyond the stack
1003    pointer that has not been
1004     "allocated". This region of memory is not to be modified by
1005    interrupt/exception/signal handlers.
1006     This allows the space to be used for temporary data without the extra
1007    overhead of modifying the
1008     stack pointer. The x86-64 ABI mandates a 128 byte red zone.[1] The OpenRISC
1009    toolchain assumes a
1010     128 byte red zone though it is not documented.
1011 */
1012 size_t ABISysV_hexagon::GetRedZoneSize() const { return 0; }
1013 
1014 // Static Functions
1015 
1016 ABISP
1017 ABISysV_hexagon::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
1018   if (arch.GetTriple().getArch() == llvm::Triple::hexagon) {
1019     return ABISP(
1020         new ABISysV_hexagon(std::move(process_sp), MakeMCRegisterInfo(arch)));
1021   }
1022   return ABISP();
1023 }
1024 
1025 bool ABISysV_hexagon::PrepareTrivialCall(Thread &thread, lldb::addr_t sp,
1026                                          lldb::addr_t pc, lldb::addr_t ra,
1027                                          llvm::ArrayRef<addr_t> args) const {
1028   // we don't use the traditional trivial call specialized for jit
1029   return false;
1030 }
1031 
1032 /*
1033 
1034 // AD:
1035 //  . safeguard the current stack
1036 //  . how can we know that the called function will create its own frame
1037 properly?
1038 //  . we could manually make a new stack first:
1039 //      2. push RA
1040 //      3. push FP
1041 //      4. FP = SP
1042 //      5. SP = SP ( since no locals in our temp frame )
1043 
1044 // AD 6/05/2014
1045 //  . variable argument list parameters are not passed via registers, they are
1046 passed on
1047 //    the stack.  This presents us with a problem, since we need to know when
1048 the valist
1049 //    starts.  Currently I can find out if a function is varg, but not how many
1050 //    real parameters it takes.  Thus I don't know when to start spilling the
1051 vargs.  For
1052 //    the time being, to progress, I will assume that it takes on real parameter
1053 before
1054 //    the vargs list starts.
1055 
1056 // AD 06/05/2014
1057 //  . how do we adhere to the stack alignment requirements
1058 
1059 // AD 06/05/2014
1060 //  . handle 64bit values and their register / stack requirements
1061 
1062 */
1063 #define HEX_ABI_DEBUG 0
1064 bool ABISysV_hexagon::PrepareTrivialCall(
1065     Thread &thread, lldb::addr_t sp, lldb::addr_t pc, lldb::addr_t ra,
1066     llvm::Type &prototype, llvm::ArrayRef<ABI::CallArgument> args) const {
1067   // default number of register passed arguments for varg functions
1068   const int nVArgRegParams = 1;
1069   Status error;
1070 
1071   // grab the process so we have access to the memory for spilling
1072   lldb::ProcessSP proc = thread.GetProcess();
1073 
1074   // get the register context for modifying all of the registers
1075   RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1076   if (!reg_ctx)
1077     return false;
1078 
1079   uint32_t pc_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
1080       eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
1081   if (pc_reg == LLDB_INVALID_REGNUM)
1082     return false;
1083 
1084   uint32_t ra_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
1085       eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
1086   if (ra_reg == LLDB_INVALID_REGNUM)
1087     return false;
1088 
1089   uint32_t sp_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
1090       eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
1091   if (sp_reg == LLDB_INVALID_REGNUM)
1092     return false;
1093 
1094   // push host data onto target
1095   for (size_t i = 0; i < args.size(); i++) {
1096     const ABI::CallArgument &arg = args[i];
1097     // skip over target values
1098     if (arg.type == ABI::CallArgument::TargetValue)
1099       continue;
1100     // round up to 8 byte multiple
1101     size_t argSize = (arg.size | 0x7) + 1;
1102 
1103     // create space on the stack for this data
1104     sp -= argSize;
1105 
1106     // write this argument onto the stack of the host process
1107     proc->WriteMemory(sp, arg.data_up.get(), arg.size, error);
1108     if (error.Fail())
1109       return false;
1110 
1111     // update the argument with the target pointer
1112     // XXX: This is a gross hack for getting around the const
1113     *const_cast<lldb::addr_t *>(&arg.value) = sp;
1114   }
1115 
1116 #if HEX_ABI_DEBUG
1117   // print the original stack pointer
1118   printf("sp : %04" PRIx64 " \n", sp);
1119 #endif
1120 
1121   // make sure number of parameters matches prototype
1122   assert(prototype.getFunctionNumParams() == args.size());
1123 
1124   // check if this is a variable argument function
1125   bool isVArg = prototype.isFunctionVarArg();
1126 
1127   // number of arguments passed by register
1128   int nRegArgs = nVArgRegParams;
1129   if (!isVArg) {
1130     // number of arguments is limited by [R0 : R5] space
1131     nRegArgs = args.size();
1132     if (nRegArgs > 6)
1133       nRegArgs = 6;
1134   }
1135 
1136   // pass arguments that are passed via registers
1137   for (int i = 0; i < nRegArgs; i++) {
1138     // get the parameter as a u32
1139     uint32_t param = (uint32_t)args[i].value;
1140     // write argument into register
1141     if (!reg_ctx->WriteRegisterFromUnsigned(i, param))
1142       return false;
1143   }
1144 
1145   // number of arguments to spill onto stack
1146   int nSpillArgs = args.size() - nRegArgs;
1147   // make space on the stack for arguments
1148   sp -= 4 * nSpillArgs;
1149   // align stack on an 8 byte boundary
1150   if (sp & 7)
1151     sp -= 4;
1152 
1153   // arguments that are passed on the stack
1154   for (size_t i = nRegArgs, offs = 0; i < args.size(); i++) {
1155     // get the parameter as a u32
1156     uint32_t param = (uint32_t)args[i].value;
1157     // write argument to stack
1158     proc->WriteMemory(sp + offs, (void *)&param, sizeof(param), error);
1159     if (!error.Success())
1160       return false;
1161     //
1162     offs += 4;
1163   }
1164 
1165   // update registers with current function call state
1166   reg_ctx->WriteRegisterFromUnsigned(pc_reg, pc);
1167   reg_ctx->WriteRegisterFromUnsigned(ra_reg, ra);
1168   reg_ctx->WriteRegisterFromUnsigned(sp_reg, sp);
1169 
1170 #if HEX_ABI_DEBUG
1171   // quick and dirty stack dumper for debugging
1172   for (int i = -8; i < 8; i++) {
1173     uint32_t data = 0;
1174     lldb::addr_t addr = sp + i * 4;
1175     proc->ReadMemory(addr, (void *)&data, sizeof(data), error);
1176     printf("\n0x%04" PRIx64 " 0x%08x ", addr, data);
1177     if (i == 0)
1178       printf("<<-- sp");
1179   }
1180   printf("\n");
1181 #endif
1182 
1183   return true;
1184 }
1185 
1186 bool ABISysV_hexagon::GetArgumentValues(Thread &thread,
1187                                         ValueList &values) const {
1188   return false;
1189 }
1190 
1191 Status
1192 ABISysV_hexagon::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
1193                                       lldb::ValueObjectSP &new_value_sp) {
1194   Status error;
1195   return error;
1196 }
1197 
1198 ValueObjectSP ABISysV_hexagon::GetReturnValueObjectSimple(
1199     Thread &thread, CompilerType &return_compiler_type) const {
1200   ValueObjectSP return_valobj_sp;
1201   return return_valobj_sp;
1202 }
1203 
1204 ValueObjectSP ABISysV_hexagon::GetReturnValueObjectImpl(
1205     Thread &thread, CompilerType &return_compiler_type) const {
1206   ValueObjectSP return_valobj_sp;
1207   return return_valobj_sp;
1208 }
1209 
1210 // called when we are on the first instruction of a new function for hexagon
1211 // the return address is in RA (R31)
1212 bool ABISysV_hexagon::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
1213   unwind_plan.Clear();
1214   unwind_plan.SetRegisterKind(eRegisterKindGeneric);
1215   unwind_plan.SetReturnAddressRegister(LLDB_REGNUM_GENERIC_RA);
1216 
1217   UnwindPlan::RowSP row(new UnwindPlan::Row);
1218 
1219   // Our Call Frame Address is the stack pointer value
1220   row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_SP, 4);
1221   row->SetOffset(0);
1222 
1223   // The previous PC is in the LR
1224   row->SetRegisterLocationToRegister(LLDB_REGNUM_GENERIC_PC,
1225                                      LLDB_REGNUM_GENERIC_RA, true);
1226   unwind_plan.AppendRow(row);
1227 
1228   unwind_plan.SetSourceName("hexagon at-func-entry default");
1229   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1230   return true;
1231 }
1232 
1233 bool ABISysV_hexagon::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
1234   unwind_plan.Clear();
1235   unwind_plan.SetRegisterKind(eRegisterKindGeneric);
1236 
1237   uint32_t fp_reg_num = LLDB_REGNUM_GENERIC_FP;
1238   uint32_t sp_reg_num = LLDB_REGNUM_GENERIC_SP;
1239   uint32_t pc_reg_num = LLDB_REGNUM_GENERIC_PC;
1240 
1241   UnwindPlan::RowSP row(new UnwindPlan::Row);
1242 
1243   row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_FP, 8);
1244 
1245   row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, -8, true);
1246   row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, true);
1247   row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
1248 
1249   unwind_plan.AppendRow(row);
1250   unwind_plan.SetSourceName("hexagon default unwind plan");
1251   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1252   unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1253   unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
1254   return true;
1255 }
1256 
1257 /*
1258     Register		Usage					Saved By
1259 
1260     R0  - R5		parameters(a)			-
1261     R6  - R15		Scratch(b)				Caller
1262     R16 - R27		Scratch					Callee
1263     R28				Scratch(b)				Caller
1264     R29 - R31		Stack Frames			Callee(c)
1265     P3:0			Processor State			Caller
1266 
1267     a = the caller can change parameter values
1268     b = R14 - R15 and R28 are used by the procedure linkage table
1269     c = R29 - R31 are saved and restored by allocframe() and deallocframe()
1270 */
1271 bool ABISysV_hexagon::RegisterIsVolatile(const RegisterInfo *reg_info) {
1272   return !RegisterIsCalleeSaved(reg_info);
1273 }
1274 
1275 bool ABISysV_hexagon::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
1276   int reg = ((reg_info->byte_offset) / 4);
1277 
1278   bool save = (reg >= 16) && (reg <= 27);
1279   save |= (reg >= 29) && (reg <= 32);
1280 
1281   return save;
1282 }
1283 
1284 void ABISysV_hexagon::Initialize() {
1285   PluginManager::RegisterPlugin(GetPluginNameStatic(),
1286                                 "System V ABI for hexagon targets",
1287                                 CreateInstance);
1288 }
1289 
1290 void ABISysV_hexagon::Terminate() {
1291   PluginManager::UnregisterPlugin(CreateInstance);
1292 }
1293 
1294 lldb_private::ConstString ABISysV_hexagon::GetPluginNameStatic() {
1295   static ConstString g_name("sysv-hexagon");
1296   return g_name;
1297 }
1298 
1299 // PluginInterface protocol
1300 
1301 lldb_private::ConstString ABISysV_hexagon::GetPluginName() {
1302   return GetPluginNameStatic();
1303 }
1304 
1305 uint32_t ABISysV_hexagon::GetPluginVersion() { return 1; }
1306 
1307 // get value object specialized to work with llvm IR types
1308 lldb::ValueObjectSP
1309 ABISysV_hexagon::GetReturnValueObjectImpl(lldb_private::Thread &thread,
1310                                           llvm::Type &retType) const {
1311   Value value;
1312   ValueObjectSP vObjSP;
1313 
1314   // get the current register context
1315   RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1316   if (!reg_ctx)
1317     return vObjSP;
1318 
1319   // for now just pop R0 to find the return value
1320   const lldb_private::RegisterInfo *r0_info =
1321       reg_ctx->GetRegisterInfoAtIndex(0);
1322   if (r0_info == nullptr)
1323     return vObjSP;
1324 
1325   // void return type
1326   if (retType.isVoidTy()) {
1327     value.GetScalar() = 0;
1328   }
1329   // integer / pointer return type
1330   else if (retType.isIntegerTy() || retType.isPointerTy()) {
1331     // read r0 register value
1332     lldb_private::RegisterValue r0_value;
1333     if (!reg_ctx->ReadRegister(r0_info, r0_value))
1334       return vObjSP;
1335 
1336     // push r0 into value
1337     uint32_t r0_u32 = r0_value.GetAsUInt32();
1338 
1339     // account for integer size
1340     if (retType.isIntegerTy() && retType.isSized()) {
1341       uint64_t size = retType.getScalarSizeInBits();
1342       uint64_t mask = (1ull << size) - 1;
1343       // mask out higher order bits then the type we expect
1344       r0_u32 &= mask;
1345     }
1346 
1347     value.GetScalar() = r0_u32;
1348   }
1349   // unsupported return type
1350   else
1351     return vObjSP;
1352 
1353   // pack the value into a ValueObjectSP
1354   vObjSP = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
1355                                           value, ConstString(""));
1356   return vObjSP;
1357 }
1358