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