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 *)&param, 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