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