Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/libunwind/src/Registers.hpp
96309 views
1
//===----------------------------------------------------------------------===//
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
// Models register sets for supported processors.
9
//
10
//===----------------------------------------------------------------------===//
11
12
#ifndef __REGISTERS_HPP__
13
#define __REGISTERS_HPP__
14
15
#include <stdint.h>
16
#include <string.h>
17
18
#include "cet_unwind.h"
19
#include "config.h"
20
#include "libunwind.h"
21
22
namespace libunwind {
23
24
// For emulating 128-bit registers
25
struct v128 { uint32_t vec[4]; };
26
27
enum {
28
REGISTERS_X86,
29
REGISTERS_X86_64,
30
REGISTERS_PPC,
31
REGISTERS_PPC64,
32
REGISTERS_ARM64,
33
REGISTERS_ARM,
34
REGISTERS_OR1K,
35
REGISTERS_MIPS_O32,
36
REGISTERS_MIPS_NEWABI,
37
REGISTERS_SPARC,
38
REGISTERS_SPARC64,
39
REGISTERS_HEXAGON,
40
REGISTERS_RISCV,
41
REGISTERS_VE,
42
REGISTERS_S390X,
43
REGISTERS_LOONGARCH,
44
};
45
46
#if defined(_LIBUNWIND_TARGET_I386)
47
class _LIBUNWIND_HIDDEN Registers_x86;
48
extern "C" void __libunwind_Registers_x86_jumpto(Registers_x86 *);
49
50
#if defined(_LIBUNWIND_USE_CET)
51
extern "C" void *__libunwind_cet_get_jump_target() {
52
return reinterpret_cast<void *>(&__libunwind_Registers_x86_jumpto);
53
}
54
#endif
55
56
/// Registers_x86 holds the register state of a thread in a 32-bit intel
57
/// process.
58
class _LIBUNWIND_HIDDEN Registers_x86 {
59
public:
60
Registers_x86();
61
Registers_x86(const void *registers);
62
63
bool validRegister(int num) const;
64
uint32_t getRegister(int num) const;
65
void setRegister(int num, uint32_t value);
66
bool validFloatRegister(int) const { return false; }
67
double getFloatRegister(int num) const;
68
void setFloatRegister(int num, double value);
69
bool validVectorRegister(int) const { return false; }
70
v128 getVectorRegister(int num) const;
71
void setVectorRegister(int num, v128 value);
72
static const char *getRegisterName(int num);
73
void jumpto() { __libunwind_Registers_x86_jumpto(this); }
74
static constexpr int lastDwarfRegNum() {
75
return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86;
76
}
77
static int getArch() { return REGISTERS_X86; }
78
79
uint32_t getSP() const { return _registers.__esp; }
80
void setSP(uint32_t value) { _registers.__esp = value; }
81
uint32_t getIP() const { return _registers.__eip; }
82
void setIP(uint32_t value) { _registers.__eip = value; }
83
uint32_t getEBP() const { return _registers.__ebp; }
84
void setEBP(uint32_t value) { _registers.__ebp = value; }
85
uint32_t getEBX() const { return _registers.__ebx; }
86
void setEBX(uint32_t value) { _registers.__ebx = value; }
87
uint32_t getECX() const { return _registers.__ecx; }
88
void setECX(uint32_t value) { _registers.__ecx = value; }
89
uint32_t getEDX() const { return _registers.__edx; }
90
void setEDX(uint32_t value) { _registers.__edx = value; }
91
uint32_t getESI() const { return _registers.__esi; }
92
void setESI(uint32_t value) { _registers.__esi = value; }
93
uint32_t getEDI() const { return _registers.__edi; }
94
void setEDI(uint32_t value) { _registers.__edi = value; }
95
96
private:
97
struct GPRs {
98
unsigned int __eax;
99
unsigned int __ebx;
100
unsigned int __ecx;
101
unsigned int __edx;
102
unsigned int __edi;
103
unsigned int __esi;
104
unsigned int __ebp;
105
unsigned int __esp;
106
unsigned int __ss;
107
unsigned int __eflags;
108
unsigned int __eip;
109
unsigned int __cs;
110
unsigned int __ds;
111
unsigned int __es;
112
unsigned int __fs;
113
unsigned int __gs;
114
};
115
116
GPRs _registers;
117
};
118
119
inline Registers_x86::Registers_x86(const void *registers) {
120
static_assert((check_fit<Registers_x86, unw_context_t>::does_fit),
121
"x86 registers do not fit into unw_context_t");
122
memcpy(&_registers, registers, sizeof(_registers));
123
}
124
125
inline Registers_x86::Registers_x86() {
126
memset(&_registers, 0, sizeof(_registers));
127
}
128
129
inline bool Registers_x86::validRegister(int regNum) const {
130
if (regNum == UNW_REG_IP)
131
return true;
132
if (regNum == UNW_REG_SP)
133
return true;
134
if (regNum < 0)
135
return false;
136
if (regNum > 7)
137
return false;
138
return true;
139
}
140
141
inline uint32_t Registers_x86::getRegister(int regNum) const {
142
switch (regNum) {
143
case UNW_REG_IP:
144
return _registers.__eip;
145
case UNW_REG_SP:
146
return _registers.__esp;
147
case UNW_X86_EAX:
148
return _registers.__eax;
149
case UNW_X86_ECX:
150
return _registers.__ecx;
151
case UNW_X86_EDX:
152
return _registers.__edx;
153
case UNW_X86_EBX:
154
return _registers.__ebx;
155
#if !defined(__APPLE__)
156
case UNW_X86_ESP:
157
#else
158
case UNW_X86_EBP:
159
#endif
160
return _registers.__ebp;
161
#if !defined(__APPLE__)
162
case UNW_X86_EBP:
163
#else
164
case UNW_X86_ESP:
165
#endif
166
return _registers.__esp;
167
case UNW_X86_ESI:
168
return _registers.__esi;
169
case UNW_X86_EDI:
170
return _registers.__edi;
171
}
172
_LIBUNWIND_ABORT("unsupported x86 register");
173
}
174
175
inline void Registers_x86::setRegister(int regNum, uint32_t value) {
176
switch (regNum) {
177
case UNW_REG_IP:
178
_registers.__eip = value;
179
return;
180
case UNW_REG_SP:
181
_registers.__esp = value;
182
return;
183
case UNW_X86_EAX:
184
_registers.__eax = value;
185
return;
186
case UNW_X86_ECX:
187
_registers.__ecx = value;
188
return;
189
case UNW_X86_EDX:
190
_registers.__edx = value;
191
return;
192
case UNW_X86_EBX:
193
_registers.__ebx = value;
194
return;
195
#if !defined(__APPLE__)
196
case UNW_X86_ESP:
197
#else
198
case UNW_X86_EBP:
199
#endif
200
_registers.__ebp = value;
201
return;
202
#if !defined(__APPLE__)
203
case UNW_X86_EBP:
204
#else
205
case UNW_X86_ESP:
206
#endif
207
_registers.__esp = value;
208
return;
209
case UNW_X86_ESI:
210
_registers.__esi = value;
211
return;
212
case UNW_X86_EDI:
213
_registers.__edi = value;
214
return;
215
}
216
_LIBUNWIND_ABORT("unsupported x86 register");
217
}
218
219
inline const char *Registers_x86::getRegisterName(int regNum) {
220
switch (regNum) {
221
case UNW_REG_IP:
222
return "ip";
223
case UNW_REG_SP:
224
return "esp";
225
case UNW_X86_EAX:
226
return "eax";
227
case UNW_X86_ECX:
228
return "ecx";
229
case UNW_X86_EDX:
230
return "edx";
231
case UNW_X86_EBX:
232
return "ebx";
233
case UNW_X86_EBP:
234
return "ebp";
235
case UNW_X86_ESP:
236
return "esp";
237
case UNW_X86_ESI:
238
return "esi";
239
case UNW_X86_EDI:
240
return "edi";
241
default:
242
return "unknown register";
243
}
244
}
245
246
inline double Registers_x86::getFloatRegister(int) const {
247
_LIBUNWIND_ABORT("no x86 float registers");
248
}
249
250
inline void Registers_x86::setFloatRegister(int, double) {
251
_LIBUNWIND_ABORT("no x86 float registers");
252
}
253
254
inline v128 Registers_x86::getVectorRegister(int) const {
255
_LIBUNWIND_ABORT("no x86 vector registers");
256
}
257
258
inline void Registers_x86::setVectorRegister(int, v128) {
259
_LIBUNWIND_ABORT("no x86 vector registers");
260
}
261
#endif // _LIBUNWIND_TARGET_I386
262
263
264
#if defined(_LIBUNWIND_TARGET_X86_64)
265
/// Registers_x86_64 holds the register state of a thread in a 64-bit intel
266
/// process.
267
class _LIBUNWIND_HIDDEN Registers_x86_64;
268
extern "C" void __libunwind_Registers_x86_64_jumpto(Registers_x86_64 *);
269
270
#if defined(_LIBUNWIND_USE_CET)
271
extern "C" void *__libunwind_cet_get_jump_target() {
272
return reinterpret_cast<void *>(&__libunwind_Registers_x86_64_jumpto);
273
}
274
#endif
275
276
class _LIBUNWIND_HIDDEN Registers_x86_64 {
277
public:
278
Registers_x86_64();
279
Registers_x86_64(const void *registers);
280
281
bool validRegister(int num) const;
282
uint64_t getRegister(int num) const;
283
void setRegister(int num, uint64_t value);
284
bool validFloatRegister(int) const { return false; }
285
double getFloatRegister(int num) const;
286
void setFloatRegister(int num, double value);
287
bool validVectorRegister(int) const;
288
v128 getVectorRegister(int num) const;
289
void setVectorRegister(int num, v128 value);
290
static const char *getRegisterName(int num);
291
void jumpto() { __libunwind_Registers_x86_64_jumpto(this); }
292
static constexpr int lastDwarfRegNum() {
293
return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64;
294
}
295
static int getArch() { return REGISTERS_X86_64; }
296
297
uint64_t getSP() const { return _registers.__rsp; }
298
void setSP(uint64_t value) { _registers.__rsp = value; }
299
uint64_t getIP() const { return _registers.__rip; }
300
void setIP(uint64_t value) { _registers.__rip = value; }
301
uint64_t getRBP() const { return _registers.__rbp; }
302
void setRBP(uint64_t value) { _registers.__rbp = value; }
303
uint64_t getRBX() const { return _registers.__rbx; }
304
void setRBX(uint64_t value) { _registers.__rbx = value; }
305
uint64_t getR12() const { return _registers.__r12; }
306
void setR12(uint64_t value) { _registers.__r12 = value; }
307
uint64_t getR13() const { return _registers.__r13; }
308
void setR13(uint64_t value) { _registers.__r13 = value; }
309
uint64_t getR14() const { return _registers.__r14; }
310
void setR14(uint64_t value) { _registers.__r14 = value; }
311
uint64_t getR15() const { return _registers.__r15; }
312
void setR15(uint64_t value) { _registers.__r15 = value; }
313
314
private:
315
struct GPRs {
316
uint64_t __rax;
317
uint64_t __rbx;
318
uint64_t __rcx;
319
uint64_t __rdx;
320
uint64_t __rdi;
321
uint64_t __rsi;
322
uint64_t __rbp;
323
uint64_t __rsp;
324
uint64_t __r8;
325
uint64_t __r9;
326
uint64_t __r10;
327
uint64_t __r11;
328
uint64_t __r12;
329
uint64_t __r13;
330
uint64_t __r14;
331
uint64_t __r15;
332
uint64_t __rip;
333
uint64_t __rflags;
334
uint64_t __cs;
335
uint64_t __fs;
336
uint64_t __gs;
337
#if defined(_WIN64)
338
uint64_t __padding; // 16-byte align
339
#endif
340
};
341
GPRs _registers;
342
#if defined(_WIN64)
343
v128 _xmm[16];
344
#endif
345
};
346
347
inline Registers_x86_64::Registers_x86_64(const void *registers) {
348
static_assert((check_fit<Registers_x86_64, unw_context_t>::does_fit),
349
"x86_64 registers do not fit into unw_context_t");
350
memcpy(&_registers, registers, sizeof(_registers));
351
}
352
353
inline Registers_x86_64::Registers_x86_64() {
354
memset(&_registers, 0, sizeof(_registers));
355
}
356
357
inline bool Registers_x86_64::validRegister(int regNum) const {
358
if (regNum == UNW_REG_IP)
359
return true;
360
if (regNum == UNW_REG_SP)
361
return true;
362
if (regNum < 0)
363
return false;
364
if (regNum > 16)
365
return false;
366
return true;
367
}
368
369
inline uint64_t Registers_x86_64::getRegister(int regNum) const {
370
switch (regNum) {
371
case UNW_REG_IP:
372
case UNW_X86_64_RIP:
373
return _registers.__rip;
374
case UNW_REG_SP:
375
return _registers.__rsp;
376
case UNW_X86_64_RAX:
377
return _registers.__rax;
378
case UNW_X86_64_RDX:
379
return _registers.__rdx;
380
case UNW_X86_64_RCX:
381
return _registers.__rcx;
382
case UNW_X86_64_RBX:
383
return _registers.__rbx;
384
case UNW_X86_64_RSI:
385
return _registers.__rsi;
386
case UNW_X86_64_RDI:
387
return _registers.__rdi;
388
case UNW_X86_64_RBP:
389
return _registers.__rbp;
390
case UNW_X86_64_RSP:
391
return _registers.__rsp;
392
case UNW_X86_64_R8:
393
return _registers.__r8;
394
case UNW_X86_64_R9:
395
return _registers.__r9;
396
case UNW_X86_64_R10:
397
return _registers.__r10;
398
case UNW_X86_64_R11:
399
return _registers.__r11;
400
case UNW_X86_64_R12:
401
return _registers.__r12;
402
case UNW_X86_64_R13:
403
return _registers.__r13;
404
case UNW_X86_64_R14:
405
return _registers.__r14;
406
case UNW_X86_64_R15:
407
return _registers.__r15;
408
}
409
_LIBUNWIND_ABORT("unsupported x86_64 register");
410
}
411
412
inline void Registers_x86_64::setRegister(int regNum, uint64_t value) {
413
switch (regNum) {
414
case UNW_REG_IP:
415
case UNW_X86_64_RIP:
416
_registers.__rip = value;
417
return;
418
case UNW_REG_SP:
419
_registers.__rsp = value;
420
return;
421
case UNW_X86_64_RAX:
422
_registers.__rax = value;
423
return;
424
case UNW_X86_64_RDX:
425
_registers.__rdx = value;
426
return;
427
case UNW_X86_64_RCX:
428
_registers.__rcx = value;
429
return;
430
case UNW_X86_64_RBX:
431
_registers.__rbx = value;
432
return;
433
case UNW_X86_64_RSI:
434
_registers.__rsi = value;
435
return;
436
case UNW_X86_64_RDI:
437
_registers.__rdi = value;
438
return;
439
case UNW_X86_64_RBP:
440
_registers.__rbp = value;
441
return;
442
case UNW_X86_64_RSP:
443
_registers.__rsp = value;
444
return;
445
case UNW_X86_64_R8:
446
_registers.__r8 = value;
447
return;
448
case UNW_X86_64_R9:
449
_registers.__r9 = value;
450
return;
451
case UNW_X86_64_R10:
452
_registers.__r10 = value;
453
return;
454
case UNW_X86_64_R11:
455
_registers.__r11 = value;
456
return;
457
case UNW_X86_64_R12:
458
_registers.__r12 = value;
459
return;
460
case UNW_X86_64_R13:
461
_registers.__r13 = value;
462
return;
463
case UNW_X86_64_R14:
464
_registers.__r14 = value;
465
return;
466
case UNW_X86_64_R15:
467
_registers.__r15 = value;
468
return;
469
}
470
_LIBUNWIND_ABORT("unsupported x86_64 register");
471
}
472
473
inline const char *Registers_x86_64::getRegisterName(int regNum) {
474
switch (regNum) {
475
case UNW_REG_IP:
476
case UNW_X86_64_RIP:
477
return "rip";
478
case UNW_REG_SP:
479
return "rsp";
480
case UNW_X86_64_RAX:
481
return "rax";
482
case UNW_X86_64_RDX:
483
return "rdx";
484
case UNW_X86_64_RCX:
485
return "rcx";
486
case UNW_X86_64_RBX:
487
return "rbx";
488
case UNW_X86_64_RSI:
489
return "rsi";
490
case UNW_X86_64_RDI:
491
return "rdi";
492
case UNW_X86_64_RBP:
493
return "rbp";
494
case UNW_X86_64_RSP:
495
return "rsp";
496
case UNW_X86_64_R8:
497
return "r8";
498
case UNW_X86_64_R9:
499
return "r9";
500
case UNW_X86_64_R10:
501
return "r10";
502
case UNW_X86_64_R11:
503
return "r11";
504
case UNW_X86_64_R12:
505
return "r12";
506
case UNW_X86_64_R13:
507
return "r13";
508
case UNW_X86_64_R14:
509
return "r14";
510
case UNW_X86_64_R15:
511
return "r15";
512
case UNW_X86_64_XMM0:
513
return "xmm0";
514
case UNW_X86_64_XMM1:
515
return "xmm1";
516
case UNW_X86_64_XMM2:
517
return "xmm2";
518
case UNW_X86_64_XMM3:
519
return "xmm3";
520
case UNW_X86_64_XMM4:
521
return "xmm4";
522
case UNW_X86_64_XMM5:
523
return "xmm5";
524
case UNW_X86_64_XMM6:
525
return "xmm6";
526
case UNW_X86_64_XMM7:
527
return "xmm7";
528
case UNW_X86_64_XMM8:
529
return "xmm8";
530
case UNW_X86_64_XMM9:
531
return "xmm9";
532
case UNW_X86_64_XMM10:
533
return "xmm10";
534
case UNW_X86_64_XMM11:
535
return "xmm11";
536
case UNW_X86_64_XMM12:
537
return "xmm12";
538
case UNW_X86_64_XMM13:
539
return "xmm13";
540
case UNW_X86_64_XMM14:
541
return "xmm14";
542
case UNW_X86_64_XMM15:
543
return "xmm15";
544
default:
545
return "unknown register";
546
}
547
}
548
549
inline double Registers_x86_64::getFloatRegister(int) const {
550
_LIBUNWIND_ABORT("no x86_64 float registers");
551
}
552
553
inline void Registers_x86_64::setFloatRegister(int, double) {
554
_LIBUNWIND_ABORT("no x86_64 float registers");
555
}
556
557
inline bool Registers_x86_64::validVectorRegister(int regNum) const {
558
#if defined(_WIN64)
559
if (regNum < UNW_X86_64_XMM0)
560
return false;
561
if (regNum > UNW_X86_64_XMM15)
562
return false;
563
return true;
564
#else
565
(void)regNum; // suppress unused parameter warning
566
return false;
567
#endif
568
}
569
570
inline v128 Registers_x86_64::getVectorRegister(int regNum) const {
571
#if defined(_WIN64)
572
assert(validVectorRegister(regNum));
573
return _xmm[regNum - UNW_X86_64_XMM0];
574
#else
575
(void)regNum; // suppress unused parameter warning
576
_LIBUNWIND_ABORT("no x86_64 vector registers");
577
#endif
578
}
579
580
inline void Registers_x86_64::setVectorRegister(int regNum, v128 value) {
581
#if defined(_WIN64)
582
assert(validVectorRegister(regNum));
583
_xmm[regNum - UNW_X86_64_XMM0] = value;
584
#else
585
(void)regNum; (void)value; // suppress unused parameter warnings
586
_LIBUNWIND_ABORT("no x86_64 vector registers");
587
#endif
588
}
589
#endif // _LIBUNWIND_TARGET_X86_64
590
591
592
#if defined(_LIBUNWIND_TARGET_PPC)
593
/// Registers_ppc holds the register state of a thread in a 32-bit PowerPC
594
/// process.
595
class _LIBUNWIND_HIDDEN Registers_ppc {
596
public:
597
Registers_ppc();
598
Registers_ppc(const void *registers);
599
600
bool validRegister(int num) const;
601
uint32_t getRegister(int num) const;
602
void setRegister(int num, uint32_t value);
603
bool validFloatRegister(int num) const;
604
double getFloatRegister(int num) const;
605
void setFloatRegister(int num, double value);
606
bool validVectorRegister(int num) const;
607
v128 getVectorRegister(int num) const;
608
void setVectorRegister(int num, v128 value);
609
static const char *getRegisterName(int num);
610
void jumpto();
611
static constexpr int lastDwarfRegNum() {
612
return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC;
613
}
614
static int getArch() { return REGISTERS_PPC; }
615
616
uint64_t getSP() const { return _registers.__r1; }
617
void setSP(uint32_t value) { _registers.__r1 = value; }
618
uint64_t getIP() const { return _registers.__srr0; }
619
void setIP(uint32_t value) { _registers.__srr0 = value; }
620
uint64_t getCR() const { return _registers.__cr; }
621
void setCR(uint32_t value) { _registers.__cr = value; }
622
uint64_t getLR() const { return _registers.__lr; }
623
void setLR(uint32_t value) { _registers.__lr = value; }
624
625
private:
626
struct ppc_thread_state_t {
627
unsigned int __srr0; /* Instruction address register (PC) */
628
unsigned int __srr1; /* Machine state register (supervisor) */
629
unsigned int __r0;
630
unsigned int __r1;
631
unsigned int __r2;
632
unsigned int __r3;
633
unsigned int __r4;
634
unsigned int __r5;
635
unsigned int __r6;
636
unsigned int __r7;
637
unsigned int __r8;
638
unsigned int __r9;
639
unsigned int __r10;
640
unsigned int __r11;
641
unsigned int __r12;
642
unsigned int __r13;
643
unsigned int __r14;
644
unsigned int __r15;
645
unsigned int __r16;
646
unsigned int __r17;
647
unsigned int __r18;
648
unsigned int __r19;
649
unsigned int __r20;
650
unsigned int __r21;
651
unsigned int __r22;
652
unsigned int __r23;
653
unsigned int __r24;
654
unsigned int __r25;
655
unsigned int __r26;
656
unsigned int __r27;
657
unsigned int __r28;
658
unsigned int __r29;
659
unsigned int __r30;
660
unsigned int __r31;
661
unsigned int __cr; /* Condition register */
662
unsigned int __xer; /* User's integer exception register */
663
unsigned int __lr; /* Link register */
664
unsigned int __ctr; /* Count register */
665
unsigned int __mq; /* MQ register (601 only) */
666
unsigned int __vrsave; /* Vector Save Register */
667
};
668
669
struct ppc_float_state_t {
670
double __fpregs[32];
671
672
unsigned int __fpscr_pad; /* fpscr is 64 bits, 32 bits of rubbish */
673
unsigned int __fpscr; /* floating point status register */
674
};
675
676
ppc_thread_state_t _registers;
677
ppc_float_state_t _floatRegisters;
678
v128 _vectorRegisters[32]; // offset 424
679
};
680
681
inline Registers_ppc::Registers_ppc(const void *registers) {
682
static_assert((check_fit<Registers_ppc, unw_context_t>::does_fit),
683
"ppc registers do not fit into unw_context_t");
684
memcpy(&_registers, static_cast<const uint8_t *>(registers),
685
sizeof(_registers));
686
static_assert(sizeof(ppc_thread_state_t) == 160,
687
"expected float register offset to be 160");
688
memcpy(&_floatRegisters,
689
static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t),
690
sizeof(_floatRegisters));
691
static_assert(sizeof(ppc_thread_state_t) + sizeof(ppc_float_state_t) == 424,
692
"expected vector register offset to be 424 bytes");
693
memcpy(_vectorRegisters,
694
static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t) +
695
sizeof(ppc_float_state_t),
696
sizeof(_vectorRegisters));
697
}
698
699
inline Registers_ppc::Registers_ppc() {
700
memset(&_registers, 0, sizeof(_registers));
701
memset(&_floatRegisters, 0, sizeof(_floatRegisters));
702
memset(&_vectorRegisters, 0, sizeof(_vectorRegisters));
703
}
704
705
inline bool Registers_ppc::validRegister(int regNum) const {
706
if (regNum == UNW_REG_IP)
707
return true;
708
if (regNum == UNW_REG_SP)
709
return true;
710
if (regNum == UNW_PPC_VRSAVE)
711
return true;
712
if (regNum < 0)
713
return false;
714
if (regNum <= UNW_PPC_R31)
715
return true;
716
if (regNum == UNW_PPC_MQ)
717
return true;
718
if (regNum == UNW_PPC_LR)
719
return true;
720
if (regNum == UNW_PPC_CTR)
721
return true;
722
if ((UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7))
723
return true;
724
return false;
725
}
726
727
inline uint32_t Registers_ppc::getRegister(int regNum) const {
728
switch (regNum) {
729
case UNW_REG_IP:
730
return _registers.__srr0;
731
case UNW_REG_SP:
732
return _registers.__r1;
733
case UNW_PPC_R0:
734
return _registers.__r0;
735
case UNW_PPC_R1:
736
return _registers.__r1;
737
case UNW_PPC_R2:
738
return _registers.__r2;
739
case UNW_PPC_R3:
740
return _registers.__r3;
741
case UNW_PPC_R4:
742
return _registers.__r4;
743
case UNW_PPC_R5:
744
return _registers.__r5;
745
case UNW_PPC_R6:
746
return _registers.__r6;
747
case UNW_PPC_R7:
748
return _registers.__r7;
749
case UNW_PPC_R8:
750
return _registers.__r8;
751
case UNW_PPC_R9:
752
return _registers.__r9;
753
case UNW_PPC_R10:
754
return _registers.__r10;
755
case UNW_PPC_R11:
756
return _registers.__r11;
757
case UNW_PPC_R12:
758
return _registers.__r12;
759
case UNW_PPC_R13:
760
return _registers.__r13;
761
case UNW_PPC_R14:
762
return _registers.__r14;
763
case UNW_PPC_R15:
764
return _registers.__r15;
765
case UNW_PPC_R16:
766
return _registers.__r16;
767
case UNW_PPC_R17:
768
return _registers.__r17;
769
case UNW_PPC_R18:
770
return _registers.__r18;
771
case UNW_PPC_R19:
772
return _registers.__r19;
773
case UNW_PPC_R20:
774
return _registers.__r20;
775
case UNW_PPC_R21:
776
return _registers.__r21;
777
case UNW_PPC_R22:
778
return _registers.__r22;
779
case UNW_PPC_R23:
780
return _registers.__r23;
781
case UNW_PPC_R24:
782
return _registers.__r24;
783
case UNW_PPC_R25:
784
return _registers.__r25;
785
case UNW_PPC_R26:
786
return _registers.__r26;
787
case UNW_PPC_R27:
788
return _registers.__r27;
789
case UNW_PPC_R28:
790
return _registers.__r28;
791
case UNW_PPC_R29:
792
return _registers.__r29;
793
case UNW_PPC_R30:
794
return _registers.__r30;
795
case UNW_PPC_R31:
796
return _registers.__r31;
797
case UNW_PPC_LR:
798
return _registers.__lr;
799
case UNW_PPC_CR0:
800
return (_registers.__cr & 0xF0000000);
801
case UNW_PPC_CR1:
802
return (_registers.__cr & 0x0F000000);
803
case UNW_PPC_CR2:
804
return (_registers.__cr & 0x00F00000);
805
case UNW_PPC_CR3:
806
return (_registers.__cr & 0x000F0000);
807
case UNW_PPC_CR4:
808
return (_registers.__cr & 0x0000F000);
809
case UNW_PPC_CR5:
810
return (_registers.__cr & 0x00000F00);
811
case UNW_PPC_CR6:
812
return (_registers.__cr & 0x000000F0);
813
case UNW_PPC_CR7:
814
return (_registers.__cr & 0x0000000F);
815
case UNW_PPC_VRSAVE:
816
return _registers.__vrsave;
817
}
818
_LIBUNWIND_ABORT("unsupported ppc register");
819
}
820
821
inline void Registers_ppc::setRegister(int regNum, uint32_t value) {
822
//fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value);
823
switch (regNum) {
824
case UNW_REG_IP:
825
_registers.__srr0 = value;
826
return;
827
case UNW_REG_SP:
828
_registers.__r1 = value;
829
return;
830
case UNW_PPC_R0:
831
_registers.__r0 = value;
832
return;
833
case UNW_PPC_R1:
834
_registers.__r1 = value;
835
return;
836
case UNW_PPC_R2:
837
_registers.__r2 = value;
838
return;
839
case UNW_PPC_R3:
840
_registers.__r3 = value;
841
return;
842
case UNW_PPC_R4:
843
_registers.__r4 = value;
844
return;
845
case UNW_PPC_R5:
846
_registers.__r5 = value;
847
return;
848
case UNW_PPC_R6:
849
_registers.__r6 = value;
850
return;
851
case UNW_PPC_R7:
852
_registers.__r7 = value;
853
return;
854
case UNW_PPC_R8:
855
_registers.__r8 = value;
856
return;
857
case UNW_PPC_R9:
858
_registers.__r9 = value;
859
return;
860
case UNW_PPC_R10:
861
_registers.__r10 = value;
862
return;
863
case UNW_PPC_R11:
864
_registers.__r11 = value;
865
return;
866
case UNW_PPC_R12:
867
_registers.__r12 = value;
868
return;
869
case UNW_PPC_R13:
870
_registers.__r13 = value;
871
return;
872
case UNW_PPC_R14:
873
_registers.__r14 = value;
874
return;
875
case UNW_PPC_R15:
876
_registers.__r15 = value;
877
return;
878
case UNW_PPC_R16:
879
_registers.__r16 = value;
880
return;
881
case UNW_PPC_R17:
882
_registers.__r17 = value;
883
return;
884
case UNW_PPC_R18:
885
_registers.__r18 = value;
886
return;
887
case UNW_PPC_R19:
888
_registers.__r19 = value;
889
return;
890
case UNW_PPC_R20:
891
_registers.__r20 = value;
892
return;
893
case UNW_PPC_R21:
894
_registers.__r21 = value;
895
return;
896
case UNW_PPC_R22:
897
_registers.__r22 = value;
898
return;
899
case UNW_PPC_R23:
900
_registers.__r23 = value;
901
return;
902
case UNW_PPC_R24:
903
_registers.__r24 = value;
904
return;
905
case UNW_PPC_R25:
906
_registers.__r25 = value;
907
return;
908
case UNW_PPC_R26:
909
_registers.__r26 = value;
910
return;
911
case UNW_PPC_R27:
912
_registers.__r27 = value;
913
return;
914
case UNW_PPC_R28:
915
_registers.__r28 = value;
916
return;
917
case UNW_PPC_R29:
918
_registers.__r29 = value;
919
return;
920
case UNW_PPC_R30:
921
_registers.__r30 = value;
922
return;
923
case UNW_PPC_R31:
924
_registers.__r31 = value;
925
return;
926
case UNW_PPC_MQ:
927
_registers.__mq = value;
928
return;
929
case UNW_PPC_LR:
930
_registers.__lr = value;
931
return;
932
case UNW_PPC_CTR:
933
_registers.__ctr = value;
934
return;
935
case UNW_PPC_CR0:
936
_registers.__cr &= 0x0FFFFFFF;
937
_registers.__cr |= (value & 0xF0000000);
938
return;
939
case UNW_PPC_CR1:
940
_registers.__cr &= 0xF0FFFFFF;
941
_registers.__cr |= (value & 0x0F000000);
942
return;
943
case UNW_PPC_CR2:
944
_registers.__cr &= 0xFF0FFFFF;
945
_registers.__cr |= (value & 0x00F00000);
946
return;
947
case UNW_PPC_CR3:
948
_registers.__cr &= 0xFFF0FFFF;
949
_registers.__cr |= (value & 0x000F0000);
950
return;
951
case UNW_PPC_CR4:
952
_registers.__cr &= 0xFFFF0FFF;
953
_registers.__cr |= (value & 0x0000F000);
954
return;
955
case UNW_PPC_CR5:
956
_registers.__cr &= 0xFFFFF0FF;
957
_registers.__cr |= (value & 0x00000F00);
958
return;
959
case UNW_PPC_CR6:
960
_registers.__cr &= 0xFFFFFF0F;
961
_registers.__cr |= (value & 0x000000F0);
962
return;
963
case UNW_PPC_CR7:
964
_registers.__cr &= 0xFFFFFFF0;
965
_registers.__cr |= (value & 0x0000000F);
966
return;
967
case UNW_PPC_VRSAVE:
968
_registers.__vrsave = value;
969
return;
970
// not saved
971
return;
972
case UNW_PPC_XER:
973
_registers.__xer = value;
974
return;
975
case UNW_PPC_AP:
976
case UNW_PPC_VSCR:
977
case UNW_PPC_SPEFSCR:
978
// not saved
979
return;
980
}
981
_LIBUNWIND_ABORT("unsupported ppc register");
982
}
983
984
inline bool Registers_ppc::validFloatRegister(int regNum) const {
985
if (regNum < UNW_PPC_F0)
986
return false;
987
if (regNum > UNW_PPC_F31)
988
return false;
989
return true;
990
}
991
992
inline double Registers_ppc::getFloatRegister(int regNum) const {
993
assert(validFloatRegister(regNum));
994
return _floatRegisters.__fpregs[regNum - UNW_PPC_F0];
995
}
996
997
inline void Registers_ppc::setFloatRegister(int regNum, double value) {
998
assert(validFloatRegister(regNum));
999
_floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value;
1000
}
1001
1002
inline bool Registers_ppc::validVectorRegister(int regNum) const {
1003
if (regNum < UNW_PPC_V0)
1004
return false;
1005
if (regNum > UNW_PPC_V31)
1006
return false;
1007
return true;
1008
}
1009
1010
inline v128 Registers_ppc::getVectorRegister(int regNum) const {
1011
assert(validVectorRegister(regNum));
1012
v128 result = _vectorRegisters[regNum - UNW_PPC_V0];
1013
return result;
1014
}
1015
1016
inline void Registers_ppc::setVectorRegister(int regNum, v128 value) {
1017
assert(validVectorRegister(regNum));
1018
_vectorRegisters[regNum - UNW_PPC_V0] = value;
1019
}
1020
1021
inline const char *Registers_ppc::getRegisterName(int regNum) {
1022
switch (regNum) {
1023
case UNW_REG_IP:
1024
return "ip";
1025
case UNW_REG_SP:
1026
return "sp";
1027
case UNW_PPC_R0:
1028
return "r0";
1029
case UNW_PPC_R1:
1030
return "r1";
1031
case UNW_PPC_R2:
1032
return "r2";
1033
case UNW_PPC_R3:
1034
return "r3";
1035
case UNW_PPC_R4:
1036
return "r4";
1037
case UNW_PPC_R5:
1038
return "r5";
1039
case UNW_PPC_R6:
1040
return "r6";
1041
case UNW_PPC_R7:
1042
return "r7";
1043
case UNW_PPC_R8:
1044
return "r8";
1045
case UNW_PPC_R9:
1046
return "r9";
1047
case UNW_PPC_R10:
1048
return "r10";
1049
case UNW_PPC_R11:
1050
return "r11";
1051
case UNW_PPC_R12:
1052
return "r12";
1053
case UNW_PPC_R13:
1054
return "r13";
1055
case UNW_PPC_R14:
1056
return "r14";
1057
case UNW_PPC_R15:
1058
return "r15";
1059
case UNW_PPC_R16:
1060
return "r16";
1061
case UNW_PPC_R17:
1062
return "r17";
1063
case UNW_PPC_R18:
1064
return "r18";
1065
case UNW_PPC_R19:
1066
return "r19";
1067
case UNW_PPC_R20:
1068
return "r20";
1069
case UNW_PPC_R21:
1070
return "r21";
1071
case UNW_PPC_R22:
1072
return "r22";
1073
case UNW_PPC_R23:
1074
return "r23";
1075
case UNW_PPC_R24:
1076
return "r24";
1077
case UNW_PPC_R25:
1078
return "r25";
1079
case UNW_PPC_R26:
1080
return "r26";
1081
case UNW_PPC_R27:
1082
return "r27";
1083
case UNW_PPC_R28:
1084
return "r28";
1085
case UNW_PPC_R29:
1086
return "r29";
1087
case UNW_PPC_R30:
1088
return "r30";
1089
case UNW_PPC_R31:
1090
return "r31";
1091
case UNW_PPC_F0:
1092
return "fp0";
1093
case UNW_PPC_F1:
1094
return "fp1";
1095
case UNW_PPC_F2:
1096
return "fp2";
1097
case UNW_PPC_F3:
1098
return "fp3";
1099
case UNW_PPC_F4:
1100
return "fp4";
1101
case UNW_PPC_F5:
1102
return "fp5";
1103
case UNW_PPC_F6:
1104
return "fp6";
1105
case UNW_PPC_F7:
1106
return "fp7";
1107
case UNW_PPC_F8:
1108
return "fp8";
1109
case UNW_PPC_F9:
1110
return "fp9";
1111
case UNW_PPC_F10:
1112
return "fp10";
1113
case UNW_PPC_F11:
1114
return "fp11";
1115
case UNW_PPC_F12:
1116
return "fp12";
1117
case UNW_PPC_F13:
1118
return "fp13";
1119
case UNW_PPC_F14:
1120
return "fp14";
1121
case UNW_PPC_F15:
1122
return "fp15";
1123
case UNW_PPC_F16:
1124
return "fp16";
1125
case UNW_PPC_F17:
1126
return "fp17";
1127
case UNW_PPC_F18:
1128
return "fp18";
1129
case UNW_PPC_F19:
1130
return "fp19";
1131
case UNW_PPC_F20:
1132
return "fp20";
1133
case UNW_PPC_F21:
1134
return "fp21";
1135
case UNW_PPC_F22:
1136
return "fp22";
1137
case UNW_PPC_F23:
1138
return "fp23";
1139
case UNW_PPC_F24:
1140
return "fp24";
1141
case UNW_PPC_F25:
1142
return "fp25";
1143
case UNW_PPC_F26:
1144
return "fp26";
1145
case UNW_PPC_F27:
1146
return "fp27";
1147
case UNW_PPC_F28:
1148
return "fp28";
1149
case UNW_PPC_F29:
1150
return "fp29";
1151
case UNW_PPC_F30:
1152
return "fp30";
1153
case UNW_PPC_F31:
1154
return "fp31";
1155
case UNW_PPC_LR:
1156
return "lr";
1157
default:
1158
return "unknown register";
1159
}
1160
1161
}
1162
#endif // _LIBUNWIND_TARGET_PPC
1163
1164
#if defined(_LIBUNWIND_TARGET_PPC64)
1165
/// Registers_ppc64 holds the register state of a thread in a 64-bit PowerPC
1166
/// process.
1167
class _LIBUNWIND_HIDDEN Registers_ppc64 {
1168
public:
1169
Registers_ppc64();
1170
Registers_ppc64(const void *registers);
1171
1172
bool validRegister(int num) const;
1173
uint64_t getRegister(int num) const;
1174
void setRegister(int num, uint64_t value);
1175
bool validFloatRegister(int num) const;
1176
double getFloatRegister(int num) const;
1177
void setFloatRegister(int num, double value);
1178
bool validVectorRegister(int num) const;
1179
v128 getVectorRegister(int num) const;
1180
void setVectorRegister(int num, v128 value);
1181
static const char *getRegisterName(int num);
1182
void jumpto();
1183
static constexpr int lastDwarfRegNum() {
1184
return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64;
1185
}
1186
static int getArch() { return REGISTERS_PPC64; }
1187
1188
uint64_t getSP() const { return _registers.__r1; }
1189
void setSP(uint64_t value) { _registers.__r1 = value; }
1190
uint64_t getIP() const { return _registers.__srr0; }
1191
void setIP(uint64_t value) { _registers.__srr0 = value; }
1192
uint64_t getCR() const { return _registers.__cr; }
1193
void setCR(uint64_t value) { _registers.__cr = value; }
1194
uint64_t getLR() const { return _registers.__lr; }
1195
void setLR(uint64_t value) { _registers.__lr = value; }
1196
1197
private:
1198
struct ppc64_thread_state_t {
1199
uint64_t __srr0; // Instruction address register (PC)
1200
uint64_t __srr1; // Machine state register (supervisor)
1201
uint64_t __r0;
1202
uint64_t __r1;
1203
uint64_t __r2;
1204
uint64_t __r3;
1205
uint64_t __r4;
1206
uint64_t __r5;
1207
uint64_t __r6;
1208
uint64_t __r7;
1209
uint64_t __r8;
1210
uint64_t __r9;
1211
uint64_t __r10;
1212
uint64_t __r11;
1213
uint64_t __r12;
1214
uint64_t __r13;
1215
uint64_t __r14;
1216
uint64_t __r15;
1217
uint64_t __r16;
1218
uint64_t __r17;
1219
uint64_t __r18;
1220
uint64_t __r19;
1221
uint64_t __r20;
1222
uint64_t __r21;
1223
uint64_t __r22;
1224
uint64_t __r23;
1225
uint64_t __r24;
1226
uint64_t __r25;
1227
uint64_t __r26;
1228
uint64_t __r27;
1229
uint64_t __r28;
1230
uint64_t __r29;
1231
uint64_t __r30;
1232
uint64_t __r31;
1233
uint64_t __cr; // Condition register
1234
uint64_t __xer; // User's integer exception register
1235
uint64_t __lr; // Link register
1236
uint64_t __ctr; // Count register
1237
uint64_t __vrsave; // Vector Save Register
1238
};
1239
1240
union ppc64_vsr_t {
1241
struct asfloat_s {
1242
double f;
1243
uint64_t v2;
1244
} asfloat;
1245
v128 v;
1246
};
1247
1248
ppc64_thread_state_t _registers;
1249
ppc64_vsr_t _vectorScalarRegisters[64];
1250
1251
static int getVectorRegNum(int num);
1252
};
1253
1254
inline Registers_ppc64::Registers_ppc64(const void *registers) {
1255
static_assert((check_fit<Registers_ppc64, unw_context_t>::does_fit),
1256
"ppc64 registers do not fit into unw_context_t");
1257
memcpy(&_registers, static_cast<const uint8_t *>(registers),
1258
sizeof(_registers));
1259
static_assert(sizeof(_registers) == 312,
1260
"expected vector scalar register offset to be 312");
1261
memcpy(&_vectorScalarRegisters,
1262
static_cast<const uint8_t *>(registers) + sizeof(_registers),
1263
sizeof(_vectorScalarRegisters));
1264
static_assert(sizeof(_registers) +
1265
sizeof(_vectorScalarRegisters) == 1336,
1266
"expected vector register offset to be 1336 bytes");
1267
}
1268
1269
inline Registers_ppc64::Registers_ppc64() {
1270
memset(&_registers, 0, sizeof(_registers));
1271
memset(&_vectorScalarRegisters, 0, sizeof(_vectorScalarRegisters));
1272
}
1273
1274
inline bool Registers_ppc64::validRegister(int regNum) const {
1275
switch (regNum) {
1276
case UNW_REG_IP:
1277
case UNW_REG_SP:
1278
case UNW_PPC64_XER:
1279
case UNW_PPC64_LR:
1280
case UNW_PPC64_CTR:
1281
case UNW_PPC64_VRSAVE:
1282
return true;
1283
}
1284
1285
if (regNum >= UNW_PPC64_R0 && regNum <= UNW_PPC64_R31)
1286
return true;
1287
if (regNum >= UNW_PPC64_CR0 && regNum <= UNW_PPC64_CR7)
1288
return true;
1289
1290
return false;
1291
}
1292
1293
inline uint64_t Registers_ppc64::getRegister(int regNum) const {
1294
switch (regNum) {
1295
case UNW_REG_IP:
1296
return _registers.__srr0;
1297
case UNW_PPC64_R0:
1298
return _registers.__r0;
1299
case UNW_PPC64_R1:
1300
case UNW_REG_SP:
1301
return _registers.__r1;
1302
case UNW_PPC64_R2:
1303
return _registers.__r2;
1304
case UNW_PPC64_R3:
1305
return _registers.__r3;
1306
case UNW_PPC64_R4:
1307
return _registers.__r4;
1308
case UNW_PPC64_R5:
1309
return _registers.__r5;
1310
case UNW_PPC64_R6:
1311
return _registers.__r6;
1312
case UNW_PPC64_R7:
1313
return _registers.__r7;
1314
case UNW_PPC64_R8:
1315
return _registers.__r8;
1316
case UNW_PPC64_R9:
1317
return _registers.__r9;
1318
case UNW_PPC64_R10:
1319
return _registers.__r10;
1320
case UNW_PPC64_R11:
1321
return _registers.__r11;
1322
case UNW_PPC64_R12:
1323
return _registers.__r12;
1324
case UNW_PPC64_R13:
1325
return _registers.__r13;
1326
case UNW_PPC64_R14:
1327
return _registers.__r14;
1328
case UNW_PPC64_R15:
1329
return _registers.__r15;
1330
case UNW_PPC64_R16:
1331
return _registers.__r16;
1332
case UNW_PPC64_R17:
1333
return _registers.__r17;
1334
case UNW_PPC64_R18:
1335
return _registers.__r18;
1336
case UNW_PPC64_R19:
1337
return _registers.__r19;
1338
case UNW_PPC64_R20:
1339
return _registers.__r20;
1340
case UNW_PPC64_R21:
1341
return _registers.__r21;
1342
case UNW_PPC64_R22:
1343
return _registers.__r22;
1344
case UNW_PPC64_R23:
1345
return _registers.__r23;
1346
case UNW_PPC64_R24:
1347
return _registers.__r24;
1348
case UNW_PPC64_R25:
1349
return _registers.__r25;
1350
case UNW_PPC64_R26:
1351
return _registers.__r26;
1352
case UNW_PPC64_R27:
1353
return _registers.__r27;
1354
case UNW_PPC64_R28:
1355
return _registers.__r28;
1356
case UNW_PPC64_R29:
1357
return _registers.__r29;
1358
case UNW_PPC64_R30:
1359
return _registers.__r30;
1360
case UNW_PPC64_R31:
1361
return _registers.__r31;
1362
case UNW_PPC64_CR0:
1363
return (_registers.__cr & 0xF0000000);
1364
case UNW_PPC64_CR1:
1365
return (_registers.__cr & 0x0F000000);
1366
case UNW_PPC64_CR2:
1367
return (_registers.__cr & 0x00F00000);
1368
case UNW_PPC64_CR3:
1369
return (_registers.__cr & 0x000F0000);
1370
case UNW_PPC64_CR4:
1371
return (_registers.__cr & 0x0000F000);
1372
case UNW_PPC64_CR5:
1373
return (_registers.__cr & 0x00000F00);
1374
case UNW_PPC64_CR6:
1375
return (_registers.__cr & 0x000000F0);
1376
case UNW_PPC64_CR7:
1377
return (_registers.__cr & 0x0000000F);
1378
case UNW_PPC64_XER:
1379
return _registers.__xer;
1380
case UNW_PPC64_LR:
1381
return _registers.__lr;
1382
case UNW_PPC64_CTR:
1383
return _registers.__ctr;
1384
case UNW_PPC64_VRSAVE:
1385
return _registers.__vrsave;
1386
}
1387
_LIBUNWIND_ABORT("unsupported ppc64 register");
1388
}
1389
1390
inline void Registers_ppc64::setRegister(int regNum, uint64_t value) {
1391
switch (regNum) {
1392
case UNW_REG_IP:
1393
_registers.__srr0 = value;
1394
return;
1395
case UNW_PPC64_R0:
1396
_registers.__r0 = value;
1397
return;
1398
case UNW_PPC64_R1:
1399
case UNW_REG_SP:
1400
_registers.__r1 = value;
1401
return;
1402
case UNW_PPC64_R2:
1403
_registers.__r2 = value;
1404
return;
1405
case UNW_PPC64_R3:
1406
_registers.__r3 = value;
1407
return;
1408
case UNW_PPC64_R4:
1409
_registers.__r4 = value;
1410
return;
1411
case UNW_PPC64_R5:
1412
_registers.__r5 = value;
1413
return;
1414
case UNW_PPC64_R6:
1415
_registers.__r6 = value;
1416
return;
1417
case UNW_PPC64_R7:
1418
_registers.__r7 = value;
1419
return;
1420
case UNW_PPC64_R8:
1421
_registers.__r8 = value;
1422
return;
1423
case UNW_PPC64_R9:
1424
_registers.__r9 = value;
1425
return;
1426
case UNW_PPC64_R10:
1427
_registers.__r10 = value;
1428
return;
1429
case UNW_PPC64_R11:
1430
_registers.__r11 = value;
1431
return;
1432
case UNW_PPC64_R12:
1433
_registers.__r12 = value;
1434
return;
1435
case UNW_PPC64_R13:
1436
_registers.__r13 = value;
1437
return;
1438
case UNW_PPC64_R14:
1439
_registers.__r14 = value;
1440
return;
1441
case UNW_PPC64_R15:
1442
_registers.__r15 = value;
1443
return;
1444
case UNW_PPC64_R16:
1445
_registers.__r16 = value;
1446
return;
1447
case UNW_PPC64_R17:
1448
_registers.__r17 = value;
1449
return;
1450
case UNW_PPC64_R18:
1451
_registers.__r18 = value;
1452
return;
1453
case UNW_PPC64_R19:
1454
_registers.__r19 = value;
1455
return;
1456
case UNW_PPC64_R20:
1457
_registers.__r20 = value;
1458
return;
1459
case UNW_PPC64_R21:
1460
_registers.__r21 = value;
1461
return;
1462
case UNW_PPC64_R22:
1463
_registers.__r22 = value;
1464
return;
1465
case UNW_PPC64_R23:
1466
_registers.__r23 = value;
1467
return;
1468
case UNW_PPC64_R24:
1469
_registers.__r24 = value;
1470
return;
1471
case UNW_PPC64_R25:
1472
_registers.__r25 = value;
1473
return;
1474
case UNW_PPC64_R26:
1475
_registers.__r26 = value;
1476
return;
1477
case UNW_PPC64_R27:
1478
_registers.__r27 = value;
1479
return;
1480
case UNW_PPC64_R28:
1481
_registers.__r28 = value;
1482
return;
1483
case UNW_PPC64_R29:
1484
_registers.__r29 = value;
1485
return;
1486
case UNW_PPC64_R30:
1487
_registers.__r30 = value;
1488
return;
1489
case UNW_PPC64_R31:
1490
_registers.__r31 = value;
1491
return;
1492
case UNW_PPC64_CR0:
1493
_registers.__cr &= 0x0FFFFFFF;
1494
_registers.__cr |= (value & 0xF0000000);
1495
return;
1496
case UNW_PPC64_CR1:
1497
_registers.__cr &= 0xF0FFFFFF;
1498
_registers.__cr |= (value & 0x0F000000);
1499
return;
1500
case UNW_PPC64_CR2:
1501
_registers.__cr &= 0xFF0FFFFF;
1502
_registers.__cr |= (value & 0x00F00000);
1503
return;
1504
case UNW_PPC64_CR3:
1505
_registers.__cr &= 0xFFF0FFFF;
1506
_registers.__cr |= (value & 0x000F0000);
1507
return;
1508
case UNW_PPC64_CR4:
1509
_registers.__cr &= 0xFFFF0FFF;
1510
_registers.__cr |= (value & 0x0000F000);
1511
return;
1512
case UNW_PPC64_CR5:
1513
_registers.__cr &= 0xFFFFF0FF;
1514
_registers.__cr |= (value & 0x00000F00);
1515
return;
1516
case UNW_PPC64_CR6:
1517
_registers.__cr &= 0xFFFFFF0F;
1518
_registers.__cr |= (value & 0x000000F0);
1519
return;
1520
case UNW_PPC64_CR7:
1521
_registers.__cr &= 0xFFFFFFF0;
1522
_registers.__cr |= (value & 0x0000000F);
1523
return;
1524
case UNW_PPC64_XER:
1525
_registers.__xer = value;
1526
return;
1527
case UNW_PPC64_LR:
1528
_registers.__lr = value;
1529
return;
1530
case UNW_PPC64_CTR:
1531
_registers.__ctr = value;
1532
return;
1533
case UNW_PPC64_VRSAVE:
1534
_registers.__vrsave = value;
1535
return;
1536
}
1537
_LIBUNWIND_ABORT("unsupported ppc64 register");
1538
}
1539
1540
inline bool Registers_ppc64::validFloatRegister(int regNum) const {
1541
return regNum >= UNW_PPC64_F0 && regNum <= UNW_PPC64_F31;
1542
}
1543
1544
inline double Registers_ppc64::getFloatRegister(int regNum) const {
1545
assert(validFloatRegister(regNum));
1546
return _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f;
1547
}
1548
1549
inline void Registers_ppc64::setFloatRegister(int regNum, double value) {
1550
assert(validFloatRegister(regNum));
1551
_vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f = value;
1552
}
1553
1554
inline bool Registers_ppc64::validVectorRegister(int regNum) const {
1555
#if defined(__VSX__)
1556
if (regNum >= UNW_PPC64_VS0 && regNum <= UNW_PPC64_VS31)
1557
return true;
1558
if (regNum >= UNW_PPC64_VS32 && regNum <= UNW_PPC64_VS63)
1559
return true;
1560
#elif defined(__ALTIVEC__)
1561
if (regNum >= UNW_PPC64_V0 && regNum <= UNW_PPC64_V31)
1562
return true;
1563
#endif
1564
return false;
1565
}
1566
1567
inline int Registers_ppc64::getVectorRegNum(int num)
1568
{
1569
if (num >= UNW_PPC64_VS0 && num <= UNW_PPC64_VS31)
1570
return num - UNW_PPC64_VS0;
1571
else
1572
return num - UNW_PPC64_VS32 + 32;
1573
}
1574
1575
inline v128 Registers_ppc64::getVectorRegister(int regNum) const {
1576
assert(validVectorRegister(regNum));
1577
return _vectorScalarRegisters[getVectorRegNum(regNum)].v;
1578
}
1579
1580
inline void Registers_ppc64::setVectorRegister(int regNum, v128 value) {
1581
assert(validVectorRegister(regNum));
1582
_vectorScalarRegisters[getVectorRegNum(regNum)].v = value;
1583
}
1584
1585
inline const char *Registers_ppc64::getRegisterName(int regNum) {
1586
switch (regNum) {
1587
case UNW_REG_IP:
1588
return "ip";
1589
case UNW_REG_SP:
1590
return "sp";
1591
case UNW_PPC64_R0:
1592
return "r0";
1593
case UNW_PPC64_R1:
1594
return "r1";
1595
case UNW_PPC64_R2:
1596
return "r2";
1597
case UNW_PPC64_R3:
1598
return "r3";
1599
case UNW_PPC64_R4:
1600
return "r4";
1601
case UNW_PPC64_R5:
1602
return "r5";
1603
case UNW_PPC64_R6:
1604
return "r6";
1605
case UNW_PPC64_R7:
1606
return "r7";
1607
case UNW_PPC64_R8:
1608
return "r8";
1609
case UNW_PPC64_R9:
1610
return "r9";
1611
case UNW_PPC64_R10:
1612
return "r10";
1613
case UNW_PPC64_R11:
1614
return "r11";
1615
case UNW_PPC64_R12:
1616
return "r12";
1617
case UNW_PPC64_R13:
1618
return "r13";
1619
case UNW_PPC64_R14:
1620
return "r14";
1621
case UNW_PPC64_R15:
1622
return "r15";
1623
case UNW_PPC64_R16:
1624
return "r16";
1625
case UNW_PPC64_R17:
1626
return "r17";
1627
case UNW_PPC64_R18:
1628
return "r18";
1629
case UNW_PPC64_R19:
1630
return "r19";
1631
case UNW_PPC64_R20:
1632
return "r20";
1633
case UNW_PPC64_R21:
1634
return "r21";
1635
case UNW_PPC64_R22:
1636
return "r22";
1637
case UNW_PPC64_R23:
1638
return "r23";
1639
case UNW_PPC64_R24:
1640
return "r24";
1641
case UNW_PPC64_R25:
1642
return "r25";
1643
case UNW_PPC64_R26:
1644
return "r26";
1645
case UNW_PPC64_R27:
1646
return "r27";
1647
case UNW_PPC64_R28:
1648
return "r28";
1649
case UNW_PPC64_R29:
1650
return "r29";
1651
case UNW_PPC64_R30:
1652
return "r30";
1653
case UNW_PPC64_R31:
1654
return "r31";
1655
case UNW_PPC64_CR0:
1656
return "cr0";
1657
case UNW_PPC64_CR1:
1658
return "cr1";
1659
case UNW_PPC64_CR2:
1660
return "cr2";
1661
case UNW_PPC64_CR3:
1662
return "cr3";
1663
case UNW_PPC64_CR4:
1664
return "cr4";
1665
case UNW_PPC64_CR5:
1666
return "cr5";
1667
case UNW_PPC64_CR6:
1668
return "cr6";
1669
case UNW_PPC64_CR7:
1670
return "cr7";
1671
case UNW_PPC64_XER:
1672
return "xer";
1673
case UNW_PPC64_LR:
1674
return "lr";
1675
case UNW_PPC64_CTR:
1676
return "ctr";
1677
case UNW_PPC64_VRSAVE:
1678
return "vrsave";
1679
case UNW_PPC64_F0:
1680
return "fp0";
1681
case UNW_PPC64_F1:
1682
return "fp1";
1683
case UNW_PPC64_F2:
1684
return "fp2";
1685
case UNW_PPC64_F3:
1686
return "fp3";
1687
case UNW_PPC64_F4:
1688
return "fp4";
1689
case UNW_PPC64_F5:
1690
return "fp5";
1691
case UNW_PPC64_F6:
1692
return "fp6";
1693
case UNW_PPC64_F7:
1694
return "fp7";
1695
case UNW_PPC64_F8:
1696
return "fp8";
1697
case UNW_PPC64_F9:
1698
return "fp9";
1699
case UNW_PPC64_F10:
1700
return "fp10";
1701
case UNW_PPC64_F11:
1702
return "fp11";
1703
case UNW_PPC64_F12:
1704
return "fp12";
1705
case UNW_PPC64_F13:
1706
return "fp13";
1707
case UNW_PPC64_F14:
1708
return "fp14";
1709
case UNW_PPC64_F15:
1710
return "fp15";
1711
case UNW_PPC64_F16:
1712
return "fp16";
1713
case UNW_PPC64_F17:
1714
return "fp17";
1715
case UNW_PPC64_F18:
1716
return "fp18";
1717
case UNW_PPC64_F19:
1718
return "fp19";
1719
case UNW_PPC64_F20:
1720
return "fp20";
1721
case UNW_PPC64_F21:
1722
return "fp21";
1723
case UNW_PPC64_F22:
1724
return "fp22";
1725
case UNW_PPC64_F23:
1726
return "fp23";
1727
case UNW_PPC64_F24:
1728
return "fp24";
1729
case UNW_PPC64_F25:
1730
return "fp25";
1731
case UNW_PPC64_F26:
1732
return "fp26";
1733
case UNW_PPC64_F27:
1734
return "fp27";
1735
case UNW_PPC64_F28:
1736
return "fp28";
1737
case UNW_PPC64_F29:
1738
return "fp29";
1739
case UNW_PPC64_F30:
1740
return "fp30";
1741
case UNW_PPC64_F31:
1742
return "fp31";
1743
case UNW_PPC64_V0:
1744
return "v0";
1745
case UNW_PPC64_V1:
1746
return "v1";
1747
case UNW_PPC64_V2:
1748
return "v2";
1749
case UNW_PPC64_V3:
1750
return "v3";
1751
case UNW_PPC64_V4:
1752
return "v4";
1753
case UNW_PPC64_V5:
1754
return "v5";
1755
case UNW_PPC64_V6:
1756
return "v6";
1757
case UNW_PPC64_V7:
1758
return "v7";
1759
case UNW_PPC64_V8:
1760
return "v8";
1761
case UNW_PPC64_V9:
1762
return "v9";
1763
case UNW_PPC64_V10:
1764
return "v10";
1765
case UNW_PPC64_V11:
1766
return "v11";
1767
case UNW_PPC64_V12:
1768
return "v12";
1769
case UNW_PPC64_V13:
1770
return "v13";
1771
case UNW_PPC64_V14:
1772
return "v14";
1773
case UNW_PPC64_V15:
1774
return "v15";
1775
case UNW_PPC64_V16:
1776
return "v16";
1777
case UNW_PPC64_V17:
1778
return "v17";
1779
case UNW_PPC64_V18:
1780
return "v18";
1781
case UNW_PPC64_V19:
1782
return "v19";
1783
case UNW_PPC64_V20:
1784
return "v20";
1785
case UNW_PPC64_V21:
1786
return "v21";
1787
case UNW_PPC64_V22:
1788
return "v22";
1789
case UNW_PPC64_V23:
1790
return "v23";
1791
case UNW_PPC64_V24:
1792
return "v24";
1793
case UNW_PPC64_V25:
1794
return "v25";
1795
case UNW_PPC64_V26:
1796
return "v26";
1797
case UNW_PPC64_V27:
1798
return "v27";
1799
case UNW_PPC64_V28:
1800
return "v28";
1801
case UNW_PPC64_V29:
1802
return "v29";
1803
case UNW_PPC64_V30:
1804
return "v30";
1805
case UNW_PPC64_V31:
1806
return "v31";
1807
}
1808
return "unknown register";
1809
}
1810
#endif // _LIBUNWIND_TARGET_PPC64
1811
1812
1813
#if defined(_LIBUNWIND_TARGET_AARCH64)
1814
/// Registers_arm64 holds the register state of a thread in a 64-bit arm
1815
/// process.
1816
class _LIBUNWIND_HIDDEN Registers_arm64;
1817
extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *);
1818
1819
#if defined(_LIBUNWIND_USE_GCS)
1820
extern "C" void *__libunwind_cet_get_jump_target() {
1821
return reinterpret_cast<void *>(&__libunwind_Registers_arm64_jumpto);
1822
}
1823
#endif
1824
1825
class _LIBUNWIND_HIDDEN Registers_arm64 {
1826
public:
1827
Registers_arm64();
1828
Registers_arm64(const void *registers);
1829
1830
bool validRegister(int num) const;
1831
uint64_t getRegister(int num) const;
1832
void setRegister(int num, uint64_t value);
1833
bool validFloatRegister(int num) const;
1834
double getFloatRegister(int num) const;
1835
void setFloatRegister(int num, double value);
1836
bool validVectorRegister(int num) const;
1837
v128 getVectorRegister(int num) const;
1838
void setVectorRegister(int num, v128 value);
1839
static const char *getRegisterName(int num);
1840
void jumpto() { __libunwind_Registers_arm64_jumpto(this); }
1841
static constexpr int lastDwarfRegNum() {
1842
return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64;
1843
}
1844
static int getArch() { return REGISTERS_ARM64; }
1845
1846
uint64_t getSP() const { return _registers.__sp; }
1847
void setSP(uint64_t value) { _registers.__sp = value; }
1848
uint64_t getIP() const { return _registers.__pc; }
1849
void setIP(uint64_t value) { _registers.__pc = value; }
1850
uint64_t getFP() const { return _registers.__fp; }
1851
void setFP(uint64_t value) { _registers.__fp = value; }
1852
1853
private:
1854
struct GPRs {
1855
uint64_t __x[29]; // x0-x28
1856
uint64_t __fp; // Frame pointer x29
1857
uint64_t __lr; // Link register x30
1858
uint64_t __sp; // Stack pointer x31
1859
uint64_t __pc; // Program counter
1860
uint64_t __ra_sign_state; // RA sign state register
1861
};
1862
1863
GPRs _registers;
1864
double _vectorHalfRegisters[32];
1865
// Currently only the lower double in 128-bit vectore registers
1866
// is perserved during unwinding. We could define new register
1867
// numbers (> 96) which mean whole vector registers, then this
1868
// struct would need to change to contain whole vector registers.
1869
};
1870
1871
inline Registers_arm64::Registers_arm64(const void *registers) {
1872
static_assert((check_fit<Registers_arm64, unw_context_t>::does_fit),
1873
"arm64 registers do not fit into unw_context_t");
1874
memcpy(&_registers, registers, sizeof(_registers));
1875
static_assert(sizeof(GPRs) == 0x110,
1876
"expected VFP registers to be at offset 272");
1877
memcpy(_vectorHalfRegisters,
1878
static_cast<const uint8_t *>(registers) + sizeof(GPRs),
1879
sizeof(_vectorHalfRegisters));
1880
}
1881
1882
inline Registers_arm64::Registers_arm64() {
1883
memset(&_registers, 0, sizeof(_registers));
1884
memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
1885
}
1886
1887
inline bool Registers_arm64::validRegister(int regNum) const {
1888
if (regNum == UNW_REG_IP)
1889
return true;
1890
if (regNum == UNW_REG_SP)
1891
return true;
1892
if (regNum < 0)
1893
return false;
1894
if (regNum > 95)
1895
return false;
1896
if (regNum == UNW_AARCH64_RA_SIGN_STATE)
1897
return true;
1898
if ((regNum > 32) && (regNum < 64))
1899
return false;
1900
return true;
1901
}
1902
1903
inline uint64_t Registers_arm64::getRegister(int regNum) const {
1904
if (regNum == UNW_REG_IP || regNum == UNW_AARCH64_PC)
1905
return _registers.__pc;
1906
if (regNum == UNW_REG_SP || regNum == UNW_AARCH64_SP)
1907
return _registers.__sp;
1908
if (regNum == UNW_AARCH64_RA_SIGN_STATE)
1909
return _registers.__ra_sign_state;
1910
if (regNum == UNW_AARCH64_FP)
1911
return _registers.__fp;
1912
if (regNum == UNW_AARCH64_LR)
1913
return _registers.__lr;
1914
if ((regNum >= 0) && (regNum < 29))
1915
return _registers.__x[regNum];
1916
_LIBUNWIND_ABORT("unsupported arm64 register");
1917
}
1918
1919
inline void Registers_arm64::setRegister(int regNum, uint64_t value) {
1920
if (regNum == UNW_REG_IP || regNum == UNW_AARCH64_PC)
1921
_registers.__pc = value;
1922
else if (regNum == UNW_REG_SP || regNum == UNW_AARCH64_SP)
1923
_registers.__sp = value;
1924
else if (regNum == UNW_AARCH64_RA_SIGN_STATE)
1925
_registers.__ra_sign_state = value;
1926
else if (regNum == UNW_AARCH64_FP)
1927
_registers.__fp = value;
1928
else if (regNum == UNW_AARCH64_LR)
1929
_registers.__lr = value;
1930
else if ((regNum >= 0) && (regNum < 29))
1931
_registers.__x[regNum] = value;
1932
else
1933
_LIBUNWIND_ABORT("unsupported arm64 register");
1934
}
1935
1936
inline const char *Registers_arm64::getRegisterName(int regNum) {
1937
switch (regNum) {
1938
case UNW_REG_IP:
1939
return "pc";
1940
case UNW_REG_SP:
1941
return "sp";
1942
case UNW_AARCH64_X0:
1943
return "x0";
1944
case UNW_AARCH64_X1:
1945
return "x1";
1946
case UNW_AARCH64_X2:
1947
return "x2";
1948
case UNW_AARCH64_X3:
1949
return "x3";
1950
case UNW_AARCH64_X4:
1951
return "x4";
1952
case UNW_AARCH64_X5:
1953
return "x5";
1954
case UNW_AARCH64_X6:
1955
return "x6";
1956
case UNW_AARCH64_X7:
1957
return "x7";
1958
case UNW_AARCH64_X8:
1959
return "x8";
1960
case UNW_AARCH64_X9:
1961
return "x9";
1962
case UNW_AARCH64_X10:
1963
return "x10";
1964
case UNW_AARCH64_X11:
1965
return "x11";
1966
case UNW_AARCH64_X12:
1967
return "x12";
1968
case UNW_AARCH64_X13:
1969
return "x13";
1970
case UNW_AARCH64_X14:
1971
return "x14";
1972
case UNW_AARCH64_X15:
1973
return "x15";
1974
case UNW_AARCH64_X16:
1975
return "x16";
1976
case UNW_AARCH64_X17:
1977
return "x17";
1978
case UNW_AARCH64_X18:
1979
return "x18";
1980
case UNW_AARCH64_X19:
1981
return "x19";
1982
case UNW_AARCH64_X20:
1983
return "x20";
1984
case UNW_AARCH64_X21:
1985
return "x21";
1986
case UNW_AARCH64_X22:
1987
return "x22";
1988
case UNW_AARCH64_X23:
1989
return "x23";
1990
case UNW_AARCH64_X24:
1991
return "x24";
1992
case UNW_AARCH64_X25:
1993
return "x25";
1994
case UNW_AARCH64_X26:
1995
return "x26";
1996
case UNW_AARCH64_X27:
1997
return "x27";
1998
case UNW_AARCH64_X28:
1999
return "x28";
2000
case UNW_AARCH64_FP:
2001
return "fp";
2002
case UNW_AARCH64_LR:
2003
return "lr";
2004
case UNW_AARCH64_SP:
2005
return "sp";
2006
case UNW_AARCH64_PC:
2007
return "pc";
2008
case UNW_AARCH64_V0:
2009
return "d0";
2010
case UNW_AARCH64_V1:
2011
return "d1";
2012
case UNW_AARCH64_V2:
2013
return "d2";
2014
case UNW_AARCH64_V3:
2015
return "d3";
2016
case UNW_AARCH64_V4:
2017
return "d4";
2018
case UNW_AARCH64_V5:
2019
return "d5";
2020
case UNW_AARCH64_V6:
2021
return "d6";
2022
case UNW_AARCH64_V7:
2023
return "d7";
2024
case UNW_AARCH64_V8:
2025
return "d8";
2026
case UNW_AARCH64_V9:
2027
return "d9";
2028
case UNW_AARCH64_V10:
2029
return "d10";
2030
case UNW_AARCH64_V11:
2031
return "d11";
2032
case UNW_AARCH64_V12:
2033
return "d12";
2034
case UNW_AARCH64_V13:
2035
return "d13";
2036
case UNW_AARCH64_V14:
2037
return "d14";
2038
case UNW_AARCH64_V15:
2039
return "d15";
2040
case UNW_AARCH64_V16:
2041
return "d16";
2042
case UNW_AARCH64_V17:
2043
return "d17";
2044
case UNW_AARCH64_V18:
2045
return "d18";
2046
case UNW_AARCH64_V19:
2047
return "d19";
2048
case UNW_AARCH64_V20:
2049
return "d20";
2050
case UNW_AARCH64_V21:
2051
return "d21";
2052
case UNW_AARCH64_V22:
2053
return "d22";
2054
case UNW_AARCH64_V23:
2055
return "d23";
2056
case UNW_AARCH64_V24:
2057
return "d24";
2058
case UNW_AARCH64_V25:
2059
return "d25";
2060
case UNW_AARCH64_V26:
2061
return "d26";
2062
case UNW_AARCH64_V27:
2063
return "d27";
2064
case UNW_AARCH64_V28:
2065
return "d28";
2066
case UNW_AARCH64_V29:
2067
return "d29";
2068
case UNW_AARCH64_V30:
2069
return "d30";
2070
case UNW_AARCH64_V31:
2071
return "d31";
2072
default:
2073
return "unknown register";
2074
}
2075
}
2076
2077
inline bool Registers_arm64::validFloatRegister(int regNum) const {
2078
if (regNum < UNW_AARCH64_V0)
2079
return false;
2080
if (regNum > UNW_AARCH64_V31)
2081
return false;
2082
return true;
2083
}
2084
2085
inline double Registers_arm64::getFloatRegister(int regNum) const {
2086
assert(validFloatRegister(regNum));
2087
return _vectorHalfRegisters[regNum - UNW_AARCH64_V0];
2088
}
2089
2090
inline void Registers_arm64::setFloatRegister(int regNum, double value) {
2091
assert(validFloatRegister(regNum));
2092
_vectorHalfRegisters[regNum - UNW_AARCH64_V0] = value;
2093
}
2094
2095
inline bool Registers_arm64::validVectorRegister(int) const {
2096
return false;
2097
}
2098
2099
inline v128 Registers_arm64::getVectorRegister(int) const {
2100
_LIBUNWIND_ABORT("no arm64 vector register support yet");
2101
}
2102
2103
inline void Registers_arm64::setVectorRegister(int, v128) {
2104
_LIBUNWIND_ABORT("no arm64 vector register support yet");
2105
}
2106
#endif // _LIBUNWIND_TARGET_AARCH64
2107
2108
#if defined(_LIBUNWIND_TARGET_ARM)
2109
/// Registers_arm holds the register state of a thread in a 32-bit arm
2110
/// process.
2111
///
2112
/// NOTE: Assumes VFPv3. On ARM processors without a floating point unit,
2113
/// this uses more memory than required.
2114
class _LIBUNWIND_HIDDEN Registers_arm {
2115
public:
2116
Registers_arm();
2117
Registers_arm(const void *registers);
2118
2119
bool validRegister(int num) const;
2120
uint32_t getRegister(int num) const;
2121
void setRegister(int num, uint32_t value);
2122
bool validFloatRegister(int num) const;
2123
unw_fpreg_t getFloatRegister(int num);
2124
void setFloatRegister(int num, unw_fpreg_t value);
2125
bool validVectorRegister(int num) const;
2126
v128 getVectorRegister(int num) const;
2127
void setVectorRegister(int num, v128 value);
2128
static const char *getRegisterName(int num);
2129
void jumpto() {
2130
restoreSavedFloatRegisters();
2131
restoreCoreAndJumpTo();
2132
}
2133
static constexpr int lastDwarfRegNum() {
2134
return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM;
2135
}
2136
static int getArch() { return REGISTERS_ARM; }
2137
2138
uint32_t getSP() const { return _registers.__sp; }
2139
void setSP(uint32_t value) { _registers.__sp = value; }
2140
uint32_t getIP() const { return _registers.__pc; }
2141
void setIP(uint32_t value) { _registers.__pc = value; }
2142
2143
void saveVFPAsX() {
2144
assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15);
2145
_use_X_for_vfp_save = true;
2146
}
2147
2148
void restoreSavedFloatRegisters() {
2149
if (_saved_vfp_d0_d15) {
2150
if (_use_X_for_vfp_save)
2151
restoreVFPWithFLDMX(_vfp_d0_d15_pad);
2152
else
2153
restoreVFPWithFLDMD(_vfp_d0_d15_pad);
2154
}
2155
if (_saved_vfp_d16_d31)
2156
restoreVFPv3(_vfp_d16_d31);
2157
#if defined(__ARM_WMMX)
2158
if (_saved_iwmmx)
2159
restoreiWMMX(_iwmmx);
2160
if (_saved_iwmmx_control)
2161
restoreiWMMXControl(_iwmmx_control);
2162
#endif
2163
}
2164
2165
private:
2166
struct GPRs {
2167
uint32_t __r[13]; // r0-r12
2168
uint32_t __sp; // Stack pointer r13
2169
uint32_t __lr; // Link register r14
2170
uint32_t __pc; // Program counter r15
2171
};
2172
2173
struct PseudoRegisters {
2174
uint32_t __pac; // Return Authentication Code (PAC)
2175
};
2176
2177
static void saveVFPWithFSTMD(void*);
2178
static void saveVFPWithFSTMX(void*);
2179
static void saveVFPv3(void*);
2180
static void restoreVFPWithFLDMD(void*);
2181
static void restoreVFPWithFLDMX(void*);
2182
static void restoreVFPv3(void*);
2183
#if defined(__ARM_WMMX)
2184
static void saveiWMMX(void*);
2185
static void saveiWMMXControl(uint32_t*);
2186
static void restoreiWMMX(void*);
2187
static void restoreiWMMXControl(uint32_t*);
2188
#endif
2189
void restoreCoreAndJumpTo();
2190
2191
// ARM registers
2192
GPRs _registers;
2193
PseudoRegisters _pseudo_registers;
2194
2195
// We save floating point registers lazily because we can't know ahead of
2196
// time which ones are used. See EHABI #4.7.
2197
2198
// Whether D0-D15 are saved in the FTSMX instead of FSTMD format.
2199
//
2200
// See EHABI #7.5 that explains how matching instruction sequences for load
2201
// and store need to be used to correctly restore the exact register bits.
2202
bool _use_X_for_vfp_save;
2203
// Whether VFP D0-D15 are saved.
2204
bool _saved_vfp_d0_d15;
2205
// Whether VFPv3 D16-D31 are saved.
2206
bool _saved_vfp_d16_d31;
2207
// VFP registers D0-D15, + padding if saved using FSTMX
2208
unw_fpreg_t _vfp_d0_d15_pad[17];
2209
// VFPv3 registers D16-D31, always saved using FSTMD
2210
unw_fpreg_t _vfp_d16_d31[16];
2211
#if defined(__ARM_WMMX)
2212
// Whether iWMMX data registers are saved.
2213
bool _saved_iwmmx;
2214
// Whether iWMMX control registers are saved.
2215
mutable bool _saved_iwmmx_control;
2216
// iWMMX registers
2217
unw_fpreg_t _iwmmx[16];
2218
// iWMMX control registers
2219
mutable uint32_t _iwmmx_control[4];
2220
#endif
2221
};
2222
2223
inline Registers_arm::Registers_arm(const void *registers)
2224
: _use_X_for_vfp_save(false),
2225
_saved_vfp_d0_d15(false),
2226
_saved_vfp_d16_d31(false) {
2227
static_assert((check_fit<Registers_arm, unw_context_t>::does_fit),
2228
"arm registers do not fit into unw_context_t");
2229
// See __unw_getcontext() note about data.
2230
memcpy(&_registers, registers, sizeof(_registers));
2231
memset(&_pseudo_registers, 0, sizeof(_pseudo_registers));
2232
memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
2233
memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
2234
#if defined(__ARM_WMMX)
2235
_saved_iwmmx = false;
2236
_saved_iwmmx_control = false;
2237
memset(&_iwmmx, 0, sizeof(_iwmmx));
2238
memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
2239
#endif
2240
}
2241
2242
inline Registers_arm::Registers_arm()
2243
: _use_X_for_vfp_save(false),
2244
_saved_vfp_d0_d15(false),
2245
_saved_vfp_d16_d31(false) {
2246
memset(&_registers, 0, sizeof(_registers));
2247
memset(&_pseudo_registers, 0, sizeof(_pseudo_registers));
2248
memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
2249
memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
2250
#if defined(__ARM_WMMX)
2251
_saved_iwmmx = false;
2252
_saved_iwmmx_control = false;
2253
memset(&_iwmmx, 0, sizeof(_iwmmx));
2254
memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
2255
#endif
2256
}
2257
2258
inline bool Registers_arm::validRegister(int regNum) const {
2259
// Returns true for all non-VFP registers supported by the EHABI
2260
// virtual register set (VRS).
2261
if (regNum == UNW_REG_IP)
2262
return true;
2263
2264
if (regNum == UNW_REG_SP)
2265
return true;
2266
2267
if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15)
2268
return true;
2269
2270
#if defined(__ARM_WMMX)
2271
if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3)
2272
return true;
2273
#endif
2274
2275
#ifdef __ARM_FEATURE_PAUTH
2276
if (regNum == UNW_ARM_RA_AUTH_CODE)
2277
return true;
2278
#endif
2279
2280
return false;
2281
}
2282
2283
inline uint32_t Registers_arm::getRegister(int regNum) const {
2284
if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
2285
return _registers.__sp;
2286
2287
if (regNum == UNW_ARM_LR)
2288
return _registers.__lr;
2289
2290
if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
2291
return _registers.__pc;
2292
2293
if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
2294
return _registers.__r[regNum];
2295
2296
#if defined(__ARM_WMMX)
2297
if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
2298
if (!_saved_iwmmx_control) {
2299
_saved_iwmmx_control = true;
2300
saveiWMMXControl(_iwmmx_control);
2301
}
2302
return _iwmmx_control[regNum - UNW_ARM_WC0];
2303
}
2304
#endif
2305
2306
#ifdef __ARM_FEATURE_PAUTH
2307
if (regNum == UNW_ARM_RA_AUTH_CODE)
2308
return _pseudo_registers.__pac;
2309
#endif
2310
2311
_LIBUNWIND_ABORT("unsupported arm register");
2312
}
2313
2314
inline void Registers_arm::setRegister(int regNum, uint32_t value) {
2315
if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) {
2316
_registers.__sp = value;
2317
return;
2318
}
2319
2320
if (regNum == UNW_ARM_LR) {
2321
_registers.__lr = value;
2322
return;
2323
}
2324
2325
if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) {
2326
_registers.__pc = value;
2327
return;
2328
}
2329
2330
if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) {
2331
_registers.__r[regNum] = value;
2332
return;
2333
}
2334
2335
#if defined(__ARM_WMMX)
2336
if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
2337
if (!_saved_iwmmx_control) {
2338
_saved_iwmmx_control = true;
2339
saveiWMMXControl(_iwmmx_control);
2340
}
2341
_iwmmx_control[regNum - UNW_ARM_WC0] = value;
2342
return;
2343
}
2344
#endif
2345
2346
if (regNum == UNW_ARM_RA_AUTH_CODE) {
2347
_pseudo_registers.__pac = value;
2348
return;
2349
}
2350
2351
_LIBUNWIND_ABORT("unsupported arm register");
2352
}
2353
2354
inline const char *Registers_arm::getRegisterName(int regNum) {
2355
switch (regNum) {
2356
case UNW_REG_IP:
2357
case UNW_ARM_IP: // UNW_ARM_R15 is alias
2358
return "pc";
2359
case UNW_ARM_LR: // UNW_ARM_R14 is alias
2360
return "lr";
2361
case UNW_REG_SP:
2362
case UNW_ARM_SP: // UNW_ARM_R13 is alias
2363
return "sp";
2364
case UNW_ARM_R0:
2365
return "r0";
2366
case UNW_ARM_R1:
2367
return "r1";
2368
case UNW_ARM_R2:
2369
return "r2";
2370
case UNW_ARM_R3:
2371
return "r3";
2372
case UNW_ARM_R4:
2373
return "r4";
2374
case UNW_ARM_R5:
2375
return "r5";
2376
case UNW_ARM_R6:
2377
return "r6";
2378
case UNW_ARM_R7:
2379
return "r7";
2380
case UNW_ARM_R8:
2381
return "r8";
2382
case UNW_ARM_R9:
2383
return "r9";
2384
case UNW_ARM_R10:
2385
return "r10";
2386
case UNW_ARM_R11:
2387
return "r11";
2388
case UNW_ARM_R12:
2389
return "r12";
2390
case UNW_ARM_S0:
2391
return "s0";
2392
case UNW_ARM_S1:
2393
return "s1";
2394
case UNW_ARM_S2:
2395
return "s2";
2396
case UNW_ARM_S3:
2397
return "s3";
2398
case UNW_ARM_S4:
2399
return "s4";
2400
case UNW_ARM_S5:
2401
return "s5";
2402
case UNW_ARM_S6:
2403
return "s6";
2404
case UNW_ARM_S7:
2405
return "s7";
2406
case UNW_ARM_S8:
2407
return "s8";
2408
case UNW_ARM_S9:
2409
return "s9";
2410
case UNW_ARM_S10:
2411
return "s10";
2412
case UNW_ARM_S11:
2413
return "s11";
2414
case UNW_ARM_S12:
2415
return "s12";
2416
case UNW_ARM_S13:
2417
return "s13";
2418
case UNW_ARM_S14:
2419
return "s14";
2420
case UNW_ARM_S15:
2421
return "s15";
2422
case UNW_ARM_S16:
2423
return "s16";
2424
case UNW_ARM_S17:
2425
return "s17";
2426
case UNW_ARM_S18:
2427
return "s18";
2428
case UNW_ARM_S19:
2429
return "s19";
2430
case UNW_ARM_S20:
2431
return "s20";
2432
case UNW_ARM_S21:
2433
return "s21";
2434
case UNW_ARM_S22:
2435
return "s22";
2436
case UNW_ARM_S23:
2437
return "s23";
2438
case UNW_ARM_S24:
2439
return "s24";
2440
case UNW_ARM_S25:
2441
return "s25";
2442
case UNW_ARM_S26:
2443
return "s26";
2444
case UNW_ARM_S27:
2445
return "s27";
2446
case UNW_ARM_S28:
2447
return "s28";
2448
case UNW_ARM_S29:
2449
return "s29";
2450
case UNW_ARM_S30:
2451
return "s30";
2452
case UNW_ARM_S31:
2453
return "s31";
2454
case UNW_ARM_D0:
2455
return "d0";
2456
case UNW_ARM_D1:
2457
return "d1";
2458
case UNW_ARM_D2:
2459
return "d2";
2460
case UNW_ARM_D3:
2461
return "d3";
2462
case UNW_ARM_D4:
2463
return "d4";
2464
case UNW_ARM_D5:
2465
return "d5";
2466
case UNW_ARM_D6:
2467
return "d6";
2468
case UNW_ARM_D7:
2469
return "d7";
2470
case UNW_ARM_D8:
2471
return "d8";
2472
case UNW_ARM_D9:
2473
return "d9";
2474
case UNW_ARM_D10:
2475
return "d10";
2476
case UNW_ARM_D11:
2477
return "d11";
2478
case UNW_ARM_D12:
2479
return "d12";
2480
case UNW_ARM_D13:
2481
return "d13";
2482
case UNW_ARM_D14:
2483
return "d14";
2484
case UNW_ARM_D15:
2485
return "d15";
2486
case UNW_ARM_D16:
2487
return "d16";
2488
case UNW_ARM_D17:
2489
return "d17";
2490
case UNW_ARM_D18:
2491
return "d18";
2492
case UNW_ARM_D19:
2493
return "d19";
2494
case UNW_ARM_D20:
2495
return "d20";
2496
case UNW_ARM_D21:
2497
return "d21";
2498
case UNW_ARM_D22:
2499
return "d22";
2500
case UNW_ARM_D23:
2501
return "d23";
2502
case UNW_ARM_D24:
2503
return "d24";
2504
case UNW_ARM_D25:
2505
return "d25";
2506
case UNW_ARM_D26:
2507
return "d26";
2508
case UNW_ARM_D27:
2509
return "d27";
2510
case UNW_ARM_D28:
2511
return "d28";
2512
case UNW_ARM_D29:
2513
return "d29";
2514
case UNW_ARM_D30:
2515
return "d30";
2516
case UNW_ARM_D31:
2517
return "d31";
2518
default:
2519
return "unknown register";
2520
}
2521
}
2522
2523
inline bool Registers_arm::validFloatRegister(int regNum) const {
2524
// NOTE: Consider the intel MMX registers floating points so the
2525
// __unw_get_fpreg can be used to transmit the 64-bit data back.
2526
return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31))
2527
#if defined(__ARM_WMMX)
2528
|| ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15))
2529
#endif
2530
;
2531
}
2532
2533
inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) {
2534
if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
2535
if (!_saved_vfp_d0_d15) {
2536
_saved_vfp_d0_d15 = true;
2537
if (_use_X_for_vfp_save)
2538
saveVFPWithFSTMX(_vfp_d0_d15_pad);
2539
else
2540
saveVFPWithFSTMD(_vfp_d0_d15_pad);
2541
}
2542
return _vfp_d0_d15_pad[regNum - UNW_ARM_D0];
2543
}
2544
2545
if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
2546
if (!_saved_vfp_d16_d31) {
2547
_saved_vfp_d16_d31 = true;
2548
saveVFPv3(_vfp_d16_d31);
2549
}
2550
return _vfp_d16_d31[regNum - UNW_ARM_D16];
2551
}
2552
2553
#if defined(__ARM_WMMX)
2554
if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
2555
if (!_saved_iwmmx) {
2556
_saved_iwmmx = true;
2557
saveiWMMX(_iwmmx);
2558
}
2559
return _iwmmx[regNum - UNW_ARM_WR0];
2560
}
2561
#endif
2562
2563
_LIBUNWIND_ABORT("Unknown ARM float register");
2564
}
2565
2566
inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) {
2567
if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
2568
if (!_saved_vfp_d0_d15) {
2569
_saved_vfp_d0_d15 = true;
2570
if (_use_X_for_vfp_save)
2571
saveVFPWithFSTMX(_vfp_d0_d15_pad);
2572
else
2573
saveVFPWithFSTMD(_vfp_d0_d15_pad);
2574
}
2575
_vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value;
2576
return;
2577
}
2578
2579
if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
2580
if (!_saved_vfp_d16_d31) {
2581
_saved_vfp_d16_d31 = true;
2582
saveVFPv3(_vfp_d16_d31);
2583
}
2584
_vfp_d16_d31[regNum - UNW_ARM_D16] = value;
2585
return;
2586
}
2587
2588
#if defined(__ARM_WMMX)
2589
if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
2590
if (!_saved_iwmmx) {
2591
_saved_iwmmx = true;
2592
saveiWMMX(_iwmmx);
2593
}
2594
_iwmmx[regNum - UNW_ARM_WR0] = value;
2595
return;
2596
}
2597
#endif
2598
2599
_LIBUNWIND_ABORT("Unknown ARM float register");
2600
}
2601
2602
inline bool Registers_arm::validVectorRegister(int) const {
2603
return false;
2604
}
2605
2606
inline v128 Registers_arm::getVectorRegister(int) const {
2607
_LIBUNWIND_ABORT("ARM vector support not implemented");
2608
}
2609
2610
inline void Registers_arm::setVectorRegister(int, v128) {
2611
_LIBUNWIND_ABORT("ARM vector support not implemented");
2612
}
2613
#endif // _LIBUNWIND_TARGET_ARM
2614
2615
2616
#if defined(_LIBUNWIND_TARGET_OR1K)
2617
/// Registers_or1k holds the register state of a thread in an OpenRISC1000
2618
/// process.
2619
class _LIBUNWIND_HIDDEN Registers_or1k {
2620
public:
2621
Registers_or1k();
2622
Registers_or1k(const void *registers);
2623
2624
bool validRegister(int num) const;
2625
uint32_t getRegister(int num) const;
2626
void setRegister(int num, uint32_t value);
2627
bool validFloatRegister(int num) const;
2628
double getFloatRegister(int num) const;
2629
void setFloatRegister(int num, double value);
2630
bool validVectorRegister(int num) const;
2631
v128 getVectorRegister(int num) const;
2632
void setVectorRegister(int num, v128 value);
2633
static const char *getRegisterName(int num);
2634
void jumpto();
2635
static constexpr int lastDwarfRegNum() {
2636
return _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K;
2637
}
2638
static int getArch() { return REGISTERS_OR1K; }
2639
2640
uint64_t getSP() const { return _registers.__r[1]; }
2641
void setSP(uint32_t value) { _registers.__r[1] = value; }
2642
uint64_t getIP() const { return _registers.__pc; }
2643
void setIP(uint32_t value) { _registers.__pc = value; }
2644
2645
private:
2646
struct or1k_thread_state_t {
2647
unsigned int __r[32]; // r0-r31
2648
unsigned int __pc; // Program counter
2649
unsigned int __epcr; // Program counter at exception
2650
};
2651
2652
or1k_thread_state_t _registers;
2653
};
2654
2655
inline Registers_or1k::Registers_or1k(const void *registers) {
2656
static_assert((check_fit<Registers_or1k, unw_context_t>::does_fit),
2657
"or1k registers do not fit into unw_context_t");
2658
memcpy(&_registers, static_cast<const uint8_t *>(registers),
2659
sizeof(_registers));
2660
}
2661
2662
inline Registers_or1k::Registers_or1k() {
2663
memset(&_registers, 0, sizeof(_registers));
2664
}
2665
2666
inline bool Registers_or1k::validRegister(int regNum) const {
2667
if (regNum == UNW_REG_IP)
2668
return true;
2669
if (regNum == UNW_REG_SP)
2670
return true;
2671
if (regNum < 0)
2672
return false;
2673
if (regNum <= UNW_OR1K_R31)
2674
return true;
2675
if (regNum == UNW_OR1K_EPCR)
2676
return true;
2677
return false;
2678
}
2679
2680
inline uint32_t Registers_or1k::getRegister(int regNum) const {
2681
if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31)
2682
return _registers.__r[regNum - UNW_OR1K_R0];
2683
2684
switch (regNum) {
2685
case UNW_REG_IP:
2686
return _registers.__pc;
2687
case UNW_REG_SP:
2688
return _registers.__r[1];
2689
case UNW_OR1K_EPCR:
2690
return _registers.__epcr;
2691
}
2692
_LIBUNWIND_ABORT("unsupported or1k register");
2693
}
2694
2695
inline void Registers_or1k::setRegister(int regNum, uint32_t value) {
2696
if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) {
2697
_registers.__r[regNum - UNW_OR1K_R0] = value;
2698
return;
2699
}
2700
2701
switch (regNum) {
2702
case UNW_REG_IP:
2703
_registers.__pc = value;
2704
return;
2705
case UNW_REG_SP:
2706
_registers.__r[1] = value;
2707
return;
2708
case UNW_OR1K_EPCR:
2709
_registers.__epcr = value;
2710
return;
2711
}
2712
_LIBUNWIND_ABORT("unsupported or1k register");
2713
}
2714
2715
inline bool Registers_or1k::validFloatRegister(int /* regNum */) const {
2716
return false;
2717
}
2718
2719
inline double Registers_or1k::getFloatRegister(int /* regNum */) const {
2720
_LIBUNWIND_ABORT("or1k float support not implemented");
2721
}
2722
2723
inline void Registers_or1k::setFloatRegister(int /* regNum */,
2724
double /* value */) {
2725
_LIBUNWIND_ABORT("or1k float support not implemented");
2726
}
2727
2728
inline bool Registers_or1k::validVectorRegister(int /* regNum */) const {
2729
return false;
2730
}
2731
2732
inline v128 Registers_or1k::getVectorRegister(int /* regNum */) const {
2733
_LIBUNWIND_ABORT("or1k vector support not implemented");
2734
}
2735
2736
inline void Registers_or1k::setVectorRegister(int /* regNum */, v128 /* value */) {
2737
_LIBUNWIND_ABORT("or1k vector support not implemented");
2738
}
2739
2740
inline const char *Registers_or1k::getRegisterName(int regNum) {
2741
switch (regNum) {
2742
case UNW_OR1K_R0:
2743
return "r0";
2744
case UNW_OR1K_R1:
2745
return "r1";
2746
case UNW_OR1K_R2:
2747
return "r2";
2748
case UNW_OR1K_R3:
2749
return "r3";
2750
case UNW_OR1K_R4:
2751
return "r4";
2752
case UNW_OR1K_R5:
2753
return "r5";
2754
case UNW_OR1K_R6:
2755
return "r6";
2756
case UNW_OR1K_R7:
2757
return "r7";
2758
case UNW_OR1K_R8:
2759
return "r8";
2760
case UNW_OR1K_R9:
2761
return "r9";
2762
case UNW_OR1K_R10:
2763
return "r10";
2764
case UNW_OR1K_R11:
2765
return "r11";
2766
case UNW_OR1K_R12:
2767
return "r12";
2768
case UNW_OR1K_R13:
2769
return "r13";
2770
case UNW_OR1K_R14:
2771
return "r14";
2772
case UNW_OR1K_R15:
2773
return "r15";
2774
case UNW_OR1K_R16:
2775
return "r16";
2776
case UNW_OR1K_R17:
2777
return "r17";
2778
case UNW_OR1K_R18:
2779
return "r18";
2780
case UNW_OR1K_R19:
2781
return "r19";
2782
case UNW_OR1K_R20:
2783
return "r20";
2784
case UNW_OR1K_R21:
2785
return "r21";
2786
case UNW_OR1K_R22:
2787
return "r22";
2788
case UNW_OR1K_R23:
2789
return "r23";
2790
case UNW_OR1K_R24:
2791
return "r24";
2792
case UNW_OR1K_R25:
2793
return "r25";
2794
case UNW_OR1K_R26:
2795
return "r26";
2796
case UNW_OR1K_R27:
2797
return "r27";
2798
case UNW_OR1K_R28:
2799
return "r28";
2800
case UNW_OR1K_R29:
2801
return "r29";
2802
case UNW_OR1K_R30:
2803
return "r30";
2804
case UNW_OR1K_R31:
2805
return "r31";
2806
case UNW_OR1K_EPCR:
2807
return "EPCR";
2808
default:
2809
return "unknown register";
2810
}
2811
2812
}
2813
#endif // _LIBUNWIND_TARGET_OR1K
2814
2815
#if defined(_LIBUNWIND_TARGET_MIPS_O32)
2816
/// Registers_mips_o32 holds the register state of a thread in a 32-bit MIPS
2817
/// process.
2818
class _LIBUNWIND_HIDDEN Registers_mips_o32 {
2819
public:
2820
Registers_mips_o32();
2821
Registers_mips_o32(const void *registers);
2822
2823
bool validRegister(int num) const;
2824
uint32_t getRegister(int num) const;
2825
void setRegister(int num, uint32_t value);
2826
bool validFloatRegister(int num) const;
2827
double getFloatRegister(int num) const;
2828
void setFloatRegister(int num, double value);
2829
bool validVectorRegister(int num) const;
2830
v128 getVectorRegister(int num) const;
2831
void setVectorRegister(int num, v128 value);
2832
static const char *getRegisterName(int num);
2833
void jumpto();
2834
static constexpr int lastDwarfRegNum() {
2835
return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS;
2836
}
2837
static int getArch() { return REGISTERS_MIPS_O32; }
2838
2839
uint32_t getSP() const { return _registers.__r[29]; }
2840
void setSP(uint32_t value) { _registers.__r[29] = value; }
2841
uint32_t getIP() const { return _registers.__pc; }
2842
void setIP(uint32_t value) { _registers.__pc = value; }
2843
2844
private:
2845
struct mips_o32_thread_state_t {
2846
uint32_t __r[32];
2847
uint32_t __pc;
2848
uint32_t __hi;
2849
uint32_t __lo;
2850
};
2851
2852
mips_o32_thread_state_t _registers;
2853
#ifdef __mips_hard_float
2854
/// O32 with 32-bit floating point registers only uses half of this
2855
/// space. However, using the same layout for 32-bit vs 64-bit
2856
/// floating point registers results in a single context size for
2857
/// O32 with hard float.
2858
uint32_t _padding;
2859
double _floats[32];
2860
#endif
2861
};
2862
2863
inline Registers_mips_o32::Registers_mips_o32(const void *registers) {
2864
static_assert((check_fit<Registers_mips_o32, unw_context_t>::does_fit),
2865
"mips_o32 registers do not fit into unw_context_t");
2866
memcpy(&_registers, static_cast<const uint8_t *>(registers),
2867
sizeof(_registers));
2868
}
2869
2870
inline Registers_mips_o32::Registers_mips_o32() {
2871
memset(&_registers, 0, sizeof(_registers));
2872
}
2873
2874
inline bool Registers_mips_o32::validRegister(int regNum) const {
2875
if (regNum == UNW_REG_IP)
2876
return true;
2877
if (regNum == UNW_REG_SP)
2878
return true;
2879
if (regNum < 0)
2880
return false;
2881
if (regNum <= UNW_MIPS_R31)
2882
return true;
2883
#if __mips_isa_rev < 6
2884
if (regNum == UNW_MIPS_HI)
2885
return true;
2886
if (regNum == UNW_MIPS_LO)
2887
return true;
2888
#endif
2889
#if defined(__mips_hard_float) && __mips_fpr == 32
2890
if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
2891
return true;
2892
#endif
2893
// FIXME: DSP accumulator registers, MSA registers
2894
return false;
2895
}
2896
2897
inline uint32_t Registers_mips_o32::getRegister(int regNum) const {
2898
if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
2899
return _registers.__r[regNum - UNW_MIPS_R0];
2900
#if defined(__mips_hard_float) && __mips_fpr == 32
2901
if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
2902
uint32_t *p;
2903
2904
if (regNum % 2 == 0)
2905
p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
2906
else
2907
p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
2908
return *p;
2909
}
2910
#endif
2911
2912
switch (regNum) {
2913
case UNW_REG_IP:
2914
return _registers.__pc;
2915
case UNW_REG_SP:
2916
return _registers.__r[29];
2917
#if __mips_isa_rev < 6
2918
case UNW_MIPS_HI:
2919
return _registers.__hi;
2920
case UNW_MIPS_LO:
2921
return _registers.__lo;
2922
#endif
2923
}
2924
_LIBUNWIND_ABORT("unsupported mips_o32 register");
2925
}
2926
2927
inline void Registers_mips_o32::setRegister(int regNum, uint32_t value) {
2928
if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
2929
_registers.__r[regNum - UNW_MIPS_R0] = value;
2930
return;
2931
}
2932
#if defined(__mips_hard_float) && __mips_fpr == 32
2933
if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
2934
uint32_t *p;
2935
2936
if (regNum % 2 == 0)
2937
p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
2938
else
2939
p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
2940
*p = value;
2941
return;
2942
}
2943
#endif
2944
2945
switch (regNum) {
2946
case UNW_REG_IP:
2947
_registers.__pc = value;
2948
return;
2949
case UNW_REG_SP:
2950
_registers.__r[29] = value;
2951
return;
2952
#if __mips_isa_rev < 6
2953
case UNW_MIPS_HI:
2954
_registers.__hi = value;
2955
return;
2956
case UNW_MIPS_LO:
2957
_registers.__lo = value;
2958
#endif
2959
return;
2960
}
2961
_LIBUNWIND_ABORT("unsupported mips_o32 register");
2962
}
2963
2964
inline bool Registers_mips_o32::validFloatRegister(int regNum) const {
2965
#if defined(__mips_hard_float) && __mips_fpr == 64
2966
if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
2967
return true;
2968
#else
2969
(void)regNum;
2970
#endif
2971
return false;
2972
}
2973
2974
inline double Registers_mips_o32::getFloatRegister(int regNum) const {
2975
#if defined(__mips_hard_float) && __mips_fpr == 64
2976
assert(validFloatRegister(regNum));
2977
return _floats[regNum - UNW_MIPS_F0];
2978
#else
2979
(void)regNum;
2980
_LIBUNWIND_ABORT("mips_o32 float support not implemented");
2981
#endif
2982
}
2983
2984
inline void Registers_mips_o32::setFloatRegister(int regNum,
2985
double value) {
2986
#if defined(__mips_hard_float) && __mips_fpr == 64
2987
assert(validFloatRegister(regNum));
2988
_floats[regNum - UNW_MIPS_F0] = value;
2989
#else
2990
(void)regNum;
2991
(void)value;
2992
_LIBUNWIND_ABORT("mips_o32 float support not implemented");
2993
#endif
2994
}
2995
2996
inline bool Registers_mips_o32::validVectorRegister(int /* regNum */) const {
2997
return false;
2998
}
2999
3000
inline v128 Registers_mips_o32::getVectorRegister(int /* regNum */) const {
3001
_LIBUNWIND_ABORT("mips_o32 vector support not implemented");
3002
}
3003
3004
inline void Registers_mips_o32::setVectorRegister(int /* regNum */, v128 /* value */) {
3005
_LIBUNWIND_ABORT("mips_o32 vector support not implemented");
3006
}
3007
3008
inline const char *Registers_mips_o32::getRegisterName(int regNum) {
3009
switch (regNum) {
3010
case UNW_MIPS_R0:
3011
return "$0";
3012
case UNW_MIPS_R1:
3013
return "$1";
3014
case UNW_MIPS_R2:
3015
return "$2";
3016
case UNW_MIPS_R3:
3017
return "$3";
3018
case UNW_MIPS_R4:
3019
return "$4";
3020
case UNW_MIPS_R5:
3021
return "$5";
3022
case UNW_MIPS_R6:
3023
return "$6";
3024
case UNW_MIPS_R7:
3025
return "$7";
3026
case UNW_MIPS_R8:
3027
return "$8";
3028
case UNW_MIPS_R9:
3029
return "$9";
3030
case UNW_MIPS_R10:
3031
return "$10";
3032
case UNW_MIPS_R11:
3033
return "$11";
3034
case UNW_MIPS_R12:
3035
return "$12";
3036
case UNW_MIPS_R13:
3037
return "$13";
3038
case UNW_MIPS_R14:
3039
return "$14";
3040
case UNW_MIPS_R15:
3041
return "$15";
3042
case UNW_MIPS_R16:
3043
return "$16";
3044
case UNW_MIPS_R17:
3045
return "$17";
3046
case UNW_MIPS_R18:
3047
return "$18";
3048
case UNW_MIPS_R19:
3049
return "$19";
3050
case UNW_MIPS_R20:
3051
return "$20";
3052
case UNW_MIPS_R21:
3053
return "$21";
3054
case UNW_MIPS_R22:
3055
return "$22";
3056
case UNW_MIPS_R23:
3057
return "$23";
3058
case UNW_MIPS_R24:
3059
return "$24";
3060
case UNW_MIPS_R25:
3061
return "$25";
3062
case UNW_MIPS_R26:
3063
return "$26";
3064
case UNW_MIPS_R27:
3065
return "$27";
3066
case UNW_MIPS_R28:
3067
return "$28";
3068
case UNW_MIPS_R29:
3069
return "$29";
3070
case UNW_MIPS_R30:
3071
return "$30";
3072
case UNW_MIPS_R31:
3073
return "$31";
3074
case UNW_MIPS_F0:
3075
return "$f0";
3076
case UNW_MIPS_F1:
3077
return "$f1";
3078
case UNW_MIPS_F2:
3079
return "$f2";
3080
case UNW_MIPS_F3:
3081
return "$f3";
3082
case UNW_MIPS_F4:
3083
return "$f4";
3084
case UNW_MIPS_F5:
3085
return "$f5";
3086
case UNW_MIPS_F6:
3087
return "$f6";
3088
case UNW_MIPS_F7:
3089
return "$f7";
3090
case UNW_MIPS_F8:
3091
return "$f8";
3092
case UNW_MIPS_F9:
3093
return "$f9";
3094
case UNW_MIPS_F10:
3095
return "$f10";
3096
case UNW_MIPS_F11:
3097
return "$f11";
3098
case UNW_MIPS_F12:
3099
return "$f12";
3100
case UNW_MIPS_F13:
3101
return "$f13";
3102
case UNW_MIPS_F14:
3103
return "$f14";
3104
case UNW_MIPS_F15:
3105
return "$f15";
3106
case UNW_MIPS_F16:
3107
return "$f16";
3108
case UNW_MIPS_F17:
3109
return "$f17";
3110
case UNW_MIPS_F18:
3111
return "$f18";
3112
case UNW_MIPS_F19:
3113
return "$f19";
3114
case UNW_MIPS_F20:
3115
return "$f20";
3116
case UNW_MIPS_F21:
3117
return "$f21";
3118
case UNW_MIPS_F22:
3119
return "$f22";
3120
case UNW_MIPS_F23:
3121
return "$f23";
3122
case UNW_MIPS_F24:
3123
return "$f24";
3124
case UNW_MIPS_F25:
3125
return "$f25";
3126
case UNW_MIPS_F26:
3127
return "$f26";
3128
case UNW_MIPS_F27:
3129
return "$f27";
3130
case UNW_MIPS_F28:
3131
return "$f28";
3132
case UNW_MIPS_F29:
3133
return "$f29";
3134
case UNW_MIPS_F30:
3135
return "$f30";
3136
case UNW_MIPS_F31:
3137
return "$f31";
3138
#if __mips_isa_rev < 6
3139
case UNW_MIPS_HI:
3140
return "$hi";
3141
case UNW_MIPS_LO:
3142
return "$lo";
3143
#endif
3144
default:
3145
return "unknown register";
3146
}
3147
}
3148
#endif // _LIBUNWIND_TARGET_MIPS_O32
3149
3150
#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI)
3151
/// Registers_mips_newabi holds the register state of a thread in a
3152
/// MIPS process using NEWABI (the N32 or N64 ABIs).
3153
class _LIBUNWIND_HIDDEN Registers_mips_newabi {
3154
public:
3155
Registers_mips_newabi();
3156
Registers_mips_newabi(const void *registers);
3157
3158
bool validRegister(int num) const;
3159
uint64_t getRegister(int num) const;
3160
void setRegister(int num, uint64_t value);
3161
bool validFloatRegister(int num) const;
3162
double getFloatRegister(int num) const;
3163
void setFloatRegister(int num, double value);
3164
bool validVectorRegister(int num) const;
3165
v128 getVectorRegister(int num) const;
3166
void setVectorRegister(int num, v128 value);
3167
static const char *getRegisterName(int num);
3168
void jumpto();
3169
static constexpr int lastDwarfRegNum() {
3170
return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS;
3171
}
3172
static int getArch() { return REGISTERS_MIPS_NEWABI; }
3173
3174
uint64_t getSP() const { return _registers.__r[29]; }
3175
void setSP(uint64_t value) { _registers.__r[29] = value; }
3176
uint64_t getIP() const { return _registers.__pc; }
3177
void setIP(uint64_t value) { _registers.__pc = value; }
3178
3179
private:
3180
struct mips_newabi_thread_state_t {
3181
uint64_t __r[32];
3182
uint64_t __pc;
3183
uint64_t __hi;
3184
uint64_t __lo;
3185
};
3186
3187
mips_newabi_thread_state_t _registers;
3188
#ifdef __mips_hard_float
3189
double _floats[32];
3190
#endif
3191
};
3192
3193
inline Registers_mips_newabi::Registers_mips_newabi(const void *registers) {
3194
static_assert((check_fit<Registers_mips_newabi, unw_context_t>::does_fit),
3195
"mips_newabi registers do not fit into unw_context_t");
3196
memcpy(&_registers, static_cast<const uint8_t *>(registers),
3197
sizeof(_registers));
3198
}
3199
3200
inline Registers_mips_newabi::Registers_mips_newabi() {
3201
memset(&_registers, 0, sizeof(_registers));
3202
}
3203
3204
inline bool Registers_mips_newabi::validRegister(int regNum) const {
3205
if (regNum == UNW_REG_IP)
3206
return true;
3207
if (regNum == UNW_REG_SP)
3208
return true;
3209
if (regNum < 0)
3210
return false;
3211
if (regNum <= UNW_MIPS_R31)
3212
return true;
3213
#if __mips_isa_rev < 6
3214
if (regNum == UNW_MIPS_HI)
3215
return true;
3216
if (regNum == UNW_MIPS_LO)
3217
return true;
3218
#endif
3219
// FIXME: Hard float, DSP accumulator registers, MSA registers
3220
return false;
3221
}
3222
3223
inline uint64_t Registers_mips_newabi::getRegister(int regNum) const {
3224
if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
3225
return _registers.__r[regNum - UNW_MIPS_R0];
3226
3227
switch (regNum) {
3228
case UNW_REG_IP:
3229
return _registers.__pc;
3230
case UNW_REG_SP:
3231
return _registers.__r[29];
3232
#if __mips_isa_rev < 6
3233
case UNW_MIPS_HI:
3234
return _registers.__hi;
3235
case UNW_MIPS_LO:
3236
return _registers.__lo;
3237
#endif
3238
}
3239
_LIBUNWIND_ABORT("unsupported mips_newabi register");
3240
}
3241
3242
inline void Registers_mips_newabi::setRegister(int regNum, uint64_t value) {
3243
if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
3244
_registers.__r[regNum - UNW_MIPS_R0] = value;
3245
return;
3246
}
3247
3248
switch (regNum) {
3249
case UNW_REG_IP:
3250
_registers.__pc = value;
3251
return;
3252
case UNW_REG_SP:
3253
_registers.__r[29] = value;
3254
return;
3255
#if __mips_isa_rev < 6
3256
case UNW_MIPS_HI:
3257
_registers.__hi = value;
3258
return;
3259
case UNW_MIPS_LO:
3260
_registers.__lo = value;
3261
return;
3262
#endif
3263
}
3264
_LIBUNWIND_ABORT("unsupported mips_newabi register");
3265
}
3266
3267
inline bool Registers_mips_newabi::validFloatRegister(int regNum) const {
3268
#ifdef __mips_hard_float
3269
if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
3270
return true;
3271
#else
3272
(void)regNum;
3273
#endif
3274
return false;
3275
}
3276
3277
inline double Registers_mips_newabi::getFloatRegister(int regNum) const {
3278
#ifdef __mips_hard_float
3279
assert(validFloatRegister(regNum));
3280
return _floats[regNum - UNW_MIPS_F0];
3281
#else
3282
(void)regNum;
3283
_LIBUNWIND_ABORT("mips_newabi float support not implemented");
3284
#endif
3285
}
3286
3287
inline void Registers_mips_newabi::setFloatRegister(int regNum,
3288
double value) {
3289
#ifdef __mips_hard_float
3290
assert(validFloatRegister(regNum));
3291
_floats[regNum - UNW_MIPS_F0] = value;
3292
#else
3293
(void)regNum;
3294
(void)value;
3295
_LIBUNWIND_ABORT("mips_newabi float support not implemented");
3296
#endif
3297
}
3298
3299
inline bool Registers_mips_newabi::validVectorRegister(int /* regNum */) const {
3300
return false;
3301
}
3302
3303
inline v128 Registers_mips_newabi::getVectorRegister(int /* regNum */) const {
3304
_LIBUNWIND_ABORT("mips_newabi vector support not implemented");
3305
}
3306
3307
inline void Registers_mips_newabi::setVectorRegister(int /* regNum */, v128 /* value */) {
3308
_LIBUNWIND_ABORT("mips_newabi vector support not implemented");
3309
}
3310
3311
inline const char *Registers_mips_newabi::getRegisterName(int regNum) {
3312
switch (regNum) {
3313
case UNW_MIPS_R0:
3314
return "$0";
3315
case UNW_MIPS_R1:
3316
return "$1";
3317
case UNW_MIPS_R2:
3318
return "$2";
3319
case UNW_MIPS_R3:
3320
return "$3";
3321
case UNW_MIPS_R4:
3322
return "$4";
3323
case UNW_MIPS_R5:
3324
return "$5";
3325
case UNW_MIPS_R6:
3326
return "$6";
3327
case UNW_MIPS_R7:
3328
return "$7";
3329
case UNW_MIPS_R8:
3330
return "$8";
3331
case UNW_MIPS_R9:
3332
return "$9";
3333
case UNW_MIPS_R10:
3334
return "$10";
3335
case UNW_MIPS_R11:
3336
return "$11";
3337
case UNW_MIPS_R12:
3338
return "$12";
3339
case UNW_MIPS_R13:
3340
return "$13";
3341
case UNW_MIPS_R14:
3342
return "$14";
3343
case UNW_MIPS_R15:
3344
return "$15";
3345
case UNW_MIPS_R16:
3346
return "$16";
3347
case UNW_MIPS_R17:
3348
return "$17";
3349
case UNW_MIPS_R18:
3350
return "$18";
3351
case UNW_MIPS_R19:
3352
return "$19";
3353
case UNW_MIPS_R20:
3354
return "$20";
3355
case UNW_MIPS_R21:
3356
return "$21";
3357
case UNW_MIPS_R22:
3358
return "$22";
3359
case UNW_MIPS_R23:
3360
return "$23";
3361
case UNW_MIPS_R24:
3362
return "$24";
3363
case UNW_MIPS_R25:
3364
return "$25";
3365
case UNW_MIPS_R26:
3366
return "$26";
3367
case UNW_MIPS_R27:
3368
return "$27";
3369
case UNW_MIPS_R28:
3370
return "$28";
3371
case UNW_MIPS_R29:
3372
return "$29";
3373
case UNW_MIPS_R30:
3374
return "$30";
3375
case UNW_MIPS_R31:
3376
return "$31";
3377
case UNW_MIPS_F0:
3378
return "$f0";
3379
case UNW_MIPS_F1:
3380
return "$f1";
3381
case UNW_MIPS_F2:
3382
return "$f2";
3383
case UNW_MIPS_F3:
3384
return "$f3";
3385
case UNW_MIPS_F4:
3386
return "$f4";
3387
case UNW_MIPS_F5:
3388
return "$f5";
3389
case UNW_MIPS_F6:
3390
return "$f6";
3391
case UNW_MIPS_F7:
3392
return "$f7";
3393
case UNW_MIPS_F8:
3394
return "$f8";
3395
case UNW_MIPS_F9:
3396
return "$f9";
3397
case UNW_MIPS_F10:
3398
return "$f10";
3399
case UNW_MIPS_F11:
3400
return "$f11";
3401
case UNW_MIPS_F12:
3402
return "$f12";
3403
case UNW_MIPS_F13:
3404
return "$f13";
3405
case UNW_MIPS_F14:
3406
return "$f14";
3407
case UNW_MIPS_F15:
3408
return "$f15";
3409
case UNW_MIPS_F16:
3410
return "$f16";
3411
case UNW_MIPS_F17:
3412
return "$f17";
3413
case UNW_MIPS_F18:
3414
return "$f18";
3415
case UNW_MIPS_F19:
3416
return "$f19";
3417
case UNW_MIPS_F20:
3418
return "$f20";
3419
case UNW_MIPS_F21:
3420
return "$f21";
3421
case UNW_MIPS_F22:
3422
return "$f22";
3423
case UNW_MIPS_F23:
3424
return "$f23";
3425
case UNW_MIPS_F24:
3426
return "$f24";
3427
case UNW_MIPS_F25:
3428
return "$f25";
3429
case UNW_MIPS_F26:
3430
return "$f26";
3431
case UNW_MIPS_F27:
3432
return "$f27";
3433
case UNW_MIPS_F28:
3434
return "$f28";
3435
case UNW_MIPS_F29:
3436
return "$f29";
3437
case UNW_MIPS_F30:
3438
return "$f30";
3439
case UNW_MIPS_F31:
3440
return "$f31";
3441
#if __mips_isa_rev < 6
3442
case UNW_MIPS_HI:
3443
return "$hi";
3444
case UNW_MIPS_LO:
3445
return "$lo";
3446
#endif
3447
default:
3448
return "unknown register";
3449
}
3450
}
3451
#endif // _LIBUNWIND_TARGET_MIPS_NEWABI
3452
3453
#if defined(_LIBUNWIND_TARGET_SPARC)
3454
/// Registers_sparc holds the register state of a thread in a 32-bit Sparc
3455
/// process.
3456
class _LIBUNWIND_HIDDEN Registers_sparc {
3457
public:
3458
Registers_sparc();
3459
Registers_sparc(const void *registers);
3460
3461
bool validRegister(int num) const;
3462
uint32_t getRegister(int num) const;
3463
void setRegister(int num, uint32_t value);
3464
bool validFloatRegister(int num) const;
3465
double getFloatRegister(int num) const;
3466
void setFloatRegister(int num, double value);
3467
bool validVectorRegister(int num) const;
3468
v128 getVectorRegister(int num) const;
3469
void setVectorRegister(int num, v128 value);
3470
static const char *getRegisterName(int num);
3471
void jumpto();
3472
static constexpr int lastDwarfRegNum() {
3473
return _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC;
3474
}
3475
static int getArch() { return REGISTERS_SPARC; }
3476
3477
uint64_t getSP() const { return _registers.__regs[UNW_SPARC_O6]; }
3478
void setSP(uint32_t value) { _registers.__regs[UNW_SPARC_O6] = value; }
3479
uint64_t getIP() const { return _registers.__regs[UNW_SPARC_O7]; }
3480
void setIP(uint32_t value) { _registers.__regs[UNW_SPARC_O7] = value; }
3481
3482
private:
3483
struct sparc_thread_state_t {
3484
unsigned int __regs[32];
3485
};
3486
3487
sparc_thread_state_t _registers;
3488
};
3489
3490
inline Registers_sparc::Registers_sparc(const void *registers) {
3491
static_assert((check_fit<Registers_sparc, unw_context_t>::does_fit),
3492
"sparc registers do not fit into unw_context_t");
3493
memcpy(&_registers, static_cast<const uint8_t *>(registers),
3494
sizeof(_registers));
3495
}
3496
3497
inline Registers_sparc::Registers_sparc() {
3498
memset(&_registers, 0, sizeof(_registers));
3499
}
3500
3501
inline bool Registers_sparc::validRegister(int regNum) const {
3502
if (regNum == UNW_REG_IP)
3503
return true;
3504
if (regNum == UNW_REG_SP)
3505
return true;
3506
if (regNum < 0)
3507
return false;
3508
if (regNum <= UNW_SPARC_I7)
3509
return true;
3510
return false;
3511
}
3512
3513
inline uint32_t Registers_sparc::getRegister(int regNum) const {
3514
if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) {
3515
return _registers.__regs[regNum];
3516
}
3517
3518
switch (regNum) {
3519
case UNW_REG_IP:
3520
return _registers.__regs[UNW_SPARC_O7];
3521
case UNW_REG_SP:
3522
return _registers.__regs[UNW_SPARC_O6];
3523
}
3524
_LIBUNWIND_ABORT("unsupported sparc register");
3525
}
3526
3527
inline void Registers_sparc::setRegister(int regNum, uint32_t value) {
3528
if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) {
3529
_registers.__regs[regNum] = value;
3530
return;
3531
}
3532
3533
switch (regNum) {
3534
case UNW_REG_IP:
3535
_registers.__regs[UNW_SPARC_O7] = value;
3536
return;
3537
case UNW_REG_SP:
3538
_registers.__regs[UNW_SPARC_O6] = value;
3539
return;
3540
}
3541
_LIBUNWIND_ABORT("unsupported sparc register");
3542
}
3543
3544
inline bool Registers_sparc::validFloatRegister(int) const { return false; }
3545
3546
inline double Registers_sparc::getFloatRegister(int) const {
3547
_LIBUNWIND_ABORT("no Sparc float registers");
3548
}
3549
3550
inline void Registers_sparc::setFloatRegister(int, double) {
3551
_LIBUNWIND_ABORT("no Sparc float registers");
3552
}
3553
3554
inline bool Registers_sparc::validVectorRegister(int) const { return false; }
3555
3556
inline v128 Registers_sparc::getVectorRegister(int) const {
3557
_LIBUNWIND_ABORT("no Sparc vector registers");
3558
}
3559
3560
inline void Registers_sparc::setVectorRegister(int, v128) {
3561
_LIBUNWIND_ABORT("no Sparc vector registers");
3562
}
3563
3564
inline const char *Registers_sparc::getRegisterName(int regNum) {
3565
switch (regNum) {
3566
case UNW_REG_IP:
3567
return "pc";
3568
case UNW_SPARC_G0:
3569
return "g0";
3570
case UNW_SPARC_G1:
3571
return "g1";
3572
case UNW_SPARC_G2:
3573
return "g2";
3574
case UNW_SPARC_G3:
3575
return "g3";
3576
case UNW_SPARC_G4:
3577
return "g4";
3578
case UNW_SPARC_G5:
3579
return "g5";
3580
case UNW_SPARC_G6:
3581
return "g6";
3582
case UNW_SPARC_G7:
3583
return "g7";
3584
case UNW_SPARC_O0:
3585
return "o0";
3586
case UNW_SPARC_O1:
3587
return "o1";
3588
case UNW_SPARC_O2:
3589
return "o2";
3590
case UNW_SPARC_O3:
3591
return "o3";
3592
case UNW_SPARC_O4:
3593
return "o4";
3594
case UNW_SPARC_O5:
3595
return "o5";
3596
case UNW_REG_SP:
3597
case UNW_SPARC_O6:
3598
return "sp";
3599
case UNW_SPARC_O7:
3600
return "o7";
3601
case UNW_SPARC_L0:
3602
return "l0";
3603
case UNW_SPARC_L1:
3604
return "l1";
3605
case UNW_SPARC_L2:
3606
return "l2";
3607
case UNW_SPARC_L3:
3608
return "l3";
3609
case UNW_SPARC_L4:
3610
return "l4";
3611
case UNW_SPARC_L5:
3612
return "l5";
3613
case UNW_SPARC_L6:
3614
return "l6";
3615
case UNW_SPARC_L7:
3616
return "l7";
3617
case UNW_SPARC_I0:
3618
return "i0";
3619
case UNW_SPARC_I1:
3620
return "i1";
3621
case UNW_SPARC_I2:
3622
return "i2";
3623
case UNW_SPARC_I3:
3624
return "i3";
3625
case UNW_SPARC_I4:
3626
return "i4";
3627
case UNW_SPARC_I5:
3628
return "i5";
3629
case UNW_SPARC_I6:
3630
return "fp";
3631
case UNW_SPARC_I7:
3632
return "i7";
3633
default:
3634
return "unknown register";
3635
}
3636
}
3637
#endif // _LIBUNWIND_TARGET_SPARC
3638
3639
#if defined(_LIBUNWIND_TARGET_SPARC64)
3640
/// Registers_sparc64 holds the register state of a thread in a 64-bit
3641
/// sparc process.
3642
class _LIBUNWIND_HIDDEN Registers_sparc64 {
3643
public:
3644
Registers_sparc64() = default;
3645
Registers_sparc64(const void *registers);
3646
3647
bool validRegister(int num) const;
3648
uint64_t getRegister(int num) const;
3649
void setRegister(int num, uint64_t value);
3650
bool validFloatRegister(int num) const;
3651
double getFloatRegister(int num) const;
3652
void setFloatRegister(int num, double value);
3653
bool validVectorRegister(int num) const;
3654
v128 getVectorRegister(int num) const;
3655
void setVectorRegister(int num, v128 value);
3656
const char *getRegisterName(int num);
3657
void jumpto();
3658
static constexpr int lastDwarfRegNum() {
3659
return _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC64;
3660
}
3661
static int getArch() { return REGISTERS_SPARC64; }
3662
3663
uint64_t getSP() const { return _registers.__regs[UNW_SPARC_O6] + 2047; }
3664
void setSP(uint64_t value) { _registers.__regs[UNW_SPARC_O6] = value - 2047; }
3665
uint64_t getIP() const { return _registers.__regs[UNW_SPARC_O7]; }
3666
void setIP(uint64_t value) { _registers.__regs[UNW_SPARC_O7] = value; }
3667
uint64_t getWCookie() const { return _wcookie; }
3668
3669
private:
3670
struct sparc64_thread_state_t {
3671
uint64_t __regs[32];
3672
};
3673
3674
sparc64_thread_state_t _registers{};
3675
uint64_t _wcookie = 0;
3676
};
3677
3678
inline Registers_sparc64::Registers_sparc64(const void *registers) {
3679
static_assert((check_fit<Registers_sparc64, unw_context_t>::does_fit),
3680
"sparc64 registers do not fit into unw_context_t");
3681
memcpy(&_registers, registers, sizeof(_registers));
3682
memcpy(&_wcookie,
3683
static_cast<const uint8_t *>(registers) + sizeof(_registers),
3684
sizeof(_wcookie));
3685
}
3686
3687
inline bool Registers_sparc64::validRegister(int regNum) const {
3688
if (regNum == UNW_REG_IP)
3689
return true;
3690
if (regNum == UNW_REG_SP)
3691
return true;
3692
if (regNum < 0)
3693
return false;
3694
if (regNum <= UNW_SPARC_I7)
3695
return true;
3696
return false;
3697
}
3698
3699
inline uint64_t Registers_sparc64::getRegister(int regNum) const {
3700
if (regNum >= UNW_SPARC_G0 && regNum <= UNW_SPARC_I7)
3701
return _registers.__regs[regNum];
3702
3703
switch (regNum) {
3704
case UNW_REG_IP:
3705
return _registers.__regs[UNW_SPARC_O7];
3706
case UNW_REG_SP:
3707
return _registers.__regs[UNW_SPARC_O6] + 2047;
3708
}
3709
_LIBUNWIND_ABORT("unsupported sparc64 register");
3710
}
3711
3712
inline void Registers_sparc64::setRegister(int regNum, uint64_t value) {
3713
if (regNum >= UNW_SPARC_G0 && regNum <= UNW_SPARC_I7) {
3714
_registers.__regs[regNum] = value;
3715
return;
3716
}
3717
3718
switch (regNum) {
3719
case UNW_REG_IP:
3720
_registers.__regs[UNW_SPARC_O7] = value;
3721
return;
3722
case UNW_REG_SP:
3723
_registers.__regs[UNW_SPARC_O6] = value - 2047;
3724
return;
3725
}
3726
_LIBUNWIND_ABORT("unsupported sparc64 register");
3727
}
3728
3729
inline bool Registers_sparc64::validFloatRegister(int) const { return false; }
3730
3731
inline double Registers_sparc64::getFloatRegister(int) const {
3732
_LIBUNWIND_ABORT("no sparc64 float registers");
3733
}
3734
3735
inline void Registers_sparc64::setFloatRegister(int, double) {
3736
_LIBUNWIND_ABORT("no sparc64 float registers");
3737
}
3738
3739
inline bool Registers_sparc64::validVectorRegister(int) const { return false; }
3740
3741
inline v128 Registers_sparc64::getVectorRegister(int) const {
3742
_LIBUNWIND_ABORT("no sparc64 vector registers");
3743
}
3744
3745
inline void Registers_sparc64::setVectorRegister(int, v128) {
3746
_LIBUNWIND_ABORT("no sparc64 vector registers");
3747
}
3748
3749
inline const char *Registers_sparc64::getRegisterName(int regNum) {
3750
switch (regNum) {
3751
case UNW_REG_IP:
3752
return "pc";
3753
case UNW_SPARC_G0:
3754
return "g0";
3755
case UNW_SPARC_G1:
3756
return "g1";
3757
case UNW_SPARC_G2:
3758
return "g2";
3759
case UNW_SPARC_G3:
3760
return "g3";
3761
case UNW_SPARC_G4:
3762
return "g4";
3763
case UNW_SPARC_G5:
3764
return "g5";
3765
case UNW_SPARC_G6:
3766
return "g6";
3767
case UNW_SPARC_G7:
3768
return "g7";
3769
case UNW_SPARC_O0:
3770
return "o0";
3771
case UNW_SPARC_O1:
3772
return "o1";
3773
case UNW_SPARC_O2:
3774
return "o2";
3775
case UNW_SPARC_O3:
3776
return "o3";
3777
case UNW_SPARC_O4:
3778
return "o4";
3779
case UNW_SPARC_O5:
3780
return "o5";
3781
case UNW_REG_SP:
3782
case UNW_SPARC_O6:
3783
return "o6";
3784
case UNW_SPARC_O7:
3785
return "o7";
3786
case UNW_SPARC_L0:
3787
return "l0";
3788
case UNW_SPARC_L1:
3789
return "l1";
3790
case UNW_SPARC_L2:
3791
return "l2";
3792
case UNW_SPARC_L3:
3793
return "l3";
3794
case UNW_SPARC_L4:
3795
return "l4";
3796
case UNW_SPARC_L5:
3797
return "l5";
3798
case UNW_SPARC_L6:
3799
return "l6";
3800
case UNW_SPARC_L7:
3801
return "l7";
3802
case UNW_SPARC_I0:
3803
return "i0";
3804
case UNW_SPARC_I1:
3805
return "i1";
3806
case UNW_SPARC_I2:
3807
return "i2";
3808
case UNW_SPARC_I3:
3809
return "i3";
3810
case UNW_SPARC_I4:
3811
return "i4";
3812
case UNW_SPARC_I5:
3813
return "i5";
3814
case UNW_SPARC_I6:
3815
return "i6";
3816
case UNW_SPARC_I7:
3817
return "i7";
3818
default:
3819
return "unknown register";
3820
}
3821
}
3822
#endif // _LIBUNWIND_TARGET_SPARC64
3823
3824
#if defined(_LIBUNWIND_TARGET_HEXAGON)
3825
/// Registers_hexagon holds the register state of a thread in a Hexagon QDSP6
3826
/// process.
3827
class _LIBUNWIND_HIDDEN Registers_hexagon {
3828
public:
3829
Registers_hexagon();
3830
Registers_hexagon(const void *registers);
3831
3832
bool validRegister(int num) const;
3833
uint32_t getRegister(int num) const;
3834
void setRegister(int num, uint32_t value);
3835
bool validFloatRegister(int num) const;
3836
double getFloatRegister(int num) const;
3837
void setFloatRegister(int num, double value);
3838
bool validVectorRegister(int num) const;
3839
v128 getVectorRegister(int num) const;
3840
void setVectorRegister(int num, v128 value);
3841
const char *getRegisterName(int num);
3842
void jumpto();
3843
static constexpr int lastDwarfRegNum() {
3844
return _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON;
3845
}
3846
static int getArch() { return REGISTERS_HEXAGON; }
3847
3848
uint32_t getSP() const { return _registers.__r[UNW_HEXAGON_R29]; }
3849
void setSP(uint32_t value) { _registers.__r[UNW_HEXAGON_R29] = value; }
3850
uint32_t getIP() const { return _registers.__r[UNW_HEXAGON_PC]; }
3851
void setIP(uint32_t value) { _registers.__r[UNW_HEXAGON_PC] = value; }
3852
3853
private:
3854
struct hexagon_thread_state_t {
3855
unsigned int __r[35];
3856
};
3857
3858
hexagon_thread_state_t _registers;
3859
};
3860
3861
inline Registers_hexagon::Registers_hexagon(const void *registers) {
3862
static_assert((check_fit<Registers_hexagon, unw_context_t>::does_fit),
3863
"hexagon registers do not fit into unw_context_t");
3864
memcpy(&_registers, static_cast<const uint8_t *>(registers),
3865
sizeof(_registers));
3866
}
3867
3868
inline Registers_hexagon::Registers_hexagon() {
3869
memset(&_registers, 0, sizeof(_registers));
3870
}
3871
3872
inline bool Registers_hexagon::validRegister(int regNum) const {
3873
if (regNum <= UNW_HEXAGON_R31)
3874
return true;
3875
return false;
3876
}
3877
3878
inline uint32_t Registers_hexagon::getRegister(int regNum) const {
3879
if (regNum >= UNW_HEXAGON_R0 && regNum <= UNW_HEXAGON_R31)
3880
return _registers.__r[regNum - UNW_HEXAGON_R0];
3881
3882
switch (regNum) {
3883
case UNW_REG_IP:
3884
return _registers.__r[UNW_HEXAGON_PC];
3885
case UNW_REG_SP:
3886
return _registers.__r[UNW_HEXAGON_R29];
3887
}
3888
_LIBUNWIND_ABORT("unsupported hexagon register");
3889
}
3890
3891
inline void Registers_hexagon::setRegister(int regNum, uint32_t value) {
3892
if (regNum >= UNW_HEXAGON_R0 && regNum <= UNW_HEXAGON_R31) {
3893
_registers.__r[regNum - UNW_HEXAGON_R0] = value;
3894
return;
3895
}
3896
3897
switch (regNum) {
3898
case UNW_REG_IP:
3899
_registers.__r[UNW_HEXAGON_PC] = value;
3900
return;
3901
case UNW_REG_SP:
3902
_registers.__r[UNW_HEXAGON_R29] = value;
3903
return;
3904
}
3905
_LIBUNWIND_ABORT("unsupported hexagon register");
3906
}
3907
3908
inline bool Registers_hexagon::validFloatRegister(int /* regNum */) const {
3909
return false;
3910
}
3911
3912
inline double Registers_hexagon::getFloatRegister(int /* regNum */) const {
3913
_LIBUNWIND_ABORT("hexagon float support not implemented");
3914
}
3915
3916
inline void Registers_hexagon::setFloatRegister(int /* regNum */,
3917
double /* value */) {
3918
_LIBUNWIND_ABORT("hexagon float support not implemented");
3919
}
3920
3921
inline bool Registers_hexagon::validVectorRegister(int /* regNum */) const {
3922
return false;
3923
}
3924
3925
inline v128 Registers_hexagon::getVectorRegister(int /* regNum */) const {
3926
_LIBUNWIND_ABORT("hexagon vector support not implemented");
3927
}
3928
3929
inline void Registers_hexagon::setVectorRegister(int /* regNum */, v128 /* value */) {
3930
_LIBUNWIND_ABORT("hexagon vector support not implemented");
3931
}
3932
3933
inline const char *Registers_hexagon::getRegisterName(int regNum) {
3934
switch (regNum) {
3935
case UNW_HEXAGON_R0:
3936
return "r0";
3937
case UNW_HEXAGON_R1:
3938
return "r1";
3939
case UNW_HEXAGON_R2:
3940
return "r2";
3941
case UNW_HEXAGON_R3:
3942
return "r3";
3943
case UNW_HEXAGON_R4:
3944
return "r4";
3945
case UNW_HEXAGON_R5:
3946
return "r5";
3947
case UNW_HEXAGON_R6:
3948
return "r6";
3949
case UNW_HEXAGON_R7:
3950
return "r7";
3951
case UNW_HEXAGON_R8:
3952
return "r8";
3953
case UNW_HEXAGON_R9:
3954
return "r9";
3955
case UNW_HEXAGON_R10:
3956
return "r10";
3957
case UNW_HEXAGON_R11:
3958
return "r11";
3959
case UNW_HEXAGON_R12:
3960
return "r12";
3961
case UNW_HEXAGON_R13:
3962
return "r13";
3963
case UNW_HEXAGON_R14:
3964
return "r14";
3965
case UNW_HEXAGON_R15:
3966
return "r15";
3967
case UNW_HEXAGON_R16:
3968
return "r16";
3969
case UNW_HEXAGON_R17:
3970
return "r17";
3971
case UNW_HEXAGON_R18:
3972
return "r18";
3973
case UNW_HEXAGON_R19:
3974
return "r19";
3975
case UNW_HEXAGON_R20:
3976
return "r20";
3977
case UNW_HEXAGON_R21:
3978
return "r21";
3979
case UNW_HEXAGON_R22:
3980
return "r22";
3981
case UNW_HEXAGON_R23:
3982
return "r23";
3983
case UNW_HEXAGON_R24:
3984
return "r24";
3985
case UNW_HEXAGON_R25:
3986
return "r25";
3987
case UNW_HEXAGON_R26:
3988
return "r26";
3989
case UNW_HEXAGON_R27:
3990
return "r27";
3991
case UNW_HEXAGON_R28:
3992
return "r28";
3993
case UNW_HEXAGON_R29:
3994
return "r29";
3995
case UNW_HEXAGON_R30:
3996
return "r30";
3997
case UNW_HEXAGON_R31:
3998
return "r31";
3999
default:
4000
return "unknown register";
4001
}
4002
4003
}
4004
#endif // _LIBUNWIND_TARGET_HEXAGON
4005
4006
4007
#if defined(_LIBUNWIND_TARGET_RISCV)
4008
/// Registers_riscv holds the register state of a thread in a RISC-V
4009
/// process.
4010
4011
// This check makes it safe when LIBUNWIND_ENABLE_CROSS_UNWINDING enabled.
4012
# ifdef __riscv
4013
# if __riscv_xlen == 32
4014
typedef uint32_t reg_t;
4015
# elif __riscv_xlen == 64
4016
typedef uint64_t reg_t;
4017
# else
4018
# error "Unsupported __riscv_xlen"
4019
# endif
4020
4021
# if defined(__riscv_flen)
4022
# if __riscv_flen == 64
4023
typedef double fp_t;
4024
# elif __riscv_flen == 32
4025
typedef float fp_t;
4026
# else
4027
# error "Unsupported __riscv_flen"
4028
# endif
4029
# else
4030
// This is just for suppressing undeclared error of fp_t.
4031
typedef double fp_t;
4032
# endif
4033
# else
4034
// Use Max possible width when cross unwinding
4035
typedef uint64_t reg_t;
4036
typedef double fp_t;
4037
# define __riscv_xlen 64
4038
# define __riscv_flen 64
4039
#endif
4040
4041
/// Registers_riscv holds the register state of a thread.
4042
class _LIBUNWIND_HIDDEN Registers_riscv {
4043
public:
4044
Registers_riscv();
4045
Registers_riscv(const void *registers);
4046
4047
bool validRegister(int num) const;
4048
reg_t getRegister(int num) const;
4049
void setRegister(int num, reg_t value);
4050
bool validFloatRegister(int num) const;
4051
fp_t getFloatRegister(int num) const;
4052
void setFloatRegister(int num, fp_t value);
4053
bool validVectorRegister(int num) const;
4054
v128 getVectorRegister(int num) const;
4055
void setVectorRegister(int num, v128 value);
4056
static const char *getRegisterName(int num);
4057
void jumpto();
4058
static constexpr int lastDwarfRegNum() {
4059
return _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV;
4060
}
4061
static int getArch() { return REGISTERS_RISCV; }
4062
4063
reg_t getSP() const { return _registers[2]; }
4064
void setSP(reg_t value) { _registers[2] = value; }
4065
reg_t getIP() const { return _registers[0]; }
4066
void setIP(reg_t value) { _registers[0] = value; }
4067
4068
private:
4069
// _registers[0] holds the pc
4070
reg_t _registers[32];
4071
# if defined(__riscv_flen)
4072
fp_t _floats[32];
4073
# endif
4074
};
4075
4076
inline Registers_riscv::Registers_riscv(const void *registers) {
4077
static_assert((check_fit<Registers_riscv, unw_context_t>::does_fit),
4078
"riscv registers do not fit into unw_context_t");
4079
memcpy(&_registers, registers, sizeof(_registers));
4080
# if __riscv_xlen == 32
4081
static_assert(sizeof(_registers) == 0x80,
4082
"expected float registers to be at offset 128");
4083
# elif __riscv_xlen == 64
4084
static_assert(sizeof(_registers) == 0x100,
4085
"expected float registers to be at offset 256");
4086
# else
4087
# error "Unexpected float registers."
4088
# endif
4089
4090
# if defined(__riscv_flen)
4091
memcpy(_floats,
4092
static_cast<const uint8_t *>(registers) + sizeof(_registers),
4093
sizeof(_floats));
4094
# endif
4095
}
4096
4097
inline Registers_riscv::Registers_riscv() {
4098
memset(&_registers, 0, sizeof(_registers));
4099
# if defined(__riscv_flen)
4100
memset(&_floats, 0, sizeof(_floats));
4101
# endif
4102
}
4103
4104
inline bool Registers_riscv::validRegister(int regNum) const {
4105
if (regNum == UNW_REG_IP)
4106
return true;
4107
if (regNum == UNW_REG_SP)
4108
return true;
4109
if (regNum < 0)
4110
return false;
4111
if (regNum == UNW_RISCV_VLENB)
4112
return true;
4113
if (regNum > UNW_RISCV_F31)
4114
return false;
4115
return true;
4116
}
4117
4118
inline reg_t Registers_riscv::getRegister(int regNum) const {
4119
if (regNum == UNW_REG_IP)
4120
return _registers[0];
4121
if (regNum == UNW_REG_SP)
4122
return _registers[2];
4123
if (regNum == UNW_RISCV_X0)
4124
return 0;
4125
if ((regNum > 0) && (regNum < 32))
4126
return _registers[regNum];
4127
if (regNum == UNW_RISCV_VLENB) {
4128
reg_t vlenb;
4129
__asm__("csrr %0, 0xC22" : "=r"(vlenb));
4130
return vlenb;
4131
}
4132
_LIBUNWIND_ABORT("unsupported riscv register");
4133
}
4134
4135
inline void Registers_riscv::setRegister(int regNum, reg_t value) {
4136
if (regNum == UNW_REG_IP)
4137
_registers[0] = value;
4138
else if (regNum == UNW_REG_SP)
4139
_registers[2] = value;
4140
else if (regNum == UNW_RISCV_X0)
4141
/* x0 is hardwired to zero */
4142
return;
4143
else if ((regNum > 0) && (regNum < 32))
4144
_registers[regNum] = value;
4145
else
4146
_LIBUNWIND_ABORT("unsupported riscv register");
4147
}
4148
4149
inline const char *Registers_riscv::getRegisterName(int regNum) {
4150
switch (regNum) {
4151
case UNW_REG_IP:
4152
return "pc";
4153
case UNW_REG_SP:
4154
return "sp";
4155
case UNW_RISCV_X0:
4156
return "zero";
4157
case UNW_RISCV_X1:
4158
return "ra";
4159
case UNW_RISCV_X2:
4160
return "sp";
4161
case UNW_RISCV_X3:
4162
return "gp";
4163
case UNW_RISCV_X4:
4164
return "tp";
4165
case UNW_RISCV_X5:
4166
return "t0";
4167
case UNW_RISCV_X6:
4168
return "t1";
4169
case UNW_RISCV_X7:
4170
return "t2";
4171
case UNW_RISCV_X8:
4172
return "s0";
4173
case UNW_RISCV_X9:
4174
return "s1";
4175
case UNW_RISCV_X10:
4176
return "a0";
4177
case UNW_RISCV_X11:
4178
return "a1";
4179
case UNW_RISCV_X12:
4180
return "a2";
4181
case UNW_RISCV_X13:
4182
return "a3";
4183
case UNW_RISCV_X14:
4184
return "a4";
4185
case UNW_RISCV_X15:
4186
return "a5";
4187
case UNW_RISCV_X16:
4188
return "a6";
4189
case UNW_RISCV_X17:
4190
return "a7";
4191
case UNW_RISCV_X18:
4192
return "s2";
4193
case UNW_RISCV_X19:
4194
return "s3";
4195
case UNW_RISCV_X20:
4196
return "s4";
4197
case UNW_RISCV_X21:
4198
return "s5";
4199
case UNW_RISCV_X22:
4200
return "s6";
4201
case UNW_RISCV_X23:
4202
return "s7";
4203
case UNW_RISCV_X24:
4204
return "s8";
4205
case UNW_RISCV_X25:
4206
return "s9";
4207
case UNW_RISCV_X26:
4208
return "s10";
4209
case UNW_RISCV_X27:
4210
return "s11";
4211
case UNW_RISCV_X28:
4212
return "t3";
4213
case UNW_RISCV_X29:
4214
return "t4";
4215
case UNW_RISCV_X30:
4216
return "t5";
4217
case UNW_RISCV_X31:
4218
return "t6";
4219
case UNW_RISCV_F0:
4220
return "ft0";
4221
case UNW_RISCV_F1:
4222
return "ft1";
4223
case UNW_RISCV_F2:
4224
return "ft2";
4225
case UNW_RISCV_F3:
4226
return "ft3";
4227
case UNW_RISCV_F4:
4228
return "ft4";
4229
case UNW_RISCV_F5:
4230
return "ft5";
4231
case UNW_RISCV_F6:
4232
return "ft6";
4233
case UNW_RISCV_F7:
4234
return "ft7";
4235
case UNW_RISCV_F8:
4236
return "fs0";
4237
case UNW_RISCV_F9:
4238
return "fs1";
4239
case UNW_RISCV_F10:
4240
return "fa0";
4241
case UNW_RISCV_F11:
4242
return "fa1";
4243
case UNW_RISCV_F12:
4244
return "fa2";
4245
case UNW_RISCV_F13:
4246
return "fa3";
4247
case UNW_RISCV_F14:
4248
return "fa4";
4249
case UNW_RISCV_F15:
4250
return "fa5";
4251
case UNW_RISCV_F16:
4252
return "fa6";
4253
case UNW_RISCV_F17:
4254
return "fa7";
4255
case UNW_RISCV_F18:
4256
return "fs2";
4257
case UNW_RISCV_F19:
4258
return "fs3";
4259
case UNW_RISCV_F20:
4260
return "fs4";
4261
case UNW_RISCV_F21:
4262
return "fs5";
4263
case UNW_RISCV_F22:
4264
return "fs6";
4265
case UNW_RISCV_F23:
4266
return "fs7";
4267
case UNW_RISCV_F24:
4268
return "fs8";
4269
case UNW_RISCV_F25:
4270
return "fs9";
4271
case UNW_RISCV_F26:
4272
return "fs10";
4273
case UNW_RISCV_F27:
4274
return "fs11";
4275
case UNW_RISCV_F28:
4276
return "ft8";
4277
case UNW_RISCV_F29:
4278
return "ft9";
4279
case UNW_RISCV_F30:
4280
return "ft10";
4281
case UNW_RISCV_F31:
4282
return "ft11";
4283
case UNW_RISCV_VLENB:
4284
return "vlenb";
4285
default:
4286
return "unknown register";
4287
}
4288
}
4289
4290
inline bool Registers_riscv::validFloatRegister(int regNum) const {
4291
# if defined(__riscv_flen)
4292
if (regNum < UNW_RISCV_F0)
4293
return false;
4294
if (regNum > UNW_RISCV_F31)
4295
return false;
4296
return true;
4297
# else
4298
(void)regNum;
4299
return false;
4300
# endif
4301
}
4302
4303
inline fp_t Registers_riscv::getFloatRegister(int regNum) const {
4304
# if defined(__riscv_flen)
4305
assert(validFloatRegister(regNum));
4306
return _floats[regNum - UNW_RISCV_F0];
4307
# else
4308
(void)regNum;
4309
_LIBUNWIND_ABORT("libunwind not built with float support");
4310
# endif
4311
}
4312
4313
inline void Registers_riscv::setFloatRegister(int regNum, fp_t value) {
4314
# if defined(__riscv_flen)
4315
assert(validFloatRegister(regNum));
4316
_floats[regNum - UNW_RISCV_F0] = value;
4317
# else
4318
(void)regNum;
4319
(void)value;
4320
_LIBUNWIND_ABORT("libunwind not built with float support");
4321
# endif
4322
}
4323
4324
inline bool Registers_riscv::validVectorRegister(int) const {
4325
return false;
4326
}
4327
4328
inline v128 Registers_riscv::getVectorRegister(int) const {
4329
_LIBUNWIND_ABORT("no riscv vector register support yet");
4330
}
4331
4332
inline void Registers_riscv::setVectorRegister(int, v128) {
4333
_LIBUNWIND_ABORT("no riscv vector register support yet");
4334
}
4335
#endif // _LIBUNWIND_TARGET_RISCV
4336
4337
#if defined(_LIBUNWIND_TARGET_VE)
4338
/// Registers_ve holds the register state of a thread in a VE process.
4339
class _LIBUNWIND_HIDDEN Registers_ve {
4340
public:
4341
Registers_ve();
4342
Registers_ve(const void *registers);
4343
4344
bool validRegister(int num) const;
4345
uint64_t getRegister(int num) const;
4346
void setRegister(int num, uint64_t value);
4347
bool validFloatRegister(int num) const;
4348
double getFloatRegister(int num) const;
4349
void setFloatRegister(int num, double value);
4350
bool validVectorRegister(int num) const;
4351
v128 getVectorRegister(int num) const;
4352
void setVectorRegister(int num, v128 value);
4353
static const char *getRegisterName(int num);
4354
void jumpto();
4355
static constexpr int lastDwarfRegNum() {
4356
return _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE;
4357
}
4358
static int getArch() { return REGISTERS_VE; }
4359
4360
uint64_t getSP() const { return _registers.__s[11]; }
4361
void setSP(uint64_t value) { _registers.__s[11] = value; }
4362
uint64_t getIP() const { return _registers.__ic; }
4363
void setIP(uint64_t value) { _registers.__ic = value; }
4364
4365
private:
4366
// FIXME: Need to store not only scalar registers but also vector and vector
4367
// mask registers. VEOS uses mcontext_t defined in ucontext.h. It takes
4368
// 524288 bytes (65536*8 bytes), though. Currently, we use libunwind for
4369
// SjLj exception support only, so Registers_ve is not implemented completely.
4370
struct ve_thread_state_t {
4371
uint64_t __s[64]; // s0-s64
4372
uint64_t __ic; // Instruction counter (IC)
4373
uint64_t __vixr; // Vector Index Register
4374
uint64_t __vl; // Vector Length Register
4375
};
4376
4377
ve_thread_state_t _registers; // total 67 registers
4378
4379
// Currently no vector register is preserved.
4380
};
4381
4382
inline Registers_ve::Registers_ve(const void *registers) {
4383
static_assert((check_fit<Registers_ve, unw_context_t>::does_fit),
4384
"ve registers do not fit into unw_context_t");
4385
memcpy(&_registers, static_cast<const uint8_t *>(registers),
4386
sizeof(_registers));
4387
static_assert(sizeof(_registers) == 536,
4388
"expected vector register offset to be 536");
4389
}
4390
4391
inline Registers_ve::Registers_ve() {
4392
memset(&_registers, 0, sizeof(_registers));
4393
}
4394
4395
inline bool Registers_ve::validRegister(int regNum) const {
4396
if (regNum >= UNW_VE_S0 && regNum <= UNW_VE_S63)
4397
return true;
4398
4399
switch (regNum) {
4400
case UNW_REG_IP:
4401
case UNW_REG_SP:
4402
case UNW_VE_VIXR:
4403
case UNW_VE_VL:
4404
return true;
4405
default:
4406
return false;
4407
}
4408
}
4409
4410
inline uint64_t Registers_ve::getRegister(int regNum) const {
4411
if (regNum >= UNW_VE_S0 && regNum <= UNW_VE_S63)
4412
return _registers.__s[regNum - UNW_VE_S0];
4413
4414
switch (regNum) {
4415
case UNW_REG_IP:
4416
return _registers.__ic;
4417
case UNW_REG_SP:
4418
return _registers.__s[11];
4419
case UNW_VE_VIXR:
4420
return _registers.__vixr;
4421
case UNW_VE_VL:
4422
return _registers.__vl;
4423
}
4424
_LIBUNWIND_ABORT("unsupported ve register");
4425
}
4426
4427
inline void Registers_ve::setRegister(int regNum, uint64_t value) {
4428
if (regNum >= UNW_VE_S0 && regNum <= UNW_VE_S63) {
4429
_registers.__s[regNum - UNW_VE_S0] = value;
4430
return;
4431
}
4432
4433
switch (regNum) {
4434
case UNW_REG_IP:
4435
_registers.__ic = value;
4436
return;
4437
case UNW_REG_SP:
4438
_registers.__s[11] = value;
4439
return;
4440
case UNW_VE_VIXR:
4441
_registers.__vixr = value;
4442
return;
4443
case UNW_VE_VL:
4444
_registers.__vl = value;
4445
return;
4446
}
4447
_LIBUNWIND_ABORT("unsupported ve register");
4448
}
4449
4450
inline bool Registers_ve::validFloatRegister(int /* regNum */) const {
4451
return false;
4452
}
4453
4454
inline double Registers_ve::getFloatRegister(int /* regNum */) const {
4455
_LIBUNWIND_ABORT("VE doesn't have float registers");
4456
}
4457
4458
inline void Registers_ve::setFloatRegister(int /* regNum */,
4459
double /* value */) {
4460
_LIBUNWIND_ABORT("VE doesn't have float registers");
4461
}
4462
4463
inline bool Registers_ve::validVectorRegister(int /* regNum */) const {
4464
return false;
4465
}
4466
4467
inline v128 Registers_ve::getVectorRegister(int /* regNum */) const {
4468
_LIBUNWIND_ABORT("VE vector support not implemented");
4469
}
4470
4471
inline void Registers_ve::setVectorRegister(int /* regNum */,
4472
v128 /* value */) {
4473
_LIBUNWIND_ABORT("VE vector support not implemented");
4474
}
4475
4476
inline const char *Registers_ve::getRegisterName(int regNum) {
4477
switch (regNum) {
4478
case UNW_REG_IP:
4479
return "ip";
4480
case UNW_REG_SP:
4481
return "sp";
4482
case UNW_VE_VIXR:
4483
return "vixr";
4484
case UNW_VE_VL:
4485
return "vl";
4486
case UNW_VE_S0:
4487
return "s0";
4488
case UNW_VE_S1:
4489
return "s1";
4490
case UNW_VE_S2:
4491
return "s2";
4492
case UNW_VE_S3:
4493
return "s3";
4494
case UNW_VE_S4:
4495
return "s4";
4496
case UNW_VE_S5:
4497
return "s5";
4498
case UNW_VE_S6:
4499
return "s6";
4500
case UNW_VE_S7:
4501
return "s7";
4502
case UNW_VE_S8:
4503
return "s8";
4504
case UNW_VE_S9:
4505
return "s9";
4506
case UNW_VE_S10:
4507
return "s10";
4508
case UNW_VE_S11:
4509
return "s11";
4510
case UNW_VE_S12:
4511
return "s12";
4512
case UNW_VE_S13:
4513
return "s13";
4514
case UNW_VE_S14:
4515
return "s14";
4516
case UNW_VE_S15:
4517
return "s15";
4518
case UNW_VE_S16:
4519
return "s16";
4520
case UNW_VE_S17:
4521
return "s17";
4522
case UNW_VE_S18:
4523
return "s18";
4524
case UNW_VE_S19:
4525
return "s19";
4526
case UNW_VE_S20:
4527
return "s20";
4528
case UNW_VE_S21:
4529
return "s21";
4530
case UNW_VE_S22:
4531
return "s22";
4532
case UNW_VE_S23:
4533
return "s23";
4534
case UNW_VE_S24:
4535
return "s24";
4536
case UNW_VE_S25:
4537
return "s25";
4538
case UNW_VE_S26:
4539
return "s26";
4540
case UNW_VE_S27:
4541
return "s27";
4542
case UNW_VE_S28:
4543
return "s28";
4544
case UNW_VE_S29:
4545
return "s29";
4546
case UNW_VE_S30:
4547
return "s30";
4548
case UNW_VE_S31:
4549
return "s31";
4550
case UNW_VE_S32:
4551
return "s32";
4552
case UNW_VE_S33:
4553
return "s33";
4554
case UNW_VE_S34:
4555
return "s34";
4556
case UNW_VE_S35:
4557
return "s35";
4558
case UNW_VE_S36:
4559
return "s36";
4560
case UNW_VE_S37:
4561
return "s37";
4562
case UNW_VE_S38:
4563
return "s38";
4564
case UNW_VE_S39:
4565
return "s39";
4566
case UNW_VE_S40:
4567
return "s40";
4568
case UNW_VE_S41:
4569
return "s41";
4570
case UNW_VE_S42:
4571
return "s42";
4572
case UNW_VE_S43:
4573
return "s43";
4574
case UNW_VE_S44:
4575
return "s44";
4576
case UNW_VE_S45:
4577
return "s45";
4578
case UNW_VE_S46:
4579
return "s46";
4580
case UNW_VE_S47:
4581
return "s47";
4582
case UNW_VE_S48:
4583
return "s48";
4584
case UNW_VE_S49:
4585
return "s49";
4586
case UNW_VE_S50:
4587
return "s50";
4588
case UNW_VE_S51:
4589
return "s51";
4590
case UNW_VE_S52:
4591
return "s52";
4592
case UNW_VE_S53:
4593
return "s53";
4594
case UNW_VE_S54:
4595
return "s54";
4596
case UNW_VE_S55:
4597
return "s55";
4598
case UNW_VE_S56:
4599
return "s56";
4600
case UNW_VE_S57:
4601
return "s57";
4602
case UNW_VE_S58:
4603
return "s58";
4604
case UNW_VE_S59:
4605
return "s59";
4606
case UNW_VE_S60:
4607
return "s60";
4608
case UNW_VE_S61:
4609
return "s61";
4610
case UNW_VE_S62:
4611
return "s62";
4612
case UNW_VE_S63:
4613
return "s63";
4614
case UNW_VE_V0:
4615
return "v0";
4616
case UNW_VE_V1:
4617
return "v1";
4618
case UNW_VE_V2:
4619
return "v2";
4620
case UNW_VE_V3:
4621
return "v3";
4622
case UNW_VE_V4:
4623
return "v4";
4624
case UNW_VE_V5:
4625
return "v5";
4626
case UNW_VE_V6:
4627
return "v6";
4628
case UNW_VE_V7:
4629
return "v7";
4630
case UNW_VE_V8:
4631
return "v8";
4632
case UNW_VE_V9:
4633
return "v9";
4634
case UNW_VE_V10:
4635
return "v10";
4636
case UNW_VE_V11:
4637
return "v11";
4638
case UNW_VE_V12:
4639
return "v12";
4640
case UNW_VE_V13:
4641
return "v13";
4642
case UNW_VE_V14:
4643
return "v14";
4644
case UNW_VE_V15:
4645
return "v15";
4646
case UNW_VE_V16:
4647
return "v16";
4648
case UNW_VE_V17:
4649
return "v17";
4650
case UNW_VE_V18:
4651
return "v18";
4652
case UNW_VE_V19:
4653
return "v19";
4654
case UNW_VE_V20:
4655
return "v20";
4656
case UNW_VE_V21:
4657
return "v21";
4658
case UNW_VE_V22:
4659
return "v22";
4660
case UNW_VE_V23:
4661
return "v23";
4662
case UNW_VE_V24:
4663
return "v24";
4664
case UNW_VE_V25:
4665
return "v25";
4666
case UNW_VE_V26:
4667
return "v26";
4668
case UNW_VE_V27:
4669
return "v27";
4670
case UNW_VE_V28:
4671
return "v28";
4672
case UNW_VE_V29:
4673
return "v29";
4674
case UNW_VE_V30:
4675
return "v30";
4676
case UNW_VE_V31:
4677
return "v31";
4678
case UNW_VE_V32:
4679
return "v32";
4680
case UNW_VE_V33:
4681
return "v33";
4682
case UNW_VE_V34:
4683
return "v34";
4684
case UNW_VE_V35:
4685
return "v35";
4686
case UNW_VE_V36:
4687
return "v36";
4688
case UNW_VE_V37:
4689
return "v37";
4690
case UNW_VE_V38:
4691
return "v38";
4692
case UNW_VE_V39:
4693
return "v39";
4694
case UNW_VE_V40:
4695
return "v40";
4696
case UNW_VE_V41:
4697
return "v41";
4698
case UNW_VE_V42:
4699
return "v42";
4700
case UNW_VE_V43:
4701
return "v43";
4702
case UNW_VE_V44:
4703
return "v44";
4704
case UNW_VE_V45:
4705
return "v45";
4706
case UNW_VE_V46:
4707
return "v46";
4708
case UNW_VE_V47:
4709
return "v47";
4710
case UNW_VE_V48:
4711
return "v48";
4712
case UNW_VE_V49:
4713
return "v49";
4714
case UNW_VE_V50:
4715
return "v50";
4716
case UNW_VE_V51:
4717
return "v51";
4718
case UNW_VE_V52:
4719
return "v52";
4720
case UNW_VE_V53:
4721
return "v53";
4722
case UNW_VE_V54:
4723
return "v54";
4724
case UNW_VE_V55:
4725
return "v55";
4726
case UNW_VE_V56:
4727
return "v56";
4728
case UNW_VE_V57:
4729
return "v57";
4730
case UNW_VE_V58:
4731
return "v58";
4732
case UNW_VE_V59:
4733
return "v59";
4734
case UNW_VE_V60:
4735
return "v60";
4736
case UNW_VE_V61:
4737
return "v61";
4738
case UNW_VE_V62:
4739
return "v62";
4740
case UNW_VE_V63:
4741
return "v63";
4742
case UNW_VE_VM0:
4743
return "vm0";
4744
case UNW_VE_VM1:
4745
return "vm1";
4746
case UNW_VE_VM2:
4747
return "vm2";
4748
case UNW_VE_VM3:
4749
return "vm3";
4750
case UNW_VE_VM4:
4751
return "vm4";
4752
case UNW_VE_VM5:
4753
return "vm5";
4754
case UNW_VE_VM6:
4755
return "vm6";
4756
case UNW_VE_VM7:
4757
return "vm7";
4758
case UNW_VE_VM8:
4759
return "vm8";
4760
case UNW_VE_VM9:
4761
return "vm9";
4762
case UNW_VE_VM10:
4763
return "vm10";
4764
case UNW_VE_VM11:
4765
return "vm11";
4766
case UNW_VE_VM12:
4767
return "vm12";
4768
case UNW_VE_VM13:
4769
return "vm13";
4770
case UNW_VE_VM14:
4771
return "vm14";
4772
case UNW_VE_VM15:
4773
return "vm15";
4774
}
4775
return "unknown register";
4776
}
4777
#endif // _LIBUNWIND_TARGET_VE
4778
4779
#if defined(_LIBUNWIND_TARGET_S390X)
4780
/// Registers_s390x holds the register state of a thread in a
4781
/// 64-bit Linux on IBM zSystems process.
4782
class _LIBUNWIND_HIDDEN Registers_s390x {
4783
public:
4784
Registers_s390x();
4785
Registers_s390x(const void *registers);
4786
4787
bool validRegister(int num) const;
4788
uint64_t getRegister(int num) const;
4789
void setRegister(int num, uint64_t value);
4790
bool validFloatRegister(int num) const;
4791
double getFloatRegister(int num) const;
4792
void setFloatRegister(int num, double value);
4793
bool validVectorRegister(int num) const;
4794
v128 getVectorRegister(int num) const;
4795
void setVectorRegister(int num, v128 value);
4796
static const char *getRegisterName(int num);
4797
void jumpto();
4798
static constexpr int lastDwarfRegNum() {
4799
return _LIBUNWIND_HIGHEST_DWARF_REGISTER_S390X;
4800
}
4801
static int getArch() { return REGISTERS_S390X; }
4802
4803
uint64_t getSP() const { return _registers.__gpr[15]; }
4804
void setSP(uint64_t value) { _registers.__gpr[15] = value; }
4805
uint64_t getIP() const { return _registers.__pswa; }
4806
void setIP(uint64_t value) { _registers.__pswa = value; }
4807
4808
private:
4809
struct s390x_thread_state_t {
4810
uint64_t __pswm; // Problem Status Word: Mask
4811
uint64_t __pswa; // Problem Status Word: Address (PC)
4812
uint64_t __gpr[16]; // General Purpose Registers
4813
double __fpr[16]; // Floating-Point Registers
4814
};
4815
4816
s390x_thread_state_t _registers;
4817
};
4818
4819
inline Registers_s390x::Registers_s390x(const void *registers) {
4820
static_assert((check_fit<Registers_s390x, unw_context_t>::does_fit),
4821
"s390x registers do not fit into unw_context_t");
4822
memcpy(&_registers, static_cast<const uint8_t *>(registers),
4823
sizeof(_registers));
4824
}
4825
4826
inline Registers_s390x::Registers_s390x() {
4827
memset(&_registers, 0, sizeof(_registers));
4828
}
4829
4830
inline bool Registers_s390x::validRegister(int regNum) const {
4831
switch (regNum) {
4832
case UNW_S390X_PSWM:
4833
case UNW_S390X_PSWA:
4834
case UNW_REG_IP:
4835
case UNW_REG_SP:
4836
return true;
4837
}
4838
4839
if (regNum >= UNW_S390X_R0 && regNum <= UNW_S390X_R15)
4840
return true;
4841
4842
return false;
4843
}
4844
4845
inline uint64_t Registers_s390x::getRegister(int regNum) const {
4846
if (regNum >= UNW_S390X_R0 && regNum <= UNW_S390X_R15)
4847
return _registers.__gpr[regNum - UNW_S390X_R0];
4848
4849
switch (regNum) {
4850
case UNW_S390X_PSWM:
4851
return _registers.__pswm;
4852
case UNW_S390X_PSWA:
4853
case UNW_REG_IP:
4854
return _registers.__pswa;
4855
case UNW_REG_SP:
4856
return _registers.__gpr[15];
4857
}
4858
_LIBUNWIND_ABORT("unsupported s390x register");
4859
}
4860
4861
inline void Registers_s390x::setRegister(int regNum, uint64_t value) {
4862
if (regNum >= UNW_S390X_R0 && regNum <= UNW_S390X_R15) {
4863
_registers.__gpr[regNum - UNW_S390X_R0] = value;
4864
return;
4865
}
4866
4867
switch (regNum) {
4868
case UNW_S390X_PSWM:
4869
_registers.__pswm = value;
4870
return;
4871
case UNW_S390X_PSWA:
4872
case UNW_REG_IP:
4873
_registers.__pswa = value;
4874
return;
4875
case UNW_REG_SP:
4876
_registers.__gpr[15] = value;
4877
return;
4878
}
4879
_LIBUNWIND_ABORT("unsupported s390x register");
4880
}
4881
4882
inline bool Registers_s390x::validFloatRegister(int regNum) const {
4883
return regNum >= UNW_S390X_F0 && regNum <= UNW_S390X_F15;
4884
}
4885
4886
inline double Registers_s390x::getFloatRegister(int regNum) const {
4887
// NOTE: FPR DWARF register numbers are not consecutive.
4888
switch (regNum) {
4889
case UNW_S390X_F0:
4890
return _registers.__fpr[0];
4891
case UNW_S390X_F1:
4892
return _registers.__fpr[1];
4893
case UNW_S390X_F2:
4894
return _registers.__fpr[2];
4895
case UNW_S390X_F3:
4896
return _registers.__fpr[3];
4897
case UNW_S390X_F4:
4898
return _registers.__fpr[4];
4899
case UNW_S390X_F5:
4900
return _registers.__fpr[5];
4901
case UNW_S390X_F6:
4902
return _registers.__fpr[6];
4903
case UNW_S390X_F7:
4904
return _registers.__fpr[7];
4905
case UNW_S390X_F8:
4906
return _registers.__fpr[8];
4907
case UNW_S390X_F9:
4908
return _registers.__fpr[9];
4909
case UNW_S390X_F10:
4910
return _registers.__fpr[10];
4911
case UNW_S390X_F11:
4912
return _registers.__fpr[11];
4913
case UNW_S390X_F12:
4914
return _registers.__fpr[12];
4915
case UNW_S390X_F13:
4916
return _registers.__fpr[13];
4917
case UNW_S390X_F14:
4918
return _registers.__fpr[14];
4919
case UNW_S390X_F15:
4920
return _registers.__fpr[15];
4921
}
4922
_LIBUNWIND_ABORT("unsupported s390x register");
4923
}
4924
4925
inline void Registers_s390x::setFloatRegister(int regNum, double value) {
4926
// NOTE: FPR DWARF register numbers are not consecutive.
4927
switch (regNum) {
4928
case UNW_S390X_F0:
4929
_registers.__fpr[0] = value;
4930
return;
4931
case UNW_S390X_F1:
4932
_registers.__fpr[1] = value;
4933
return;
4934
case UNW_S390X_F2:
4935
_registers.__fpr[2] = value;
4936
return;
4937
case UNW_S390X_F3:
4938
_registers.__fpr[3] = value;
4939
return;
4940
case UNW_S390X_F4:
4941
_registers.__fpr[4] = value;
4942
return;
4943
case UNW_S390X_F5:
4944
_registers.__fpr[5] = value;
4945
return;
4946
case UNW_S390X_F6:
4947
_registers.__fpr[6] = value;
4948
return;
4949
case UNW_S390X_F7:
4950
_registers.__fpr[7] = value;
4951
return;
4952
case UNW_S390X_F8:
4953
_registers.__fpr[8] = value;
4954
return;
4955
case UNW_S390X_F9:
4956
_registers.__fpr[9] = value;
4957
return;
4958
case UNW_S390X_F10:
4959
_registers.__fpr[10] = value;
4960
return;
4961
case UNW_S390X_F11:
4962
_registers.__fpr[11] = value;
4963
return;
4964
case UNW_S390X_F12:
4965
_registers.__fpr[12] = value;
4966
return;
4967
case UNW_S390X_F13:
4968
_registers.__fpr[13] = value;
4969
return;
4970
case UNW_S390X_F14:
4971
_registers.__fpr[14] = value;
4972
return;
4973
case UNW_S390X_F15:
4974
_registers.__fpr[15] = value;
4975
return;
4976
}
4977
_LIBUNWIND_ABORT("unsupported s390x register");
4978
}
4979
4980
inline bool Registers_s390x::validVectorRegister(int /*regNum*/) const {
4981
return false;
4982
}
4983
4984
inline v128 Registers_s390x::getVectorRegister(int /*regNum*/) const {
4985
_LIBUNWIND_ABORT("s390x vector support not implemented");
4986
}
4987
4988
inline void Registers_s390x::setVectorRegister(int /*regNum*/, v128 /*value*/) {
4989
_LIBUNWIND_ABORT("s390x vector support not implemented");
4990
}
4991
4992
inline const char *Registers_s390x::getRegisterName(int regNum) {
4993
switch (regNum) {
4994
case UNW_REG_IP:
4995
return "ip";
4996
case UNW_REG_SP:
4997
return "sp";
4998
case UNW_S390X_R0:
4999
return "r0";
5000
case UNW_S390X_R1:
5001
return "r1";
5002
case UNW_S390X_R2:
5003
return "r2";
5004
case UNW_S390X_R3:
5005
return "r3";
5006
case UNW_S390X_R4:
5007
return "r4";
5008
case UNW_S390X_R5:
5009
return "r5";
5010
case UNW_S390X_R6:
5011
return "r6";
5012
case UNW_S390X_R7:
5013
return "r7";
5014
case UNW_S390X_R8:
5015
return "r8";
5016
case UNW_S390X_R9:
5017
return "r9";
5018
case UNW_S390X_R10:
5019
return "r10";
5020
case UNW_S390X_R11:
5021
return "r11";
5022
case UNW_S390X_R12:
5023
return "r12";
5024
case UNW_S390X_R13:
5025
return "r13";
5026
case UNW_S390X_R14:
5027
return "r14";
5028
case UNW_S390X_R15:
5029
return "r15";
5030
case UNW_S390X_F0:
5031
return "f0";
5032
case UNW_S390X_F1:
5033
return "f1";
5034
case UNW_S390X_F2:
5035
return "f2";
5036
case UNW_S390X_F3:
5037
return "f3";
5038
case UNW_S390X_F4:
5039
return "f4";
5040
case UNW_S390X_F5:
5041
return "f5";
5042
case UNW_S390X_F6:
5043
return "f6";
5044
case UNW_S390X_F7:
5045
return "f7";
5046
case UNW_S390X_F8:
5047
return "f8";
5048
case UNW_S390X_F9:
5049
return "f9";
5050
case UNW_S390X_F10:
5051
return "f10";
5052
case UNW_S390X_F11:
5053
return "f11";
5054
case UNW_S390X_F12:
5055
return "f12";
5056
case UNW_S390X_F13:
5057
return "f13";
5058
case UNW_S390X_F14:
5059
return "f14";
5060
case UNW_S390X_F15:
5061
return "f15";
5062
}
5063
return "unknown register";
5064
}
5065
#endif // _LIBUNWIND_TARGET_S390X
5066
5067
#if defined(_LIBUNWIND_TARGET_LOONGARCH)
5068
/// Registers_loongarch holds the register state of a thread in a 64-bit
5069
/// LoongArch process.
5070
class _LIBUNWIND_HIDDEN Registers_loongarch {
5071
public:
5072
Registers_loongarch();
5073
Registers_loongarch(const void *registers);
5074
5075
bool validRegister(int num) const;
5076
uint64_t getRegister(int num) const;
5077
void setRegister(int num, uint64_t value);
5078
bool validFloatRegister(int num) const;
5079
double getFloatRegister(int num) const;
5080
void setFloatRegister(int num, double value);
5081
bool validVectorRegister(int num) const;
5082
v128 getVectorRegister(int num) const;
5083
void setVectorRegister(int num, v128 value);
5084
static const char *getRegisterName(int num);
5085
void jumpto();
5086
static constexpr int lastDwarfRegNum() {
5087
return _LIBUNWIND_HIGHEST_DWARF_REGISTER_LOONGARCH;
5088
}
5089
static int getArch() { return REGISTERS_LOONGARCH; }
5090
5091
uint64_t getSP() const { return _registers.__r[3]; }
5092
void setSP(uint64_t value) { _registers.__r[3] = value; }
5093
uint64_t getIP() const { return _registers.__pc; }
5094
void setIP(uint64_t value) { _registers.__pc = value; }
5095
5096
private:
5097
struct loongarch_thread_state_t {
5098
uint64_t __r[32];
5099
uint64_t __pc;
5100
};
5101
5102
loongarch_thread_state_t _registers;
5103
#if __loongarch_frlen == 64
5104
double _floats[32];
5105
#endif
5106
};
5107
5108
inline Registers_loongarch::Registers_loongarch(const void *registers) {
5109
static_assert((check_fit<Registers_loongarch, unw_context_t>::does_fit),
5110
"loongarch registers do not fit into unw_context_t");
5111
memcpy(&_registers, registers, sizeof(_registers));
5112
static_assert(sizeof(_registers) == 0x108,
5113
"expected float registers to be at offset 264");
5114
#if __loongarch_frlen == 64
5115
memcpy(_floats, static_cast<const uint8_t *>(registers) + sizeof(_registers),
5116
sizeof(_floats));
5117
#endif
5118
}
5119
5120
inline Registers_loongarch::Registers_loongarch() {
5121
memset(&_registers, 0, sizeof(_registers));
5122
#if __loongarch_frlen == 64
5123
memset(&_floats, 0, sizeof(_floats));
5124
#endif
5125
}
5126
5127
inline bool Registers_loongarch::validRegister(int regNum) const {
5128
if (regNum == UNW_REG_IP || regNum == UNW_REG_SP)
5129
return true;
5130
if (regNum < 0 || regNum > UNW_LOONGARCH_F31)
5131
return false;
5132
return true;
5133
}
5134
5135
inline uint64_t Registers_loongarch::getRegister(int regNum) const {
5136
if (regNum >= UNW_LOONGARCH_R0 && regNum <= UNW_LOONGARCH_R31)
5137
return _registers.__r[regNum - UNW_LOONGARCH_R0];
5138
5139
if (regNum == UNW_REG_IP)
5140
return _registers.__pc;
5141
if (regNum == UNW_REG_SP)
5142
return _registers.__r[3];
5143
_LIBUNWIND_ABORT("unsupported loongarch register");
5144
}
5145
5146
inline void Registers_loongarch::setRegister(int regNum, uint64_t value) {
5147
if (regNum >= UNW_LOONGARCH_R0 && regNum <= UNW_LOONGARCH_R31)
5148
_registers.__r[regNum - UNW_LOONGARCH_R0] = value;
5149
else if (regNum == UNW_REG_IP)
5150
_registers.__pc = value;
5151
else if (regNum == UNW_REG_SP)
5152
_registers.__r[3] = value;
5153
else
5154
_LIBUNWIND_ABORT("unsupported loongarch register");
5155
}
5156
5157
inline const char *Registers_loongarch::getRegisterName(int regNum) {
5158
switch (regNum) {
5159
case UNW_REG_IP:
5160
return "$pc";
5161
case UNW_REG_SP:
5162
return "$sp";
5163
case UNW_LOONGARCH_R0:
5164
return "$r0";
5165
case UNW_LOONGARCH_R1:
5166
return "$r1";
5167
case UNW_LOONGARCH_R2:
5168
return "$r2";
5169
case UNW_LOONGARCH_R3:
5170
return "$r3";
5171
case UNW_LOONGARCH_R4:
5172
return "$r4";
5173
case UNW_LOONGARCH_R5:
5174
return "$r5";
5175
case UNW_LOONGARCH_R6:
5176
return "$r6";
5177
case UNW_LOONGARCH_R7:
5178
return "$r7";
5179
case UNW_LOONGARCH_R8:
5180
return "$r8";
5181
case UNW_LOONGARCH_R9:
5182
return "$r9";
5183
case UNW_LOONGARCH_R10:
5184
return "$r10";
5185
case UNW_LOONGARCH_R11:
5186
return "$r11";
5187
case UNW_LOONGARCH_R12:
5188
return "$r12";
5189
case UNW_LOONGARCH_R13:
5190
return "$r13";
5191
case UNW_LOONGARCH_R14:
5192
return "$r14";
5193
case UNW_LOONGARCH_R15:
5194
return "$r15";
5195
case UNW_LOONGARCH_R16:
5196
return "$r16";
5197
case UNW_LOONGARCH_R17:
5198
return "$r17";
5199
case UNW_LOONGARCH_R18:
5200
return "$r18";
5201
case UNW_LOONGARCH_R19:
5202
return "$r19";
5203
case UNW_LOONGARCH_R20:
5204
return "$r20";
5205
case UNW_LOONGARCH_R21:
5206
return "$r21";
5207
case UNW_LOONGARCH_R22:
5208
return "$r22";
5209
case UNW_LOONGARCH_R23:
5210
return "$r23";
5211
case UNW_LOONGARCH_R24:
5212
return "$r24";
5213
case UNW_LOONGARCH_R25:
5214
return "$r25";
5215
case UNW_LOONGARCH_R26:
5216
return "$r26";
5217
case UNW_LOONGARCH_R27:
5218
return "$r27";
5219
case UNW_LOONGARCH_R28:
5220
return "$r28";
5221
case UNW_LOONGARCH_R29:
5222
return "$r29";
5223
case UNW_LOONGARCH_R30:
5224
return "$r30";
5225
case UNW_LOONGARCH_R31:
5226
return "$r31";
5227
case UNW_LOONGARCH_F0:
5228
return "$f0";
5229
case UNW_LOONGARCH_F1:
5230
return "$f1";
5231
case UNW_LOONGARCH_F2:
5232
return "$f2";
5233
case UNW_LOONGARCH_F3:
5234
return "$f3";
5235
case UNW_LOONGARCH_F4:
5236
return "$f4";
5237
case UNW_LOONGARCH_F5:
5238
return "$f5";
5239
case UNW_LOONGARCH_F6:
5240
return "$f6";
5241
case UNW_LOONGARCH_F7:
5242
return "$f7";
5243
case UNW_LOONGARCH_F8:
5244
return "$f8";
5245
case UNW_LOONGARCH_F9:
5246
return "$f9";
5247
case UNW_LOONGARCH_F10:
5248
return "$f10";
5249
case UNW_LOONGARCH_F11:
5250
return "$f11";
5251
case UNW_LOONGARCH_F12:
5252
return "$f12";
5253
case UNW_LOONGARCH_F13:
5254
return "$f13";
5255
case UNW_LOONGARCH_F14:
5256
return "$f14";
5257
case UNW_LOONGARCH_F15:
5258
return "$f15";
5259
case UNW_LOONGARCH_F16:
5260
return "$f16";
5261
case UNW_LOONGARCH_F17:
5262
return "$f17";
5263
case UNW_LOONGARCH_F18:
5264
return "$f18";
5265
case UNW_LOONGARCH_F19:
5266
return "$f19";
5267
case UNW_LOONGARCH_F20:
5268
return "$f20";
5269
case UNW_LOONGARCH_F21:
5270
return "$f21";
5271
case UNW_LOONGARCH_F22:
5272
return "$f22";
5273
case UNW_LOONGARCH_F23:
5274
return "$f23";
5275
case UNW_LOONGARCH_F24:
5276
return "$f24";
5277
case UNW_LOONGARCH_F25:
5278
return "$f25";
5279
case UNW_LOONGARCH_F26:
5280
return "$f26";
5281
case UNW_LOONGARCH_F27:
5282
return "$f27";
5283
case UNW_LOONGARCH_F28:
5284
return "$f28";
5285
case UNW_LOONGARCH_F29:
5286
return "$f29";
5287
case UNW_LOONGARCH_F30:
5288
return "$f30";
5289
case UNW_LOONGARCH_F31:
5290
return "$f31";
5291
default:
5292
return "unknown register";
5293
}
5294
}
5295
5296
inline bool Registers_loongarch::validFloatRegister(int regNum) const {
5297
if (regNum < UNW_LOONGARCH_F0 || regNum > UNW_LOONGARCH_F31)
5298
return false;
5299
return true;
5300
}
5301
5302
inline double Registers_loongarch::getFloatRegister(int regNum) const {
5303
#if __loongarch_frlen == 64
5304
assert(validFloatRegister(regNum));
5305
return _floats[regNum - UNW_LOONGARCH_F0];
5306
#else
5307
_LIBUNWIND_ABORT("libunwind not built with float support");
5308
#endif
5309
}
5310
5311
inline void Registers_loongarch::setFloatRegister(int regNum, double value) {
5312
#if __loongarch_frlen == 64
5313
assert(validFloatRegister(regNum));
5314
_floats[regNum - UNW_LOONGARCH_F0] = value;
5315
#else
5316
_LIBUNWIND_ABORT("libunwind not built with float support");
5317
#endif
5318
}
5319
5320
inline bool Registers_loongarch::validVectorRegister(int) const {
5321
return false;
5322
}
5323
5324
inline v128 Registers_loongarch::getVectorRegister(int) const {
5325
_LIBUNWIND_ABORT("loongarch vector support not implemented");
5326
}
5327
5328
inline void Registers_loongarch::setVectorRegister(int, v128) {
5329
_LIBUNWIND_ABORT("loongarch vector support not implemented");
5330
}
5331
#endif //_LIBUNWIND_TARGET_LOONGARCH
5332
5333
} // namespace libunwind
5334
5335
#endif // __REGISTERS_HPP__
5336
5337