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