]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp
MFC r355940:
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / source / Plugins / Process / minidump / RegisterContextMinidump_ARM64.cpp
1 //===-- RegisterContextMinidump_ARM64.cpp -----------------------*- C++ -*-===//
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 "RegisterContextMinidump_ARM64.h"
10
11 #include "Utility/ARM64_DWARF_Registers.h"
12 #include "lldb/Utility/RegisterValue.h"
13 #include "lldb/Utility/DataExtractor.h"
14 #include "lldb/lldb-enumerations.h"
15
16 // C includes
17 #include <assert.h>
18
19 // C++ includes
20
21 using namespace lldb;
22 using namespace lldb_private;
23 using namespace minidump;
24
25 #define INV LLDB_INVALID_REGNUM
26 #define OFFSET(r) (offsetof(RegisterContextMinidump_ARM64::Context, r))
27
28 #define DEF_X(i)                                                               \
29   {                                                                            \
30     "x" #i, nullptr, 8, OFFSET(x) + i * 8, eEncodingUint, eFormatHex,          \
31         {arm64_dwarf::x##i, arm64_dwarf::x##i, INV, INV, reg_x##i},            \
32         nullptr, nullptr, nullptr, 0                                           \
33   }
34
35 #define DEF_W(i)                                                               \
36   {                                                                            \
37     "w" #i, nullptr, 4, OFFSET(x) + i * 8, eEncodingUint, eFormatHex,          \
38         {INV, INV, INV, INV, reg_w##i}, nullptr, nullptr, nullptr, 0           \
39   }
40
41 #define DEF_X_ARG(i, n)                                                        \
42   {                                                                            \
43     "x" #i, "arg" #n, 8, OFFSET(x) + i * 8, eEncodingUint, eFormatHex,         \
44         {arm64_dwarf::x##i, arm64_dwarf::x##i, LLDB_REGNUM_GENERIC_ARG1 + i,   \
45          INV, reg_x##i}, nullptr, nullptr, nullptr, 0                          \
46   }
47
48 #define DEF_V(i)                                                               \
49   {                                                                            \
50     "v" #i, nullptr, 16, OFFSET(v) + i * 16, eEncodingVector,                  \
51         eFormatVectorOfUInt8, {arm64_dwarf::v##i, arm64_dwarf::v##i, INV, INV, \
52         reg_v##i}, nullptr, nullptr, nullptr, 0                                \
53   }
54
55 #define DEF_D(i)                                                               \
56   {                                                                            \
57     "d" #i, nullptr, 8, OFFSET(v) + i * 16, eEncodingVector,                   \
58         eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_d##i}, nullptr,         \
59         nullptr, nullptr, 0                                                    \
60   }
61
62 #define DEF_S(i)                                                               \
63   {                                                                            \
64     "s" #i, nullptr, 4, OFFSET(v) + i * 16, eEncodingVector,                   \
65         eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_s##i}, nullptr,         \
66         nullptr, nullptr, 0                                                    \
67   }
68
69 #define DEF_H(i)                                                               \
70   {                                                                            \
71     "h" #i, nullptr, 2, OFFSET(v) + i * 16, eEncodingVector,                   \
72         eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_h##i}, nullptr,         \
73         nullptr, nullptr, 0                                                    \
74   }
75
76 // Zero based LLDB register numbers for this register context
77 enum {
78   // General Purpose Registers
79   reg_x0 = 0,
80   reg_x1,
81   reg_x2,
82   reg_x3,
83   reg_x4,
84   reg_x5,
85   reg_x6,
86   reg_x7,
87   reg_x8,
88   reg_x9,
89   reg_x10,
90   reg_x11,
91   reg_x12,
92   reg_x13,
93   reg_x14,
94   reg_x15,
95   reg_x16,
96   reg_x17,
97   reg_x18,
98   reg_x19,
99   reg_x20,
100   reg_x21,
101   reg_x22,
102   reg_x23,
103   reg_x24,
104   reg_x25,
105   reg_x26,
106   reg_x27,
107   reg_x28,
108   reg_fp,
109   reg_lr,
110   reg_sp,
111   reg_pc,
112   reg_w0,
113   reg_w1,
114   reg_w2,
115   reg_w3,
116   reg_w4,
117   reg_w5,
118   reg_w6,
119   reg_w7,
120   reg_w8,
121   reg_w9,
122   reg_w10,
123   reg_w11,
124   reg_w12,
125   reg_w13,
126   reg_w14,
127   reg_w15,
128   reg_w16,
129   reg_w17,
130   reg_w18,
131   reg_w19,
132   reg_w20,
133   reg_w21,
134   reg_w22,
135   reg_w23,
136   reg_w24,
137   reg_w25,
138   reg_w26,
139   reg_w27,
140   reg_w28,
141   reg_w29,
142   reg_w30,
143   reg_w31,
144   reg_cpsr,
145   // Floating Point Registers
146   reg_fpsr,
147   reg_fpcr,
148   reg_v0,
149   reg_v1,
150   reg_v2,
151   reg_v3,
152   reg_v4,
153   reg_v5,
154   reg_v6,
155   reg_v7,
156   reg_v8,
157   reg_v9,
158   reg_v10,
159   reg_v11,
160   reg_v12,
161   reg_v13,
162   reg_v14,
163   reg_v15,
164   reg_v16,
165   reg_v17,
166   reg_v18,
167   reg_v19,
168   reg_v20,
169   reg_v21,
170   reg_v22,
171   reg_v23,
172   reg_v24,
173   reg_v25,
174   reg_v26,
175   reg_v27,
176   reg_v28,
177   reg_v29,
178   reg_v30,
179   reg_v31,
180   reg_d0,
181   reg_d1,
182   reg_d2,
183   reg_d3,
184   reg_d4,
185   reg_d5,
186   reg_d6,
187   reg_d7,
188   reg_d8,
189   reg_d9,
190   reg_d10,
191   reg_d11,
192   reg_d12,
193   reg_d13,
194   reg_d14,
195   reg_d15,
196   reg_d16,
197   reg_d17,
198   reg_d18,
199   reg_d19,
200   reg_d20,
201   reg_d21,
202   reg_d22,
203   reg_d23,
204   reg_d24,
205   reg_d25,
206   reg_d26,
207   reg_d27,
208   reg_d28,
209   reg_d29,
210   reg_d30,
211   reg_d31,
212   reg_s0,
213   reg_s1,
214   reg_s2,
215   reg_s3,
216   reg_s4,
217   reg_s5,
218   reg_s6,
219   reg_s7,
220   reg_s8,
221   reg_s9,
222   reg_s10,
223   reg_s11,
224   reg_s12,
225   reg_s13,
226   reg_s14,
227   reg_s15,
228   reg_s16,
229   reg_s17,
230   reg_s18,
231   reg_s19,
232   reg_s20,
233   reg_s21,
234   reg_s22,
235   reg_s23,
236   reg_s24,
237   reg_s25,
238   reg_s26,
239   reg_s27,
240   reg_s28,
241   reg_s29,
242   reg_s30,
243   reg_s31,
244   reg_h0,
245   reg_h1,
246   reg_h2,
247   reg_h3,
248   reg_h4,
249   reg_h5,
250   reg_h6,
251   reg_h7,
252   reg_h8,
253   reg_h9,
254   reg_h10,
255   reg_h11,
256   reg_h12,
257   reg_h13,
258   reg_h14,
259   reg_h15,
260   reg_h16,
261   reg_h17,
262   reg_h18,
263   reg_h19,
264   reg_h20,
265   reg_h21,
266   reg_h22,
267   reg_h23,
268   reg_h24,
269   reg_h25,
270   reg_h26,
271   reg_h27,
272   reg_h28,
273   reg_h29,
274   reg_h30,
275   reg_h31,
276   k_num_regs
277 };
278
279 // Register info definitions for this register context
280 static RegisterInfo g_reg_infos[] = {
281     DEF_X_ARG(0, 1),
282     DEF_X_ARG(1, 2),
283     DEF_X_ARG(2, 3),
284     DEF_X_ARG(3, 4),
285     DEF_X_ARG(4, 5),
286     DEF_X_ARG(5, 6),
287     DEF_X_ARG(6, 7),
288     DEF_X_ARG(7, 8),
289     DEF_X(8),
290     DEF_X(9),
291     DEF_X(10),
292     DEF_X(11),
293     DEF_X(12),
294     DEF_X(13),
295     DEF_X(14),
296     DEF_X(15),
297     DEF_X(16),
298     DEF_X(17),
299     DEF_X(18),
300     DEF_X(19),
301     DEF_X(20),
302     DEF_X(21),
303     DEF_X(22),
304     DEF_X(23),
305     DEF_X(24),
306     DEF_X(25),
307     DEF_X(26),
308     DEF_X(27),
309     DEF_X(28),
310     {"fp",
311      "x29",
312      8,
313      OFFSET(x) + 29 * 8,
314      eEncodingUint,
315      eFormatHex,
316      {arm64_dwarf::x29, arm64_dwarf::x29, LLDB_REGNUM_GENERIC_FP, INV, reg_fp},
317      nullptr,
318      nullptr,
319      nullptr,
320      0},
321     {"lr",
322      "x30",
323      8,
324      OFFSET(x) + 30 * 8,
325      eEncodingUint,
326      eFormatHex,
327      {arm64_dwarf::x30, arm64_dwarf::x30, LLDB_REGNUM_GENERIC_RA, INV, reg_lr},
328      nullptr,
329      nullptr,
330      nullptr,
331      0},
332     {"sp",
333      "x31",
334      8,
335      OFFSET(x) + 31 * 8,
336      eEncodingUint,
337      eFormatHex,
338      {arm64_dwarf::x31, arm64_dwarf::x31, LLDB_REGNUM_GENERIC_SP, INV, reg_sp},
339      nullptr,
340      nullptr,
341      nullptr,
342      0},
343     {"pc",
344      nullptr,
345      8,
346      OFFSET(pc),
347      eEncodingUint,
348      eFormatHex,
349      {arm64_dwarf::pc, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc},
350      nullptr,
351      nullptr,
352      nullptr,
353      0},
354     // w0 - w31
355     DEF_W(0),
356     DEF_W(1),
357     DEF_W(2),
358     DEF_W(3),
359     DEF_W(4),
360     DEF_W(5),
361     DEF_W(6),
362     DEF_W(7),
363     DEF_W(8),
364     DEF_W(9),
365     DEF_W(10),
366     DEF_W(11),
367     DEF_W(12),
368     DEF_W(13),
369     DEF_W(14),
370     DEF_W(15),
371     DEF_W(16),
372     DEF_W(17),
373     DEF_W(18),
374     DEF_W(19),
375     DEF_W(20),
376     DEF_W(21),
377     DEF_W(22),
378     DEF_W(23),
379     DEF_W(24),
380     DEF_W(25),
381     DEF_W(26),
382     DEF_W(27),
383     DEF_W(28),
384     DEF_W(29),
385     DEF_W(30),
386     DEF_W(31),
387     {"cpsr",
388      "psr",
389      4,
390      OFFSET(cpsr),
391      eEncodingUint,
392      eFormatHex,
393      {INV, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr},
394      nullptr,
395      nullptr,
396      nullptr,
397      0},
398     {"fpsr",
399      nullptr,
400      4,
401      OFFSET(fpsr),
402      eEncodingUint,
403      eFormatHex,
404      {INV, INV, INV, INV, reg_fpsr},
405      nullptr,
406      nullptr,
407      nullptr,
408      0},
409     {"fpcr",
410      nullptr,
411      4,
412      OFFSET(fpcr),
413      eEncodingUint,
414      eFormatHex,
415      {INV, INV, INV, INV, reg_fpcr},
416      nullptr,
417      nullptr,
418      nullptr,
419      0},
420     // v0 - v31
421     DEF_V(0),
422     DEF_V(1),
423     DEF_V(2),
424     DEF_V(3),
425     DEF_V(4),
426     DEF_V(5),
427     DEF_V(6),
428     DEF_V(7),
429     DEF_V(8),
430     DEF_V(9),
431     DEF_V(10),
432     DEF_V(11),
433     DEF_V(12),
434     DEF_V(13),
435     DEF_V(14),
436     DEF_V(15),
437     DEF_V(16),
438     DEF_V(17),
439     DEF_V(18),
440     DEF_V(19),
441     DEF_V(20),
442     DEF_V(21),
443     DEF_V(22),
444     DEF_V(23),
445     DEF_V(24),
446     DEF_V(25),
447     DEF_V(26),
448     DEF_V(27),
449     DEF_V(28),
450     DEF_V(29),
451     DEF_V(30),
452     DEF_V(31),
453     // d0 - d31
454     DEF_D(0),
455     DEF_D(1),
456     DEF_D(2),
457     DEF_D(3),
458     DEF_D(4),
459     DEF_D(5),
460     DEF_D(6),
461     DEF_D(7),
462     DEF_D(8),
463     DEF_D(9),
464     DEF_D(10),
465     DEF_D(11),
466     DEF_D(12),
467     DEF_D(13),
468     DEF_D(14),
469     DEF_D(15),
470     DEF_D(16),
471     DEF_D(17),
472     DEF_D(18),
473     DEF_D(19),
474     DEF_D(20),
475     DEF_D(21),
476     DEF_D(22),
477     DEF_D(23),
478     DEF_D(24),
479     DEF_D(25),
480     DEF_D(26),
481     DEF_D(27),
482     DEF_D(28),
483     DEF_D(29),
484     DEF_D(30),
485     DEF_D(31),
486     // s0 - s31
487     DEF_S(0),
488     DEF_S(1),
489     DEF_S(2),
490     DEF_S(3),
491     DEF_S(4),
492     DEF_S(5),
493     DEF_S(6),
494     DEF_S(7),
495     DEF_S(8),
496     DEF_S(9),
497     DEF_S(10),
498     DEF_S(11),
499     DEF_S(12),
500     DEF_S(13),
501     DEF_S(14),
502     DEF_S(15),
503     DEF_S(16),
504     DEF_S(17),
505     DEF_S(18),
506     DEF_S(19),
507     DEF_S(20),
508     DEF_S(21),
509     DEF_S(22),
510     DEF_S(23),
511     DEF_S(24),
512     DEF_S(25),
513     DEF_S(26),
514     DEF_S(27),
515     DEF_S(28),
516     DEF_S(29),
517     DEF_S(30),
518     DEF_S(31),
519     // h0 - h31
520     DEF_H(0),
521     DEF_H(1),
522     DEF_H(2),
523     DEF_H(3),
524     DEF_H(4),
525     DEF_H(5),
526     DEF_H(6),
527     DEF_H(7),
528     DEF_H(8),
529     DEF_H(9),
530     DEF_H(10),
531     DEF_H(11),
532     DEF_H(12),
533     DEF_H(13),
534     DEF_H(14),
535     DEF_H(15),
536     DEF_H(16),
537     DEF_H(17),
538     DEF_H(18),
539     DEF_H(19),
540     DEF_H(20),
541     DEF_H(21),
542     DEF_H(22),
543     DEF_H(23),
544     DEF_H(24),
545     DEF_H(25),
546     DEF_H(26),
547     DEF_H(27),
548     DEF_H(28),
549     DEF_H(29),
550     DEF_H(30),
551     DEF_H(31),
552 };
553
554 constexpr size_t k_num_reg_infos = llvm::array_lengthof(g_reg_infos);
555
556 // ARM64 general purpose registers.
557 const uint32_t g_gpr_regnums[] = {
558     reg_x0,
559     reg_x1,
560     reg_x2,
561     reg_x3,
562     reg_x4,
563     reg_x5,
564     reg_x6,
565     reg_x7,
566     reg_x8,
567     reg_x9,
568     reg_x10,
569     reg_x11,
570     reg_x12,
571     reg_x13,
572     reg_x14,
573     reg_x15,
574     reg_x16,
575     reg_x17,
576     reg_x18,
577     reg_x19,
578     reg_x20,
579     reg_x21,
580     reg_x22,
581     reg_x23,
582     reg_x24,
583     reg_x25,
584     reg_x26,
585     reg_x27,
586     reg_x28,
587     reg_fp,
588     reg_lr,
589     reg_sp,
590     reg_w0,
591     reg_w1,
592     reg_w2,
593     reg_w3,
594     reg_w4,
595     reg_w5,
596     reg_w6,
597     reg_w7,
598     reg_w8,
599     reg_w9,
600     reg_w10,
601     reg_w11,
602     reg_w12,
603     reg_w13,
604     reg_w14,
605     reg_w15,
606     reg_w16,
607     reg_w17,
608     reg_w18,
609     reg_w19,
610     reg_w20,
611     reg_w21,
612     reg_w22,
613     reg_w23,
614     reg_w24,
615     reg_w25,
616     reg_w26,
617     reg_w27,
618     reg_w28,
619     reg_w29,
620     reg_w30,
621     reg_w31,
622     reg_pc,
623     reg_cpsr,
624     LLDB_INVALID_REGNUM // register sets need to end with this flag
625 };
626 const uint32_t g_fpu_regnums[] = {
627     reg_v0,
628     reg_v1,
629     reg_v2,
630     reg_v3,
631     reg_v4,
632     reg_v5,
633     reg_v6,
634     reg_v7,
635     reg_v8,
636     reg_v9,
637     reg_v10,
638     reg_v11,
639     reg_v12,
640     reg_v13,
641     reg_v14,
642     reg_v15,
643     reg_v16,
644     reg_v17,
645     reg_v18,
646     reg_v19,
647     reg_v20,
648     reg_v21,
649     reg_v22,
650     reg_v23,
651     reg_v24,
652     reg_v25,
653     reg_v26,
654     reg_v27,
655     reg_v28,
656     reg_v29,
657     reg_v30,
658     reg_v31,
659     reg_d0,
660     reg_d1,
661     reg_d2,
662     reg_d3,
663     reg_d4,
664     reg_d5,
665     reg_d6,
666     reg_d7,
667     reg_d8,
668     reg_d9,
669     reg_d10,
670     reg_d11,
671     reg_d12,
672     reg_d13,
673     reg_d14,
674     reg_d15,
675     reg_d16,
676     reg_d17,
677     reg_d18,
678     reg_d19,
679     reg_d20,
680     reg_d21,
681     reg_d22,
682     reg_d23,
683     reg_d24,
684     reg_d25,
685     reg_d26,
686     reg_d27,
687     reg_d28,
688     reg_d29,
689     reg_d30,
690     reg_d31,
691     reg_s0,
692     reg_s1,
693     reg_s2,
694     reg_s3,
695     reg_s4,
696     reg_s5,
697     reg_s6,
698     reg_s7,
699     reg_s8,
700     reg_s9,
701     reg_s10,
702     reg_s11,
703     reg_s12,
704     reg_s13,
705     reg_s14,
706     reg_s15,
707     reg_s16,
708     reg_s17,
709     reg_s18,
710     reg_s19,
711     reg_s20,
712     reg_s21,
713     reg_s22,
714     reg_s23,
715     reg_s24,
716     reg_s25,
717     reg_s26,
718     reg_s27,
719     reg_s28,
720     reg_s29,
721     reg_s30,
722     reg_s31,
723     reg_h0,
724     reg_h1,
725     reg_h2,
726     reg_h3,
727     reg_h4,
728     reg_h5,
729     reg_h6,
730     reg_h7,
731     reg_h8,
732     reg_h9,
733     reg_h10,
734     reg_h11,
735     reg_h12,
736     reg_h13,
737     reg_h14,
738     reg_h15,
739     reg_h16,
740     reg_h17,
741     reg_h18,
742     reg_h19,
743     reg_h20,
744     reg_h21,
745     reg_h22,
746     reg_h23,
747     reg_h24,
748     reg_h25,
749     reg_h26,
750     reg_h27,
751     reg_h28,
752     reg_h29,
753     reg_h30,
754     reg_h31,
755     reg_fpsr,
756     reg_fpcr,
757     LLDB_INVALID_REGNUM // register sets need to end with this flag
758 };
759
760 // Skip the last LLDB_INVALID_REGNUM in each count below by subtracting 1
761 constexpr size_t k_num_gpr_regs = llvm::array_lengthof(g_gpr_regnums) - 1;
762 constexpr size_t k_num_fpu_regs = llvm::array_lengthof(g_fpu_regnums) - 1;
763
764 static RegisterSet g_reg_sets[] = {
765     {"General Purpose Registers", "gpr", k_num_gpr_regs, g_gpr_regnums},
766     {"Floating Point Registers", "fpu", k_num_fpu_regs, g_fpu_regnums},
767 };
768
769 constexpr size_t k_num_reg_sets = llvm::array_lengthof(g_reg_sets);
770
771 RegisterContextMinidump_ARM64::RegisterContextMinidump_ARM64(
772     lldb_private::Thread &thread, const DataExtractor &data)
773     : RegisterContext(thread, 0) {
774   lldb::offset_t offset = 0;
775   m_regs.context_flags = data.GetU64(&offset);
776   for (unsigned i = 0; i < 32; ++i)
777     m_regs.x[i] = data.GetU64(&offset);
778   m_regs.pc = data.GetU64(&offset);
779   m_regs.cpsr = data.GetU32(&offset);
780   m_regs.fpsr = data.GetU32(&offset);
781   m_regs.fpcr = data.GetU32(&offset);
782   auto regs_data = data.GetData(&offset, sizeof(m_regs.v));
783   if (regs_data)
784     memcpy(m_regs.v, regs_data, sizeof(m_regs.v));
785   static_assert(k_num_regs == k_num_reg_infos, "");
786 }
787 size_t RegisterContextMinidump_ARM64::GetRegisterCount() { return k_num_regs; }
788
789 const RegisterInfo *
790 RegisterContextMinidump_ARM64::GetRegisterInfoAtIndex(size_t reg) {
791   if (reg < k_num_reg_infos)
792     return &g_reg_infos[reg];
793   return nullptr;
794 }
795
796 size_t RegisterContextMinidump_ARM64::GetRegisterSetCount() {
797   return k_num_reg_sets;
798 }
799
800 const RegisterSet *RegisterContextMinidump_ARM64::GetRegisterSet(size_t set) {
801   if (set < k_num_reg_sets)
802     return &g_reg_sets[set];
803   return nullptr;
804 }
805
806 const char *RegisterContextMinidump_ARM64::GetRegisterName(unsigned reg) {
807   if (reg < k_num_reg_infos)
808     return g_reg_infos[reg].name;
809   return nullptr;
810 }
811
812 bool RegisterContextMinidump_ARM64::ReadRegister(const RegisterInfo *reg_info,
813                                                  RegisterValue &reg_value) {
814   Status error;
815   reg_value.SetFromMemoryData(
816       reg_info, (const uint8_t *)&m_regs + reg_info->byte_offset,
817       reg_info->byte_size, lldb::eByteOrderLittle, error);
818   return error.Success();
819 }
820
821 bool RegisterContextMinidump_ARM64::WriteRegister(const RegisterInfo *,
822                                                   const RegisterValue &) {
823   return false;
824 }
825
826 uint32_t RegisterContextMinidump_ARM64::ConvertRegisterKindToRegisterNumber(
827     lldb::RegisterKind kind, uint32_t num) {
828   for (size_t i = 0; i < k_num_regs; ++i) {
829     if (g_reg_infos[i].kinds[kind] == num)
830       return i;
831   }
832   return LLDB_INVALID_REGNUM;
833 }