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 const 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);
977 
978 const lldb_private::RegisterInfo *
980  count = k_num_register_infos;
981  return g_register_infos;
982 }
983 
984 /*
985  http://en.wikipedia.org/wiki/Red_zone_%28computing%29
986 
987  In computing, a red zone is a fixed size area in memory beyond the stack
988  pointer that has not been
989  "allocated". This region of memory is not to be modified by
990  interrupt/exception/signal handlers.
991  This allows the space to be used for temporary data without the extra
992  overhead of modifying the
993  stack pointer. The x86-64 ABI mandates a 128 byte red zone.[1] The OpenRISC
994  toolchain assumes a
995  128 byte red zone though it is not documented.
996 */
997 size_t ABISysV_hexagon::GetRedZoneSize() const { return 0; }
998 
999 // Static Functions
1000 
1001 ABISP
1002 ABISysV_hexagon::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
1003  if (arch.GetTriple().getArch() == llvm::Triple::hexagon) {
1004  return ABISP(
1005  new ABISysV_hexagon(std::move(process_sp), MakeMCRegisterInfo(arch)));
1006  }
1007  return ABISP();
1008 }
1009 
1012  llvm::ArrayRef<addr_t> args) const {
1013  // we don't use the traditional trivial call specialized for jit
1014  return false;
1015 }
1016 
1017 /*
1018 
1019 // AD:
1020 // . safeguard the current stack
1021 // . how can we know that the called function will create its own frame
1022 properly?
1023 // . we could manually make a new stack first:
1024 // 2. push RA
1025 // 3. push FP
1026 // 4. FP = SP
1027 // 5. SP = SP ( since no locals in our temp frame )
1028 
1029 // AD 6/05/2014
1030 // . variable argument list parameters are not passed via registers, they are
1031 passed on
1032 // the stack. This presents us with a problem, since we need to know when
1033 the valist
1034 // starts. Currently I can find out if a function is varg, but not how many
1035 // real parameters it takes. Thus I don't know when to start spilling the
1036 vargs. For
1037 // the time being, to progress, I will assume that it takes on real parameter
1038 before
1039 // the vargs list starts.
1040 
1041 // AD 06/05/2014
1042 // . how do we adhere to the stack alignment requirements
1043 
1044 // AD 06/05/2014
1045 // . handle 64bit values and their register / stack requirements
1046 
1047 */
1048 #define HEX_ABI_DEBUG 0
1051  llvm::Type &prototype, llvm::ArrayRef<ABI::CallArgument> args) const {
1052  // default number of register passed arguments for varg functions
1053  const int nVArgRegParams = 1;
1054  Status error;
1055 
1056  // grab the process so we have access to the memory for spilling
1057  lldb::ProcessSP proc = thread.GetProcess();
1058 
1059  // get the register context for modifying all of the registers
1060  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1061  if (!reg_ctx)
1062  return false;
1063 
1066  if (pc_reg == LLDB_INVALID_REGNUM)
1067  return false;
1068 
1071  if (ra_reg == LLDB_INVALID_REGNUM)
1072  return false;
1073 
1076  if (sp_reg == LLDB_INVALID_REGNUM)
1077  return false;
1078 
1079  // push host data onto target
1080  for (size_t i = 0; i < args.size(); i++) {
1081  const ABI::CallArgument &arg = args[i];
1082  // skip over target values
1083  if (arg.type == ABI::CallArgument::TargetValue)
1084  continue;
1085  // round up to 8 byte multiple
1086  size_t argSize = (arg.size | 0x7) + 1;
1087 
1088  // create space on the stack for this data
1089  sp -= argSize;
1090 
1091  // write this argument onto the stack of the host process
1092  proc->WriteMemory(sp, arg.data_up.get(), arg.size, error);
1093  if (error.Fail())
1094  return false;
1095 
1096  // update the argument with the target pointer
1097  // XXX: This is a gross hack for getting around the const
1098  *const_cast<lldb::addr_t *>(&arg.value) = sp;
1099  }
1100 
1101 #if HEX_ABI_DEBUG
1102  // print the original stack pointer
1103  printf("sp : %04" PRIx64 " \n", sp);
1104 #endif
1105 
1106  // make sure number of parameters matches prototype
1107  assert(prototype.getFunctionNumParams() == args.size());
1108 
1109  // check if this is a variable argument function
1110  bool isVArg = prototype.isFunctionVarArg();
1111 
1112  // number of arguments passed by register
1113  int nRegArgs = nVArgRegParams;
1114  if (!isVArg) {
1115  // number of arguments is limited by [R0 : R5] space
1116  nRegArgs = args.size();
1117  if (nRegArgs > 6)
1118  nRegArgs = 6;
1119  }
1120 
1121  // pass arguments that are passed via registers
1122  for (int i = 0; i < nRegArgs; i++) {
1123  // get the parameter as a u32
1124  uint32_t param = (uint32_t)args[i].value;
1125  // write argument into register
1126  if (!reg_ctx->WriteRegisterFromUnsigned(i, param))
1127  return false;
1128  }
1129 
1130  // number of arguments to spill onto stack
1131  int nSpillArgs = args.size() - nRegArgs;
1132  // make space on the stack for arguments
1133  sp -= 4 * nSpillArgs;
1134  // align stack on an 8 byte boundary
1135  if (sp & 7)
1136  sp -= 4;
1137 
1138  // arguments that are passed on the stack
1139  for (size_t i = nRegArgs, offs = 0; i < args.size(); i++) {
1140  // get the parameter as a u32
1141  uint32_t param = (uint32_t)args[i].value;
1142  // write argument to stack
1143  proc->WriteMemory(sp + offs, (void *)&param, sizeof(param), error);
1144  if (!error.Success())
1145  return false;
1146  //
1147  offs += 4;
1148  }
1149 
1150  // update registers with current function call state
1151  reg_ctx->WriteRegisterFromUnsigned(pc_reg, pc);
1152  reg_ctx->WriteRegisterFromUnsigned(ra_reg, ra);
1153  reg_ctx->WriteRegisterFromUnsigned(sp_reg, sp);
1154 
1155 #if HEX_ABI_DEBUG
1156  // quick and dirty stack dumper for debugging
1157  for (int i = -8; i < 8; i++) {
1158  uint32_t data = 0;
1159  lldb::addr_t addr = sp + i * 4;
1160  proc->ReadMemory(addr, (void *)&data, sizeof(data), error);
1161  printf("\n0x%04" PRIx64 " 0x%08x ", addr, data);
1162  if (i == 0)
1163  printf("<<-- sp");
1164  }
1165  printf("\n");
1166 #endif
1167 
1168  return true;
1169 }
1170 
1172  ValueList &values) const {
1173  return false;
1174 }
1175 
1176 Status
1177 ABISysV_hexagon::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
1178  lldb::ValueObjectSP &new_value_sp) {
1179  Status error;
1180  return error;
1181 }
1182 
1184  Thread &thread, CompilerType &return_compiler_type) const {
1185  ValueObjectSP return_valobj_sp;
1186  return return_valobj_sp;
1187 }
1188 
1190  Thread &thread, CompilerType &return_compiler_type) const {
1191  ValueObjectSP return_valobj_sp;
1192  return return_valobj_sp;
1193 }
1194 
1195 // called when we are on the first instruction of a new function for hexagon
1196 // the return address is in RA (R31)
1198  unwind_plan.Clear();
1201 
1203 
1204  // Our Call Frame Address is the stack pointer value
1205  row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_SP, 4);
1206  row->SetOffset(0);
1207 
1208  // The previous PC is in the LR
1209  row->SetRegisterLocationToRegister(LLDB_REGNUM_GENERIC_PC,
1210  LLDB_REGNUM_GENERIC_RA, true);
1211  unwind_plan.AppendRow(row);
1212 
1213  unwind_plan.SetSourceName("hexagon at-func-entry default");
1214  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1215  return true;
1216 }
1217 
1219  unwind_plan.Clear();
1221 
1222  uint32_t fp_reg_num = LLDB_REGNUM_GENERIC_FP;
1223  uint32_t sp_reg_num = LLDB_REGNUM_GENERIC_SP;
1224  uint32_t pc_reg_num = LLDB_REGNUM_GENERIC_PC;
1225 
1227 
1228  row->SetUnspecifiedRegistersAreUndefined(true);
1229  row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_FP, 8);
1230 
1231  row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, -8, true);
1232  row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, true);
1233  row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
1234 
1235  unwind_plan.AppendRow(row);
1236  unwind_plan.SetSourceName("hexagon default unwind plan");
1237  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1240  return true;
1241 }
1242 
1243 /*
1244  Register Usage Saved By
1245 
1246  R0 - R5 parameters(a) -
1247  R6 - R15 Scratch(b) Caller
1248  R16 - R27 Scratch Callee
1249  R28 Scratch(b) Caller
1250  R29 - R31 Stack Frames Callee(c)
1251  P3:0 Processor State Caller
1252 
1253  a = the caller can change parameter values
1254  b = R14 - R15 and R28 are used by the procedure linkage table
1255  c = R29 - R31 are saved and restored by allocframe() and deallocframe()
1256 */
1257 bool ABISysV_hexagon::RegisterIsVolatile(const RegisterInfo *reg_info) {
1258  return !RegisterIsCalleeSaved(reg_info);
1259 }
1260 
1261 bool ABISysV_hexagon::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
1262  int reg = ((reg_info->byte_offset) / 4);
1263 
1264  bool save = (reg >= 16) && (reg <= 27);
1265  save |= (reg >= 29) && (reg <= 32);
1266 
1267  return save;
1268 }
1269 
1271  PluginManager::RegisterPlugin(GetPluginNameStatic(),
1272  "System V ABI for hexagon targets",
1273  CreateInstance);
1274 }
1275 
1277  PluginManager::UnregisterPlugin(CreateInstance);
1278 }
1279 
1281  static ConstString g_name("sysv-hexagon");
1282  return g_name;
1283 }
1284 
1285 // PluginInterface protocol
1286 
1288  return GetPluginNameStatic();
1289 }
1290 
1292 
1293 // get value object specialized to work with llvm IR types
1294 lldb::ValueObjectSP
1296  llvm::Type &retType) const {
1297  Value value;
1298  ValueObjectSP vObjSP;
1299 
1300  // get the current register context
1301  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1302  if (!reg_ctx)
1303  return vObjSP;
1304 
1305  // for now just pop R0 to find the return value
1306  const lldb_private::RegisterInfo *r0_info =
1307  reg_ctx->GetRegisterInfoAtIndex(0);
1308  if (r0_info == nullptr)
1309  return vObjSP;
1310 
1311  // void return type
1312  if (retType.isVoidTy()) {
1313  value.GetScalar() = 0;
1314  }
1315  // integer / pointer return type
1316  else if (retType.isIntegerTy() || retType.isPointerTy()) {
1317  // read r0 register value
1318  lldb_private::RegisterValue r0_value;
1319  if (!reg_ctx->ReadRegister(r0_info, r0_value))
1320  return vObjSP;
1321 
1322  // push r0 into value
1323  uint32_t r0_u32 = r0_value.GetAsUInt32();
1324 
1325  // account for integer size
1326  if (retType.isIntegerTy() && retType.isSized()) {
1327  uint64_t size = retType.getScalarSizeInBits();
1328  uint64_t mask = (1ull << size) - 1;
1329  // mask out higher order bits then the type we expect
1330  r0_u32 &= mask;
1331  }
1332 
1333  value.GetScalar() = r0_u32;
1334  }
1335  // unsupported return type
1336  else
1337  return vObjSP;
1338 
1339  // pack the value into a ValueObjectSP
1340  vObjSP = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
1341  value, ConstString(""));
1342  return vObjSP;
1343 }
ABISysV_hexagon
Definition: ABISysV_hexagon.h:16
lldb_private::UnwindPlan::AppendRow
void AppendRow(const RowSP &row_sp)
Definition: UnwindPlan.cpp:361
lldb_private::ArchSpec
Definition: ArchSpec.h:33
LLDB_INVALID_REGNUM
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:91
lldb_private::RegisterValue
Definition: RegisterValue.h:28
lldb_private::UnwindPlan::SetRegisterKind
void SetRegisterKind(lldb::RegisterKind kind)
Definition: UnwindPlan.h:439
lldb_private::Value
Definition: Value.h:38
lldb::eRegisterKindGeneric
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
Definition: lldb-enumerations.h:230
ABISysV_hexagon::RegisterIsVolatile
bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override
Definition: ABISysV_hexagon.cpp:1257
ABISysV_hexagon::Initialize
static void Initialize()
Definition: ABISysV_hexagon.cpp:1270
lldb_private::UnwindPlan::SetUnwindPlanValidAtAllInstructions
void SetUnwindPlanValidAtAllInstructions(lldb_private::LazyBool valid_at_all_insn)
Definition: UnwindPlan.h:492
ABISysV_hexagon::GetReturnValueObjectSimple
lldb::ValueObjectSP GetReturnValueObjectSimple(lldb_private::Thread &thread, lldb_private::CompilerType &ast_type) const
Definition: ABISysV_hexagon.cpp:1183
lldb_private::RegisterContext::ReadRegister
virtual bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)=0
lldb_private::ABI::CallArgument::type
eType type
Definition: ABI.h:33
ABISysV_hexagon::PrepareTrivialCall
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
Module.h
lldb_private::RegisterContext::ConvertRegisterKindToRegisterNumber
virtual uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num)
Convert from a given register numbering scheme to the lldb register numbering scheme.
Definition: RegisterContext.cpp:294
lldb_private::UnwindPlan::SetUnwindPlanForSignalTrap
void SetUnwindPlanForSignalTrap(lldb_private::LazyBool is_for_signal_trap)
Definition: UnwindPlan.h:504
RegisterValue.h
lldb_private::ValueList
Definition: Value.h:157
StackFrame.h
ValueObjectMemory.h
ra
@ ra
Definition: CompactUnwindInfo.cpp:1248
lldb_private::ArchSpec::GetTriple
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:444
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
pc
@ pc
Definition: CompactUnwindInfo.cpp:1250
lldb_private::RegisterContext::GetRegisterInfoAtIndex
virtual const RegisterInfo * GetRegisterInfoAtIndex(size_t reg)=0
lldb_private::UnwindPlan::SetSourceName
void SetSourceName(const char *)
Definition: UnwindPlan.cpp:563
LLDB_PLUGIN_DEFINE_ADV
LLDB_PLUGIN_DEFINE_ADV(ObjectContainerUniversalMachO, ObjectContainerMachOArchive) void ObjectContainerUniversalMachO
Definition: ObjectContainerUniversalMachO.cpp:23
ABISysV_hexagon::GetPluginVersion
uint32_t GetPluginVersion() override
Definition: ABISysV_hexagon.cpp:1291
Process.h
Target.h
lldb_private::Value::GetScalar
const Scalar & GetScalar() const
Definition: Value.h:112
lldb_private::Thread::GetProcess
lldb::ProcessSP GetProcess() const
Definition: Thread.h:154
lldb::eEncodingInvalid
@ eEncodingInvalid
Definition: lldb-enumerations.h:147
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
Log.h
lldb_private::UnwindPlan::SetReturnAddressRegister
void SetReturnAddressRegister(uint32_t regnum)
Definition: UnwindPlan.h:441
lldb_private::Thread
Definition: Thread.h:62
ABISysV_hexagon::Terminate
static void Terminate()
Definition: ABISysV_hexagon.cpp:1276
ABISysV_hexagon::GetRedZoneSize
size_t GetRedZoneSize() const override
Definition: ABISysV_hexagon.cpp:997
lldb_private::UnwindPlan::SetSourcedFromCompiler
void SetSourcedFromCompiler(lldb_private::LazyBool from_compiler)
Definition: UnwindPlan.h:480
ValueObjectRegister.h
lldb::eEncodingUint
@ eEncodingUint
unsigned integer
Definition: lldb-enumerations.h:148
lldb_private::ConstString
Definition: ConstString.h:40
ABISysV_hexagon::CreateInstance
static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch)
Definition: ABISysV_hexagon.cpp:1002
sp
@ sp
Definition: CompactUnwindInfo.cpp:1249
Thread.h
UnwindPlan.h
lldb_private::RegisterContext
Definition: RegisterContext.h:17
k_num_register_infos
static const uint32_t k_num_register_infos
Definition: ABISysV_hexagon.cpp:975
ABISysV_hexagon::RegisterIsCalleeSaved
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info)
Definition: ABISysV_hexagon.cpp:1261
ValueObjectConstResult.h
lldb_private::UnwindPlan::RowSP
std::shared_ptr< Row > RowSP
Definition: UnwindPlan.h:395
ABISysV_hexagon::CreateDefaultUnwindPlan
bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
Definition: ABISysV_hexagon.cpp:1218
lldb_private::UnwindPlan::Clear
void Clear()
Definition: UnwindPlan.h:510
lldb_private::Status
Definition: Status.h:44
lldb_private::ABI::CallArgument
Definition: ABI.h:28
lldb_private::RegisterContext::WriteRegisterFromUnsigned
bool WriteRegisterFromUnsigned(uint32_t reg, uint64_t uval)
Definition: RegisterContext.cpp:231
ABISysV_hexagon::GetPluginName
lldb_private::ConstString GetPluginName() override
Definition: ABISysV_hexagon.cpp:1287
lldb_private::UnwindPlan::Row
Definition: UnwindPlan.h:55
uint32_t
lldb_private::eLazyBoolNo
@ eLazyBoolNo
Definition: lldb-private-enumerations.h:115
ABISysV_hexagon.h
LLDB_REGNUM_GENERIC_SP
#define LLDB_REGNUM_GENERIC_SP
Definition: lldb-defines.h:64
g_register_infos
static const RegisterInfo g_register_infos[]
Definition: ABISysV_hexagon.cpp:37
ABISysV_hexagon::GetArgumentValues
bool GetArgumentValues(lldb_private::Thread &thread, lldb_private::ValueList &values) const override
Definition: ABISysV_hexagon.cpp:1171
ABISysV_hexagon::SetReturnValueObject
lldb_private::Status SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override
Definition: ABISysV_hexagon.cpp:1177
ABISysV_hexagon::GetReturnValueObjectImpl
lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &type) const override
Definition: ABISysV_hexagon.cpp:1189
lldb_private::ABI::CallArgument::value
lldb::addr_t value
Definition: ABI.h:36
PluginManager.h
DataExtractor.h
lldb_private::CompilerType
Generic representation of a type in a programming language.
Definition: CompilerType.h:33
Status.h
ABISysV_hexagon::GetPluginNameStatic
static lldb_private::ConstString GetPluginNameStatic()
Definition: ABISysV_hexagon.cpp:1280
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
LLDB_REGNUM_GENERIC_FP
#define LLDB_REGNUM_GENERIC_FP
Definition: lldb-defines.h:65
ABISysV_hexagon::GetRegisterInfoArray
const lldb_private::RegisterInfo * GetRegisterInfoArray(uint32_t &count) override
Definition: ABISysV_hexagon.cpp:979
lldb_private::ABI::CallArgument::size
size_t size
Definition: ABI.h:34
LLDB_REGNUM_GENERIC_PC
#define LLDB_REGNUM_GENERIC_PC
Definition: lldb-defines.h:63
ConstString.h
lldb_private::Thread::GetStackFrameAtIndex
virtual lldb::StackFrameSP GetStackFrameAtIndex(uint32_t idx)
Definition: Thread.h:399
lldb_private::Thread::GetRegisterContext
virtual lldb::RegisterContextSP GetRegisterContext()=0
lldb_private::RegisterValue::GetAsUInt32
uint32_t GetAsUInt32(uint32_t fail_value=UINT32_MAX, bool *success_ptr=nullptr) const
Definition: RegisterValue.cpp:533
lldb_private::UnwindPlan
Definition: UnwindPlan.h:53
lldb
Definition: SBAddress.h:15
RegisterContext.h
Value.h
lldb::eFormatAddressInfo
@ eFormatAddressInfo
Describe what an address points to (func + offset.
Definition: lldb-enumerations.h:196
lldb_private::ABI::CallArgument::data_up
std::unique_ptr< uint8_t[]> data_up
Definition: ABI.h:37
lldb::eFormatInvalid
@ eFormatInvalid
Definition: lldb-enumerations.h:157
LLDB_REGNUM_GENERIC_RA
#define LLDB_REGNUM_GENERIC_RA
Definition: lldb-defines.h:66
ABISysV_hexagon::CreateFunctionEntryUnwindPlan
bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
Definition: ABISysV_hexagon.cpp:1197