LLDB  mainline
ABISysV_hexagon.cpp
Go to the documentation of this file.
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"
16 #include "lldb/Core/Value.h"
20 #include "lldb/Symbol/UnwindPlan.h"
21 #include "lldb/Target/Process.h"
23 #include "lldb/Target/StackFrame.h"
24 #include "lldb/Target/Target.h"
25 #include "lldb/Target/Thread.h"
28 #include "lldb/Utility/Log.h"
30 #include "lldb/Utility/Status.h"
31 
32 using namespace lldb;
33 using namespace lldb_private;
34 
35 static RegisterInfo g_register_infos[] = {
36  // hexagon-core.xml
37  {"r00",
38  "",
39  4,
40  0,
43  {0, 0, LLDB_INVALID_REGNUM, 0, 0},
44  nullptr,
45  nullptr,
46  nullptr,
47  0},
48  {"r01",
49  "",
50  4,
51  0,
54  {1, 1, LLDB_INVALID_REGNUM, 1, 1},
55  nullptr,
56  nullptr,
57  nullptr,
58  0},
59  {"r02",
60  "",
61  4,
62  0,
65  {2, 2, LLDB_INVALID_REGNUM, 2, 2},
66  nullptr,
67  nullptr,
68  nullptr,
69  0},
70  {"r03",
71  "",
72  4,
73  0,
76  {3, 3, LLDB_INVALID_REGNUM, 3, 3},
77  nullptr,
78  nullptr,
79  nullptr,
80  0},
81  {"r04",
82  "",
83  4,
84  0,
87  {4, 4, LLDB_INVALID_REGNUM, 4, 4},
88  nullptr,
89  nullptr,
90  nullptr,
91  0},
92  {"r05",
93  "",
94  4,
95  0,
98  {5, 5, LLDB_INVALID_REGNUM, 5, 5},
99  nullptr,
100  nullptr,
101  nullptr,
102  0},
103  {"r06",
104  "",
105  4,
106  0,
109  {6, 6, LLDB_INVALID_REGNUM, 6, 6},
110  nullptr,
111  nullptr,
112  nullptr,
113  0},
114  {"r07",
115  "",
116  4,
117  0,
120  {7, 7, LLDB_INVALID_REGNUM, 7, 7},
121  nullptr,
122  nullptr,
123  nullptr,
124  0},
125  {"r08",
126  "",
127  4,
128  0,
131  {8, 8, LLDB_INVALID_REGNUM, 8, 8},
132  nullptr,
133  nullptr,
134  nullptr,
135  0},
136  {"r09",
137  "",
138  4,
139  0,
142  {9, 9, LLDB_INVALID_REGNUM, 9, 9},
143  nullptr,
144  nullptr,
145  nullptr,
146  0},
147  {"r10",
148  "",
149  4,
150  0,
153  {10, 10, LLDB_INVALID_REGNUM, 10, 10},
154  nullptr,
155  nullptr,
156  nullptr,
157  0},
158  {"r11",
159  "",
160  4,
161  0,
164  {11, 11, LLDB_INVALID_REGNUM, 11, 11},
165  nullptr,
166  nullptr,
167  nullptr,
168  0},
169  {"r12",
170  "",
171  4,
172  0,
175  {12, 12, LLDB_INVALID_REGNUM, 12, 12},
176  nullptr,
177  nullptr,
178  nullptr,
179  0},
180  {"r13",
181  "",
182  4,
183  0,
186  {13, 13, LLDB_INVALID_REGNUM, 13, 13},
187  nullptr,
188  nullptr,
189  nullptr,
190  0},
191  {"r14",
192  "",
193  4,
194  0,
197  {14, 14, LLDB_INVALID_REGNUM, 14, 14},
198  nullptr,
199  nullptr,
200  nullptr,
201  0},
202  {"r15",
203  "",
204  4,
205  0,
208  {15, 15, LLDB_INVALID_REGNUM, 15, 15},
209  nullptr,
210  nullptr,
211  nullptr,
212  0},
213  {"r16",
214  "",
215  4,
216  0,
219  {16, 16, LLDB_INVALID_REGNUM, 16, 16},
220  nullptr,
221  nullptr,
222  nullptr,
223  0},
224  {"r17",
225  "",
226  4,
227  0,
230  {17, 17, LLDB_INVALID_REGNUM, 17, 17},
231  nullptr,
232  nullptr,
233  nullptr,
234  0},
235  {"r18",
236  "",
237  4,
238  0,
241  {18, 18, LLDB_INVALID_REGNUM, 18, 18},
242  nullptr,
243  nullptr,
244  nullptr,
245  0},
246  {"r19",
247  "",
248  4,
249  0,
252  {19, 19, LLDB_INVALID_REGNUM, 19, 19},
253  nullptr,
254  nullptr,
255  nullptr,
256  0},
257  {"r20",
258  "",
259  4,
260  0,
263  {20, 20, LLDB_INVALID_REGNUM, 20, 20},
264  nullptr,
265  nullptr,
266  nullptr,
267  0},
268  {"r21",
269  "",
270  4,
271  0,
274  {21, 21, LLDB_INVALID_REGNUM, 21, 21},
275  nullptr,
276  nullptr,
277  nullptr,
278  0},
279  {"r22",
280  "",
281  4,
282  0,
285  {22, 22, LLDB_INVALID_REGNUM, 22, 22},
286  nullptr,
287  nullptr,
288  nullptr,
289  0},
290  {"r23",
291  "",
292  4,
293  0,
296  {23, 23, LLDB_INVALID_REGNUM, 23, 23},
297  nullptr,
298  nullptr,
299  nullptr,
300  0},
301  {"r24",
302  "",
303  4,
304  0,
307  {24, 24, LLDB_INVALID_REGNUM, 24, 24},
308  nullptr,
309  nullptr,
310  nullptr,
311  0},
312  {"r25",
313  "",
314  4,
315  0,
318  {25, 25, LLDB_INVALID_REGNUM, 25, 25},
319  nullptr,
320  nullptr,
321  nullptr,
322  0},
323  {"r26",
324  "",
325  4,
326  0,
329  {26, 26, LLDB_INVALID_REGNUM, 26, 26},
330  nullptr,
331  nullptr,
332  nullptr,
333  0},
334  {"r27",
335  "",
336  4,
337  0,
340  {27, 27, LLDB_INVALID_REGNUM, 27, 27},
341  nullptr,
342  nullptr,
343  nullptr,
344  0},
345  {"r28",
346  "",
347  4,
348  0,
351  {28, 28, LLDB_INVALID_REGNUM, 28, 28},
352  nullptr,
353  nullptr,
354  nullptr,
355  0},
356  {"sp",
357  "r29",
358  4,
359  0,
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,
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,
384  {31, 31, LLDB_REGNUM_GENERIC_RA, 31, 31},
385  nullptr,
386  nullptr,
387  nullptr,
388  0},
389  {"sa0",
390  "",
391  4,
392  0,
395  {32, 32, LLDB_INVALID_REGNUM, 32, 32},
396  nullptr,
397  nullptr,
398  nullptr,
399  0},
400  {"lc0",
401  "",
402  4,
403  0,
406  {33, 33, LLDB_INVALID_REGNUM, 33, 33},
407  nullptr,
408  nullptr,
409  nullptr,
410  0},
411  {"sa1",
412  "",
413  4,
414  0,
417  {34, 34, LLDB_INVALID_REGNUM, 34, 34},
418  nullptr,
419  nullptr,
420  nullptr,
421  0},
422  {"lc1",
423  "",
424  4,
425  0,
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,
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,
452  {37, 37, LLDB_INVALID_REGNUM, 37, 37},
453  nullptr,
454  nullptr,
455  nullptr,
456  0},
457  // }
458  {"m0",
459  "",
460  4,
461  0,
464  {38, 38, LLDB_INVALID_REGNUM, 38, 38},
465  nullptr,
466  nullptr,
467  nullptr,
468  0},
469  {"m1",
470  "",
471  4,
472  0,
475  {39, 39, LLDB_INVALID_REGNUM, 39, 39},
476  nullptr,
477  nullptr,
478  nullptr,
479  0},
480  {"usr",
481  "",
482  4,
483  0,
486  {40, 40, LLDB_INVALID_REGNUM, 40, 40},
487  nullptr,
488  nullptr,
489  nullptr,
490  0},
491  {"pc",
492  "",
493  4,
494  0,
497  {41, 41, LLDB_REGNUM_GENERIC_PC, 41, 41},
498  nullptr,
499  nullptr,
500  nullptr,
501  0},
502  {"ugp",
503  "",
504  4,
505  0,
508  {42, 42, LLDB_INVALID_REGNUM, 42, 42},
509  nullptr,
510  nullptr,
511  nullptr,
512  0},
513  {"gp",
514  "",
515  4,
516  0,
519  {43, 43, LLDB_INVALID_REGNUM, 43, 43},
520  nullptr,
521  nullptr,
522  nullptr,
523  0},
524  {"cs0",
525  "",
526  4,
527  0,
530  {44, 44, LLDB_INVALID_REGNUM, 44, 44},
531  nullptr,
532  nullptr,
533  nullptr,
534  0},
535  {"cs1",
536  "",
537  4,
538  0,
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,
553  {46, 46, LLDB_INVALID_REGNUM, 46, 46},
554  nullptr,
555  nullptr,
556  nullptr,
557  0},
558  {"p02",
559  "",
560  4,
561  0,
564  {47, 47, LLDB_INVALID_REGNUM, 47, 47},
565  nullptr,
566  nullptr,
567  nullptr,
568  0},
569  {"p03",
570  "",
571  4,
572  0,
575  {48, 48, LLDB_INVALID_REGNUM, 48, 48},
576  nullptr,
577  nullptr,
578  nullptr,
579  0},
580  {"p04",
581  "",
582  4,
583  0,
586  {49, 49, LLDB_INVALID_REGNUM, 49, 49},
587  nullptr,
588  nullptr,
589  nullptr,
590  0},
591  {"p05",
592  "",
593  4,
594  0,
597  {50, 50, LLDB_INVALID_REGNUM, 50, 50},
598  nullptr,
599  nullptr,
600  nullptr,
601  0},
602  {"p06",
603  "",
604  4,
605  0,
608  {51, 51, LLDB_INVALID_REGNUM, 51, 51},
609  nullptr,
610  nullptr,
611  nullptr,
612  0},
613  {"p07",
614  "",
615  4,
616  0,
619  {52, 52, LLDB_INVALID_REGNUM, 52, 52},
620  nullptr,
621  nullptr,
622  nullptr,
623  0},
624  {"p08",
625  "",
626  4,
627  0,
630  {53, 53, LLDB_INVALID_REGNUM, 53, 53},
631  nullptr,
632  nullptr,
633  nullptr,
634  0},
635  {"p09",
636  "",
637  4,
638  0,
641  {54, 54, LLDB_INVALID_REGNUM, 54, 54},
642  nullptr,
643  nullptr,
644  nullptr,
645  0},
646  {"p10",
647  "",
648  4,
649  0,
652  {55, 55, LLDB_INVALID_REGNUM, 55, 55},
653  nullptr,
654  nullptr,
655  nullptr,
656  0},
657  {"p11",
658  "",
659  4,
660  0,
663  {56, 56, LLDB_INVALID_REGNUM, 56, 56},
664  nullptr,
665  nullptr,
666  nullptr,
667  0},
668  {"p12",
669  "",
670  4,
671  0,
674  {57, 57, LLDB_INVALID_REGNUM, 57, 57},
675  nullptr,
676  nullptr,
677  nullptr,
678  0},
679  {"p13",
680  "",
681  4,
682  0,
685  {58, 58, LLDB_INVALID_REGNUM, 58, 58},
686  nullptr,
687  nullptr,
688  nullptr,
689  0},
690  {"p14",
691  "",
692  4,
693  0,
696  {59, 59, LLDB_INVALID_REGNUM, 59, 59},
697  nullptr,
698  nullptr,
699  nullptr,
700  0},
701  {"p15",
702  "",
703  4,
704  0,
707  {60, 60, LLDB_INVALID_REGNUM, 60, 60},
708  nullptr,
709  nullptr,
710  nullptr,
711  0},
712  {"p16",
713  "",
714  4,
715  0,
718  {61, 61, LLDB_INVALID_REGNUM, 61, 61},
719  nullptr,
720  nullptr,
721  nullptr,
722  0},
723  {"p17",
724  "",
725  4,
726  0,
729  {62, 62, LLDB_INVALID_REGNUM, 62, 62},
730  nullptr,
731  nullptr,
732  nullptr,
733  0},
734  {"p18",
735  "",
736  4,
737  0,
740  {63, 63, LLDB_INVALID_REGNUM, 63, 63},
741  nullptr,
742  nullptr,
743  nullptr,
744  0},
745  // }
746  {"sgp0",
747  "",
748  4,
749  0,
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,
764  {65, 65, LLDB_INVALID_REGNUM, 65, 65},
765  nullptr,
766  nullptr,
767  nullptr,
768  0},
769  // }
770  {"stid",
771  "",
772  4,
773  0,
776  {66, 66, LLDB_INVALID_REGNUM, 66, 66},
777  nullptr,
778  nullptr,
779  nullptr,
780  0},
781  {"elr",
782  "",
783  4,
784  0,
787  {67, 67, LLDB_INVALID_REGNUM, 67, 67},
788  nullptr,
789  nullptr,
790  nullptr,
791  0},
792  {"badva0",
793  "",
794  4,
795  0,
798  {68, 68, LLDB_INVALID_REGNUM, 68, 68},
799  nullptr,
800  nullptr,
801  nullptr,
802  0},
803  {"badva1",
804  "",
805  4,
806  0,
809  {69, 69, LLDB_INVALID_REGNUM, 69, 69},
810  nullptr,
811  nullptr,
812  nullptr,
813  0},
814  {"ssr",
815  "",
816  4,
817  0,
820  {70, 70, LLDB_INVALID_REGNUM, 70, 70},
821  nullptr,
822  nullptr,
823  nullptr,
824  0},
825  {"ccr",
826  "",
827  4,
828  0,
831  {71, 71, LLDB_INVALID_REGNUM, 71, 71},
832  nullptr,
833  nullptr,
834  nullptr,
835  0},
836  {"htid",
837  "",
838  4,
839  0,
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,
854  {73, 73, LLDB_INVALID_REGNUM, 73, 73},
855  nullptr,
856  nullptr,
857  nullptr,
858  0},
859  // }
860  {"imask",
861  "",
862  4,
863  0,
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,
878  {75, 75, LLDB_INVALID_REGNUM, 75, 75},
879  nullptr,
880  nullptr,
881  nullptr,
882  0},
883  {"p22",
884  "",
885  4,
886  0,
889  {76, 76, LLDB_INVALID_REGNUM, 76, 76},
890  nullptr,
891  nullptr,
892  nullptr,
893  0},
894  {"p23",
895  "",
896  4,
897  0,
900  {77, 77, LLDB_INVALID_REGNUM, 77, 77},
901  nullptr,
902  nullptr,
903  nullptr,
904  0},
905  {"p24",
906  "",
907  4,
908  0,
911  {78, 78, LLDB_INVALID_REGNUM, 78, 78},
912  nullptr,
913  nullptr,
914  nullptr,
915  0},
916  {"p25",
917  "",
918  4,
919  0,
922  {79, 79, LLDB_INVALID_REGNUM, 79, 79},
923  nullptr,
924  nullptr,
925  nullptr,
926  0},
927  // }
928  {"g0",
929  "",
930  4,
931  0,
934  {80, 80, LLDB_INVALID_REGNUM, 80, 80},
935  nullptr,
936  nullptr,
937  nullptr,
938  0},
939  {"g1",
940  "",
941  4,
942  0,
945  {81, 81, LLDB_INVALID_REGNUM, 81, 81},
946  nullptr,
947  nullptr,
948  nullptr,
949  0},
950  {"g2",
951  "",
952  4,
953  0,
956  {82, 82, LLDB_INVALID_REGNUM, 82, 82},
957  nullptr,
958  nullptr,
959  nullptr,
960  0},
961  {"g3",
962  "",
963  4,
964  0,
967  {83, 83, LLDB_INVALID_REGNUM, 83, 83},
968  nullptr,
969  nullptr,
970  nullptr,
971  0}};
972 
974  sizeof(g_register_infos) / sizeof(RegisterInfo);
976 
977 const lldb_private::RegisterInfo *
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 =
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 */
1010 size_t ABISysV_hexagon::GetRedZoneSize() const { return 0; }
1011 
1012 // Static Functions
1013 
1014 ABISP
1015 ABISysV_hexagon::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
1016  if (arch.GetTriple().getArch() == llvm::Triple::hexagon) {
1017  return ABISP(new ABISysV_hexagon(process_sp));
1018  }
1019  return ABISP();
1020 }
1021 
1024  llvm::ArrayRef<addr_t> args) const {
1025  // we don't use the traditional trivial call specialized for jit
1026  return false;
1027 }
1028 
1029 /*
1030 
1031 // AD:
1032 // . safeguard the current stack
1033 // . how can we know that the called function will create its own frame
1034 properly?
1035 // . we could manually make a new stack first:
1036 // 2. push RA
1037 // 3. push FP
1038 // 4. FP = SP
1039 // 5. SP = SP ( since no locals in our temp frame )
1040 
1041 // AD 6/05/2014
1042 // . variable argument list parameters are not passed via registers, they are
1043 passed on
1044 // the stack. This presents us with a problem, since we need to know when
1045 the valist
1046 // starts. Currently I can find out if a function is varg, but not how many
1047 // real parameters it takes. Thus I don't know when to start spilling the
1048 vargs. For
1049 // the time being, to progress, I will assume that it takes on real parameter
1050 before
1051 // the vargs list starts.
1052 
1053 // AD 06/05/2014
1054 // . how do we adhere to the stack alignment requirements
1055 
1056 // AD 06/05/2014
1057 // . handle 64bit values and their register / stack requirements
1058 
1059 */
1060 #define HEX_ABI_DEBUG 0
1062  Thread &thread, lldb::addr_t sp, lldb::addr_t pc, lldb::addr_t ra,
1063  llvm::Type &prototype, llvm::ArrayRef<ABI::CallArgument> args) const {
1064  // default number of register passed arguments for varg functions
1065  const int nVArgRegParams = 1;
1066  Status error;
1067 
1068  // grab the process so we have access to the memory for spilling
1069  lldb::ProcessSP proc = thread.GetProcess();
1070 
1071  // get the register context for modifying all of the registers
1072  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1073  if (!reg_ctx)
1074  return false;
1075 
1078  if (pc_reg == LLDB_INVALID_REGNUM)
1079  return false;
1080 
1083  if (ra_reg == LLDB_INVALID_REGNUM)
1084  return false;
1085 
1088  if (sp_reg == LLDB_INVALID_REGNUM)
1089  return false;
1090 
1091  // push host data onto target
1092  for (size_t i = 0; i < args.size(); i++) {
1093  const ABI::CallArgument &arg = args[i];
1094  // skip over target values
1095  if (arg.type == ABI::CallArgument::TargetValue)
1096  continue;
1097  // round up to 8 byte multiple
1098  size_t argSize = (arg.size | 0x7) + 1;
1099 
1100  // create space on the stack for this data
1101  sp -= argSize;
1102 
1103  // write this argument onto the stack of the host process
1104  proc->WriteMemory(sp, arg.data_up.get(), arg.size, error);
1105  if (error.Fail())
1106  return false;
1107 
1108  // update the argument with the target pointer
1109  // XXX: This is a gross hack for getting around the const
1110  *const_cast<lldb::addr_t *>(&arg.value) = sp;
1111  }
1112 
1113 #if HEX_ABI_DEBUG
1114  // print the original stack pointer
1115  printf("sp : %04" PRIx64 " \n", sp);
1116 #endif
1117 
1118  // make sure number of parameters matches prototype
1119  assert(prototype.getFunctionNumParams() == args.size());
1120 
1121  // check if this is a variable argument function
1122  bool isVArg = prototype.isFunctionVarArg();
1123 
1124  // number of arguments passed by register
1125  int nRegArgs = nVArgRegParams;
1126  if (!isVArg) {
1127  // number of arguments is limited by [R0 : R5] space
1128  nRegArgs = args.size();
1129  if (nRegArgs > 6)
1130  nRegArgs = 6;
1131  }
1132 
1133  // pass arguments that are passed via registers
1134  for (int i = 0; i < nRegArgs; i++) {
1135  // get the parameter as a u32
1136  uint32_t param = (uint32_t)args[i].value;
1137  // write argument into register
1138  if (!reg_ctx->WriteRegisterFromUnsigned(i, param))
1139  return false;
1140  }
1141 
1142  // number of arguments to spill onto stack
1143  int nSpillArgs = args.size() - nRegArgs;
1144  // make space on the stack for arguments
1145  sp -= 4 * nSpillArgs;
1146  // align stack on an 8 byte boundary
1147  if (sp & 7)
1148  sp -= 4;
1149 
1150  // arguments that are passed on the stack
1151  for (size_t i = nRegArgs, offs = 0; i < args.size(); i++) {
1152  // get the parameter as a u32
1153  uint32_t param = (uint32_t)args[i].value;
1154  // write argument to stack
1155  proc->WriteMemory(sp + offs, (void *)&param, sizeof(param), error);
1156  if (!error.Success())
1157  return false;
1158  //
1159  offs += 4;
1160  }
1161 
1162  // update registers with current function call state
1163  reg_ctx->WriteRegisterFromUnsigned(pc_reg, pc);
1164  reg_ctx->WriteRegisterFromUnsigned(ra_reg, ra);
1165  reg_ctx->WriteRegisterFromUnsigned(sp_reg, sp);
1166 
1167 #if HEX_ABI_DEBUG
1168  // quick and dirty stack dumper for debugging
1169  for (int i = -8; i < 8; i++) {
1170  uint32_t data = 0;
1171  lldb::addr_t addr = sp + i * 4;
1172  proc->ReadMemory(addr, (void *)&data, sizeof(data), error);
1173  printf("\n0x%04" PRIx64 " 0x%08x ", addr, data);
1174  if (i == 0)
1175  printf("<<-- sp");
1176  }
1177  printf("\n");
1178 #endif
1179 
1180  return true;
1181 }
1182 
1184  ValueList &values) const {
1185  return false;
1186 }
1187 
1188 Status
1189 ABISysV_hexagon::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
1190  lldb::ValueObjectSP &new_value_sp) {
1191  Status error;
1192  return error;
1193 }
1194 
1196  Thread &thread, CompilerType &return_compiler_type) const {
1197  ValueObjectSP return_valobj_sp;
1198  return return_valobj_sp;
1199 }
1200 
1202  Thread &thread, CompilerType &return_compiler_type) const {
1203  ValueObjectSP return_valobj_sp;
1204  return return_valobj_sp;
1205 }
1206 
1207 // called when we are on the first instruction of a new function for hexagon
1208 // the return address is in RA (R31)
1210  unwind_plan.Clear();
1213 
1215 
1216  // Our Call Frame Address is the stack pointer value
1217  row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_SP, 4);
1218  row->SetOffset(0);
1219 
1220  // The previous PC is in the LR
1221  row->SetRegisterLocationToRegister(LLDB_REGNUM_GENERIC_PC,
1222  LLDB_REGNUM_GENERIC_RA, true);
1223  unwind_plan.AppendRow(row);
1224 
1225  unwind_plan.SetSourceName("hexagon at-func-entry default");
1226  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1227  return true;
1228 }
1229 
1231  unwind_plan.Clear();
1233 
1234  uint32_t fp_reg_num = LLDB_REGNUM_GENERIC_FP;
1235  uint32_t sp_reg_num = LLDB_REGNUM_GENERIC_SP;
1236  uint32_t pc_reg_num = LLDB_REGNUM_GENERIC_PC;
1237 
1239 
1240  row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_FP, 8);
1241 
1242  row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, -8, true);
1243  row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, true);
1244  row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
1245 
1246  unwind_plan.AppendRow(row);
1247  unwind_plan.SetSourceName("hexagon default unwind plan");
1248  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1250  return true;
1251 }
1252 
1253 /*
1254  Register Usage Saved By
1255 
1256  R0 - R5 parameters(a) -
1257  R6 - R15 Scratch(b) Caller
1258  R16 - R27 Scratch Callee
1259  R28 Scratch(b) Caller
1260  R29 - R31 Stack Frames Callee(c)
1261  P3:0 Processor State Caller
1262 
1263  a = the caller can change parameter values
1264  b = R14 - R15 and R28 are used by the procedure linkage table
1265  c = R29 - R31 are saved and restored by allocframe() and deallocframe()
1266 */
1267 bool ABISysV_hexagon::RegisterIsVolatile(const RegisterInfo *reg_info) {
1268  return !RegisterIsCalleeSaved(reg_info);
1269 }
1270 
1271 bool ABISysV_hexagon::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
1272  int reg = ((reg_info->byte_offset) / 4);
1273 
1274  bool save = (reg >= 16) && (reg <= 27);
1275  save |= (reg >= 29) && (reg <= 32);
1276 
1277  return save;
1278 }
1279 
1281  PluginManager::RegisterPlugin(GetPluginNameStatic(),
1282  "System V ABI for hexagon targets",
1283  CreateInstance);
1284 }
1285 
1287  PluginManager::UnregisterPlugin(CreateInstance);
1288 }
1289 
1291  static ConstString g_name("sysv-hexagon");
1292  return g_name;
1293 }
1294 
1295 // PluginInterface protocol
1296 
1298  return GetPluginNameStatic();
1299 }
1300 
1302 
1303 // get value object specialized to work with llvm IR types
1304 lldb::ValueObjectSP
1306  llvm::Type &retType) const {
1307  Value value;
1308  ValueObjectSP vObjSP;
1309 
1310  // get the current register context
1311  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1312  if (!reg_ctx)
1313  return vObjSP;
1314 
1315  // for now just pop R0 to find the return value
1316  const lldb_private::RegisterInfo *r0_info =
1317  reg_ctx->GetRegisterInfoAtIndex(0);
1318  if (r0_info == nullptr)
1319  return vObjSP;
1320 
1321  // void return type
1322  if (retType.isVoidTy()) {
1323  value.GetScalar() = 0;
1324  }
1325  // integer / pointer return type
1326  else if (retType.isIntegerTy() || retType.isPointerTy()) {
1327  // read r0 register value
1328  lldb_private::RegisterValue r0_value;
1329  if (!reg_ctx->ReadRegister(r0_info, r0_value))
1330  return vObjSP;
1331 
1332  // push r0 into value
1333  uint32_t r0_u32 = r0_value.GetAsUInt32();
1334 
1335  // account for integer size
1336  if (retType.isIntegerTy() && retType.isSized()) {
1337  uint64_t size = retType.getScalarSizeInBits();
1338  uint64_t mask = (1ull << size) - 1;
1339  // mask out higher order bits then the type we expect
1340  r0_u32 &= mask;
1341  }
1342 
1343  value.GetScalar() = r0_u32;
1344  }
1345  // unsupported return type
1346  else
1347  return vObjSP;
1348 
1349  // pack the value into a ValueObjectSP
1350  vObjSP = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
1351  value, ConstString(""));
1352  return vObjSP;
1353 }
#define LLDB_REGNUM_GENERIC_PC
Definition: lldb-defines.h:63
void SetSourceName(const char *)
Definition: UnwindPlan.cpp:542
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
lldb_private::Status SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override
static RegisterInfo g_register_infos[]
#define LLDB_REGNUM_GENERIC_RA
Definition: lldb-defines.h:66
static void Initialize()
lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &type) const override
static void Terminate()
lldb::ValueObjectSP GetReturnValueObjectSimple(lldb_private::Thread &thread, lldb_private::CompilerType &ast_type) const
virtual uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num)=0
Convert from a given register numbering scheme to the lldb register numbering scheme.
const lldb_private::RegisterInfo * GetRegisterInfoArray(uint32_t &count) override
An architecture specification class.
Definition: ArchSpec.h:32
#define LLDB_REGNUM_GENERIC_SP
Definition: lldb-defines.h:64
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:431
#define LLDB_REGNUM_GENERIC_FP
Definition: lldb-defines.h:65
lldb_private::ConstString GetPluginName() override
static lldb_private::ConstString GetPluginNameStatic()
std::shared_ptr< Row > RowSP
Definition: UnwindPlan.h:366
void AppendRow(const RowSP &row_sp)
Definition: UnwindPlan.cpp:355
virtual lldb::RegisterContextSP GetRegisterContext()=0
virtual const RegisterInfo * GetRegisterInfoAtIndex(size_t reg)=0
virtual bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)=0
size_t GetRedZoneSize() const override
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info)
bool Success() const
Test for success condition.
Definition: Status.cpp:287
static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch)
void SetRegisterKind(lldb::RegisterKind kind)
Definition: UnwindPlan.h:408
bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
bool WriteRegisterFromUnsigned(uint32_t reg, uint64_t uval)
lldb::ProcessSP GetProcess() const
Definition: Thread.h:154
uint32_t GetPluginVersion() override
uint32_t GetAsUInt32(uint32_t fail_value=UINT32_MAX, bool *success_ptr=nullptr) const
void SetUnwindPlanValidAtAllInstructions(lldb_private::LazyBool valid_at_all_insn)
Definition: UnwindPlan.h:461
bool GetArgumentValues(lldb_private::Thread &thread, lldb_private::ValueList &values) const override
uint64_t addr_t
Definition: lldb-types.h:83
static const uint32_t k_num_register_infos
A uniqued constant string class.
Definition: ConstString.h:38
bool Fail() const
Test for error condition.
Definition: Status.cpp:181
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:247
Definition: SBAddress.h:15
std::unique_ptr< uint8_t[]> data_up
Definition: ABI.h:37
bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, lldb::addr_t functionAddress, lldb::addr_t returnAddress, llvm::ArrayRef< lldb::addr_t > args) const override
const Scalar & GetScalar() const
Definition: Value.h:178
bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override
virtual lldb::StackFrameSP GetStackFrameAtIndex(uint32_t idx)
Definition: Thread.h:395
void SetSourcedFromCompiler(lldb_private::LazyBool from_compiler)
Definition: UnwindPlan.h:449
bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
void SetReturnAddressRegister(uint32_t regnum)
Definition: UnwindPlan.h:410
An error handling class.
Definition: Status.h:44
static bool g_register_info_names_constified
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:90