Coverage Report

Created: 2022-01-18 06:27

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