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