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