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"
15 #include "lldb/Core/PluginManager.h"
16 #include "lldb/Core/Value.h"
17 #include "lldb/Core/ValueObjectConstResult.h"
18 #include "lldb/Core/ValueObjectMemory.h"
19 #include "lldb/Core/ValueObjectRegister.h"
20 #include "lldb/Symbol/UnwindPlan.h"
21 #include "lldb/Target/Process.h"
22 #include "lldb/Target/RegisterContext.h"
23 #include "lldb/Target/StackFrame.h"
24 #include "lldb/Target/Target.h"
25 #include "lldb/Target/Thread.h"
26 #include "lldb/Utility/ConstString.h"
27 #include "lldb/Utility/DataExtractor.h"
28 #include "lldb/Utility/Log.h"
29 #include "lldb/Utility/RegisterValue.h"
30 #include "lldb/Utility/Status.h"
31
32 using namespace lldb;
33 using namespace lldb_private;
34
35 LLDB_PLUGIN_DEFINE_ADV(ABISysV_hexagon, ABIHexagon)
36
37 static const RegisterInfo g_register_infos[] = {
38 // hexagon-core.xml
39 {"r00",
40 "",
41 4,
42 0,
43 eEncodingUint,
44 eFormatAddressInfo,
45 {0, 0, LLDB_INVALID_REGNUM, 0, 0},
46 nullptr,
47 nullptr,
48 },
49 {"r01",
50 "",
51 4,
52 0,
53 eEncodingUint,
54 eFormatAddressInfo,
55 {1, 1, LLDB_INVALID_REGNUM, 1, 1},
56 nullptr,
57 nullptr,
58 },
59 {"r02",
60 "",
61 4,
62 0,
63 eEncodingUint,
64 eFormatAddressInfo,
65 {2, 2, LLDB_INVALID_REGNUM, 2, 2},
66 nullptr,
67 nullptr,
68 },
69 {"r03",
70 "",
71 4,
72 0,
73 eEncodingUint,
74 eFormatAddressInfo,
75 {3, 3, LLDB_INVALID_REGNUM, 3, 3},
76 nullptr,
77 nullptr,
78 },
79 {"r04",
80 "",
81 4,
82 0,
83 eEncodingUint,
84 eFormatAddressInfo,
85 {4, 4, LLDB_INVALID_REGNUM, 4, 4},
86 nullptr,
87 nullptr,
88 },
89 {"r05",
90 "",
91 4,
92 0,
93 eEncodingUint,
94 eFormatAddressInfo,
95 {5, 5, LLDB_INVALID_REGNUM, 5, 5},
96 nullptr,
97 nullptr,
98 },
99 {"r06",
100 "",
101 4,
102 0,
103 eEncodingUint,
104 eFormatAddressInfo,
105 {6, 6, LLDB_INVALID_REGNUM, 6, 6},
106 nullptr,
107 nullptr,
108 },
109 {"r07",
110 "",
111 4,
112 0,
113 eEncodingUint,
114 eFormatAddressInfo,
115 {7, 7, LLDB_INVALID_REGNUM, 7, 7},
116 nullptr,
117 nullptr,
118 },
119 {"r08",
120 "",
121 4,
122 0,
123 eEncodingUint,
124 eFormatAddressInfo,
125 {8, 8, LLDB_INVALID_REGNUM, 8, 8},
126 nullptr,
127 nullptr,
128 },
129 {"r09",
130 "",
131 4,
132 0,
133 eEncodingUint,
134 eFormatAddressInfo,
135 {9, 9, LLDB_INVALID_REGNUM, 9, 9},
136 nullptr,
137 nullptr,
138 },
139 {"r10",
140 "",
141 4,
142 0,
143 eEncodingUint,
144 eFormatAddressInfo,
145 {10, 10, LLDB_INVALID_REGNUM, 10, 10},
146 nullptr,
147 nullptr,
148 },
149 {"r11",
150 "",
151 4,
152 0,
153 eEncodingUint,
154 eFormatAddressInfo,
155 {11, 11, LLDB_INVALID_REGNUM, 11, 11},
156 nullptr,
157 nullptr,
158 },
159 {"r12",
160 "",
161 4,
162 0,
163 eEncodingUint,
164 eFormatAddressInfo,
165 {12, 12, LLDB_INVALID_REGNUM, 12, 12},
166 nullptr,
167 nullptr,
168 },
169 {"r13",
170 "",
171 4,
172 0,
173 eEncodingUint,
174 eFormatAddressInfo,
175 {13, 13, LLDB_INVALID_REGNUM, 13, 13},
176 nullptr,
177 nullptr,
178 },
179 {"r14",
180 "",
181 4,
182 0,
183 eEncodingUint,
184 eFormatAddressInfo,
185 {14, 14, LLDB_INVALID_REGNUM, 14, 14},
186 nullptr,
187 nullptr,
188 },
189 {"r15",
190 "",
191 4,
192 0,
193 eEncodingUint,
194 eFormatAddressInfo,
195 {15, 15, LLDB_INVALID_REGNUM, 15, 15},
196 nullptr,
197 nullptr,
198 },
199 {"r16",
200 "",
201 4,
202 0,
203 eEncodingUint,
204 eFormatAddressInfo,
205 {16, 16, LLDB_INVALID_REGNUM, 16, 16},
206 nullptr,
207 nullptr,
208 },
209 {"r17",
210 "",
211 4,
212 0,
213 eEncodingUint,
214 eFormatAddressInfo,
215 {17, 17, LLDB_INVALID_REGNUM, 17, 17},
216 nullptr,
217 nullptr,
218 },
219 {"r18",
220 "",
221 4,
222 0,
223 eEncodingUint,
224 eFormatAddressInfo,
225 {18, 18, LLDB_INVALID_REGNUM, 18, 18},
226 nullptr,
227 nullptr,
228 },
229 {"r19",
230 "",
231 4,
232 0,
233 eEncodingUint,
234 eFormatAddressInfo,
235 {19, 19, LLDB_INVALID_REGNUM, 19, 19},
236 nullptr,
237 nullptr,
238 },
239 {"r20",
240 "",
241 4,
242 0,
243 eEncodingUint,
244 eFormatAddressInfo,
245 {20, 20, LLDB_INVALID_REGNUM, 20, 20},
246 nullptr,
247 nullptr,
248 },
249 {"r21",
250 "",
251 4,
252 0,
253 eEncodingUint,
254 eFormatAddressInfo,
255 {21, 21, LLDB_INVALID_REGNUM, 21, 21},
256 nullptr,
257 nullptr,
258 },
259 {"r22",
260 "",
261 4,
262 0,
263 eEncodingUint,
264 eFormatAddressInfo,
265 {22, 22, LLDB_INVALID_REGNUM, 22, 22},
266 nullptr,
267 nullptr,
268 },
269 {"r23",
270 "",
271 4,
272 0,
273 eEncodingUint,
274 eFormatAddressInfo,
275 {23, 23, LLDB_INVALID_REGNUM, 23, 23},
276 nullptr,
277 nullptr,
278 },
279 {"r24",
280 "",
281 4,
282 0,
283 eEncodingUint,
284 eFormatAddressInfo,
285 {24, 24, LLDB_INVALID_REGNUM, 24, 24},
286 nullptr,
287 nullptr,
288 },
289 {"r25",
290 "",
291 4,
292 0,
293 eEncodingUint,
294 eFormatAddressInfo,
295 {25, 25, LLDB_INVALID_REGNUM, 25, 25},
296 nullptr,
297 nullptr,
298 },
299 {"r26",
300 "",
301 4,
302 0,
303 eEncodingUint,
304 eFormatAddressInfo,
305 {26, 26, LLDB_INVALID_REGNUM, 26, 26},
306 nullptr,
307 nullptr,
308 },
309 {"r27",
310 "",
311 4,
312 0,
313 eEncodingUint,
314 eFormatAddressInfo,
315 {27, 27, LLDB_INVALID_REGNUM, 27, 27},
316 nullptr,
317 nullptr,
318 },
319 {"r28",
320 "",
321 4,
322 0,
323 eEncodingUint,
324 eFormatAddressInfo,
325 {28, 28, LLDB_INVALID_REGNUM, 28, 28},
326 nullptr,
327 nullptr,
328 },
329 {"sp",
330 "r29",
331 4,
332 0,
333 eEncodingUint,
334 eFormatAddressInfo,
335 {29, 29, LLDB_REGNUM_GENERIC_SP, 29, 29},
336 nullptr,
337 nullptr,
338 },
339 {"fp",
340 "r30",
341 4,
342 0,
343 eEncodingUint,
344 eFormatAddressInfo,
345 {30, 30, LLDB_REGNUM_GENERIC_FP, 30, 30},
346 nullptr,
347 nullptr,
348 },
349 {"lr",
350 "r31",
351 4,
352 0,
353 eEncodingUint,
354 eFormatAddressInfo,
355 {31, 31, LLDB_REGNUM_GENERIC_RA, 31, 31},
356 nullptr,
357 nullptr,
358 },
359 {"sa0",
360 "",
361 4,
362 0,
363 eEncodingUint,
364 eFormatAddressInfo,
365 {32, 32, LLDB_INVALID_REGNUM, 32, 32},
366 nullptr,
367 nullptr,
368 },
369 {"lc0",
370 "",
371 4,
372 0,
373 eEncodingUint,
374 eFormatAddressInfo,
375 {33, 33, LLDB_INVALID_REGNUM, 33, 33},
376 nullptr,
377 nullptr,
378 },
379 {"sa1",
380 "",
381 4,
382 0,
383 eEncodingUint,
384 eFormatAddressInfo,
385 {34, 34, LLDB_INVALID_REGNUM, 34, 34},
386 nullptr,
387 nullptr,
388 },
389 {"lc1",
390 "",
391 4,
392 0,
393 eEncodingUint,
394 eFormatAddressInfo,
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,
404 eEncodingUint,
405 eFormatAddressInfo,
406 {36, 36, LLDB_INVALID_REGNUM, 36, 36},
407 nullptr,
408 nullptr,
409 },
410 // PADDING {
411 {"p00",
412 "",
413 4,
414 0,
415 eEncodingInvalid,
416 eFormatInvalid,
417 {37, 37, LLDB_INVALID_REGNUM, 37, 37},
418 nullptr,
419 nullptr,
420 },
421 // }
422 {"m0",
423 "",
424 4,
425 0,
426 eEncodingUint,
427 eFormatAddressInfo,
428 {38, 38, LLDB_INVALID_REGNUM, 38, 38},
429 nullptr,
430 nullptr,
431 },
432 {"m1",
433 "",
434 4,
435 0,
436 eEncodingUint,
437 eFormatAddressInfo,
438 {39, 39, LLDB_INVALID_REGNUM, 39, 39},
439 nullptr,
440 nullptr,
441 },
442 {"usr",
443 "",
444 4,
445 0,
446 eEncodingUint,
447 eFormatAddressInfo,
448 {40, 40, LLDB_INVALID_REGNUM, 40, 40},
449 nullptr,
450 nullptr,
451 },
452 {"pc",
453 "",
454 4,
455 0,
456 eEncodingUint,
457 eFormatAddressInfo,
458 {41, 41, LLDB_REGNUM_GENERIC_PC, 41, 41},
459 nullptr,
460 nullptr,
461 },
462 {"ugp",
463 "",
464 4,
465 0,
466 eEncodingUint,
467 eFormatAddressInfo,
468 {42, 42, LLDB_INVALID_REGNUM, 42, 42},
469 nullptr,
470 nullptr,
471 },
472 {"gp",
473 "",
474 4,
475 0,
476 eEncodingUint,
477 eFormatAddressInfo,
478 {43, 43, LLDB_INVALID_REGNUM, 43, 43},
479 nullptr,
480 nullptr,
481 },
482 {"cs0",
483 "",
484 4,
485 0,
486 eEncodingUint,
487 eFormatAddressInfo,
488 {44, 44, LLDB_INVALID_REGNUM, 44, 44},
489 nullptr,
490 nullptr,
491 },
492 {"cs1",
493 "",
494 4,
495 0,
496 eEncodingUint,
497 eFormatAddressInfo,
498 {45, 45, LLDB_INVALID_REGNUM, 45, 45},
499 nullptr,
500 nullptr,
501 },
502 // PADDING {
503 {"p01",
504 "",
505 4,
506 0,
507 eEncodingInvalid,
508 eFormatInvalid,
509 {46, 46, LLDB_INVALID_REGNUM, 46, 46},
510 nullptr,
511 nullptr,
512 },
513 {"p02",
514 "",
515 4,
516 0,
517 eEncodingInvalid,
518 eFormatInvalid,
519 {47, 47, LLDB_INVALID_REGNUM, 47, 47},
520 nullptr,
521 nullptr,
522 },
523 {"p03",
524 "",
525 4,
526 0,
527 eEncodingInvalid,
528 eFormatInvalid,
529 {48, 48, LLDB_INVALID_REGNUM, 48, 48},
530 nullptr,
531 nullptr,
532 },
533 {"p04",
534 "",
535 4,
536 0,
537 eEncodingInvalid,
538 eFormatInvalid,
539 {49, 49, LLDB_INVALID_REGNUM, 49, 49},
540 nullptr,
541 nullptr,
542 },
543 {"p05",
544 "",
545 4,
546 0,
547 eEncodingInvalid,
548 eFormatInvalid,
549 {50, 50, LLDB_INVALID_REGNUM, 50, 50},
550 nullptr,
551 nullptr,
552 },
553 {"p06",
554 "",
555 4,
556 0,
557 eEncodingInvalid,
558 eFormatInvalid,
559 {51, 51, LLDB_INVALID_REGNUM, 51, 51},
560 nullptr,
561 nullptr,
562 },
563 {"p07",
564 "",
565 4,
566 0,
567 eEncodingInvalid,
568 eFormatInvalid,
569 {52, 52, LLDB_INVALID_REGNUM, 52, 52},
570 nullptr,
571 nullptr,
572 },
573 {"p08",
574 "",
575 4,
576 0,
577 eEncodingInvalid,
578 eFormatInvalid,
579 {53, 53, LLDB_INVALID_REGNUM, 53, 53},
580 nullptr,
581 nullptr,
582 },
583 {"p09",
584 "",
585 4,
586 0,
587 eEncodingInvalid,
588 eFormatInvalid,
589 {54, 54, LLDB_INVALID_REGNUM, 54, 54},
590 nullptr,
591 nullptr,
592 },
593 {"p10",
594 "",
595 4,
596 0,
597 eEncodingInvalid,
598 eFormatInvalid,
599 {55, 55, LLDB_INVALID_REGNUM, 55, 55},
600 nullptr,
601 nullptr,
602 },
603 {"p11",
604 "",
605 4,
606 0,
607 eEncodingInvalid,
608 eFormatInvalid,
609 {56, 56, LLDB_INVALID_REGNUM, 56, 56},
610 nullptr,
611 nullptr,
612 },
613 {"p12",
614 "",
615 4,
616 0,
617 eEncodingInvalid,
618 eFormatInvalid,
619 {57, 57, LLDB_INVALID_REGNUM, 57, 57},
620 nullptr,
621 nullptr,
622 },
623 {"p13",
624 "",
625 4,
626 0,
627 eEncodingInvalid,
628 eFormatInvalid,
629 {58, 58, LLDB_INVALID_REGNUM, 58, 58},
630 nullptr,
631 nullptr,
632 },
633 {"p14",
634 "",
635 4,
636 0,
637 eEncodingInvalid,
638 eFormatInvalid,
639 {59, 59, LLDB_INVALID_REGNUM, 59, 59},
640 nullptr,
641 nullptr,
642 },
643 {"p15",
644 "",
645 4,
646 0,
647 eEncodingInvalid,
648 eFormatInvalid,
649 {60, 60, LLDB_INVALID_REGNUM, 60, 60},
650 nullptr,
651 nullptr,
652 },
653 {"p16",
654 "",
655 4,
656 0,
657 eEncodingInvalid,
658 eFormatInvalid,
659 {61, 61, LLDB_INVALID_REGNUM, 61, 61},
660 nullptr,
661 nullptr,
662 },
663 {"p17",
664 "",
665 4,
666 0,
667 eEncodingInvalid,
668 eFormatInvalid,
669 {62, 62, LLDB_INVALID_REGNUM, 62, 62},
670 nullptr,
671 nullptr,
672 },
673 {"p18",
674 "",
675 4,
676 0,
677 eEncodingInvalid,
678 eFormatInvalid,
679 {63, 63, LLDB_INVALID_REGNUM, 63, 63},
680 nullptr,
681 nullptr,
682 },
683 // }
684 {"sgp0",
685 "",
686 4,
687 0,
688 eEncodingUint,
689 eFormatAddressInfo,
690 {64, 64, LLDB_INVALID_REGNUM, 64, 64},
691 nullptr,
692 nullptr,
693 },
694 // PADDING {
695 {"p19",
696 "",
697 4,
698 0,
699 eEncodingInvalid,
700 eFormatInvalid,
701 {65, 65, LLDB_INVALID_REGNUM, 65, 65},
702 nullptr,
703 nullptr,
704 },
705 // }
706 {"stid",
707 "",
708 4,
709 0,
710 eEncodingUint,
711 eFormatAddressInfo,
712 {66, 66, LLDB_INVALID_REGNUM, 66, 66},
713 nullptr,
714 nullptr,
715 },
716 {"elr",
717 "",
718 4,
719 0,
720 eEncodingUint,
721 eFormatAddressInfo,
722 {67, 67, LLDB_INVALID_REGNUM, 67, 67},
723 nullptr,
724 nullptr,
725 },
726 {"badva0",
727 "",
728 4,
729 0,
730 eEncodingUint,
731 eFormatAddressInfo,
732 {68, 68, LLDB_INVALID_REGNUM, 68, 68},
733 nullptr,
734 nullptr,
735 },
736 {"badva1",
737 "",
738 4,
739 0,
740 eEncodingUint,
741 eFormatAddressInfo,
742 {69, 69, LLDB_INVALID_REGNUM, 69, 69},
743 nullptr,
744 nullptr,
745 },
746 {"ssr",
747 "",
748 4,
749 0,
750 eEncodingUint,
751 eFormatAddressInfo,
752 {70, 70, LLDB_INVALID_REGNUM, 70, 70},
753 nullptr,
754 nullptr,
755 },
756 {"ccr",
757 "",
758 4,
759 0,
760 eEncodingUint,
761 eFormatAddressInfo,
762 {71, 71, LLDB_INVALID_REGNUM, 71, 71},
763 nullptr,
764 nullptr,
765 },
766 {"htid",
767 "",
768 4,
769 0,
770 eEncodingUint,
771 eFormatAddressInfo,
772 {72, 72, LLDB_INVALID_REGNUM, 72, 72},
773 nullptr,
774 nullptr,
775 },
776 // PADDING {
777 {"p20",
778 "",
779 4,
780 0,
781 eEncodingInvalid,
782 eFormatInvalid,
783 {73, 73, LLDB_INVALID_REGNUM, 73, 73},
784 nullptr,
785 nullptr,
786 },
787 // }
788 {"imask",
789 "",
790 4,
791 0,
792 eEncodingUint,
793 eFormatAddressInfo,
794 {74, 74, LLDB_INVALID_REGNUM, 74, 74},
795 nullptr,
796 nullptr,
797 },
798 // PADDING {
799 {"p21",
800 "",
801 4,
802 0,
803 eEncodingInvalid,
804 eFormatInvalid,
805 {75, 75, LLDB_INVALID_REGNUM, 75, 75},
806 nullptr,
807 nullptr,
808 },
809 {"p22",
810 "",
811 4,
812 0,
813 eEncodingInvalid,
814 eFormatInvalid,
815 {76, 76, LLDB_INVALID_REGNUM, 76, 76},
816 nullptr,
817 nullptr,
818 },
819 {"p23",
820 "",
821 4,
822 0,
823 eEncodingInvalid,
824 eFormatInvalid,
825 {77, 77, LLDB_INVALID_REGNUM, 77, 77},
826 nullptr,
827 nullptr,
828 },
829 {"p24",
830 "",
831 4,
832 0,
833 eEncodingInvalid,
834 eFormatInvalid,
835 {78, 78, LLDB_INVALID_REGNUM, 78, 78},
836 nullptr,
837 nullptr,
838 },
839 {"p25",
840 "",
841 4,
842 0,
843 eEncodingInvalid,
844 eFormatInvalid,
845 {79, 79, LLDB_INVALID_REGNUM, 79, 79},
846 nullptr,
847 nullptr,
848 },
849 // }
850 {"g0",
851 "",
852 4,
853 0,
854 eEncodingUint,
855 eFormatAddressInfo,
856 {80, 80, LLDB_INVALID_REGNUM, 80, 80},
857 nullptr,
858 nullptr,
859 },
860 {"g1",
861 "",
862 4,
863 0,
864 eEncodingUint,
865 eFormatAddressInfo,
866 {81, 81, LLDB_INVALID_REGNUM, 81, 81},
867 nullptr,
868 nullptr,
869 },
870 {"g2",
871 "",
872 4,
873 0,
874 eEncodingUint,
875 eFormatAddressInfo,
876 {82, 82, LLDB_INVALID_REGNUM, 82, 82},
877 nullptr,
878 nullptr,
879 },
880 {"g3",
881 "",
882 4,
883 0,
884 eEncodingUint,
885 eFormatAddressInfo,
886 {83, 83, LLDB_INVALID_REGNUM, 83, 83},
887 nullptr,
888 nullptr,
889 }};
890
891 static const uint32_t k_num_register_infos =
892 sizeof(g_register_infos) / sizeof(RegisterInfo);
893
894 const lldb_private::RegisterInfo *
GetRegisterInfoArray(uint32_t & count)895 ABISysV_hexagon::GetRegisterInfoArray(uint32_t &count) {
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 */
GetRedZoneSize() const913 size_t ABISysV_hexagon::GetRedZoneSize() const { return 0; }
914
915 // Static Functions
916
917 ABISP
CreateInstance(lldb::ProcessSP process_sp,const ArchSpec & arch)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
PrepareTrivialCall(Thread & thread,lldb::addr_t sp,lldb::addr_t pc,lldb::addr_t ra,llvm::ArrayRef<addr_t> args) const926 bool ABISysV_hexagon::PrepareTrivialCall(Thread &thread, lldb::addr_t sp,
927 lldb::addr_t pc, lldb::addr_t ra,
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
PrepareTrivialCall(Thread & thread,lldb::addr_t sp,lldb::addr_t pc,lldb::addr_t ra,llvm::Type & prototype,llvm::ArrayRef<ABI::CallArgument> args) const965 bool ABISysV_hexagon::PrepareTrivialCall(
966 Thread &thread, lldb::addr_t sp, lldb::addr_t pc, lldb::addr_t ra,
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
980 uint32_t pc_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
981 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
982 if (pc_reg == LLDB_INVALID_REGNUM)
983 return false;
984
985 uint32_t ra_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
986 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
987 if (ra_reg == LLDB_INVALID_REGNUM)
988 return false;
989
990 uint32_t sp_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
991 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
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 *)¶m, 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
GetArgumentValues(Thread & thread,ValueList & values) const1087 bool ABISysV_hexagon::GetArgumentValues(Thread &thread,
1088 ValueList &values) const {
1089 return false;
1090 }
1091
1092 Status
SetReturnValueObject(lldb::StackFrameSP & frame_sp,lldb::ValueObjectSP & new_value_sp)1093 ABISysV_hexagon::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
1094 lldb::ValueObjectSP &new_value_sp) {
1095 Status error;
1096 return error;
1097 }
1098
GetReturnValueObjectSimple(Thread & thread,CompilerType & return_compiler_type) const1099 ValueObjectSP ABISysV_hexagon::GetReturnValueObjectSimple(
1100 Thread &thread, CompilerType &return_compiler_type) const {
1101 ValueObjectSP return_valobj_sp;
1102 return return_valobj_sp;
1103 }
1104
GetReturnValueObjectImpl(Thread & thread,CompilerType & return_compiler_type) const1105 ValueObjectSP ABISysV_hexagon::GetReturnValueObjectImpl(
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)
CreateFunctionEntryUnwindPlan(UnwindPlan & unwind_plan)1113 bool ABISysV_hexagon::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
1114 unwind_plan.Clear();
1115 unwind_plan.SetRegisterKind(eRegisterKindGeneric);
1116 unwind_plan.SetReturnAddressRegister(LLDB_REGNUM_GENERIC_RA);
1117
1118 UnwindPlan::RowSP row(new UnwindPlan::Row);
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
CreateDefaultUnwindPlan(UnwindPlan & unwind_plan)1134 bool ABISysV_hexagon::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
1135 unwind_plan.Clear();
1136 unwind_plan.SetRegisterKind(eRegisterKindGeneric);
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
1142 UnwindPlan::RowSP row(new UnwindPlan::Row);
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);
1154 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1155 unwind_plan.SetUnwindPlanForSignalTrap(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 */
RegisterIsVolatile(const RegisterInfo * reg_info)1173 bool ABISysV_hexagon::RegisterIsVolatile(const RegisterInfo *reg_info) {
1174 return !RegisterIsCalleeSaved(reg_info);
1175 }
1176
RegisterIsCalleeSaved(const RegisterInfo * reg_info)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
Initialize()1186 void ABISysV_hexagon::Initialize() {
1187 PluginManager::RegisterPlugin(GetPluginNameStatic(),
1188 "System V ABI for hexagon targets",
1189 CreateInstance);
1190 }
1191
Terminate()1192 void ABISysV_hexagon::Terminate() {
1193 PluginManager::UnregisterPlugin(CreateInstance);
1194 }
1195
1196 // get value object specialized to work with llvm IR types
1197 lldb::ValueObjectSP
GetReturnValueObjectImpl(lldb_private::Thread & thread,llvm::Type & retType) const1198 ABISysV_hexagon::GetReturnValueObjectImpl(lldb_private::Thread &thread,
1199 llvm::Type &retType) const {
1200 Value value;
1201 ValueObjectSP vObjSP;
1202
1203 // get the current register context
1204 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1205 if (!reg_ctx)
1206 return vObjSP;
1207
1208 // for now just pop R0 to find the return value
1209 const lldb_private::RegisterInfo *r0_info =
1210 reg_ctx->GetRegisterInfoAtIndex(0);
1211 if (r0_info == nullptr)
1212 return vObjSP;
1213
1214 // void return type
1215 if (retType.isVoidTy()) {
1216 value.GetScalar() = 0;
1217 }
1218 // integer / pointer return type
1219 else if (retType.isIntegerTy() || retType.isPointerTy()) {
1220 // read r0 register value
1221 lldb_private::RegisterValue r0_value;
1222 if (!reg_ctx->ReadRegister(r0_info, r0_value))
1223 return vObjSP;
1224
1225 // push r0 into value
1226 uint32_t r0_u32 = r0_value.GetAsUInt32();
1227
1228 // account for integer size
1229 if (retType.isIntegerTy() && retType.isSized()) {
1230 uint64_t size = retType.getScalarSizeInBits();
1231 uint64_t mask = (1ull << size) - 1;
1232 // mask out higher order bits then the type we expect
1233 r0_u32 &= mask;
1234 }
1235
1236 value.GetScalar() = r0_u32;
1237 }
1238 // unsupported return type
1239 else
1240 return vObjSP;
1241
1242 // pack the value into a ValueObjectSP
1243 vObjSP = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
1244 value, ConstString(""));
1245 return vObjSP;
1246 }
1247