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