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 *
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 */
998 size_t ABISysV_hexagon::GetRedZoneSize() const { return 0; }
999 
1000 // Static Functions
1001 
1002 ABISP
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 
1011 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
1050 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 *)&param, 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 
1172 bool ABISysV_hexagon::GetArgumentValues(Thread &thread,
1173                                         ValueList &values) const {
1174   return false;
1175 }
1176 
1177 Status
1178 ABISysV_hexagon::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
1179                                       lldb::ValueObjectSP &new_value_sp) {
1180   Status error;
1181   return error;
1182 }
1183 
1184 ValueObjectSP ABISysV_hexagon::GetReturnValueObjectSimple(
1185     Thread &thread, CompilerType &return_compiler_type) const {
1186   ValueObjectSP return_valobj_sp;
1187   return return_valobj_sp;
1188 }
1189 
1190 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)
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 
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 */
1258 bool ABISysV_hexagon::RegisterIsVolatile(const RegisterInfo *reg_info) {
1259   return !RegisterIsCalleeSaved(reg_info);
1260 }
1261 
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 
1271 void ABISysV_hexagon::Initialize() {
1272   PluginManager::RegisterPlugin(GetPluginNameStatic(),
1273                                 "System V ABI for hexagon targets",
1274                                 CreateInstance);
1275 }
1276 
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
1283 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