Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp
96383 views
1
//===-- RegisterContextMinidump_ARM64.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 "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 <cassert>
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, \
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, \
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, \
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, \
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, \
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, \
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, \
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
},
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
},
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
},
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
},
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
},
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
},
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
},
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 = std::size(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 = std::size(g_gpr_regnums) - 1;
762
constexpr size_t k_num_fpu_regs = std::size(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 = std::size(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
}
834
835