Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp
39648 views
1
//===-- ABISysV_arm.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_arm.h"
10
11
#include <optional>
12
#include <vector>
13
14
#include "llvm/ADT/STLExtras.h"
15
#include "llvm/TargetParser/Triple.h"
16
17
#include "lldb/Core/Module.h"
18
#include "lldb/Core/PluginManager.h"
19
#include "lldb/Core/Value.h"
20
#include "lldb/Core/ValueObjectConstResult.h"
21
#include "lldb/Symbol/UnwindPlan.h"
22
#include "lldb/Target/Process.h"
23
#include "lldb/Target/RegisterContext.h"
24
#include "lldb/Target/Target.h"
25
#include "lldb/Target/Thread.h"
26
#include "lldb/Utility/ConstString.h"
27
#include "lldb/Utility/RegisterValue.h"
28
#include "lldb/Utility/Scalar.h"
29
#include "lldb/Utility/Status.h"
30
31
#include "Plugins/Process/Utility/ARMDefines.h"
32
#include "Utility/ARM_DWARF_Registers.h"
33
#include "Utility/ARM_ehframe_Registers.h"
34
35
using namespace lldb;
36
using namespace lldb_private;
37
38
LLDB_PLUGIN_DEFINE(ABISysV_arm)
39
40
static const RegisterInfo g_register_infos[] = {
41
// NAME ALT SZ OFF ENCODING FORMAT EH_FRAME
42
// DWARF GENERIC PROCESS PLUGIN
43
// LLDB NATIVE VALUE REGS INVALIDATE REGS
44
// ========== ======= == === ============= ============
45
// ======================= =================== ===========================
46
// ======================= ====================== ==========
47
// ===============
48
{"r0",
49
nullptr,
50
4,
51
0,
52
eEncodingUint,
53
eFormatHex,
54
{ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM,
55
LLDB_INVALID_REGNUM},
56
nullptr,
57
nullptr,
58
nullptr,
59
},
60
{"r1",
61
nullptr,
62
4,
63
0,
64
eEncodingUint,
65
eFormatHex,
66
{ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM,
67
LLDB_INVALID_REGNUM},
68
nullptr,
69
nullptr,
70
nullptr,
71
},
72
{"r2",
73
nullptr,
74
4,
75
0,
76
eEncodingUint,
77
eFormatHex,
78
{ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM,
79
LLDB_INVALID_REGNUM},
80
nullptr,
81
nullptr,
82
nullptr,
83
},
84
{"r3",
85
nullptr,
86
4,
87
0,
88
eEncodingUint,
89
eFormatHex,
90
{ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM,
91
LLDB_INVALID_REGNUM},
92
nullptr,
93
nullptr,
94
nullptr,
95
},
96
{"r4",
97
nullptr,
98
4,
99
0,
100
eEncodingUint,
101
eFormatHex,
102
{ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
103
LLDB_INVALID_REGNUM},
104
nullptr,
105
nullptr,
106
nullptr,
107
},
108
{"r5",
109
nullptr,
110
4,
111
0,
112
eEncodingUint,
113
eFormatHex,
114
{ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
115
LLDB_INVALID_REGNUM},
116
nullptr,
117
nullptr,
118
nullptr,
119
},
120
{"r6",
121
nullptr,
122
4,
123
0,
124
eEncodingUint,
125
eFormatHex,
126
{ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
127
LLDB_INVALID_REGNUM},
128
nullptr,
129
nullptr,
130
nullptr,
131
},
132
{"r7",
133
nullptr,
134
4,
135
0,
136
eEncodingUint,
137
eFormatHex,
138
{ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
139
LLDB_INVALID_REGNUM},
140
nullptr,
141
nullptr,
142
nullptr,
143
},
144
{"r8",
145
nullptr,
146
4,
147
0,
148
eEncodingUint,
149
eFormatHex,
150
{ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
151
LLDB_INVALID_REGNUM},
152
nullptr,
153
nullptr,
154
nullptr,
155
},
156
{"r9",
157
nullptr,
158
4,
159
0,
160
eEncodingUint,
161
eFormatHex,
162
{ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
163
LLDB_INVALID_REGNUM},
164
nullptr,
165
nullptr,
166
nullptr,
167
},
168
{"r10",
169
nullptr,
170
4,
171
0,
172
eEncodingUint,
173
eFormatHex,
174
{ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
175
LLDB_INVALID_REGNUM},
176
nullptr,
177
nullptr,
178
nullptr,
179
},
180
{"r11",
181
nullptr,
182
4,
183
0,
184
eEncodingUint,
185
eFormatHex,
186
{ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
187
LLDB_INVALID_REGNUM},
188
nullptr,
189
nullptr,
190
nullptr,
191
},
192
{"r12",
193
nullptr,
194
4,
195
0,
196
eEncodingUint,
197
eFormatHex,
198
{ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
199
LLDB_INVALID_REGNUM},
200
nullptr,
201
nullptr,
202
nullptr,
203
},
204
{"sp",
205
"r13",
206
4,
207
0,
208
eEncodingUint,
209
eFormatHex,
210
{ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
211
LLDB_INVALID_REGNUM},
212
nullptr,
213
nullptr,
214
nullptr,
215
},
216
{"lr",
217
"r14",
218
4,
219
0,
220
eEncodingUint,
221
eFormatHex,
222
{ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM,
223
LLDB_INVALID_REGNUM},
224
nullptr,
225
nullptr,
226
nullptr,
227
},
228
{"pc",
229
"r15",
230
4,
231
0,
232
eEncodingUint,
233
eFormatHex,
234
{ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
235
LLDB_INVALID_REGNUM},
236
nullptr,
237
nullptr,
238
nullptr,
239
},
240
{"cpsr",
241
"psr",
242
4,
243
0,
244
eEncodingUint,
245
eFormatHex,
246
{ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM,
247
LLDB_INVALID_REGNUM},
248
nullptr,
249
nullptr,
250
nullptr,
251
},
252
{"s0",
253
nullptr,
254
4,
255
0,
256
eEncodingIEEE754,
257
eFormatFloat,
258
{LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
259
LLDB_INVALID_REGNUM},
260
nullptr,
261
nullptr,
262
nullptr,
263
},
264
{"s1",
265
nullptr,
266
4,
267
0,
268
eEncodingIEEE754,
269
eFormatFloat,
270
{LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
271
LLDB_INVALID_REGNUM},
272
nullptr,
273
nullptr,
274
nullptr,
275
},
276
{"s2",
277
nullptr,
278
4,
279
0,
280
eEncodingIEEE754,
281
eFormatFloat,
282
{LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
283
LLDB_INVALID_REGNUM},
284
nullptr,
285
nullptr,
286
nullptr,
287
},
288
{"s3",
289
nullptr,
290
4,
291
0,
292
eEncodingIEEE754,
293
eFormatFloat,
294
{LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
295
LLDB_INVALID_REGNUM},
296
nullptr,
297
nullptr,
298
nullptr,
299
},
300
{"s4",
301
nullptr,
302
4,
303
0,
304
eEncodingIEEE754,
305
eFormatFloat,
306
{LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
307
LLDB_INVALID_REGNUM},
308
nullptr,
309
nullptr,
310
nullptr,
311
},
312
{"s5",
313
nullptr,
314
4,
315
0,
316
eEncodingIEEE754,
317
eFormatFloat,
318
{LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
319
LLDB_INVALID_REGNUM},
320
nullptr,
321
nullptr,
322
nullptr,
323
},
324
{"s6",
325
nullptr,
326
4,
327
0,
328
eEncodingIEEE754,
329
eFormatFloat,
330
{LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
331
LLDB_INVALID_REGNUM},
332
nullptr,
333
nullptr,
334
nullptr,
335
},
336
{"s7",
337
nullptr,
338
4,
339
0,
340
eEncodingIEEE754,
341
eFormatFloat,
342
{LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
343
LLDB_INVALID_REGNUM},
344
nullptr,
345
nullptr,
346
nullptr,
347
},
348
{"s8",
349
nullptr,
350
4,
351
0,
352
eEncodingIEEE754,
353
eFormatFloat,
354
{LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
355
LLDB_INVALID_REGNUM},
356
nullptr,
357
nullptr,
358
nullptr,
359
},
360
{"s9",
361
nullptr,
362
4,
363
0,
364
eEncodingIEEE754,
365
eFormatFloat,
366
{LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
367
LLDB_INVALID_REGNUM},
368
nullptr,
369
nullptr,
370
nullptr,
371
},
372
{"s10",
373
nullptr,
374
4,
375
0,
376
eEncodingIEEE754,
377
eFormatFloat,
378
{LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
379
LLDB_INVALID_REGNUM},
380
nullptr,
381
nullptr,
382
nullptr,
383
},
384
{"s11",
385
nullptr,
386
4,
387
0,
388
eEncodingIEEE754,
389
eFormatFloat,
390
{LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
391
LLDB_INVALID_REGNUM},
392
nullptr,
393
nullptr,
394
nullptr,
395
},
396
{"s12",
397
nullptr,
398
4,
399
0,
400
eEncodingIEEE754,
401
eFormatFloat,
402
{LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
403
LLDB_INVALID_REGNUM},
404
nullptr,
405
nullptr,
406
nullptr,
407
},
408
{"s13",
409
nullptr,
410
4,
411
0,
412
eEncodingIEEE754,
413
eFormatFloat,
414
{LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
415
LLDB_INVALID_REGNUM},
416
nullptr,
417
nullptr,
418
nullptr,
419
},
420
{"s14",
421
nullptr,
422
4,
423
0,
424
eEncodingIEEE754,
425
eFormatFloat,
426
{LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
427
LLDB_INVALID_REGNUM},
428
nullptr,
429
nullptr,
430
nullptr,
431
},
432
{"s15",
433
nullptr,
434
4,
435
0,
436
eEncodingIEEE754,
437
eFormatFloat,
438
{LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
439
LLDB_INVALID_REGNUM},
440
nullptr,
441
nullptr,
442
nullptr,
443
},
444
{"s16",
445
nullptr,
446
4,
447
0,
448
eEncodingIEEE754,
449
eFormatFloat,
450
{LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
451
LLDB_INVALID_REGNUM},
452
nullptr,
453
nullptr,
454
nullptr,
455
},
456
{"s17",
457
nullptr,
458
4,
459
0,
460
eEncodingIEEE754,
461
eFormatFloat,
462
{LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
463
LLDB_INVALID_REGNUM},
464
nullptr,
465
nullptr,
466
nullptr,
467
},
468
{"s18",
469
nullptr,
470
4,
471
0,
472
eEncodingIEEE754,
473
eFormatFloat,
474
{LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
475
LLDB_INVALID_REGNUM},
476
nullptr,
477
nullptr,
478
nullptr,
479
},
480
{"s19",
481
nullptr,
482
4,
483
0,
484
eEncodingIEEE754,
485
eFormatFloat,
486
{LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
487
LLDB_INVALID_REGNUM},
488
nullptr,
489
nullptr,
490
nullptr,
491
},
492
{"s20",
493
nullptr,
494
4,
495
0,
496
eEncodingIEEE754,
497
eFormatFloat,
498
{LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
499
LLDB_INVALID_REGNUM},
500
nullptr,
501
nullptr,
502
nullptr,
503
},
504
{"s21",
505
nullptr,
506
4,
507
0,
508
eEncodingIEEE754,
509
eFormatFloat,
510
{LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
511
LLDB_INVALID_REGNUM},
512
nullptr,
513
nullptr,
514
nullptr,
515
},
516
{"s22",
517
nullptr,
518
4,
519
0,
520
eEncodingIEEE754,
521
eFormatFloat,
522
{LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
523
LLDB_INVALID_REGNUM},
524
nullptr,
525
nullptr,
526
nullptr,
527
},
528
{"s23",
529
nullptr,
530
4,
531
0,
532
eEncodingIEEE754,
533
eFormatFloat,
534
{LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
535
LLDB_INVALID_REGNUM},
536
nullptr,
537
nullptr,
538
nullptr,
539
},
540
{"s24",
541
nullptr,
542
4,
543
0,
544
eEncodingIEEE754,
545
eFormatFloat,
546
{LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
547
LLDB_INVALID_REGNUM},
548
nullptr,
549
nullptr,
550
nullptr,
551
},
552
{"s25",
553
nullptr,
554
4,
555
0,
556
eEncodingIEEE754,
557
eFormatFloat,
558
{LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
559
LLDB_INVALID_REGNUM},
560
nullptr,
561
nullptr,
562
nullptr,
563
},
564
{"s26",
565
nullptr,
566
4,
567
0,
568
eEncodingIEEE754,
569
eFormatFloat,
570
{LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
571
LLDB_INVALID_REGNUM},
572
nullptr,
573
nullptr,
574
nullptr,
575
},
576
{"s27",
577
nullptr,
578
4,
579
0,
580
eEncodingIEEE754,
581
eFormatFloat,
582
{LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
583
LLDB_INVALID_REGNUM},
584
nullptr,
585
nullptr,
586
nullptr,
587
},
588
{"s28",
589
nullptr,
590
4,
591
0,
592
eEncodingIEEE754,
593
eFormatFloat,
594
{LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
595
LLDB_INVALID_REGNUM},
596
nullptr,
597
nullptr,
598
nullptr,
599
},
600
{"s29",
601
nullptr,
602
4,
603
0,
604
eEncodingIEEE754,
605
eFormatFloat,
606
{LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
607
LLDB_INVALID_REGNUM},
608
nullptr,
609
nullptr,
610
nullptr,
611
},
612
{"s30",
613
nullptr,
614
4,
615
0,
616
eEncodingIEEE754,
617
eFormatFloat,
618
{LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
619
LLDB_INVALID_REGNUM},
620
nullptr,
621
nullptr,
622
nullptr,
623
},
624
{"s31",
625
nullptr,
626
4,
627
0,
628
eEncodingIEEE754,
629
eFormatFloat,
630
{LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
631
LLDB_INVALID_REGNUM},
632
nullptr,
633
nullptr,
634
nullptr,
635
},
636
{"fpscr",
637
nullptr,
638
4,
639
0,
640
eEncodingUint,
641
eFormatHex,
642
{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
643
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
644
nullptr,
645
nullptr,
646
nullptr,
647
},
648
{"d0",
649
nullptr,
650
8,
651
0,
652
eEncodingIEEE754,
653
eFormatFloat,
654
{LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
655
LLDB_INVALID_REGNUM},
656
nullptr,
657
nullptr,
658
nullptr,
659
},
660
{"d1",
661
nullptr,
662
8,
663
0,
664
eEncodingIEEE754,
665
eFormatFloat,
666
{LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
667
LLDB_INVALID_REGNUM},
668
nullptr,
669
nullptr,
670
nullptr,
671
},
672
{"d2",
673
nullptr,
674
8,
675
0,
676
eEncodingIEEE754,
677
eFormatFloat,
678
{LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
679
LLDB_INVALID_REGNUM},
680
nullptr,
681
nullptr,
682
nullptr,
683
},
684
{"d3",
685
nullptr,
686
8,
687
0,
688
eEncodingIEEE754,
689
eFormatFloat,
690
{LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
691
LLDB_INVALID_REGNUM},
692
nullptr,
693
nullptr,
694
nullptr,
695
},
696
{"d4",
697
nullptr,
698
8,
699
0,
700
eEncodingIEEE754,
701
eFormatFloat,
702
{LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
703
LLDB_INVALID_REGNUM},
704
nullptr,
705
nullptr,
706
nullptr,
707
},
708
{"d5",
709
nullptr,
710
8,
711
0,
712
eEncodingIEEE754,
713
eFormatFloat,
714
{LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
715
LLDB_INVALID_REGNUM},
716
nullptr,
717
nullptr,
718
nullptr,
719
},
720
{"d6",
721
nullptr,
722
8,
723
0,
724
eEncodingIEEE754,
725
eFormatFloat,
726
{LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
727
LLDB_INVALID_REGNUM},
728
nullptr,
729
nullptr,
730
nullptr,
731
},
732
{"d7",
733
nullptr,
734
8,
735
0,
736
eEncodingIEEE754,
737
eFormatFloat,
738
{LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
739
LLDB_INVALID_REGNUM},
740
nullptr,
741
nullptr,
742
nullptr,
743
},
744
{"d8",
745
nullptr,
746
8,
747
0,
748
eEncodingIEEE754,
749
eFormatFloat,
750
{LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
751
LLDB_INVALID_REGNUM},
752
nullptr,
753
nullptr,
754
nullptr,
755
},
756
{"d9",
757
nullptr,
758
8,
759
0,
760
eEncodingIEEE754,
761
eFormatFloat,
762
{LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
763
LLDB_INVALID_REGNUM},
764
nullptr,
765
nullptr,
766
nullptr,
767
},
768
{"d10",
769
nullptr,
770
8,
771
0,
772
eEncodingIEEE754,
773
eFormatFloat,
774
{LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
775
LLDB_INVALID_REGNUM},
776
nullptr,
777
nullptr,
778
nullptr,
779
},
780
{"d11",
781
nullptr,
782
8,
783
0,
784
eEncodingIEEE754,
785
eFormatFloat,
786
{LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
787
LLDB_INVALID_REGNUM},
788
nullptr,
789
nullptr,
790
nullptr,
791
},
792
{"d12",
793
nullptr,
794
8,
795
0,
796
eEncodingIEEE754,
797
eFormatFloat,
798
{LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
799
LLDB_INVALID_REGNUM},
800
nullptr,
801
nullptr,
802
nullptr,
803
},
804
{"d13",
805
nullptr,
806
8,
807
0,
808
eEncodingIEEE754,
809
eFormatFloat,
810
{LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
811
LLDB_INVALID_REGNUM},
812
nullptr,
813
nullptr,
814
nullptr,
815
},
816
{"d14",
817
nullptr,
818
8,
819
0,
820
eEncodingIEEE754,
821
eFormatFloat,
822
{LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
823
LLDB_INVALID_REGNUM},
824
nullptr,
825
nullptr,
826
nullptr,
827
},
828
{"d15",
829
nullptr,
830
8,
831
0,
832
eEncodingIEEE754,
833
eFormatFloat,
834
{LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
835
LLDB_INVALID_REGNUM},
836
nullptr,
837
nullptr,
838
nullptr,
839
},
840
{"d16",
841
nullptr,
842
8,
843
0,
844
eEncodingIEEE754,
845
eFormatFloat,
846
{LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
847
LLDB_INVALID_REGNUM},
848
nullptr,
849
nullptr,
850
nullptr,
851
},
852
{"d17",
853
nullptr,
854
8,
855
0,
856
eEncodingIEEE754,
857
eFormatFloat,
858
{LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
859
LLDB_INVALID_REGNUM},
860
nullptr,
861
nullptr,
862
nullptr,
863
},
864
{"d18",
865
nullptr,
866
8,
867
0,
868
eEncodingIEEE754,
869
eFormatFloat,
870
{LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
871
LLDB_INVALID_REGNUM},
872
nullptr,
873
nullptr,
874
nullptr,
875
},
876
{"d19",
877
nullptr,
878
8,
879
0,
880
eEncodingIEEE754,
881
eFormatFloat,
882
{LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
883
LLDB_INVALID_REGNUM},
884
nullptr,
885
nullptr,
886
nullptr,
887
},
888
{"d20",
889
nullptr,
890
8,
891
0,
892
eEncodingIEEE754,
893
eFormatFloat,
894
{LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
895
LLDB_INVALID_REGNUM},
896
nullptr,
897
nullptr,
898
nullptr,
899
},
900
{"d21",
901
nullptr,
902
8,
903
0,
904
eEncodingIEEE754,
905
eFormatFloat,
906
{LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
907
LLDB_INVALID_REGNUM},
908
nullptr,
909
nullptr,
910
nullptr,
911
},
912
{"d22",
913
nullptr,
914
8,
915
0,
916
eEncodingIEEE754,
917
eFormatFloat,
918
{LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
919
LLDB_INVALID_REGNUM},
920
nullptr,
921
nullptr,
922
nullptr,
923
},
924
{"d23",
925
nullptr,
926
8,
927
0,
928
eEncodingIEEE754,
929
eFormatFloat,
930
{LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
931
LLDB_INVALID_REGNUM},
932
nullptr,
933
nullptr,
934
nullptr,
935
},
936
{"d24",
937
nullptr,
938
8,
939
0,
940
eEncodingIEEE754,
941
eFormatFloat,
942
{LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
943
LLDB_INVALID_REGNUM},
944
nullptr,
945
nullptr,
946
nullptr,
947
},
948
{"d25",
949
nullptr,
950
8,
951
0,
952
eEncodingIEEE754,
953
eFormatFloat,
954
{LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
955
LLDB_INVALID_REGNUM},
956
nullptr,
957
nullptr,
958
nullptr,
959
},
960
{"d26",
961
nullptr,
962
8,
963
0,
964
eEncodingIEEE754,
965
eFormatFloat,
966
{LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
967
LLDB_INVALID_REGNUM},
968
nullptr,
969
nullptr,
970
nullptr,
971
},
972
{"d27",
973
nullptr,
974
8,
975
0,
976
eEncodingIEEE754,
977
eFormatFloat,
978
{LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
979
LLDB_INVALID_REGNUM},
980
nullptr,
981
nullptr,
982
nullptr,
983
},
984
{"d28",
985
nullptr,
986
8,
987
0,
988
eEncodingIEEE754,
989
eFormatFloat,
990
{LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
991
LLDB_INVALID_REGNUM},
992
nullptr,
993
nullptr,
994
nullptr,
995
},
996
{"d29",
997
nullptr,
998
8,
999
0,
1000
eEncodingIEEE754,
1001
eFormatFloat,
1002
{LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1003
LLDB_INVALID_REGNUM},
1004
nullptr,
1005
nullptr,
1006
nullptr,
1007
},
1008
{"d30",
1009
nullptr,
1010
8,
1011
0,
1012
eEncodingIEEE754,
1013
eFormatFloat,
1014
{LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1015
LLDB_INVALID_REGNUM},
1016
nullptr,
1017
nullptr,
1018
nullptr,
1019
},
1020
{"d31",
1021
nullptr,
1022
8,
1023
0,
1024
eEncodingIEEE754,
1025
eFormatFloat,
1026
{LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1027
LLDB_INVALID_REGNUM},
1028
nullptr,
1029
nullptr,
1030
nullptr,
1031
},
1032
{"r8_usr",
1033
nullptr,
1034
4,
1035
0,
1036
eEncodingUint,
1037
eFormatHex,
1038
{LLDB_INVALID_REGNUM, dwarf_r8_usr, LLDB_INVALID_REGNUM,
1039
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1040
nullptr,
1041
nullptr,
1042
nullptr,
1043
},
1044
{"r9_usr",
1045
nullptr,
1046
4,
1047
0,
1048
eEncodingUint,
1049
eFormatHex,
1050
{LLDB_INVALID_REGNUM, dwarf_r9_usr, LLDB_INVALID_REGNUM,
1051
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1052
nullptr,
1053
nullptr,
1054
nullptr,
1055
},
1056
{"r10_usr",
1057
nullptr,
1058
4,
1059
0,
1060
eEncodingUint,
1061
eFormatHex,
1062
{LLDB_INVALID_REGNUM, dwarf_r10_usr, LLDB_INVALID_REGNUM,
1063
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1064
nullptr,
1065
nullptr,
1066
nullptr,
1067
},
1068
{"r11_usr",
1069
nullptr,
1070
4,
1071
0,
1072
eEncodingUint,
1073
eFormatHex,
1074
{LLDB_INVALID_REGNUM, dwarf_r11_usr, LLDB_INVALID_REGNUM,
1075
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1076
nullptr,
1077
nullptr,
1078
nullptr,
1079
},
1080
{"r12_usr",
1081
nullptr,
1082
4,
1083
0,
1084
eEncodingUint,
1085
eFormatHex,
1086
{LLDB_INVALID_REGNUM, dwarf_r12_usr, LLDB_INVALID_REGNUM,
1087
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1088
nullptr,
1089
nullptr,
1090
nullptr,
1091
},
1092
{"r13_usr",
1093
"sp_usr",
1094
4,
1095
0,
1096
eEncodingUint,
1097
eFormatHex,
1098
{LLDB_INVALID_REGNUM, dwarf_r13_usr, LLDB_INVALID_REGNUM,
1099
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1100
nullptr,
1101
nullptr,
1102
nullptr,
1103
},
1104
{"r14_usr",
1105
"lr_usr",
1106
4,
1107
0,
1108
eEncodingUint,
1109
eFormatHex,
1110
{LLDB_INVALID_REGNUM, dwarf_r14_usr, LLDB_INVALID_REGNUM,
1111
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1112
nullptr,
1113
nullptr,
1114
nullptr,
1115
},
1116
{"r8_fiq",
1117
nullptr,
1118
4,
1119
0,
1120
eEncodingUint,
1121
eFormatHex,
1122
{LLDB_INVALID_REGNUM, dwarf_r8_fiq, LLDB_INVALID_REGNUM,
1123
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1124
nullptr,
1125
nullptr,
1126
nullptr,
1127
},
1128
{"r9_fiq",
1129
nullptr,
1130
4,
1131
0,
1132
eEncodingUint,
1133
eFormatHex,
1134
{LLDB_INVALID_REGNUM, dwarf_r9_fiq, LLDB_INVALID_REGNUM,
1135
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1136
nullptr,
1137
nullptr,
1138
nullptr,
1139
},
1140
{"r10_fiq",
1141
nullptr,
1142
4,
1143
0,
1144
eEncodingUint,
1145
eFormatHex,
1146
{LLDB_INVALID_REGNUM, dwarf_r10_fiq, LLDB_INVALID_REGNUM,
1147
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1148
nullptr,
1149
nullptr,
1150
nullptr,
1151
},
1152
{"r11_fiq",
1153
nullptr,
1154
4,
1155
0,
1156
eEncodingUint,
1157
eFormatHex,
1158
{LLDB_INVALID_REGNUM, dwarf_r11_fiq, LLDB_INVALID_REGNUM,
1159
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1160
nullptr,
1161
nullptr,
1162
nullptr,
1163
},
1164
{"r12_fiq",
1165
nullptr,
1166
4,
1167
0,
1168
eEncodingUint,
1169
eFormatHex,
1170
{LLDB_INVALID_REGNUM, dwarf_r12_fiq, LLDB_INVALID_REGNUM,
1171
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1172
nullptr,
1173
nullptr,
1174
nullptr,
1175
},
1176
{"r13_fiq",
1177
"sp_fiq",
1178
4,
1179
0,
1180
eEncodingUint,
1181
eFormatHex,
1182
{LLDB_INVALID_REGNUM, dwarf_r13_fiq, LLDB_INVALID_REGNUM,
1183
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1184
nullptr,
1185
nullptr,
1186
nullptr,
1187
},
1188
{"r14_fiq",
1189
"lr_fiq",
1190
4,
1191
0,
1192
eEncodingUint,
1193
eFormatHex,
1194
{LLDB_INVALID_REGNUM, dwarf_r14_fiq, LLDB_INVALID_REGNUM,
1195
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1196
nullptr,
1197
nullptr,
1198
nullptr,
1199
},
1200
{"r13_irq",
1201
"sp_irq",
1202
4,
1203
0,
1204
eEncodingUint,
1205
eFormatHex,
1206
{LLDB_INVALID_REGNUM, dwarf_r13_irq, LLDB_INVALID_REGNUM,
1207
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1208
nullptr,
1209
nullptr,
1210
nullptr,
1211
},
1212
{"r14_irq",
1213
"lr_irq",
1214
4,
1215
0,
1216
eEncodingUint,
1217
eFormatHex,
1218
{LLDB_INVALID_REGNUM, dwarf_r14_irq, LLDB_INVALID_REGNUM,
1219
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1220
nullptr,
1221
nullptr,
1222
nullptr,
1223
},
1224
{"r13_abt",
1225
"sp_abt",
1226
4,
1227
0,
1228
eEncodingUint,
1229
eFormatHex,
1230
{LLDB_INVALID_REGNUM, dwarf_r13_abt, LLDB_INVALID_REGNUM,
1231
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1232
nullptr,
1233
nullptr,
1234
nullptr,
1235
},
1236
{"r14_abt",
1237
"lr_abt",
1238
4,
1239
0,
1240
eEncodingUint,
1241
eFormatHex,
1242
{LLDB_INVALID_REGNUM, dwarf_r14_abt, LLDB_INVALID_REGNUM,
1243
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1244
nullptr,
1245
nullptr,
1246
nullptr,
1247
},
1248
{"r13_und",
1249
"sp_und",
1250
4,
1251
0,
1252
eEncodingUint,
1253
eFormatHex,
1254
{LLDB_INVALID_REGNUM, dwarf_r13_und, LLDB_INVALID_REGNUM,
1255
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1256
nullptr,
1257
nullptr,
1258
nullptr,
1259
},
1260
{"r14_und",
1261
"lr_und",
1262
4,
1263
0,
1264
eEncodingUint,
1265
eFormatHex,
1266
{LLDB_INVALID_REGNUM, dwarf_r14_und, LLDB_INVALID_REGNUM,
1267
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1268
nullptr,
1269
nullptr,
1270
nullptr,
1271
1272
},
1273
{"r13_svc",
1274
"sp_svc",
1275
4,
1276
0,
1277
eEncodingUint,
1278
eFormatHex,
1279
{LLDB_INVALID_REGNUM, dwarf_r13_svc, LLDB_INVALID_REGNUM,
1280
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1281
nullptr,
1282
nullptr,
1283
nullptr,
1284
},
1285
{"r14_svc",
1286
"lr_svc",
1287
4,
1288
0,
1289
eEncodingUint,
1290
eFormatHex,
1291
{LLDB_INVALID_REGNUM, dwarf_r14_svc, LLDB_INVALID_REGNUM,
1292
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1293
nullptr,
1294
nullptr,
1295
nullptr,
1296
}};
1297
1298
static const uint32_t k_num_register_infos = std::size(g_register_infos);
1299
1300
const lldb_private::RegisterInfo *
1301
ABISysV_arm::GetRegisterInfoArray(uint32_t &count) {
1302
count = k_num_register_infos;
1303
return g_register_infos;
1304
}
1305
1306
size_t ABISysV_arm::GetRedZoneSize() const { return 0; }
1307
1308
// Static Functions
1309
1310
ABISP
1311
ABISysV_arm::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
1312
const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
1313
const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor();
1314
1315
if (vendor_type != llvm::Triple::Apple) {
1316
if ((arch_type == llvm::Triple::arm) ||
1317
(arch_type == llvm::Triple::thumb)) {
1318
return ABISP(
1319
new ABISysV_arm(std::move(process_sp), MakeMCRegisterInfo(arch)));
1320
}
1321
}
1322
1323
return ABISP();
1324
}
1325
1326
bool ABISysV_arm::PrepareTrivialCall(Thread &thread, addr_t sp,
1327
addr_t function_addr, addr_t return_addr,
1328
llvm::ArrayRef<addr_t> args) const {
1329
RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1330
if (!reg_ctx)
1331
return false;
1332
1333
const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1334
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
1335
const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1336
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
1337
const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1338
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
1339
1340
RegisterValue reg_value;
1341
1342
const uint8_t reg_names[] = {
1343
LLDB_REGNUM_GENERIC_ARG1, LLDB_REGNUM_GENERIC_ARG2,
1344
LLDB_REGNUM_GENERIC_ARG3, LLDB_REGNUM_GENERIC_ARG4};
1345
1346
llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end();
1347
1348
for (size_t i = 0; i < std::size(reg_names); ++i) {
1349
if (ai == ae)
1350
break;
1351
1352
reg_value.SetUInt32(*ai);
1353
if (!reg_ctx->WriteRegister(
1354
reg_ctx->GetRegisterInfo(eRegisterKindGeneric, reg_names[i]),
1355
reg_value))
1356
return false;
1357
1358
++ai;
1359
}
1360
1361
if (ai != ae) {
1362
// Spill onto the stack
1363
size_t num_stack_regs = ae - ai;
1364
1365
sp -= (num_stack_regs * 4);
1366
// Keep the stack 8 byte aligned, not that we need to
1367
sp &= ~(8ull - 1ull);
1368
1369
// just using arg1 to get the right size
1370
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
1371
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
1372
1373
addr_t arg_pos = sp;
1374
1375
for (; ai != ae; ++ai) {
1376
reg_value.SetUInt32(*ai);
1377
if (reg_ctx
1378
->WriteRegisterValueToMemory(reg_info, arg_pos,
1379
reg_info->byte_size, reg_value)
1380
.Fail())
1381
return false;
1382
arg_pos += reg_info->byte_size;
1383
}
1384
}
1385
1386
TargetSP target_sp(thread.CalculateTarget());
1387
Address so_addr;
1388
1389
// Figure out if our return address is ARM or Thumb by using the
1390
// Address::GetCallableLoadAddress(Target*) which will figure out the ARM
1391
// thumb-ness and set the correct address bits for us.
1392
so_addr.SetLoadAddress(return_addr, target_sp.get());
1393
return_addr = so_addr.GetCallableLoadAddress(target_sp.get());
1394
1395
// Set "lr" to the return address
1396
if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_num, return_addr))
1397
return false;
1398
1399
// Set "sp" to the requested value
1400
if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_num, sp))
1401
return false;
1402
1403
// If bit zero or 1 is set, this must be a thumb function, no need to figure
1404
// this out from the symbols.
1405
so_addr.SetLoadAddress(function_addr, target_sp.get());
1406
function_addr = so_addr.GetCallableLoadAddress(target_sp.get());
1407
1408
const RegisterInfo *cpsr_reg_info =
1409
reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
1410
const uint32_t curr_cpsr = reg_ctx->ReadRegisterAsUnsigned(cpsr_reg_info, 0);
1411
1412
// Make a new CPSR and mask out any Thumb IT (if/then) bits
1413
uint32_t new_cpsr = curr_cpsr & ~MASK_CPSR_IT_MASK;
1414
// If bit zero or 1 is set, this must be thumb...
1415
if (function_addr & 1ull)
1416
new_cpsr |= MASK_CPSR_T; // Set T bit in CPSR
1417
else
1418
new_cpsr &= ~MASK_CPSR_T; // Clear T bit in CPSR
1419
1420
if (new_cpsr != curr_cpsr) {
1421
if (!reg_ctx->WriteRegisterFromUnsigned(cpsr_reg_info, new_cpsr))
1422
return false;
1423
}
1424
1425
function_addr &=
1426
~1ull; // clear bit zero since the CPSR will take care of the mode for us
1427
1428
// Set "pc" to the address requested
1429
return reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, function_addr);
1430
}
1431
1432
bool ABISysV_arm::GetArgumentValues(Thread &thread, ValueList &values) const {
1433
uint32_t num_values = values.GetSize();
1434
1435
ExecutionContext exe_ctx(thread.shared_from_this());
1436
// For now, assume that the types in the AST values come from the Target's
1437
// scratch AST.
1438
1439
// Extract the register context so we can read arguments from registers
1440
1441
RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1442
1443
if (!reg_ctx)
1444
return false;
1445
1446
addr_t sp = 0;
1447
1448
for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) {
1449
// We currently only support extracting values with Clang QualTypes. Do we
1450
// care about others?
1451
Value *value = values.GetValueAtIndex(value_idx);
1452
1453
if (!value)
1454
return false;
1455
1456
CompilerType compiler_type = value->GetCompilerType();
1457
if (compiler_type) {
1458
bool is_signed = false;
1459
size_t bit_width = 0;
1460
if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1461
compiler_type.IsPointerOrReferenceType()) {
1462
if (std::optional<uint64_t> size = compiler_type.GetBitSize(&thread))
1463
bit_width = *size;
1464
} else {
1465
// We only handle integer, pointer and reference types currently...
1466
return false;
1467
}
1468
1469
if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) {
1470
if (value_idx < 4) {
1471
// Arguments 1-4 are in r0-r3...
1472
const RegisterInfo *arg_reg_info = nullptr;
1473
arg_reg_info = reg_ctx->GetRegisterInfo(
1474
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
1475
if (arg_reg_info) {
1476
RegisterValue reg_value;
1477
1478
if (reg_ctx->ReadRegister(arg_reg_info, reg_value)) {
1479
if (is_signed)
1480
reg_value.SignExtend(bit_width);
1481
if (!reg_value.GetScalarValue(value->GetScalar()))
1482
return false;
1483
continue;
1484
}
1485
}
1486
return false;
1487
} else {
1488
if (sp == 0) {
1489
// Read the stack pointer if it already hasn't been read
1490
sp = reg_ctx->GetSP(0);
1491
if (sp == 0)
1492
return false;
1493
}
1494
1495
// Arguments 5 on up are on the stack
1496
const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8;
1497
Status error;
1498
if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory(
1499
sp, arg_byte_size, is_signed, value->GetScalar(), error))
1500
return false;
1501
1502
sp += arg_byte_size;
1503
}
1504
}
1505
}
1506
}
1507
return true;
1508
}
1509
1510
static bool GetReturnValuePassedInMemory(Thread &thread,
1511
RegisterContext *reg_ctx,
1512
size_t byte_size, Value &value) {
1513
Status error;
1514
DataBufferHeap buffer(byte_size, 0);
1515
1516
const RegisterInfo *r0_reg_info =
1517
reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
1518
uint32_t address =
1519
reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1520
thread.GetProcess()->ReadMemory(address, buffer.GetBytes(),
1521
buffer.GetByteSize(), error);
1522
1523
if (error.Fail())
1524
return false;
1525
1526
value.SetBytes(buffer.GetBytes(), buffer.GetByteSize());
1527
return true;
1528
}
1529
1530
bool ABISysV_arm::IsArmHardFloat(Thread &thread) const {
1531
ProcessSP process_sp(thread.GetProcess());
1532
if (process_sp) {
1533
const ArchSpec &arch(process_sp->GetTarget().GetArchitecture());
1534
1535
return (arch.GetFlags() & ArchSpec::eARM_abi_hard_float) != 0;
1536
}
1537
1538
return false;
1539
}
1540
1541
ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl(
1542
Thread &thread, lldb_private::CompilerType &compiler_type) const {
1543
Value value;
1544
ValueObjectSP return_valobj_sp;
1545
1546
if (!compiler_type)
1547
return return_valobj_sp;
1548
1549
// value.SetContext (Value::eContextTypeClangType,
1550
// compiler_type.GetOpaqueQualType());
1551
value.SetCompilerType(compiler_type);
1552
1553
RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1554
if (!reg_ctx)
1555
return return_valobj_sp;
1556
1557
bool is_signed;
1558
bool is_complex;
1559
uint32_t float_count;
1560
bool is_vfp_candidate = false;
1561
uint8_t vfp_count = 0;
1562
uint8_t vfp_byte_size = 0;
1563
1564
// Get the pointer to the first stack argument so we have a place to start
1565
// when reading data
1566
1567
const RegisterInfo *r0_reg_info =
1568
reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
1569
std::optional<uint64_t> bit_width = compiler_type.GetBitSize(&thread);
1570
std::optional<uint64_t> byte_size = compiler_type.GetByteSize(&thread);
1571
if (!bit_width || !byte_size)
1572
return return_valobj_sp;
1573
1574
if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
1575
switch (*bit_width) {
1576
default:
1577
return return_valobj_sp;
1578
case 64: {
1579
const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo(
1580
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
1581
uint64_t raw_value;
1582
raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1583
raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) &
1584
UINT32_MAX))
1585
<< 32;
1586
if (is_signed)
1587
value.GetScalar() = (int64_t)raw_value;
1588
else
1589
value.GetScalar() = (uint64_t)raw_value;
1590
} break;
1591
case 32:
1592
if (is_signed)
1593
value.GetScalar() = (int32_t)(
1594
reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
1595
else
1596
value.GetScalar() = (uint32_t)(
1597
reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
1598
break;
1599
case 16:
1600
if (is_signed)
1601
value.GetScalar() = (int16_t)(
1602
reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
1603
else
1604
value.GetScalar() = (uint16_t)(
1605
reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
1606
break;
1607
case 8:
1608
if (is_signed)
1609
value.GetScalar() = (int8_t)(
1610
reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
1611
else
1612
value.GetScalar() = (uint8_t)(
1613
reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
1614
break;
1615
}
1616
} else if (compiler_type.IsPointerType()) {
1617
uint32_t ptr =
1618
thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) &
1619
UINT32_MAX;
1620
value.GetScalar() = ptr;
1621
} else if (compiler_type.IsVectorType()) {
1622
if (IsArmHardFloat(thread) && (*byte_size == 8 || *byte_size == 16)) {
1623
is_vfp_candidate = true;
1624
vfp_byte_size = 8;
1625
vfp_count = (*byte_size == 8 ? 1 : 2);
1626
} else if (*byte_size <= 16) {
1627
DataBufferHeap buffer(16, 0);
1628
uint32_t *buffer_ptr = (uint32_t *)buffer.GetBytes();
1629
1630
for (uint32_t i = 0; 4 * i < *byte_size; ++i) {
1631
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
1632
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
1633
buffer_ptr[i] =
1634
reg_ctx->ReadRegisterAsUnsigned(reg_info, 0) & UINT32_MAX;
1635
}
1636
value.SetBytes(buffer.GetBytes(), *byte_size);
1637
} else {
1638
if (!GetReturnValuePassedInMemory(thread, reg_ctx, *byte_size, value))
1639
return return_valobj_sp;
1640
}
1641
} else if (compiler_type.IsFloatingPointType(float_count, is_complex)) {
1642
if (float_count == 1 && !is_complex) {
1643
switch (*bit_width) {
1644
default:
1645
return return_valobj_sp;
1646
case 64: {
1647
static_assert(sizeof(double) == sizeof(uint64_t));
1648
1649
if (IsArmHardFloat(thread)) {
1650
RegisterValue reg_value;
1651
const RegisterInfo *d0_reg_info =
1652
reg_ctx->GetRegisterInfoByName("d0", 0);
1653
reg_ctx->ReadRegister(d0_reg_info, reg_value);
1654
value.GetScalar() = reg_value.GetAsDouble();
1655
} else {
1656
uint64_t raw_value;
1657
const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo(
1658
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
1659
raw_value =
1660
reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1661
raw_value |=
1662
((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) &
1663
UINT32_MAX))
1664
<< 32;
1665
value.GetScalar() = *reinterpret_cast<double *>(&raw_value);
1666
}
1667
break;
1668
}
1669
case 16: // Half precision returned after a conversion to single precision
1670
case 32: {
1671
static_assert(sizeof(float) == sizeof(uint32_t));
1672
1673
if (IsArmHardFloat(thread)) {
1674
RegisterValue reg_value;
1675
const RegisterInfo *s0_reg_info =
1676
reg_ctx->GetRegisterInfoByName("s0", 0);
1677
reg_ctx->ReadRegister(s0_reg_info, reg_value);
1678
value.GetScalar() = reg_value.GetAsFloat();
1679
} else {
1680
uint32_t raw_value;
1681
raw_value =
1682
reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1683
value.GetScalar() = *reinterpret_cast<float *>(&raw_value);
1684
}
1685
break;
1686
}
1687
}
1688
} else if (is_complex && float_count == 2) {
1689
if (IsArmHardFloat(thread)) {
1690
is_vfp_candidate = true;
1691
vfp_byte_size = *byte_size / 2;
1692
vfp_count = 2;
1693
} else if (!GetReturnValuePassedInMemory(thread, reg_ctx, *bit_width / 8,
1694
value))
1695
return return_valobj_sp;
1696
} else
1697
// not handled yet
1698
return return_valobj_sp;
1699
} else if (compiler_type.IsAggregateType()) {
1700
if (IsArmHardFloat(thread)) {
1701
CompilerType base_type;
1702
const uint32_t homogeneous_count =
1703
compiler_type.IsHomogeneousAggregate(&base_type);
1704
1705
if (homogeneous_count > 0 && homogeneous_count <= 4) {
1706
std::optional<uint64_t> base_byte_size = base_type.GetByteSize(&thread);
1707
if (base_type.IsVectorType()) {
1708
if (base_byte_size &&
1709
(*base_byte_size == 8 || *base_byte_size == 16)) {
1710
is_vfp_candidate = true;
1711
vfp_byte_size = 8;
1712
vfp_count = (*base_byte_size == 8 ? homogeneous_count
1713
: homogeneous_count * 2);
1714
}
1715
} else if (base_type.IsFloatingPointType(float_count, is_complex)) {
1716
if (float_count == 1 && !is_complex) {
1717
is_vfp_candidate = true;
1718
if (base_byte_size)
1719
vfp_byte_size = *base_byte_size;
1720
vfp_count = homogeneous_count;
1721
}
1722
}
1723
} else if (homogeneous_count == 0) {
1724
const uint32_t num_children = compiler_type.GetNumFields();
1725
1726
if (num_children > 0 && num_children <= 2) {
1727
uint32_t index = 0;
1728
for (index = 0; index < num_children; index++) {
1729
std::string name;
1730
base_type = compiler_type.GetFieldAtIndex(index, name, nullptr,
1731
nullptr, nullptr);
1732
1733
if (base_type.IsFloatingPointType(float_count, is_complex)) {
1734
std::optional<uint64_t> base_byte_size =
1735
base_type.GetByteSize(&thread);
1736
if (float_count == 2 && is_complex) {
1737
if (index != 0 && base_byte_size &&
1738
vfp_byte_size != *base_byte_size)
1739
break;
1740
else if (base_byte_size)
1741
vfp_byte_size = *base_byte_size;
1742
} else
1743
break;
1744
} else
1745
break;
1746
}
1747
1748
if (index == num_children) {
1749
is_vfp_candidate = true;
1750
vfp_byte_size = (vfp_byte_size >> 1);
1751
vfp_count = (num_children << 1);
1752
}
1753
}
1754
}
1755
}
1756
1757
if (*byte_size <= 4) {
1758
RegisterValue r0_reg_value;
1759
uint32_t raw_value =
1760
reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1761
value.SetBytes(&raw_value, *byte_size);
1762
} else if (!is_vfp_candidate) {
1763
if (!GetReturnValuePassedInMemory(thread, reg_ctx, *byte_size, value))
1764
return return_valobj_sp;
1765
}
1766
} else {
1767
// not handled yet
1768
return return_valobj_sp;
1769
}
1770
1771
if (is_vfp_candidate) {
1772
ProcessSP process_sp(thread.GetProcess());
1773
ByteOrder byte_order = process_sp->GetByteOrder();
1774
1775
WritableDataBufferSP data_sp(new DataBufferHeap(*byte_size, 0));
1776
uint32_t data_offset = 0;
1777
1778
for (uint32_t reg_index = 0; reg_index < vfp_count; reg_index++) {
1779
uint32_t regnum = 0;
1780
1781
if (vfp_byte_size == 4)
1782
regnum = dwarf_s0 + reg_index;
1783
else if (vfp_byte_size == 8)
1784
regnum = dwarf_d0 + reg_index;
1785
else
1786
break;
1787
1788
const RegisterInfo *reg_info =
1789
reg_ctx->GetRegisterInfo(eRegisterKindDWARF, regnum);
1790
if (reg_info == nullptr)
1791
break;
1792
1793
RegisterValue reg_value;
1794
if (!reg_ctx->ReadRegister(reg_info, reg_value))
1795
break;
1796
1797
// Make sure we have enough room in "data_sp"
1798
if ((data_offset + vfp_byte_size) <= data_sp->GetByteSize()) {
1799
Status error;
1800
const size_t bytes_copied = reg_value.GetAsMemoryData(
1801
*reg_info, data_sp->GetBytes() + data_offset, vfp_byte_size,
1802
byte_order, error);
1803
if (bytes_copied != vfp_byte_size)
1804
break;
1805
1806
data_offset += bytes_copied;
1807
}
1808
}
1809
1810
if (data_offset == *byte_size) {
1811
DataExtractor data;
1812
data.SetByteOrder(byte_order);
1813
data.SetAddressByteSize(process_sp->GetAddressByteSize());
1814
data.SetData(data_sp);
1815
1816
return ValueObjectConstResult::Create(&thread, compiler_type,
1817
ConstString(""), data);
1818
} else { // Some error occurred while getting values from registers
1819
return return_valobj_sp;
1820
}
1821
}
1822
1823
// If we get here, we have a valid Value, so make our ValueObject out of it:
1824
1825
return_valobj_sp = ValueObjectConstResult::Create(
1826
thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
1827
return return_valobj_sp;
1828
}
1829
1830
Status ABISysV_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
1831
lldb::ValueObjectSP &new_value_sp) {
1832
Status error;
1833
if (!new_value_sp) {
1834
error.SetErrorString("Empty value object for return value.");
1835
return error;
1836
}
1837
1838
CompilerType compiler_type = new_value_sp->GetCompilerType();
1839
if (!compiler_type) {
1840
error.SetErrorString("Null clang type for return value.");
1841
return error;
1842
}
1843
1844
Thread *thread = frame_sp->GetThread().get();
1845
1846
bool is_signed;
1847
uint32_t count;
1848
bool is_complex;
1849
1850
RegisterContext *reg_ctx = thread->GetRegisterContext().get();
1851
1852
bool set_it_simple = false;
1853
if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1854
compiler_type.IsPointerType()) {
1855
DataExtractor data;
1856
Status data_error;
1857
size_t num_bytes = new_value_sp->GetData(data, data_error);
1858
if (data_error.Fail()) {
1859
error.SetErrorStringWithFormat(
1860
"Couldn't convert return value to raw data: %s",
1861
data_error.AsCString());
1862
return error;
1863
}
1864
lldb::offset_t offset = 0;
1865
if (num_bytes <= 8) {
1866
const RegisterInfo *r0_info = reg_ctx->GetRegisterInfo(
1867
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
1868
if (num_bytes <= 4) {
1869
uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
1870
1871
if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value))
1872
set_it_simple = true;
1873
} else {
1874
uint32_t raw_value = data.GetMaxU32(&offset, 4);
1875
1876
if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value)) {
1877
const RegisterInfo *r1_info = reg_ctx->GetRegisterInfo(
1878
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
1879
uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
1880
1881
if (reg_ctx->WriteRegisterFromUnsigned(r1_info, raw_value))
1882
set_it_simple = true;
1883
}
1884
}
1885
} else {
1886
error.SetErrorString("We don't support returning longer than 64 bit "
1887
"integer values at present.");
1888
}
1889
} else if (compiler_type.IsFloatingPointType(count, is_complex)) {
1890
if (is_complex)
1891
error.SetErrorString(
1892
"We don't support returning complex values at present");
1893
else
1894
error.SetErrorString(
1895
"We don't support returning float values at present");
1896
}
1897
1898
if (!set_it_simple)
1899
error.SetErrorString(
1900
"We only support setting simple integer return types at present.");
1901
1902
return error;
1903
}
1904
1905
bool ABISysV_arm::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
1906
unwind_plan.Clear();
1907
unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1908
1909
uint32_t lr_reg_num = dwarf_lr;
1910
uint32_t sp_reg_num = dwarf_sp;
1911
uint32_t pc_reg_num = dwarf_pc;
1912
1913
UnwindPlan::RowSP row(new UnwindPlan::Row);
1914
1915
// Our Call Frame Address is the stack pointer value
1916
row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
1917
1918
// The previous PC is in the LR
1919
row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
1920
unwind_plan.AppendRow(row);
1921
1922
// All other registers are the same.
1923
1924
unwind_plan.SetSourceName("arm at-func-entry default");
1925
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1926
1927
return true;
1928
}
1929
1930
bool ABISysV_arm::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
1931
unwind_plan.Clear();
1932
unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1933
1934
// TODO: Handle thumb
1935
uint32_t fp_reg_num = dwarf_r11;
1936
uint32_t pc_reg_num = dwarf_pc;
1937
1938
UnwindPlan::RowSP row(new UnwindPlan::Row);
1939
const int32_t ptr_size = 4;
1940
1941
row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
1942
row->SetOffset(0);
1943
row->SetUnspecifiedRegistersAreUndefined(true);
1944
1945
row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
1946
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
1947
1948
unwind_plan.AppendRow(row);
1949
unwind_plan.SetSourceName("arm default unwind plan");
1950
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1951
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1952
unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
1953
1954
return true;
1955
}
1956
1957
// cf. "ARMv6 Function Calling Conventions"
1958
1959
// ARMv7 on GNU/Linux general purpose reg rules:
1960
// r0-r3 not preserved (used for argument passing)
1961
// r4-r11 preserved (v1-v8)
1962
// r12 not presrved
1963
// r13 preserved (stack pointer)
1964
// r14 preserved (link register)
1965
// r15 preserved (pc)
1966
// cpsr not preserved (different rules for different bits)
1967
1968
// ARMv7 VFP register rules:
1969
// d0-d7 not preserved (aka s0-s15, q0-q3)
1970
// d8-d15 preserved (aka s16-s31, q4-q7)
1971
// d16-d31 not preserved (aka q8-q15)
1972
1973
bool ABISysV_arm::RegisterIsVolatile(const RegisterInfo *reg_info) {
1974
if (reg_info) {
1975
// Volatile registers are: r0, r1, r2, r3, r9, r12, r13 (aka sp)
1976
const char *name = reg_info->name;
1977
if (name[0] == 'r') {
1978
switch (name[1]) {
1979
case '0':
1980
return name[2] == '\0'; // r0
1981
case '1':
1982
switch (name[2]) {
1983
case '\0':
1984
return true; // r1
1985
case '2':
1986
return name[3] == '\0'; // r12
1987
default:
1988
break;
1989
}
1990
break;
1991
1992
case '2':
1993
return name[2] == '\0'; // r2
1994
case '3':
1995
return name[2] == '\0'; // r3
1996
default:
1997
break;
1998
}
1999
} else if (name[0] == 'd') {
2000
switch (name[1]) {
2001
case '0':
2002
return name[2] == '\0'; // d0 is volatile
2003
2004
case '1':
2005
switch (name[2]) {
2006
case '\0':
2007
return true; // d1 is volatile
2008
case '6':
2009
case '7':
2010
case '8':
2011
case '9':
2012
return name[3] == '\0'; // d16 - d19 are volatile
2013
default:
2014
break;
2015
}
2016
break;
2017
2018
case '2':
2019
switch (name[2]) {
2020
case '\0':
2021
return true; // d2 is volatile
2022
case '0':
2023
case '1':
2024
case '2':
2025
case '3':
2026
case '4':
2027
case '5':
2028
case '6':
2029
case '7':
2030
case '8':
2031
case '9':
2032
return name[3] == '\0'; // d20 - d29 are volatile
2033
default:
2034
break;
2035
}
2036
break;
2037
2038
case '3':
2039
switch (name[2]) {
2040
case '\0':
2041
return true; // d3 is volatile
2042
case '0':
2043
case '1':
2044
return name[3] == '\0'; // d30 - d31 are volatile
2045
default:
2046
break;
2047
}
2048
break;
2049
case '4':
2050
case '5':
2051
case '6':
2052
case '7':
2053
return name[2] == '\0'; // d4 - d7 are volatile
2054
2055
default:
2056
break;
2057
}
2058
} else if (name[0] == 's') {
2059
switch (name[1]) {
2060
case '0':
2061
return name[2] == '\0'; // s0 is volatile
2062
2063
case '1':
2064
switch (name[2]) {
2065
case '\0':
2066
return true; // s1 is volatile
2067
case '0':
2068
case '1':
2069
case '2':
2070
case '3':
2071
case '4':
2072
case '5':
2073
return name[3] == '\0'; // s10 - s15 are volatile
2074
default:
2075
break;
2076
}
2077
break;
2078
2079
case '2':
2080
case '3':
2081
case '4':
2082
case '5':
2083
case '6':
2084
case '7':
2085
case '8':
2086
case '9':
2087
return name[2] == '\0'; // s2 - s9 are volatile
2088
2089
default:
2090
break;
2091
}
2092
} else if (name[0] == 'q') {
2093
switch (name[1]) {
2094
case '1':
2095
switch (name[2]) {
2096
case '\0':
2097
return true; // q1 is volatile
2098
case '0':
2099
case '1':
2100
case '2':
2101
case '3':
2102
case '4':
2103
case '5':
2104
return true; // q10-q15 are volatile
2105
default:
2106
return false;
2107
}
2108
break;
2109
2110
case '0':
2111
case '2':
2112
case '3':
2113
return name[2] == '\0'; // q0-q3 are volatile
2114
case '8':
2115
case '9':
2116
return name[2] == '\0'; // q8-q9 are volatile
2117
default:
2118
break;
2119
}
2120
} else if (name[0] == 's' && name[1] == 'p' && name[2] == '\0')
2121
return true;
2122
}
2123
return false;
2124
}
2125
2126
void ABISysV_arm::Initialize() {
2127
PluginManager::RegisterPlugin(GetPluginNameStatic(),
2128
"SysV ABI for arm targets", CreateInstance);
2129
}
2130
2131
void ABISysV_arm::Terminate() {
2132
PluginManager::UnregisterPlugin(CreateInstance);
2133
}
2134
2135