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