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 class _LIBUNWIND_HIDDEN Registers_arm64 {
1819 public:
1820   Registers_arm64();
1821   Registers_arm64(const void *registers);
1822 
1823   bool        validRegister(int num) const;
1824   uint64_t    getRegister(int num) const;
1825   void        setRegister(int num, uint64_t value);
1826   bool        validFloatRegister(int num) const;
1827   double      getFloatRegister(int num) const;
1828   void        setFloatRegister(int num, double value);
1829   bool        validVectorRegister(int num) const;
1830   v128        getVectorRegister(int num) const;
1831   void        setVectorRegister(int num, v128 value);
1832   static const char *getRegisterName(int num);
jumpto()1833   void        jumpto() { __libunwind_Registers_arm64_jumpto(this); }
lastDwarfRegNum()1834   static constexpr int lastDwarfRegNum() {
1835     return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64;
1836   }
getArch()1837   static int  getArch() { return REGISTERS_ARM64; }
1838 
getSP() const1839   uint64_t  getSP() const         { return _registers.__sp; }
setSP(uint64_t value)1840   void      setSP(uint64_t value) { _registers.__sp = value; }
getIP() const1841   uint64_t  getIP() const         { return _registers.__pc; }
setIP(uint64_t value)1842   void      setIP(uint64_t value) { _registers.__pc = value; }
getFP() const1843   uint64_t  getFP() const         { return _registers.__fp; }
setFP(uint64_t value)1844   void      setFP(uint64_t value) { _registers.__fp = value; }
1845 
1846 private:
1847   struct GPRs {
1848     uint64_t __x[29]; // x0-x28
1849     uint64_t __fp;    // Frame pointer x29
1850     uint64_t __lr;    // Link register x30
1851     uint64_t __sp;    // Stack pointer x31
1852     uint64_t __pc;    // Program counter
1853     uint64_t __ra_sign_state; // RA sign state register
1854   };
1855 
1856   GPRs    _registers;
1857   double  _vectorHalfRegisters[32];
1858   // Currently only the lower double in 128-bit vectore registers
1859   // is perserved during unwinding.  We could define new register
1860   // numbers (> 96) which mean whole vector registers, then this
1861   // struct would need to change to contain whole vector registers.
1862 };
1863 
Registers_arm64(const void * registers)1864 inline Registers_arm64::Registers_arm64(const void *registers) {
1865   static_assert((check_fit<Registers_arm64, unw_context_t>::does_fit),
1866                 "arm64 registers do not fit into unw_context_t");
1867   memcpy(&_registers, registers, sizeof(_registers));
1868   static_assert(sizeof(GPRs) == 0x110,
1869                 "expected VFP registers to be at offset 272");
1870   memcpy(_vectorHalfRegisters,
1871          static_cast<const uint8_t *>(registers) + sizeof(GPRs),
1872          sizeof(_vectorHalfRegisters));
1873 }
1874 
Registers_arm64()1875 inline Registers_arm64::Registers_arm64() {
1876   memset(&_registers, 0, sizeof(_registers));
1877   memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
1878 }
1879 
validRegister(int regNum) const1880 inline bool Registers_arm64::validRegister(int regNum) const {
1881   if (regNum == UNW_REG_IP)
1882     return true;
1883   if (regNum == UNW_REG_SP)
1884     return true;
1885   if (regNum < 0)
1886     return false;
1887   if (regNum > 95)
1888     return false;
1889   if (regNum == UNW_AARCH64_RA_SIGN_STATE)
1890     return true;
1891   if ((regNum > 32) && (regNum < 64))
1892     return false;
1893   return true;
1894 }
1895 
getRegister(int regNum) const1896 inline uint64_t Registers_arm64::getRegister(int regNum) const {
1897   if (regNum == UNW_REG_IP || regNum == UNW_AARCH64_PC)
1898     return _registers.__pc;
1899   if (regNum == UNW_REG_SP || regNum == UNW_AARCH64_SP)
1900     return _registers.__sp;
1901   if (regNum == UNW_AARCH64_RA_SIGN_STATE)
1902     return _registers.__ra_sign_state;
1903   if (regNum == UNW_AARCH64_FP)
1904     return _registers.__fp;
1905   if (regNum == UNW_AARCH64_LR)
1906     return _registers.__lr;
1907   if ((regNum >= 0) && (regNum < 29))
1908     return _registers.__x[regNum];
1909   _LIBUNWIND_ABORT("unsupported arm64 register");
1910 }
1911 
setRegister(int regNum,uint64_t value)1912 inline void Registers_arm64::setRegister(int regNum, uint64_t value) {
1913   if (regNum == UNW_REG_IP || regNum == UNW_AARCH64_PC)
1914     _registers.__pc = value;
1915   else if (regNum == UNW_REG_SP || regNum == UNW_AARCH64_SP)
1916     _registers.__sp = value;
1917   else if (regNum == UNW_AARCH64_RA_SIGN_STATE)
1918     _registers.__ra_sign_state = value;
1919   else if (regNum == UNW_AARCH64_FP)
1920     _registers.__fp = value;
1921   else if (regNum == UNW_AARCH64_LR)
1922     _registers.__lr = value;
1923   else if ((regNum >= 0) && (regNum < 29))
1924     _registers.__x[regNum] = value;
1925   else
1926     _LIBUNWIND_ABORT("unsupported arm64 register");
1927 }
1928 
getRegisterName(int regNum)1929 inline const char *Registers_arm64::getRegisterName(int regNum) {
1930   switch (regNum) {
1931   case UNW_REG_IP:
1932     return "pc";
1933   case UNW_REG_SP:
1934     return "sp";
1935   case UNW_AARCH64_X0:
1936     return "x0";
1937   case UNW_AARCH64_X1:
1938     return "x1";
1939   case UNW_AARCH64_X2:
1940     return "x2";
1941   case UNW_AARCH64_X3:
1942     return "x3";
1943   case UNW_AARCH64_X4:
1944     return "x4";
1945   case UNW_AARCH64_X5:
1946     return "x5";
1947   case UNW_AARCH64_X6:
1948     return "x6";
1949   case UNW_AARCH64_X7:
1950     return "x7";
1951   case UNW_AARCH64_X8:
1952     return "x8";
1953   case UNW_AARCH64_X9:
1954     return "x9";
1955   case UNW_AARCH64_X10:
1956     return "x10";
1957   case UNW_AARCH64_X11:
1958     return "x11";
1959   case UNW_AARCH64_X12:
1960     return "x12";
1961   case UNW_AARCH64_X13:
1962     return "x13";
1963   case UNW_AARCH64_X14:
1964     return "x14";
1965   case UNW_AARCH64_X15:
1966     return "x15";
1967   case UNW_AARCH64_X16:
1968     return "x16";
1969   case UNW_AARCH64_X17:
1970     return "x17";
1971   case UNW_AARCH64_X18:
1972     return "x18";
1973   case UNW_AARCH64_X19:
1974     return "x19";
1975   case UNW_AARCH64_X20:
1976     return "x20";
1977   case UNW_AARCH64_X21:
1978     return "x21";
1979   case UNW_AARCH64_X22:
1980     return "x22";
1981   case UNW_AARCH64_X23:
1982     return "x23";
1983   case UNW_AARCH64_X24:
1984     return "x24";
1985   case UNW_AARCH64_X25:
1986     return "x25";
1987   case UNW_AARCH64_X26:
1988     return "x26";
1989   case UNW_AARCH64_X27:
1990     return "x27";
1991   case UNW_AARCH64_X28:
1992     return "x28";
1993   case UNW_AARCH64_FP:
1994     return "fp";
1995   case UNW_AARCH64_LR:
1996     return "lr";
1997   case UNW_AARCH64_SP:
1998     return "sp";
1999   case UNW_AARCH64_PC:
2000     return "pc";
2001   case UNW_AARCH64_V0:
2002     return "d0";
2003   case UNW_AARCH64_V1:
2004     return "d1";
2005   case UNW_AARCH64_V2:
2006     return "d2";
2007   case UNW_AARCH64_V3:
2008     return "d3";
2009   case UNW_AARCH64_V4:
2010     return "d4";
2011   case UNW_AARCH64_V5:
2012     return "d5";
2013   case UNW_AARCH64_V6:
2014     return "d6";
2015   case UNW_AARCH64_V7:
2016     return "d7";
2017   case UNW_AARCH64_V8:
2018     return "d8";
2019   case UNW_AARCH64_V9:
2020     return "d9";
2021   case UNW_AARCH64_V10:
2022     return "d10";
2023   case UNW_AARCH64_V11:
2024     return "d11";
2025   case UNW_AARCH64_V12:
2026     return "d12";
2027   case UNW_AARCH64_V13:
2028     return "d13";
2029   case UNW_AARCH64_V14:
2030     return "d14";
2031   case UNW_AARCH64_V15:
2032     return "d15";
2033   case UNW_AARCH64_V16:
2034     return "d16";
2035   case UNW_AARCH64_V17:
2036     return "d17";
2037   case UNW_AARCH64_V18:
2038     return "d18";
2039   case UNW_AARCH64_V19:
2040     return "d19";
2041   case UNW_AARCH64_V20:
2042     return "d20";
2043   case UNW_AARCH64_V21:
2044     return "d21";
2045   case UNW_AARCH64_V22:
2046     return "d22";
2047   case UNW_AARCH64_V23:
2048     return "d23";
2049   case UNW_AARCH64_V24:
2050     return "d24";
2051   case UNW_AARCH64_V25:
2052     return "d25";
2053   case UNW_AARCH64_V26:
2054     return "d26";
2055   case UNW_AARCH64_V27:
2056     return "d27";
2057   case UNW_AARCH64_V28:
2058     return "d28";
2059   case UNW_AARCH64_V29:
2060     return "d29";
2061   case UNW_AARCH64_V30:
2062     return "d30";
2063   case UNW_AARCH64_V31:
2064     return "d31";
2065   default:
2066     return "unknown register";
2067   }
2068 }
2069 
validFloatRegister(int regNum) const2070 inline bool Registers_arm64::validFloatRegister(int regNum) const {
2071   if (regNum < UNW_AARCH64_V0)
2072     return false;
2073   if (regNum > UNW_AARCH64_V31)
2074     return false;
2075   return true;
2076 }
2077 
getFloatRegister(int regNum) const2078 inline double Registers_arm64::getFloatRegister(int regNum) const {
2079   assert(validFloatRegister(regNum));
2080   return _vectorHalfRegisters[regNum - UNW_AARCH64_V0];
2081 }
2082 
setFloatRegister(int regNum,double value)2083 inline void Registers_arm64::setFloatRegister(int regNum, double value) {
2084   assert(validFloatRegister(regNum));
2085   _vectorHalfRegisters[regNum - UNW_AARCH64_V0] = value;
2086 }
2087 
validVectorRegister(int) const2088 inline bool Registers_arm64::validVectorRegister(int) const {
2089   return false;
2090 }
2091 
getVectorRegister(int) const2092 inline v128 Registers_arm64::getVectorRegister(int) const {
2093   _LIBUNWIND_ABORT("no arm64 vector register support yet");
2094 }
2095 
setVectorRegister(int,v128)2096 inline void Registers_arm64::setVectorRegister(int, v128) {
2097   _LIBUNWIND_ABORT("no arm64 vector register support yet");
2098 }
2099 #endif // _LIBUNWIND_TARGET_AARCH64
2100 
2101 #if defined(_LIBUNWIND_TARGET_ARM)
2102 /// Registers_arm holds the register state of a thread in a 32-bit arm
2103 /// process.
2104 ///
2105 /// NOTE: Assumes VFPv3. On ARM processors without a floating point unit,
2106 /// this uses more memory than required.
2107 class _LIBUNWIND_HIDDEN Registers_arm {
2108 public:
2109   Registers_arm();
2110   Registers_arm(const void *registers);
2111 
2112   bool        validRegister(int num) const;
2113   uint32_t    getRegister(int num) const;
2114   void        setRegister(int num, uint32_t value);
2115   bool        validFloatRegister(int num) const;
2116   unw_fpreg_t getFloatRegister(int num);
2117   void        setFloatRegister(int num, unw_fpreg_t value);
2118   bool        validVectorRegister(int num) const;
2119   v128        getVectorRegister(int num) const;
2120   void        setVectorRegister(int num, v128 value);
2121   static const char *getRegisterName(int num);
jumpto()2122   void        jumpto() {
2123     restoreSavedFloatRegisters();
2124     restoreCoreAndJumpTo();
2125   }
lastDwarfRegNum()2126   static constexpr int lastDwarfRegNum() {
2127     return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM;
2128   }
getArch()2129   static int  getArch() { return REGISTERS_ARM; }
2130 
getSP() const2131   uint32_t  getSP() const         { return _registers.__sp; }
setSP(uint32_t value)2132   void      setSP(uint32_t value) { _registers.__sp = value; }
getIP() const2133   uint32_t  getIP() const         { return _registers.__pc; }
setIP(uint32_t value)2134   void      setIP(uint32_t value) { _registers.__pc = value; }
2135 
saveVFPAsX()2136   void saveVFPAsX() {
2137     assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15);
2138     _use_X_for_vfp_save = true;
2139   }
2140 
restoreSavedFloatRegisters()2141   void restoreSavedFloatRegisters() {
2142     if (_saved_vfp_d0_d15) {
2143       if (_use_X_for_vfp_save)
2144         restoreVFPWithFLDMX(_vfp_d0_d15_pad);
2145       else
2146         restoreVFPWithFLDMD(_vfp_d0_d15_pad);
2147     }
2148     if (_saved_vfp_d16_d31)
2149       restoreVFPv3(_vfp_d16_d31);
2150 #if defined(__ARM_WMMX)
2151     if (_saved_iwmmx)
2152       restoreiWMMX(_iwmmx);
2153     if (_saved_iwmmx_control)
2154       restoreiWMMXControl(_iwmmx_control);
2155 #endif
2156   }
2157 
2158 private:
2159   struct GPRs {
2160     uint32_t __r[13]; // r0-r12
2161     uint32_t __sp;    // Stack pointer r13
2162     uint32_t __lr;    // Link register r14
2163     uint32_t __pc;    // Program counter r15
2164   };
2165 
2166   struct PseudoRegisters {
2167     uint32_t __pac; // Return Authentication Code (PAC)
2168   };
2169 
2170   static void saveVFPWithFSTMD(void*);
2171   static void saveVFPWithFSTMX(void*);
2172   static void saveVFPv3(void*);
2173   static void restoreVFPWithFLDMD(void*);
2174   static void restoreVFPWithFLDMX(void*);
2175   static void restoreVFPv3(void*);
2176 #if defined(__ARM_WMMX)
2177   static void saveiWMMX(void*);
2178   static void saveiWMMXControl(uint32_t*);
2179   static void restoreiWMMX(void*);
2180   static void restoreiWMMXControl(uint32_t*);
2181 #endif
2182   void restoreCoreAndJumpTo();
2183 
2184   // ARM registers
2185   GPRs _registers;
2186   PseudoRegisters _pseudo_registers;
2187 
2188   // We save floating point registers lazily because we can't know ahead of
2189   // time which ones are used. See EHABI #4.7.
2190 
2191   // Whether D0-D15 are saved in the FTSMX instead of FSTMD format.
2192   //
2193   // See EHABI #7.5 that explains how matching instruction sequences for load
2194   // and store need to be used to correctly restore the exact register bits.
2195   bool _use_X_for_vfp_save;
2196   // Whether VFP D0-D15 are saved.
2197   bool _saved_vfp_d0_d15;
2198   // Whether VFPv3 D16-D31 are saved.
2199   bool _saved_vfp_d16_d31;
2200   // VFP registers D0-D15, + padding if saved using FSTMX
2201   unw_fpreg_t _vfp_d0_d15_pad[17];
2202   // VFPv3 registers D16-D31, always saved using FSTMD
2203   unw_fpreg_t _vfp_d16_d31[16];
2204 #if defined(__ARM_WMMX)
2205   // Whether iWMMX data registers are saved.
2206   bool _saved_iwmmx;
2207   // Whether iWMMX control registers are saved.
2208   mutable bool _saved_iwmmx_control;
2209   // iWMMX registers
2210   unw_fpreg_t _iwmmx[16];
2211   // iWMMX control registers
2212   mutable uint32_t _iwmmx_control[4];
2213 #endif
2214 };
2215 
Registers_arm(const void * registers)2216 inline Registers_arm::Registers_arm(const void *registers)
2217   : _use_X_for_vfp_save(false),
2218     _saved_vfp_d0_d15(false),
2219     _saved_vfp_d16_d31(false) {
2220   static_assert((check_fit<Registers_arm, unw_context_t>::does_fit),
2221                 "arm registers do not fit into unw_context_t");
2222   // See __unw_getcontext() note about data.
2223   memcpy(&_registers, registers, sizeof(_registers));
2224   memset(&_pseudo_registers, 0, sizeof(_pseudo_registers));
2225   memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
2226   memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
2227 #if defined(__ARM_WMMX)
2228   _saved_iwmmx = false;
2229   _saved_iwmmx_control = false;
2230   memset(&_iwmmx, 0, sizeof(_iwmmx));
2231   memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
2232 #endif
2233 }
2234 
Registers_arm()2235 inline Registers_arm::Registers_arm()
2236   : _use_X_for_vfp_save(false),
2237     _saved_vfp_d0_d15(false),
2238     _saved_vfp_d16_d31(false) {
2239   memset(&_registers, 0, sizeof(_registers));
2240   memset(&_pseudo_registers, 0, sizeof(_pseudo_registers));
2241   memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
2242   memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
2243 #if defined(__ARM_WMMX)
2244   _saved_iwmmx = false;
2245   _saved_iwmmx_control = false;
2246   memset(&_iwmmx, 0, sizeof(_iwmmx));
2247   memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
2248 #endif
2249 }
2250 
validRegister(int regNum) const2251 inline bool Registers_arm::validRegister(int regNum) const {
2252   // Returns true for all non-VFP registers supported by the EHABI
2253   // virtual register set (VRS).
2254   if (regNum == UNW_REG_IP)
2255     return true;
2256 
2257   if (regNum == UNW_REG_SP)
2258     return true;
2259 
2260   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15)
2261     return true;
2262 
2263 #if defined(__ARM_WMMX)
2264   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3)
2265     return true;
2266 #endif
2267 
2268 #ifdef __ARM_FEATURE_PAUTH
2269   if (regNum == UNW_ARM_RA_AUTH_CODE)
2270     return true;
2271 #endif
2272 
2273   return false;
2274 }
2275 
getRegister(int regNum) const2276 inline uint32_t Registers_arm::getRegister(int regNum) const {
2277   if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
2278     return _registers.__sp;
2279 
2280   if (regNum == UNW_ARM_LR)
2281     return _registers.__lr;
2282 
2283   if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
2284     return _registers.__pc;
2285 
2286   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
2287     return _registers.__r[regNum];
2288 
2289 #if defined(__ARM_WMMX)
2290   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
2291     if (!_saved_iwmmx_control) {
2292       _saved_iwmmx_control = true;
2293       saveiWMMXControl(_iwmmx_control);
2294     }
2295     return _iwmmx_control[regNum - UNW_ARM_WC0];
2296   }
2297 #endif
2298 
2299 #ifdef __ARM_FEATURE_PAUTH
2300   if (regNum == UNW_ARM_RA_AUTH_CODE)
2301     return _pseudo_registers.__pac;
2302 #endif
2303 
2304   _LIBUNWIND_ABORT("unsupported arm register");
2305 }
2306 
setRegister(int regNum,uint32_t value)2307 inline void Registers_arm::setRegister(int regNum, uint32_t value) {
2308   if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) {
2309     _registers.__sp = value;
2310     return;
2311   }
2312 
2313   if (regNum == UNW_ARM_LR) {
2314     _registers.__lr = value;
2315     return;
2316   }
2317 
2318   if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) {
2319     _registers.__pc = value;
2320     return;
2321   }
2322 
2323   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) {
2324     _registers.__r[regNum] = value;
2325     return;
2326   }
2327 
2328 #if defined(__ARM_WMMX)
2329   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
2330     if (!_saved_iwmmx_control) {
2331       _saved_iwmmx_control = true;
2332       saveiWMMXControl(_iwmmx_control);
2333     }
2334     _iwmmx_control[regNum - UNW_ARM_WC0] = value;
2335     return;
2336   }
2337 #endif
2338 
2339   if (regNum == UNW_ARM_RA_AUTH_CODE) {
2340     _pseudo_registers.__pac = value;
2341     return;
2342   }
2343 
2344   _LIBUNWIND_ABORT("unsupported arm register");
2345 }
2346 
getRegisterName(int regNum)2347 inline const char *Registers_arm::getRegisterName(int regNum) {
2348   switch (regNum) {
2349   case UNW_REG_IP:
2350   case UNW_ARM_IP: // UNW_ARM_R15 is alias
2351     return "pc";
2352   case UNW_ARM_LR: // UNW_ARM_R14 is alias
2353     return "lr";
2354   case UNW_REG_SP:
2355   case UNW_ARM_SP: // UNW_ARM_R13 is alias
2356     return "sp";
2357   case UNW_ARM_R0:
2358     return "r0";
2359   case UNW_ARM_R1:
2360     return "r1";
2361   case UNW_ARM_R2:
2362     return "r2";
2363   case UNW_ARM_R3:
2364     return "r3";
2365   case UNW_ARM_R4:
2366     return "r4";
2367   case UNW_ARM_R5:
2368     return "r5";
2369   case UNW_ARM_R6:
2370     return "r6";
2371   case UNW_ARM_R7:
2372     return "r7";
2373   case UNW_ARM_R8:
2374     return "r8";
2375   case UNW_ARM_R9:
2376     return "r9";
2377   case UNW_ARM_R10:
2378     return "r10";
2379   case UNW_ARM_R11:
2380     return "r11";
2381   case UNW_ARM_R12:
2382     return "r12";
2383   case UNW_ARM_S0:
2384     return "s0";
2385   case UNW_ARM_S1:
2386     return "s1";
2387   case UNW_ARM_S2:
2388     return "s2";
2389   case UNW_ARM_S3:
2390     return "s3";
2391   case UNW_ARM_S4:
2392     return "s4";
2393   case UNW_ARM_S5:
2394     return "s5";
2395   case UNW_ARM_S6:
2396     return "s6";
2397   case UNW_ARM_S7:
2398     return "s7";
2399   case UNW_ARM_S8:
2400     return "s8";
2401   case UNW_ARM_S9:
2402     return "s9";
2403   case UNW_ARM_S10:
2404     return "s10";
2405   case UNW_ARM_S11:
2406     return "s11";
2407   case UNW_ARM_S12:
2408     return "s12";
2409   case UNW_ARM_S13:
2410     return "s13";
2411   case UNW_ARM_S14:
2412     return "s14";
2413   case UNW_ARM_S15:
2414     return "s15";
2415   case UNW_ARM_S16:
2416     return "s16";
2417   case UNW_ARM_S17:
2418     return "s17";
2419   case UNW_ARM_S18:
2420     return "s18";
2421   case UNW_ARM_S19:
2422     return "s19";
2423   case UNW_ARM_S20:
2424     return "s20";
2425   case UNW_ARM_S21:
2426     return "s21";
2427   case UNW_ARM_S22:
2428     return "s22";
2429   case UNW_ARM_S23:
2430     return "s23";
2431   case UNW_ARM_S24:
2432     return "s24";
2433   case UNW_ARM_S25:
2434     return "s25";
2435   case UNW_ARM_S26:
2436     return "s26";
2437   case UNW_ARM_S27:
2438     return "s27";
2439   case UNW_ARM_S28:
2440     return "s28";
2441   case UNW_ARM_S29:
2442     return "s29";
2443   case UNW_ARM_S30:
2444     return "s30";
2445   case UNW_ARM_S31:
2446     return "s31";
2447   case UNW_ARM_D0:
2448     return "d0";
2449   case UNW_ARM_D1:
2450     return "d1";
2451   case UNW_ARM_D2:
2452     return "d2";
2453   case UNW_ARM_D3:
2454     return "d3";
2455   case UNW_ARM_D4:
2456     return "d4";
2457   case UNW_ARM_D5:
2458     return "d5";
2459   case UNW_ARM_D6:
2460     return "d6";
2461   case UNW_ARM_D7:
2462     return "d7";
2463   case UNW_ARM_D8:
2464     return "d8";
2465   case UNW_ARM_D9:
2466     return "d9";
2467   case UNW_ARM_D10:
2468     return "d10";
2469   case UNW_ARM_D11:
2470     return "d11";
2471   case UNW_ARM_D12:
2472     return "d12";
2473   case UNW_ARM_D13:
2474     return "d13";
2475   case UNW_ARM_D14:
2476     return "d14";
2477   case UNW_ARM_D15:
2478     return "d15";
2479   case UNW_ARM_D16:
2480     return "d16";
2481   case UNW_ARM_D17:
2482     return "d17";
2483   case UNW_ARM_D18:
2484     return "d18";
2485   case UNW_ARM_D19:
2486     return "d19";
2487   case UNW_ARM_D20:
2488     return "d20";
2489   case UNW_ARM_D21:
2490     return "d21";
2491   case UNW_ARM_D22:
2492     return "d22";
2493   case UNW_ARM_D23:
2494     return "d23";
2495   case UNW_ARM_D24:
2496     return "d24";
2497   case UNW_ARM_D25:
2498     return "d25";
2499   case UNW_ARM_D26:
2500     return "d26";
2501   case UNW_ARM_D27:
2502     return "d27";
2503   case UNW_ARM_D28:
2504     return "d28";
2505   case UNW_ARM_D29:
2506     return "d29";
2507   case UNW_ARM_D30:
2508     return "d30";
2509   case UNW_ARM_D31:
2510     return "d31";
2511   default:
2512     return "unknown register";
2513   }
2514 }
2515 
validFloatRegister(int regNum) const2516 inline bool Registers_arm::validFloatRegister(int regNum) const {
2517   // NOTE: Consider the intel MMX registers floating points so the
2518   // __unw_get_fpreg can be used to transmit the 64-bit data back.
2519   return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31))
2520 #if defined(__ARM_WMMX)
2521       || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15))
2522 #endif
2523       ;
2524 }
2525 
getFloatRegister(int regNum)2526 inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) {
2527   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
2528     if (!_saved_vfp_d0_d15) {
2529       _saved_vfp_d0_d15 = true;
2530       if (_use_X_for_vfp_save)
2531         saveVFPWithFSTMX(_vfp_d0_d15_pad);
2532       else
2533         saveVFPWithFSTMD(_vfp_d0_d15_pad);
2534     }
2535     return _vfp_d0_d15_pad[regNum - UNW_ARM_D0];
2536   }
2537 
2538   if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
2539     if (!_saved_vfp_d16_d31) {
2540       _saved_vfp_d16_d31 = true;
2541       saveVFPv3(_vfp_d16_d31);
2542     }
2543     return _vfp_d16_d31[regNum - UNW_ARM_D16];
2544   }
2545 
2546 #if defined(__ARM_WMMX)
2547   if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
2548     if (!_saved_iwmmx) {
2549       _saved_iwmmx = true;
2550       saveiWMMX(_iwmmx);
2551     }
2552     return _iwmmx[regNum - UNW_ARM_WR0];
2553   }
2554 #endif
2555 
2556   _LIBUNWIND_ABORT("Unknown ARM float register");
2557 }
2558 
setFloatRegister(int regNum,unw_fpreg_t value)2559 inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) {
2560   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
2561     if (!_saved_vfp_d0_d15) {
2562       _saved_vfp_d0_d15 = true;
2563       if (_use_X_for_vfp_save)
2564         saveVFPWithFSTMX(_vfp_d0_d15_pad);
2565       else
2566         saveVFPWithFSTMD(_vfp_d0_d15_pad);
2567     }
2568     _vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value;
2569     return;
2570   }
2571 
2572   if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
2573     if (!_saved_vfp_d16_d31) {
2574       _saved_vfp_d16_d31 = true;
2575       saveVFPv3(_vfp_d16_d31);
2576     }
2577     _vfp_d16_d31[regNum - UNW_ARM_D16] = value;
2578     return;
2579   }
2580 
2581 #if defined(__ARM_WMMX)
2582   if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
2583     if (!_saved_iwmmx) {
2584       _saved_iwmmx = true;
2585       saveiWMMX(_iwmmx);
2586     }
2587     _iwmmx[regNum - UNW_ARM_WR0] = value;
2588     return;
2589   }
2590 #endif
2591 
2592   _LIBUNWIND_ABORT("Unknown ARM float register");
2593 }
2594 
validVectorRegister(int) const2595 inline bool Registers_arm::validVectorRegister(int) const {
2596   return false;
2597 }
2598 
getVectorRegister(int) const2599 inline v128 Registers_arm::getVectorRegister(int) const {
2600   _LIBUNWIND_ABORT("ARM vector support not implemented");
2601 }
2602 
setVectorRegister(int,v128)2603 inline void Registers_arm::setVectorRegister(int, v128) {
2604   _LIBUNWIND_ABORT("ARM vector support not implemented");
2605 }
2606 #endif // _LIBUNWIND_TARGET_ARM
2607 
2608 
2609 #if defined(_LIBUNWIND_TARGET_OR1K)
2610 /// Registers_or1k holds the register state of a thread in an OpenRISC1000
2611 /// process.
2612 class _LIBUNWIND_HIDDEN Registers_or1k {
2613 public:
2614   Registers_or1k();
2615   Registers_or1k(const void *registers);
2616 
2617   bool        validRegister(int num) const;
2618   uint32_t    getRegister(int num) const;
2619   void        setRegister(int num, uint32_t value);
2620   bool        validFloatRegister(int num) const;
2621   double      getFloatRegister(int num) const;
2622   void        setFloatRegister(int num, double value);
2623   bool        validVectorRegister(int num) const;
2624   v128        getVectorRegister(int num) const;
2625   void        setVectorRegister(int num, v128 value);
2626   static const char *getRegisterName(int num);
2627   void        jumpto();
lastDwarfRegNum()2628   static constexpr int lastDwarfRegNum() {
2629     return _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K;
2630   }
getArch()2631   static int  getArch() { return REGISTERS_OR1K; }
2632 
getSP() const2633   uint64_t  getSP() const         { return _registers.__r[1]; }
setSP(uint32_t value)2634   void      setSP(uint32_t value) { _registers.__r[1] = value; }
getIP() const2635   uint64_t  getIP() const         { return _registers.__pc; }
setIP(uint32_t value)2636   void      setIP(uint32_t value) { _registers.__pc = value; }
2637 
2638 private:
2639   struct or1k_thread_state_t {
2640     unsigned int __r[32]; // r0-r31
2641     unsigned int __pc;    // Program counter
2642     unsigned int __epcr;  // Program counter at exception
2643   };
2644 
2645   or1k_thread_state_t _registers;
2646 };
2647 
Registers_or1k(const void * registers)2648 inline Registers_or1k::Registers_or1k(const void *registers) {
2649   static_assert((check_fit<Registers_or1k, unw_context_t>::does_fit),
2650                 "or1k registers do not fit into unw_context_t");
2651   memcpy(&_registers, static_cast<const uint8_t *>(registers),
2652          sizeof(_registers));
2653 }
2654 
Registers_or1k()2655 inline Registers_or1k::Registers_or1k() {
2656   memset(&_registers, 0, sizeof(_registers));
2657 }
2658 
validRegister(int regNum) const2659 inline bool Registers_or1k::validRegister(int regNum) const {
2660   if (regNum == UNW_REG_IP)
2661     return true;
2662   if (regNum == UNW_REG_SP)
2663     return true;
2664   if (regNum < 0)
2665     return false;
2666   if (regNum <= UNW_OR1K_R31)
2667     return true;
2668   if (regNum == UNW_OR1K_EPCR)
2669     return true;
2670   return false;
2671 }
2672 
getRegister(int regNum) const2673 inline uint32_t Registers_or1k::getRegister(int regNum) const {
2674   if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31)
2675     return _registers.__r[regNum - UNW_OR1K_R0];
2676 
2677   switch (regNum) {
2678   case UNW_REG_IP:
2679     return _registers.__pc;
2680   case UNW_REG_SP:
2681     return _registers.__r[1];
2682   case UNW_OR1K_EPCR:
2683     return _registers.__epcr;
2684   }
2685   _LIBUNWIND_ABORT("unsupported or1k register");
2686 }
2687 
setRegister(int regNum,uint32_t value)2688 inline void Registers_or1k::setRegister(int regNum, uint32_t value) {
2689   if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) {
2690     _registers.__r[regNum - UNW_OR1K_R0] = value;
2691     return;
2692   }
2693 
2694   switch (regNum) {
2695   case UNW_REG_IP:
2696     _registers.__pc = value;
2697     return;
2698   case UNW_REG_SP:
2699     _registers.__r[1] = value;
2700     return;
2701   case UNW_OR1K_EPCR:
2702     _registers.__epcr = value;
2703     return;
2704   }
2705   _LIBUNWIND_ABORT("unsupported or1k register");
2706 }
2707 
validFloatRegister(int) const2708 inline bool Registers_or1k::validFloatRegister(int /* regNum */) const {
2709   return false;
2710 }
2711 
getFloatRegister(int) const2712 inline double Registers_or1k::getFloatRegister(int /* regNum */) const {
2713   _LIBUNWIND_ABORT("or1k float support not implemented");
2714 }
2715 
setFloatRegister(int,double)2716 inline void Registers_or1k::setFloatRegister(int /* regNum */,
2717                                              double /* value */) {
2718   _LIBUNWIND_ABORT("or1k float support not implemented");
2719 }
2720 
validVectorRegister(int) const2721 inline bool Registers_or1k::validVectorRegister(int /* regNum */) const {
2722   return false;
2723 }
2724 
getVectorRegister(int) const2725 inline v128 Registers_or1k::getVectorRegister(int /* regNum */) const {
2726   _LIBUNWIND_ABORT("or1k vector support not implemented");
2727 }
2728 
setVectorRegister(int,v128)2729 inline void Registers_or1k::setVectorRegister(int /* regNum */, v128 /* value */) {
2730   _LIBUNWIND_ABORT("or1k vector support not implemented");
2731 }
2732 
getRegisterName(int regNum)2733 inline const char *Registers_or1k::getRegisterName(int regNum) {
2734   switch (regNum) {
2735   case UNW_OR1K_R0:
2736     return "r0";
2737   case UNW_OR1K_R1:
2738     return "r1";
2739   case UNW_OR1K_R2:
2740     return "r2";
2741   case UNW_OR1K_R3:
2742     return "r3";
2743   case UNW_OR1K_R4:
2744     return "r4";
2745   case UNW_OR1K_R5:
2746     return "r5";
2747   case UNW_OR1K_R6:
2748     return "r6";
2749   case UNW_OR1K_R7:
2750     return "r7";
2751   case UNW_OR1K_R8:
2752     return "r8";
2753   case UNW_OR1K_R9:
2754     return "r9";
2755   case UNW_OR1K_R10:
2756     return "r10";
2757   case UNW_OR1K_R11:
2758     return "r11";
2759   case UNW_OR1K_R12:
2760     return "r12";
2761   case UNW_OR1K_R13:
2762     return "r13";
2763   case UNW_OR1K_R14:
2764     return "r14";
2765   case UNW_OR1K_R15:
2766     return "r15";
2767   case UNW_OR1K_R16:
2768     return "r16";
2769   case UNW_OR1K_R17:
2770     return "r17";
2771   case UNW_OR1K_R18:
2772     return "r18";
2773   case UNW_OR1K_R19:
2774     return "r19";
2775   case UNW_OR1K_R20:
2776     return "r20";
2777   case UNW_OR1K_R21:
2778     return "r21";
2779   case UNW_OR1K_R22:
2780     return "r22";
2781   case UNW_OR1K_R23:
2782     return "r23";
2783   case UNW_OR1K_R24:
2784     return "r24";
2785   case UNW_OR1K_R25:
2786     return "r25";
2787   case UNW_OR1K_R26:
2788     return "r26";
2789   case UNW_OR1K_R27:
2790     return "r27";
2791   case UNW_OR1K_R28:
2792     return "r28";
2793   case UNW_OR1K_R29:
2794     return "r29";
2795   case UNW_OR1K_R30:
2796     return "r30";
2797   case UNW_OR1K_R31:
2798     return "r31";
2799   case UNW_OR1K_EPCR:
2800     return "EPCR";
2801   default:
2802     return "unknown register";
2803   }
2804 
2805 }
2806 #endif // _LIBUNWIND_TARGET_OR1K
2807 
2808 #if defined(_LIBUNWIND_TARGET_MIPS_O32)
2809 /// Registers_mips_o32 holds the register state of a thread in a 32-bit MIPS
2810 /// process.
2811 class _LIBUNWIND_HIDDEN Registers_mips_o32 {
2812 public:
2813   Registers_mips_o32();
2814   Registers_mips_o32(const void *registers);
2815 
2816   bool        validRegister(int num) const;
2817   uint32_t    getRegister(int num) const;
2818   void        setRegister(int num, uint32_t value);
2819   bool        validFloatRegister(int num) const;
2820   double      getFloatRegister(int num) const;
2821   void        setFloatRegister(int num, double value);
2822   bool        validVectorRegister(int num) const;
2823   v128        getVectorRegister(int num) const;
2824   void        setVectorRegister(int num, v128 value);
2825   static const char *getRegisterName(int num);
2826   void        jumpto();
lastDwarfRegNum()2827   static constexpr int lastDwarfRegNum() {
2828     return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS;
2829   }
getArch()2830   static int  getArch() { return REGISTERS_MIPS_O32; }
2831 
getSP() const2832   uint32_t  getSP() const         { return _registers.__r[29]; }
setSP(uint32_t value)2833   void      setSP(uint32_t value) { _registers.__r[29] = value; }
getIP() const2834   uint32_t  getIP() const         { return _registers.__pc; }
setIP(uint32_t value)2835   void      setIP(uint32_t value) { _registers.__pc = value; }
2836 
2837 private:
2838   struct mips_o32_thread_state_t {
2839     uint32_t __r[32];
2840     uint32_t __pc;
2841     uint32_t __hi;
2842     uint32_t __lo;
2843   };
2844 
2845   mips_o32_thread_state_t _registers;
2846 #ifdef __mips_hard_float
2847   /// O32 with 32-bit floating point registers only uses half of this
2848   /// space.  However, using the same layout for 32-bit vs 64-bit
2849   /// floating point registers results in a single context size for
2850   /// O32 with hard float.
2851   uint32_t _padding;
2852   double _floats[32];
2853 #endif
2854 };
2855 
Registers_mips_o32(const void * registers)2856 inline Registers_mips_o32::Registers_mips_o32(const void *registers) {
2857   static_assert((check_fit<Registers_mips_o32, unw_context_t>::does_fit),
2858                 "mips_o32 registers do not fit into unw_context_t");
2859   memcpy(&_registers, static_cast<const uint8_t *>(registers),
2860          sizeof(_registers));
2861 }
2862 
Registers_mips_o32()2863 inline Registers_mips_o32::Registers_mips_o32() {
2864   memset(&_registers, 0, sizeof(_registers));
2865 }
2866 
validRegister(int regNum) const2867 inline bool Registers_mips_o32::validRegister(int regNum) const {
2868   if (regNum == UNW_REG_IP)
2869     return true;
2870   if (regNum == UNW_REG_SP)
2871     return true;
2872   if (regNum < 0)
2873     return false;
2874   if (regNum <= UNW_MIPS_R31)
2875     return true;
2876 #if __mips_isa_rev < 6
2877   if (regNum == UNW_MIPS_HI)
2878     return true;
2879   if (regNum == UNW_MIPS_LO)
2880     return true;
2881 #endif
2882 #if defined(__mips_hard_float) && __mips_fpr == 32
2883   if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
2884     return true;
2885 #endif
2886   // FIXME: DSP accumulator registers, MSA registers
2887   return false;
2888 }
2889 
getRegister(int regNum) const2890 inline uint32_t Registers_mips_o32::getRegister(int regNum) const {
2891   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
2892     return _registers.__r[regNum - UNW_MIPS_R0];
2893 #if defined(__mips_hard_float) && __mips_fpr == 32
2894   if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
2895     uint32_t *p;
2896 
2897     if (regNum % 2 == 0)
2898       p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
2899     else
2900       p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
2901     return *p;
2902   }
2903 #endif
2904 
2905   switch (regNum) {
2906   case UNW_REG_IP:
2907     return _registers.__pc;
2908   case UNW_REG_SP:
2909     return _registers.__r[29];
2910 #if __mips_isa_rev < 6
2911   case UNW_MIPS_HI:
2912     return _registers.__hi;
2913   case UNW_MIPS_LO:
2914     return _registers.__lo;
2915 #endif
2916   }
2917   _LIBUNWIND_ABORT("unsupported mips_o32 register");
2918 }
2919 
setRegister(int regNum,uint32_t value)2920 inline void Registers_mips_o32::setRegister(int regNum, uint32_t value) {
2921   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
2922     _registers.__r[regNum - UNW_MIPS_R0] = value;
2923     return;
2924   }
2925 #if defined(__mips_hard_float) && __mips_fpr == 32
2926   if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
2927     uint32_t *p;
2928 
2929     if (regNum % 2 == 0)
2930       p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
2931     else
2932       p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
2933     *p = value;
2934     return;
2935   }
2936 #endif
2937 
2938   switch (regNum) {
2939   case UNW_REG_IP:
2940     _registers.__pc = value;
2941     return;
2942   case UNW_REG_SP:
2943     _registers.__r[29] = value;
2944     return;
2945 #if __mips_isa_rev < 6
2946   case UNW_MIPS_HI:
2947     _registers.__hi = value;
2948     return;
2949   case UNW_MIPS_LO:
2950     _registers.__lo = value;
2951 #endif
2952     return;
2953   }
2954   _LIBUNWIND_ABORT("unsupported mips_o32 register");
2955 }
2956 
validFloatRegister(int regNum) const2957 inline bool Registers_mips_o32::validFloatRegister(int regNum) const {
2958 #if defined(__mips_hard_float) && __mips_fpr == 64
2959   if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
2960     return true;
2961 #else
2962   (void)regNum;
2963 #endif
2964   return false;
2965 }
2966 
getFloatRegister(int regNum) const2967 inline double Registers_mips_o32::getFloatRegister(int regNum) const {
2968 #if defined(__mips_hard_float) && __mips_fpr == 64
2969   assert(validFloatRegister(regNum));
2970   return _floats[regNum - UNW_MIPS_F0];
2971 #else
2972   (void)regNum;
2973   _LIBUNWIND_ABORT("mips_o32 float support not implemented");
2974 #endif
2975 }
2976 
setFloatRegister(int regNum,double value)2977 inline void Registers_mips_o32::setFloatRegister(int regNum,
2978                                                  double value) {
2979 #if defined(__mips_hard_float) && __mips_fpr == 64
2980   assert(validFloatRegister(regNum));
2981   _floats[regNum - UNW_MIPS_F0] = value;
2982 #else
2983   (void)regNum;
2984   (void)value;
2985   _LIBUNWIND_ABORT("mips_o32 float support not implemented");
2986 #endif
2987 }
2988 
validVectorRegister(int) const2989 inline bool Registers_mips_o32::validVectorRegister(int /* regNum */) const {
2990   return false;
2991 }
2992 
getVectorRegister(int) const2993 inline v128 Registers_mips_o32::getVectorRegister(int /* regNum */) const {
2994   _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
2995 }
2996 
setVectorRegister(int,v128)2997 inline void Registers_mips_o32::setVectorRegister(int /* regNum */, v128 /* value */) {
2998   _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
2999 }
3000 
getRegisterName(int regNum)3001 inline const char *Registers_mips_o32::getRegisterName(int regNum) {
3002   switch (regNum) {
3003   case UNW_MIPS_R0:
3004     return "$0";
3005   case UNW_MIPS_R1:
3006     return "$1";
3007   case UNW_MIPS_R2:
3008     return "$2";
3009   case UNW_MIPS_R3:
3010     return "$3";
3011   case UNW_MIPS_R4:
3012     return "$4";
3013   case UNW_MIPS_R5:
3014     return "$5";
3015   case UNW_MIPS_R6:
3016     return "$6";
3017   case UNW_MIPS_R7:
3018     return "$7";
3019   case UNW_MIPS_R8:
3020     return "$8";
3021   case UNW_MIPS_R9:
3022     return "$9";
3023   case UNW_MIPS_R10:
3024     return "$10";
3025   case UNW_MIPS_R11:
3026     return "$11";
3027   case UNW_MIPS_R12:
3028     return "$12";
3029   case UNW_MIPS_R13:
3030     return "$13";
3031   case UNW_MIPS_R14:
3032     return "$14";
3033   case UNW_MIPS_R15:
3034     return "$15";
3035   case UNW_MIPS_R16:
3036     return "$16";
3037   case UNW_MIPS_R17:
3038     return "$17";
3039   case UNW_MIPS_R18:
3040     return "$18";
3041   case UNW_MIPS_R19:
3042     return "$19";
3043   case UNW_MIPS_R20:
3044     return "$20";
3045   case UNW_MIPS_R21:
3046     return "$21";
3047   case UNW_MIPS_R22:
3048     return "$22";
3049   case UNW_MIPS_R23:
3050     return "$23";
3051   case UNW_MIPS_R24:
3052     return "$24";
3053   case UNW_MIPS_R25:
3054     return "$25";
3055   case UNW_MIPS_R26:
3056     return "$26";
3057   case UNW_MIPS_R27:
3058     return "$27";
3059   case UNW_MIPS_R28:
3060     return "$28";
3061   case UNW_MIPS_R29:
3062     return "$29";
3063   case UNW_MIPS_R30:
3064     return "$30";
3065   case UNW_MIPS_R31:
3066     return "$31";
3067   case UNW_MIPS_F0:
3068     return "$f0";
3069   case UNW_MIPS_F1:
3070     return "$f1";
3071   case UNW_MIPS_F2:
3072     return "$f2";
3073   case UNW_MIPS_F3:
3074     return "$f3";
3075   case UNW_MIPS_F4:
3076     return "$f4";
3077   case UNW_MIPS_F5:
3078     return "$f5";
3079   case UNW_MIPS_F6:
3080     return "$f6";
3081   case UNW_MIPS_F7:
3082     return "$f7";
3083   case UNW_MIPS_F8:
3084     return "$f8";
3085   case UNW_MIPS_F9:
3086     return "$f9";
3087   case UNW_MIPS_F10:
3088     return "$f10";
3089   case UNW_MIPS_F11:
3090     return "$f11";
3091   case UNW_MIPS_F12:
3092     return "$f12";
3093   case UNW_MIPS_F13:
3094     return "$f13";
3095   case UNW_MIPS_F14:
3096     return "$f14";
3097   case UNW_MIPS_F15:
3098     return "$f15";
3099   case UNW_MIPS_F16:
3100     return "$f16";
3101   case UNW_MIPS_F17:
3102     return "$f17";
3103   case UNW_MIPS_F18:
3104     return "$f18";
3105   case UNW_MIPS_F19:
3106     return "$f19";
3107   case UNW_MIPS_F20:
3108     return "$f20";
3109   case UNW_MIPS_F21:
3110     return "$f21";
3111   case UNW_MIPS_F22:
3112     return "$f22";
3113   case UNW_MIPS_F23:
3114     return "$f23";
3115   case UNW_MIPS_F24:
3116     return "$f24";
3117   case UNW_MIPS_F25:
3118     return "$f25";
3119   case UNW_MIPS_F26:
3120     return "$f26";
3121   case UNW_MIPS_F27:
3122     return "$f27";
3123   case UNW_MIPS_F28:
3124     return "$f28";
3125   case UNW_MIPS_F29:
3126     return "$f29";
3127   case UNW_MIPS_F30:
3128     return "$f30";
3129   case UNW_MIPS_F31:
3130     return "$f31";
3131 #if __mips_isa_rev < 6
3132   case UNW_MIPS_HI:
3133     return "$hi";
3134   case UNW_MIPS_LO:
3135     return "$lo";
3136 #endif
3137   default:
3138     return "unknown register";
3139   }
3140 }
3141 #endif // _LIBUNWIND_TARGET_MIPS_O32
3142 
3143 #if defined(_LIBUNWIND_TARGET_MIPS_NEWABI)
3144 /// Registers_mips_newabi holds the register state of a thread in a
3145 /// MIPS process using NEWABI (the N32 or N64 ABIs).
3146 class _LIBUNWIND_HIDDEN Registers_mips_newabi {
3147 public:
3148   Registers_mips_newabi();
3149   Registers_mips_newabi(const void *registers);
3150 
3151   bool        validRegister(int num) const;
3152   uint64_t    getRegister(int num) const;
3153   void        setRegister(int num, uint64_t value);
3154   bool        validFloatRegister(int num) const;
3155   double      getFloatRegister(int num) const;
3156   void        setFloatRegister(int num, double value);
3157   bool        validVectorRegister(int num) const;
3158   v128        getVectorRegister(int num) const;
3159   void        setVectorRegister(int num, v128 value);
3160   static const char *getRegisterName(int num);
3161   void        jumpto();
lastDwarfRegNum()3162   static constexpr int lastDwarfRegNum() {
3163     return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS;
3164   }
getArch()3165   static int  getArch() { return REGISTERS_MIPS_NEWABI; }
3166 
getSP() const3167   uint64_t  getSP() const         { return _registers.__r[29]; }
setSP(uint64_t value)3168   void      setSP(uint64_t value) { _registers.__r[29] = value; }
getIP() const3169   uint64_t  getIP() const         { return _registers.__pc; }
setIP(uint64_t value)3170   void      setIP(uint64_t value) { _registers.__pc = value; }
3171 
3172 private:
3173   struct mips_newabi_thread_state_t {
3174     uint64_t __r[32];
3175     uint64_t __pc;
3176     uint64_t __hi;
3177     uint64_t __lo;
3178   };
3179 
3180   mips_newabi_thread_state_t _registers;
3181 #ifdef __mips_hard_float
3182   double _floats[32];
3183 #endif
3184 };
3185 
Registers_mips_newabi(const void * registers)3186 inline Registers_mips_newabi::Registers_mips_newabi(const void *registers) {
3187   static_assert((check_fit<Registers_mips_newabi, unw_context_t>::does_fit),
3188                 "mips_newabi registers do not fit into unw_context_t");
3189   memcpy(&_registers, static_cast<const uint8_t *>(registers),
3190          sizeof(_registers));
3191 }
3192 
Registers_mips_newabi()3193 inline Registers_mips_newabi::Registers_mips_newabi() {
3194   memset(&_registers, 0, sizeof(_registers));
3195 }
3196 
validRegister(int regNum) const3197 inline bool Registers_mips_newabi::validRegister(int regNum) const {
3198   if (regNum == UNW_REG_IP)
3199     return true;
3200   if (regNum == UNW_REG_SP)
3201     return true;
3202   if (regNum < 0)
3203     return false;
3204   if (regNum <= UNW_MIPS_R31)
3205     return true;
3206 #if __mips_isa_rev < 6
3207   if (regNum == UNW_MIPS_HI)
3208     return true;
3209   if (regNum == UNW_MIPS_LO)
3210     return true;
3211 #endif
3212   // FIXME: Hard float, DSP accumulator registers, MSA registers
3213   return false;
3214 }
3215 
getRegister(int regNum) const3216 inline uint64_t Registers_mips_newabi::getRegister(int regNum) const {
3217   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
3218     return _registers.__r[regNum - UNW_MIPS_R0];
3219 
3220   switch (regNum) {
3221   case UNW_REG_IP:
3222     return _registers.__pc;
3223   case UNW_REG_SP:
3224     return _registers.__r[29];
3225 #if __mips_isa_rev < 6
3226   case UNW_MIPS_HI:
3227     return _registers.__hi;
3228   case UNW_MIPS_LO:
3229     return _registers.__lo;
3230 #endif
3231   }
3232   _LIBUNWIND_ABORT("unsupported mips_newabi register");
3233 }
3234 
setRegister(int regNum,uint64_t value)3235 inline void Registers_mips_newabi::setRegister(int regNum, uint64_t value) {
3236   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
3237     _registers.__r[regNum - UNW_MIPS_R0] = value;
3238     return;
3239   }
3240 
3241   switch (regNum) {
3242   case UNW_REG_IP:
3243     _registers.__pc = value;
3244     return;
3245   case UNW_REG_SP:
3246     _registers.__r[29] = value;
3247     return;
3248 #if __mips_isa_rev < 6
3249   case UNW_MIPS_HI:
3250     _registers.__hi = value;
3251     return;
3252   case UNW_MIPS_LO:
3253     _registers.__lo = value;
3254     return;
3255 #endif
3256   }
3257   _LIBUNWIND_ABORT("unsupported mips_newabi register");
3258 }
3259 
validFloatRegister(int regNum) const3260 inline bool Registers_mips_newabi::validFloatRegister(int regNum) const {
3261 #ifdef __mips_hard_float
3262   if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
3263     return true;
3264 #else
3265   (void)regNum;
3266 #endif
3267   return false;
3268 }
3269 
getFloatRegister(int regNum) const3270 inline double Registers_mips_newabi::getFloatRegister(int regNum) const {
3271 #ifdef __mips_hard_float
3272   assert(validFloatRegister(regNum));
3273   return _floats[regNum - UNW_MIPS_F0];
3274 #else
3275   (void)regNum;
3276   _LIBUNWIND_ABORT("mips_newabi float support not implemented");
3277 #endif
3278 }
3279 
setFloatRegister(int regNum,double value)3280 inline void Registers_mips_newabi::setFloatRegister(int regNum,
3281                                                     double value) {
3282 #ifdef __mips_hard_float
3283   assert(validFloatRegister(regNum));
3284   _floats[regNum - UNW_MIPS_F0] = value;
3285 #else
3286   (void)regNum;
3287   (void)value;
3288   _LIBUNWIND_ABORT("mips_newabi float support not implemented");
3289 #endif
3290 }
3291 
validVectorRegister(int) const3292 inline bool Registers_mips_newabi::validVectorRegister(int /* regNum */) const {
3293   return false;
3294 }
3295 
getVectorRegister(int) const3296 inline v128 Registers_mips_newabi::getVectorRegister(int /* regNum */) const {
3297   _LIBUNWIND_ABORT("mips_newabi vector support not implemented");
3298 }
3299 
setVectorRegister(int,v128)3300 inline void Registers_mips_newabi::setVectorRegister(int /* regNum */, v128 /* value */) {
3301   _LIBUNWIND_ABORT("mips_newabi vector support not implemented");
3302 }
3303 
getRegisterName(int regNum)3304 inline const char *Registers_mips_newabi::getRegisterName(int regNum) {
3305   switch (regNum) {
3306   case UNW_MIPS_R0:
3307     return "$0";
3308   case UNW_MIPS_R1:
3309     return "$1";
3310   case UNW_MIPS_R2:
3311     return "$2";
3312   case UNW_MIPS_R3:
3313     return "$3";
3314   case UNW_MIPS_R4:
3315     return "$4";
3316   case UNW_MIPS_R5:
3317     return "$5";
3318   case UNW_MIPS_R6:
3319     return "$6";
3320   case UNW_MIPS_R7:
3321     return "$7";
3322   case UNW_MIPS_R8:
3323     return "$8";
3324   case UNW_MIPS_R9:
3325     return "$9";
3326   case UNW_MIPS_R10:
3327     return "$10";
3328   case UNW_MIPS_R11:
3329     return "$11";
3330   case UNW_MIPS_R12:
3331     return "$12";
3332   case UNW_MIPS_R13:
3333     return "$13";
3334   case UNW_MIPS_R14:
3335     return "$14";
3336   case UNW_MIPS_R15:
3337     return "$15";
3338   case UNW_MIPS_R16:
3339     return "$16";
3340   case UNW_MIPS_R17:
3341     return "$17";
3342   case UNW_MIPS_R18:
3343     return "$18";
3344   case UNW_MIPS_R19:
3345     return "$19";
3346   case UNW_MIPS_R20:
3347     return "$20";
3348   case UNW_MIPS_R21:
3349     return "$21";
3350   case UNW_MIPS_R22:
3351     return "$22";
3352   case UNW_MIPS_R23:
3353     return "$23";
3354   case UNW_MIPS_R24:
3355     return "$24";
3356   case UNW_MIPS_R25:
3357     return "$25";
3358   case UNW_MIPS_R26:
3359     return "$26";
3360   case UNW_MIPS_R27:
3361     return "$27";
3362   case UNW_MIPS_R28:
3363     return "$28";
3364   case UNW_MIPS_R29:
3365     return "$29";
3366   case UNW_MIPS_R30:
3367     return "$30";
3368   case UNW_MIPS_R31:
3369     return "$31";
3370   case UNW_MIPS_F0:
3371     return "$f0";
3372   case UNW_MIPS_F1:
3373     return "$f1";
3374   case UNW_MIPS_F2:
3375     return "$f2";
3376   case UNW_MIPS_F3:
3377     return "$f3";
3378   case UNW_MIPS_F4:
3379     return "$f4";
3380   case UNW_MIPS_F5:
3381     return "$f5";
3382   case UNW_MIPS_F6:
3383     return "$f6";
3384   case UNW_MIPS_F7:
3385     return "$f7";
3386   case UNW_MIPS_F8:
3387     return "$f8";
3388   case UNW_MIPS_F9:
3389     return "$f9";
3390   case UNW_MIPS_F10:
3391     return "$f10";
3392   case UNW_MIPS_F11:
3393     return "$f11";
3394   case UNW_MIPS_F12:
3395     return "$f12";
3396   case UNW_MIPS_F13:
3397     return "$f13";
3398   case UNW_MIPS_F14:
3399     return "$f14";
3400   case UNW_MIPS_F15:
3401     return "$f15";
3402   case UNW_MIPS_F16:
3403     return "$f16";
3404   case UNW_MIPS_F17:
3405     return "$f17";
3406   case UNW_MIPS_F18:
3407     return "$f18";
3408   case UNW_MIPS_F19:
3409     return "$f19";
3410   case UNW_MIPS_F20:
3411     return "$f20";
3412   case UNW_MIPS_F21:
3413     return "$f21";
3414   case UNW_MIPS_F22:
3415     return "$f22";
3416   case UNW_MIPS_F23:
3417     return "$f23";
3418   case UNW_MIPS_F24:
3419     return "$f24";
3420   case UNW_MIPS_F25:
3421     return "$f25";
3422   case UNW_MIPS_F26:
3423     return "$f26";
3424   case UNW_MIPS_F27:
3425     return "$f27";
3426   case UNW_MIPS_F28:
3427     return "$f28";
3428   case UNW_MIPS_F29:
3429     return "$f29";
3430   case UNW_MIPS_F30:
3431     return "$f30";
3432   case UNW_MIPS_F31:
3433     return "$f31";
3434 #if __mips_isa_rev < 6
3435   case UNW_MIPS_HI:
3436     return "$hi";
3437   case UNW_MIPS_LO:
3438     return "$lo";
3439 #endif
3440   default:
3441     return "unknown register";
3442   }
3443 }
3444 #endif // _LIBUNWIND_TARGET_MIPS_NEWABI
3445 
3446 #if defined(_LIBUNWIND_TARGET_SPARC)
3447 /// Registers_sparc holds the register state of a thread in a 32-bit Sparc
3448 /// process.
3449 class _LIBUNWIND_HIDDEN Registers_sparc {
3450 public:
3451   Registers_sparc();
3452   Registers_sparc(const void *registers);
3453 
3454   bool        validRegister(int num) const;
3455   uint32_t    getRegister(int num) const;
3456   void        setRegister(int num, uint32_t value);
3457   bool        validFloatRegister(int num) const;
3458   double      getFloatRegister(int num) const;
3459   void        setFloatRegister(int num, double value);
3460   bool        validVectorRegister(int num) const;
3461   v128        getVectorRegister(int num) const;
3462   void        setVectorRegister(int num, v128 value);
3463   static const char *getRegisterName(int num);
3464   void        jumpto();
lastDwarfRegNum()3465   static constexpr int lastDwarfRegNum() {
3466     return _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC;
3467   }
getArch()3468   static int  getArch() { return REGISTERS_SPARC; }
3469 
getSP() const3470   uint64_t  getSP() const         { return _registers.__regs[UNW_SPARC_O6]; }
setSP(uint32_t value)3471   void      setSP(uint32_t value) { _registers.__regs[UNW_SPARC_O6] = value; }
getIP() const3472   uint64_t  getIP() const         { return _registers.__regs[UNW_SPARC_O7]; }
setIP(uint32_t value)3473   void      setIP(uint32_t value) { _registers.__regs[UNW_SPARC_O7] = value; }
3474 
3475 private:
3476   struct sparc_thread_state_t {
3477     unsigned int __regs[32];
3478   };
3479 
3480   sparc_thread_state_t _registers;
3481 };
3482 
Registers_sparc(const void * registers)3483 inline Registers_sparc::Registers_sparc(const void *registers) {
3484   static_assert((check_fit<Registers_sparc, unw_context_t>::does_fit),
3485                 "sparc registers do not fit into unw_context_t");
3486   memcpy(&_registers, static_cast<const uint8_t *>(registers),
3487          sizeof(_registers));
3488 }
3489 
Registers_sparc()3490 inline Registers_sparc::Registers_sparc() {
3491   memset(&_registers, 0, sizeof(_registers));
3492 }
3493 
validRegister(int regNum) const3494 inline bool Registers_sparc::validRegister(int regNum) const {
3495   if (regNum == UNW_REG_IP)
3496     return true;
3497   if (regNum == UNW_REG_SP)
3498     return true;
3499   if (regNum < 0)
3500     return false;
3501   if (regNum <= UNW_SPARC_I7)
3502     return true;
3503   return false;
3504 }
3505 
getRegister(int regNum) const3506 inline uint32_t Registers_sparc::getRegister(int regNum) const {
3507   if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) {
3508     return _registers.__regs[regNum];
3509   }
3510 
3511   switch (regNum) {
3512   case UNW_REG_IP:
3513     return _registers.__regs[UNW_SPARC_O7];
3514   case UNW_REG_SP:
3515     return _registers.__regs[UNW_SPARC_O6];
3516   }
3517   _LIBUNWIND_ABORT("unsupported sparc register");
3518 }
3519 
setRegister(int regNum,uint32_t value)3520 inline void Registers_sparc::setRegister(int regNum, uint32_t value) {
3521   if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) {
3522     _registers.__regs[regNum] = value;
3523     return;
3524   }
3525 
3526   switch (regNum) {
3527   case UNW_REG_IP:
3528     _registers.__regs[UNW_SPARC_O7] = value;
3529     return;
3530   case UNW_REG_SP:
3531     _registers.__regs[UNW_SPARC_O6] = value;
3532     return;
3533   }
3534   _LIBUNWIND_ABORT("unsupported sparc register");
3535 }
3536 
validFloatRegister(int) const3537 inline bool Registers_sparc::validFloatRegister(int) const { return false; }
3538 
getFloatRegister(int) const3539 inline double Registers_sparc::getFloatRegister(int) const {
3540   _LIBUNWIND_ABORT("no Sparc float registers");
3541 }
3542 
setFloatRegister(int,double)3543 inline void Registers_sparc::setFloatRegister(int, double) {
3544   _LIBUNWIND_ABORT("no Sparc float registers");
3545 }
3546 
validVectorRegister(int) const3547 inline bool Registers_sparc::validVectorRegister(int) const { return false; }
3548 
getVectorRegister(int) const3549 inline v128 Registers_sparc::getVectorRegister(int) const {
3550   _LIBUNWIND_ABORT("no Sparc vector registers");
3551 }
3552 
setVectorRegister(int,v128)3553 inline void Registers_sparc::setVectorRegister(int, v128) {
3554   _LIBUNWIND_ABORT("no Sparc vector registers");
3555 }
3556 
getRegisterName(int regNum)3557 inline const char *Registers_sparc::getRegisterName(int regNum) {
3558   switch (regNum) {
3559   case UNW_REG_IP:
3560     return "pc";
3561   case UNW_SPARC_G0:
3562     return "g0";
3563   case UNW_SPARC_G1:
3564     return "g1";
3565   case UNW_SPARC_G2:
3566     return "g2";
3567   case UNW_SPARC_G3:
3568     return "g3";
3569   case UNW_SPARC_G4:
3570     return "g4";
3571   case UNW_SPARC_G5:
3572     return "g5";
3573   case UNW_SPARC_G6:
3574     return "g6";
3575   case UNW_SPARC_G7:
3576     return "g7";
3577   case UNW_SPARC_O0:
3578     return "o0";
3579   case UNW_SPARC_O1:
3580     return "o1";
3581   case UNW_SPARC_O2:
3582     return "o2";
3583   case UNW_SPARC_O3:
3584     return "o3";
3585   case UNW_SPARC_O4:
3586     return "o4";
3587   case UNW_SPARC_O5:
3588     return "o5";
3589   case UNW_REG_SP:
3590   case UNW_SPARC_O6:
3591     return "sp";
3592   case UNW_SPARC_O7:
3593     return "o7";
3594   case UNW_SPARC_L0:
3595     return "l0";
3596   case UNW_SPARC_L1:
3597     return "l1";
3598   case UNW_SPARC_L2:
3599     return "l2";
3600   case UNW_SPARC_L3:
3601     return "l3";
3602   case UNW_SPARC_L4:
3603     return "l4";
3604   case UNW_SPARC_L5:
3605     return "l5";
3606   case UNW_SPARC_L6:
3607     return "l6";
3608   case UNW_SPARC_L7:
3609     return "l7";
3610   case UNW_SPARC_I0:
3611     return "i0";
3612   case UNW_SPARC_I1:
3613     return "i1";
3614   case UNW_SPARC_I2:
3615     return "i2";
3616   case UNW_SPARC_I3:
3617     return "i3";
3618   case UNW_SPARC_I4:
3619     return "i4";
3620   case UNW_SPARC_I5:
3621     return "i5";
3622   case UNW_SPARC_I6:
3623     return "fp";
3624   case UNW_SPARC_I7:
3625     return "i7";
3626   default:
3627     return "unknown register";
3628   }
3629 }
3630 #endif // _LIBUNWIND_TARGET_SPARC
3631 
3632 #if defined(_LIBUNWIND_TARGET_SPARC64)
3633 /// Registers_sparc64 holds the register state of a thread in a 64-bit
3634 /// sparc process.
3635 class _LIBUNWIND_HIDDEN Registers_sparc64 {
3636 public:
3637   Registers_sparc64() = default;
3638   Registers_sparc64(const void *registers);
3639 
3640   bool validRegister(int num) const;
3641   uint64_t getRegister(int num) const;
3642   void setRegister(int num, uint64_t value);
3643   bool validFloatRegister(int num) const;
3644   double getFloatRegister(int num) const;
3645   void setFloatRegister(int num, double value);
3646   bool validVectorRegister(int num) const;
3647   v128 getVectorRegister(int num) const;
3648   void setVectorRegister(int num, v128 value);
3649   const char *getRegisterName(int num);
3650   void jumpto();
lastDwarfRegNum()3651   static constexpr int lastDwarfRegNum() {
3652     return _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC64;
3653   }
getArch()3654   static int getArch() { return REGISTERS_SPARC64; }
3655 
getSP() const3656   uint64_t getSP() const { return _registers.__regs[UNW_SPARC_O6] + 2047; }
setSP(uint64_t value)3657   void setSP(uint64_t value) { _registers.__regs[UNW_SPARC_O6] = value - 2047; }
getIP() const3658   uint64_t getIP() const { return _registers.__regs[UNW_SPARC_O7]; }
setIP(uint64_t value)3659   void setIP(uint64_t value) { _registers.__regs[UNW_SPARC_O7] = value; }
getWCookie() const3660   uint64_t getWCookie() const { return _wcookie; }
3661 
3662 private:
3663   struct sparc64_thread_state_t {
3664     uint64_t __regs[32];
3665   };
3666 
3667   sparc64_thread_state_t _registers{};
3668   uint64_t _wcookie = 0;
3669 };
3670 
Registers_sparc64(const void * registers)3671 inline Registers_sparc64::Registers_sparc64(const void *registers) {
3672   static_assert((check_fit<Registers_sparc64, unw_context_t>::does_fit),
3673                 "sparc64 registers do not fit into unw_context_t");
3674   memcpy(&_registers, registers, sizeof(_registers));
3675   memcpy(&_wcookie,
3676          static_cast<const uint8_t *>(registers) + sizeof(_registers),
3677          sizeof(_wcookie));
3678 }
3679 
validRegister(int regNum) const3680 inline bool Registers_sparc64::validRegister(int regNum) const {
3681   if (regNum == UNW_REG_IP)
3682     return true;
3683   if (regNum == UNW_REG_SP)
3684     return true;
3685   if (regNum < 0)
3686     return false;
3687   if (regNum <= UNW_SPARC_I7)
3688     return true;
3689   return false;
3690 }
3691 
getRegister(int regNum) const3692 inline uint64_t Registers_sparc64::getRegister(int regNum) const {
3693   if (regNum >= UNW_SPARC_G0 && regNum <= UNW_SPARC_I7)
3694     return _registers.__regs[regNum];
3695 
3696   switch (regNum) {
3697   case UNW_REG_IP:
3698     return _registers.__regs[UNW_SPARC_O7];
3699   case UNW_REG_SP:
3700     return _registers.__regs[UNW_SPARC_O6] + 2047;
3701   }
3702   _LIBUNWIND_ABORT("unsupported sparc64 register");
3703 }
3704 
setRegister(int regNum,uint64_t value)3705 inline void Registers_sparc64::setRegister(int regNum, uint64_t value) {
3706   if (regNum >= UNW_SPARC_G0 && regNum <= UNW_SPARC_I7) {
3707     _registers.__regs[regNum] = value;
3708     return;
3709   }
3710 
3711   switch (regNum) {
3712   case UNW_REG_IP:
3713     _registers.__regs[UNW_SPARC_O7] = value;
3714     return;
3715   case UNW_REG_SP:
3716     _registers.__regs[UNW_SPARC_O6] = value - 2047;
3717     return;
3718   }
3719   _LIBUNWIND_ABORT("unsupported sparc64 register");
3720 }
3721 
validFloatRegister(int) const3722 inline bool Registers_sparc64::validFloatRegister(int) const { return false; }
3723 
getFloatRegister(int) const3724 inline double Registers_sparc64::getFloatRegister(int) const {
3725   _LIBUNWIND_ABORT("no sparc64 float registers");
3726 }
3727 
setFloatRegister(int,double)3728 inline void Registers_sparc64::setFloatRegister(int, double) {
3729   _LIBUNWIND_ABORT("no sparc64 float registers");
3730 }
3731 
validVectorRegister(int) const3732 inline bool Registers_sparc64::validVectorRegister(int) const { return false; }
3733 
getVectorRegister(int) const3734 inline v128 Registers_sparc64::getVectorRegister(int) const {
3735   _LIBUNWIND_ABORT("no sparc64 vector registers");
3736 }
3737 
setVectorRegister(int,v128)3738 inline void Registers_sparc64::setVectorRegister(int, v128) {
3739   _LIBUNWIND_ABORT("no sparc64 vector registers");
3740 }
3741 
getRegisterName(int regNum)3742 inline const char *Registers_sparc64::getRegisterName(int regNum) {
3743   switch (regNum) {
3744   case UNW_REG_IP:
3745     return "pc";
3746   case UNW_SPARC_G0:
3747     return "g0";
3748   case UNW_SPARC_G1:
3749     return "g1";
3750   case UNW_SPARC_G2:
3751     return "g2";
3752   case UNW_SPARC_G3:
3753     return "g3";
3754   case UNW_SPARC_G4:
3755     return "g4";
3756   case UNW_SPARC_G5:
3757     return "g5";
3758   case UNW_SPARC_G6:
3759     return "g6";
3760   case UNW_SPARC_G7:
3761     return "g7";
3762   case UNW_SPARC_O0:
3763     return "o0";
3764   case UNW_SPARC_O1:
3765     return "o1";
3766   case UNW_SPARC_O2:
3767     return "o2";
3768   case UNW_SPARC_O3:
3769     return "o3";
3770   case UNW_SPARC_O4:
3771     return "o4";
3772   case UNW_SPARC_O5:
3773     return "o5";
3774   case UNW_REG_SP:
3775   case UNW_SPARC_O6:
3776     return "o6";
3777   case UNW_SPARC_O7:
3778     return "o7";
3779   case UNW_SPARC_L0:
3780     return "l0";
3781   case UNW_SPARC_L1:
3782     return "l1";
3783   case UNW_SPARC_L2:
3784     return "l2";
3785   case UNW_SPARC_L3:
3786     return "l3";
3787   case UNW_SPARC_L4:
3788     return "l4";
3789   case UNW_SPARC_L5:
3790     return "l5";
3791   case UNW_SPARC_L6:
3792     return "l6";
3793   case UNW_SPARC_L7:
3794     return "l7";
3795   case UNW_SPARC_I0:
3796     return "i0";
3797   case UNW_SPARC_I1:
3798     return "i1";
3799   case UNW_SPARC_I2:
3800     return "i2";
3801   case UNW_SPARC_I3:
3802     return "i3";
3803   case UNW_SPARC_I4:
3804     return "i4";
3805   case UNW_SPARC_I5:
3806     return "i5";
3807   case UNW_SPARC_I6:
3808     return "i6";
3809   case UNW_SPARC_I7:
3810     return "i7";
3811   default:
3812     return "unknown register";
3813   }
3814 }
3815 #endif // _LIBUNWIND_TARGET_SPARC64
3816 
3817 #if defined(_LIBUNWIND_TARGET_HEXAGON)
3818 /// Registers_hexagon holds the register state of a thread in a Hexagon QDSP6
3819 /// process.
3820 class _LIBUNWIND_HIDDEN Registers_hexagon {
3821 public:
3822   Registers_hexagon();
3823   Registers_hexagon(const void *registers);
3824 
3825   bool        validRegister(int num) const;
3826   uint32_t    getRegister(int num) const;
3827   void        setRegister(int num, uint32_t value);
3828   bool        validFloatRegister(int num) const;
3829   double      getFloatRegister(int num) const;
3830   void        setFloatRegister(int num, double value);
3831   bool        validVectorRegister(int num) const;
3832   v128        getVectorRegister(int num) const;
3833   void        setVectorRegister(int num, v128 value);
3834   const char *getRegisterName(int num);
3835   void        jumpto();
lastDwarfRegNum()3836   static constexpr int lastDwarfRegNum() {
3837     return _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON;
3838   }
getArch()3839   static int  getArch() { return REGISTERS_HEXAGON; }
3840 
getSP() const3841   uint32_t  getSP() const         { return _registers.__r[UNW_HEXAGON_R29]; }
setSP(uint32_t value)3842   void      setSP(uint32_t value) { _registers.__r[UNW_HEXAGON_R29] = value; }
getIP() const3843   uint32_t  getIP() const         { return _registers.__r[UNW_HEXAGON_PC]; }
setIP(uint32_t value)3844   void      setIP(uint32_t value) { _registers.__r[UNW_HEXAGON_PC] = value; }
3845 
3846 private:
3847   struct hexagon_thread_state_t {
3848     unsigned int __r[35];
3849   };
3850 
3851   hexagon_thread_state_t _registers;
3852 };
3853 
Registers_hexagon(const void * registers)3854 inline Registers_hexagon::Registers_hexagon(const void *registers) {
3855   static_assert((check_fit<Registers_hexagon, unw_context_t>::does_fit),
3856                 "hexagon registers do not fit into unw_context_t");
3857   memcpy(&_registers, static_cast<const uint8_t *>(registers),
3858          sizeof(_registers));
3859 }
3860 
Registers_hexagon()3861 inline Registers_hexagon::Registers_hexagon() {
3862   memset(&_registers, 0, sizeof(_registers));
3863 }
3864 
validRegister(int regNum) const3865 inline bool Registers_hexagon::validRegister(int regNum) const {
3866   if (regNum <= UNW_HEXAGON_R31)
3867     return true;
3868   return false;
3869 }
3870 
getRegister(int regNum) const3871 inline uint32_t Registers_hexagon::getRegister(int regNum) const {
3872   if (regNum >= UNW_HEXAGON_R0 && regNum <= UNW_HEXAGON_R31)
3873     return _registers.__r[regNum - UNW_HEXAGON_R0];
3874 
3875   switch (regNum) {
3876   case UNW_REG_IP:
3877     return _registers.__r[UNW_HEXAGON_PC];
3878   case UNW_REG_SP:
3879     return _registers.__r[UNW_HEXAGON_R29];
3880   }
3881   _LIBUNWIND_ABORT("unsupported hexagon register");
3882 }
3883 
setRegister(int regNum,uint32_t value)3884 inline void Registers_hexagon::setRegister(int regNum, uint32_t value) {
3885   if (regNum >= UNW_HEXAGON_R0 && regNum <= UNW_HEXAGON_R31) {
3886     _registers.__r[regNum - UNW_HEXAGON_R0] = value;
3887     return;
3888   }
3889 
3890   switch (regNum) {
3891   case UNW_REG_IP:
3892     _registers.__r[UNW_HEXAGON_PC] = value;
3893     return;
3894   case UNW_REG_SP:
3895     _registers.__r[UNW_HEXAGON_R29] = value;
3896     return;
3897   }
3898   _LIBUNWIND_ABORT("unsupported hexagon register");
3899 }
3900 
validFloatRegister(int) const3901 inline bool Registers_hexagon::validFloatRegister(int /* regNum */) const {
3902   return false;
3903 }
3904 
getFloatRegister(int) const3905 inline double Registers_hexagon::getFloatRegister(int /* regNum */) const {
3906   _LIBUNWIND_ABORT("hexagon float support not implemented");
3907 }
3908 
setFloatRegister(int,double)3909 inline void Registers_hexagon::setFloatRegister(int /* regNum */,
3910                                              double /* value */) {
3911   _LIBUNWIND_ABORT("hexagon float support not implemented");
3912 }
3913 
validVectorRegister(int) const3914 inline bool Registers_hexagon::validVectorRegister(int /* regNum */) const {
3915   return false;
3916 }
3917 
getVectorRegister(int) const3918 inline v128 Registers_hexagon::getVectorRegister(int /* regNum */) const {
3919   _LIBUNWIND_ABORT("hexagon vector support not implemented");
3920 }
3921 
setVectorRegister(int,v128)3922 inline void Registers_hexagon::setVectorRegister(int /* regNum */, v128 /* value */) {
3923   _LIBUNWIND_ABORT("hexagon vector support not implemented");
3924 }
3925 
getRegisterName(int regNum)3926 inline const char *Registers_hexagon::getRegisterName(int regNum) {
3927   switch (regNum) {
3928   case UNW_HEXAGON_R0:
3929     return "r0";
3930   case UNW_HEXAGON_R1:
3931     return "r1";
3932   case UNW_HEXAGON_R2:
3933     return "r2";
3934   case UNW_HEXAGON_R3:
3935     return "r3";
3936   case UNW_HEXAGON_R4:
3937     return "r4";
3938   case UNW_HEXAGON_R5:
3939     return "r5";
3940   case UNW_HEXAGON_R6:
3941     return "r6";
3942   case UNW_HEXAGON_R7:
3943     return "r7";
3944   case UNW_HEXAGON_R8:
3945     return "r8";
3946   case UNW_HEXAGON_R9:
3947     return "r9";
3948   case UNW_HEXAGON_R10:
3949     return "r10";
3950   case UNW_HEXAGON_R11:
3951     return "r11";
3952   case UNW_HEXAGON_R12:
3953     return "r12";
3954   case UNW_HEXAGON_R13:
3955     return "r13";
3956   case UNW_HEXAGON_R14:
3957     return "r14";
3958   case UNW_HEXAGON_R15:
3959     return "r15";
3960   case UNW_HEXAGON_R16:
3961     return "r16";
3962   case UNW_HEXAGON_R17:
3963     return "r17";
3964   case UNW_HEXAGON_R18:
3965     return "r18";
3966   case UNW_HEXAGON_R19:
3967     return "r19";
3968   case UNW_HEXAGON_R20:
3969     return "r20";
3970   case UNW_HEXAGON_R21:
3971     return "r21";
3972   case UNW_HEXAGON_R22:
3973     return "r22";
3974   case UNW_HEXAGON_R23:
3975     return "r23";
3976   case UNW_HEXAGON_R24:
3977     return "r24";
3978   case UNW_HEXAGON_R25:
3979     return "r25";
3980   case UNW_HEXAGON_R26:
3981     return "r26";
3982   case UNW_HEXAGON_R27:
3983     return "r27";
3984   case UNW_HEXAGON_R28:
3985     return "r28";
3986   case UNW_HEXAGON_R29:
3987     return "r29";
3988   case UNW_HEXAGON_R30:
3989     return "r30";
3990   case UNW_HEXAGON_R31:
3991     return "r31";
3992   default:
3993     return "unknown register";
3994   }
3995 
3996 }
3997 #endif // _LIBUNWIND_TARGET_HEXAGON
3998 
3999 
4000 #if defined(_LIBUNWIND_TARGET_RISCV)
4001 /// Registers_riscv holds the register state of a thread in a RISC-V
4002 /// process.
4003 
4004 // This check makes it safe when LIBUNWIND_ENABLE_CROSS_UNWINDING enabled.
4005 # ifdef __riscv
4006 #  if __riscv_xlen == 32
4007 typedef uint32_t reg_t;
4008 #  elif __riscv_xlen == 64
4009 typedef uint64_t reg_t;
4010 #  else
4011 #   error "Unsupported __riscv_xlen"
4012 #  endif
4013 
4014 #  if defined(__riscv_flen)
4015 #   if __riscv_flen == 64
4016 typedef double fp_t;
4017 #   elif __riscv_flen == 32
4018 typedef float fp_t;
4019 #   else
4020 #    error "Unsupported __riscv_flen"
4021 #   endif
4022 #  else
4023 // This is just for suppressing undeclared error of fp_t.
4024 typedef double fp_t;
4025 #  endif
4026 # else
4027 // Use Max possible width when cross unwinding
4028 typedef uint64_t reg_t;
4029 typedef double fp_t;
4030 # define __riscv_xlen 64
4031 # define __riscv_flen 64
4032 #endif
4033 
4034 /// Registers_riscv holds the register state of a thread.
4035 class _LIBUNWIND_HIDDEN Registers_riscv {
4036 public:
4037   Registers_riscv();
4038   Registers_riscv(const void *registers);
4039 
4040   bool        validRegister(int num) const;
4041   reg_t       getRegister(int num) const;
4042   void        setRegister(int num, reg_t value);
4043   bool        validFloatRegister(int num) const;
4044   fp_t        getFloatRegister(int num) const;
4045   void        setFloatRegister(int num, fp_t value);
4046   bool        validVectorRegister(int num) const;
4047   v128        getVectorRegister(int num) const;
4048   void        setVectorRegister(int num, v128 value);
4049   static const char *getRegisterName(int num);
4050   void        jumpto();
lastDwarfRegNum()4051   static constexpr int lastDwarfRegNum() {
4052     return _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV;
4053   }
getArch()4054   static int  getArch() { return REGISTERS_RISCV; }
4055 
getSP() const4056   reg_t       getSP() const { return _registers[2]; }
setSP(reg_t value)4057   void        setSP(reg_t value) { _registers[2] = value; }
getIP() const4058   reg_t       getIP() const { return _registers[0]; }
setIP(reg_t value)4059   void        setIP(reg_t value) { _registers[0] = value; }
4060 
4061 private:
4062   // _registers[0] holds the pc
4063   reg_t _registers[32];
4064 # if defined(__riscv_flen)
4065   fp_t _floats[32];
4066 # endif
4067 };
4068 
Registers_riscv(const void * registers)4069 inline Registers_riscv::Registers_riscv(const void *registers) {
4070   static_assert((check_fit<Registers_riscv, unw_context_t>::does_fit),
4071                 "riscv registers do not fit into unw_context_t");
4072   memcpy(&_registers, registers, sizeof(_registers));
4073 # if __riscv_xlen == 32
4074   static_assert(sizeof(_registers) == 0x80,
4075                 "expected float registers to be at offset 128");
4076 # elif __riscv_xlen == 64
4077   static_assert(sizeof(_registers) == 0x100,
4078                 "expected float registers to be at offset 256");
4079 # else
4080 # error "Unexpected float registers."
4081 # endif
4082 
4083 # if defined(__riscv_flen)
4084   memcpy(_floats,
4085          static_cast<const uint8_t *>(registers) + sizeof(_registers),
4086          sizeof(_floats));
4087 # endif
4088 }
4089 
Registers_riscv()4090 inline Registers_riscv::Registers_riscv() {
4091   memset(&_registers, 0, sizeof(_registers));
4092 # if defined(__riscv_flen)
4093   memset(&_floats, 0, sizeof(_floats));
4094 # endif
4095 }
4096 
validRegister(int regNum) const4097 inline bool Registers_riscv::validRegister(int regNum) const {
4098   if (regNum == UNW_REG_IP)
4099     return true;
4100   if (regNum == UNW_REG_SP)
4101     return true;
4102   if (regNum < 0)
4103     return false;
4104   if (regNum == UNW_RISCV_VLENB)
4105     return true;
4106   if (regNum > UNW_RISCV_F31)
4107     return false;
4108   return true;
4109 }
4110 
getRegister(int regNum) const4111 inline reg_t Registers_riscv::getRegister(int regNum) const {
4112   if (regNum == UNW_REG_IP)
4113     return _registers[0];
4114   if (regNum == UNW_REG_SP)
4115     return _registers[2];
4116   if (regNum == UNW_RISCV_X0)
4117     return 0;
4118   if ((regNum > 0) && (regNum < 32))
4119     return _registers[regNum];
4120   if (regNum == UNW_RISCV_VLENB) {
4121     reg_t vlenb;
4122     __asm__("csrr %0, 0xC22" : "=r"(vlenb));
4123     return vlenb;
4124   }
4125   _LIBUNWIND_ABORT("unsupported riscv register");
4126 }
4127 
setRegister(int regNum,reg_t value)4128 inline void Registers_riscv::setRegister(int regNum, reg_t value) {
4129   if (regNum == UNW_REG_IP)
4130     _registers[0] = value;
4131   else if (regNum == UNW_REG_SP)
4132     _registers[2] = value;
4133   else if (regNum == UNW_RISCV_X0)
4134     /* x0 is hardwired to zero */
4135     return;
4136   else if ((regNum > 0) && (regNum < 32))
4137     _registers[regNum] = value;
4138   else
4139     _LIBUNWIND_ABORT("unsupported riscv register");
4140 }
4141 
getRegisterName(int regNum)4142 inline const char *Registers_riscv::getRegisterName(int regNum) {
4143   switch (regNum) {
4144   case UNW_REG_IP:
4145     return "pc";
4146   case UNW_REG_SP:
4147     return "sp";
4148   case UNW_RISCV_X0:
4149     return "zero";
4150   case UNW_RISCV_X1:
4151     return "ra";
4152   case UNW_RISCV_X2:
4153     return "sp";
4154   case UNW_RISCV_X3:
4155     return "gp";
4156   case UNW_RISCV_X4:
4157     return "tp";
4158   case UNW_RISCV_X5:
4159     return "t0";
4160   case UNW_RISCV_X6:
4161     return "t1";
4162   case UNW_RISCV_X7:
4163     return "t2";
4164   case UNW_RISCV_X8:
4165     return "s0";
4166   case UNW_RISCV_X9:
4167     return "s1";
4168   case UNW_RISCV_X10:
4169     return "a0";
4170   case UNW_RISCV_X11:
4171     return "a1";
4172   case UNW_RISCV_X12:
4173     return "a2";
4174   case UNW_RISCV_X13:
4175     return "a3";
4176   case UNW_RISCV_X14:
4177     return "a4";
4178   case UNW_RISCV_X15:
4179     return "a5";
4180   case UNW_RISCV_X16:
4181     return "a6";
4182   case UNW_RISCV_X17:
4183     return "a7";
4184   case UNW_RISCV_X18:
4185     return "s2";
4186   case UNW_RISCV_X19:
4187     return "s3";
4188   case UNW_RISCV_X20:
4189     return "s4";
4190   case UNW_RISCV_X21:
4191     return "s5";
4192   case UNW_RISCV_X22:
4193     return "s6";
4194   case UNW_RISCV_X23:
4195     return "s7";
4196   case UNW_RISCV_X24:
4197     return "s8";
4198   case UNW_RISCV_X25:
4199     return "s9";
4200   case UNW_RISCV_X26:
4201     return "s10";
4202   case UNW_RISCV_X27:
4203     return "s11";
4204   case UNW_RISCV_X28:
4205     return "t3";
4206   case UNW_RISCV_X29:
4207     return "t4";
4208   case UNW_RISCV_X30:
4209     return "t5";
4210   case UNW_RISCV_X31:
4211     return "t6";
4212   case UNW_RISCV_F0:
4213     return "ft0";
4214   case UNW_RISCV_F1:
4215     return "ft1";
4216   case UNW_RISCV_F2:
4217     return "ft2";
4218   case UNW_RISCV_F3:
4219     return "ft3";
4220   case UNW_RISCV_F4:
4221     return "ft4";
4222   case UNW_RISCV_F5:
4223     return "ft5";
4224   case UNW_RISCV_F6:
4225     return "ft6";
4226   case UNW_RISCV_F7:
4227     return "ft7";
4228   case UNW_RISCV_F8:
4229     return "fs0";
4230   case UNW_RISCV_F9:
4231     return "fs1";
4232   case UNW_RISCV_F10:
4233     return "fa0";
4234   case UNW_RISCV_F11:
4235     return "fa1";
4236   case UNW_RISCV_F12:
4237     return "fa2";
4238   case UNW_RISCV_F13:
4239     return "fa3";
4240   case UNW_RISCV_F14:
4241     return "fa4";
4242   case UNW_RISCV_F15:
4243     return "fa5";
4244   case UNW_RISCV_F16:
4245     return "fa6";
4246   case UNW_RISCV_F17:
4247     return "fa7";
4248   case UNW_RISCV_F18:
4249     return "fs2";
4250   case UNW_RISCV_F19:
4251     return "fs3";
4252   case UNW_RISCV_F20:
4253     return "fs4";
4254   case UNW_RISCV_F21:
4255     return "fs5";
4256   case UNW_RISCV_F22:
4257     return "fs6";
4258   case UNW_RISCV_F23:
4259     return "fs7";
4260   case UNW_RISCV_F24:
4261     return "fs8";
4262   case UNW_RISCV_F25:
4263     return "fs9";
4264   case UNW_RISCV_F26:
4265     return "fs10";
4266   case UNW_RISCV_F27:
4267     return "fs11";
4268   case UNW_RISCV_F28:
4269     return "ft8";
4270   case UNW_RISCV_F29:
4271     return "ft9";
4272   case UNW_RISCV_F30:
4273     return "ft10";
4274   case UNW_RISCV_F31:
4275     return "ft11";
4276   case UNW_RISCV_VLENB:
4277     return "vlenb";
4278   default:
4279     return "unknown register";
4280   }
4281 }
4282 
validFloatRegister(int regNum) const4283 inline bool Registers_riscv::validFloatRegister(int regNum) const {
4284 # if defined(__riscv_flen)
4285   if (regNum < UNW_RISCV_F0)
4286     return false;
4287   if (regNum > UNW_RISCV_F31)
4288     return false;
4289   return true;
4290 # else
4291   (void)regNum;
4292   return false;
4293 # endif
4294 }
4295 
getFloatRegister(int regNum) const4296 inline fp_t Registers_riscv::getFloatRegister(int regNum) const {
4297 # if defined(__riscv_flen)
4298   assert(validFloatRegister(regNum));
4299   return _floats[regNum - UNW_RISCV_F0];
4300 # else
4301   (void)regNum;
4302   _LIBUNWIND_ABORT("libunwind not built with float support");
4303 # endif
4304 }
4305 
setFloatRegister(int regNum,fp_t value)4306 inline void Registers_riscv::setFloatRegister(int regNum, fp_t value) {
4307 # if defined(__riscv_flen)
4308   assert(validFloatRegister(regNum));
4309   _floats[regNum - UNW_RISCV_F0] = value;
4310 # else
4311   (void)regNum;
4312   (void)value;
4313   _LIBUNWIND_ABORT("libunwind not built with float support");
4314 # endif
4315 }
4316 
validVectorRegister(int) const4317 inline bool Registers_riscv::validVectorRegister(int) const {
4318   return false;
4319 }
4320 
getVectorRegister(int) const4321 inline v128 Registers_riscv::getVectorRegister(int) const {
4322   _LIBUNWIND_ABORT("no riscv vector register support yet");
4323 }
4324 
setVectorRegister(int,v128)4325 inline void Registers_riscv::setVectorRegister(int, v128) {
4326   _LIBUNWIND_ABORT("no riscv vector register support yet");
4327 }
4328 #endif // _LIBUNWIND_TARGET_RISCV
4329 
4330 #if defined(_LIBUNWIND_TARGET_VE)
4331 /// Registers_ve holds the register state of a thread in a VE process.
4332 class _LIBUNWIND_HIDDEN Registers_ve {
4333 public:
4334   Registers_ve();
4335   Registers_ve(const void *registers);
4336 
4337   bool        validRegister(int num) const;
4338   uint64_t    getRegister(int num) const;
4339   void        setRegister(int num, uint64_t value);
4340   bool        validFloatRegister(int num) const;
4341   double      getFloatRegister(int num) const;
4342   void        setFloatRegister(int num, double value);
4343   bool        validVectorRegister(int num) const;
4344   v128        getVectorRegister(int num) const;
4345   void        setVectorRegister(int num, v128 value);
4346   static const char *getRegisterName(int num);
4347   void        jumpto();
lastDwarfRegNum()4348   static constexpr int lastDwarfRegNum() {
4349     return _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE;
4350   }
getArch()4351   static int  getArch() { return REGISTERS_VE; }
4352 
getSP() const4353   uint64_t  getSP() const         { return _registers.__s[11]; }
setSP(uint64_t value)4354   void      setSP(uint64_t value) { _registers.__s[11] = value; }
getIP() const4355   uint64_t  getIP() const         { return _registers.__ic; }
setIP(uint64_t value)4356   void      setIP(uint64_t value) { _registers.__ic = value; }
4357 
4358 private:
4359   // FIXME: Need to store not only scalar registers but also vector and vector
4360   // mask registers.  VEOS uses mcontext_t defined in ucontext.h.  It takes
4361   // 524288 bytes (65536*8 bytes), though.  Currently, we use libunwind for
4362   // SjLj exception support only, so Registers_ve is not implemented completely.
4363   struct ve_thread_state_t {
4364     uint64_t __s[64]; // s0-s64
4365     uint64_t __ic;    // Instruction counter (IC)
4366     uint64_t __vixr;  // Vector Index Register
4367     uint64_t __vl;    // Vector Length Register
4368   };
4369 
4370   ve_thread_state_t _registers; // total 67 registers
4371 
4372   // Currently no vector register is preserved.
4373 };
4374 
Registers_ve(const void * registers)4375 inline Registers_ve::Registers_ve(const void *registers) {
4376   static_assert((check_fit<Registers_ve, unw_context_t>::does_fit),
4377                 "ve registers do not fit into unw_context_t");
4378   memcpy(&_registers, static_cast<const uint8_t *>(registers),
4379          sizeof(_registers));
4380   static_assert(sizeof(_registers) == 536,
4381                 "expected vector register offset to be 536");
4382 }
4383 
Registers_ve()4384 inline Registers_ve::Registers_ve() {
4385   memset(&_registers, 0, sizeof(_registers));
4386 }
4387 
validRegister(int regNum) const4388 inline bool Registers_ve::validRegister(int regNum) const {
4389   if (regNum >= UNW_VE_S0 && regNum <= UNW_VE_S63)
4390     return true;
4391 
4392   switch (regNum) {
4393   case UNW_REG_IP:
4394   case UNW_REG_SP:
4395   case UNW_VE_VIXR:
4396   case UNW_VE_VL:
4397     return true;
4398   default:
4399     return false;
4400   }
4401 }
4402 
getRegister(int regNum) const4403 inline uint64_t Registers_ve::getRegister(int regNum) const {
4404   if (regNum >= UNW_VE_S0 && regNum <= UNW_VE_S63)
4405     return _registers.__s[regNum - UNW_VE_S0];
4406 
4407   switch (regNum) {
4408   case UNW_REG_IP:
4409     return _registers.__ic;
4410   case UNW_REG_SP:
4411     return _registers.__s[11];
4412   case UNW_VE_VIXR:
4413     return _registers.__vixr;
4414   case UNW_VE_VL:
4415     return _registers.__vl;
4416   }
4417   _LIBUNWIND_ABORT("unsupported ve register");
4418 }
4419 
setRegister(int regNum,uint64_t value)4420 inline void Registers_ve::setRegister(int regNum, uint64_t value) {
4421   if (regNum >= UNW_VE_S0 && regNum <= UNW_VE_S63) {
4422     _registers.__s[regNum - UNW_VE_S0] = value;
4423     return;
4424   }
4425 
4426   switch (regNum) {
4427   case UNW_REG_IP:
4428     _registers.__ic = value;
4429     return;
4430   case UNW_REG_SP:
4431     _registers.__s[11] = value;
4432     return;
4433   case UNW_VE_VIXR:
4434     _registers.__vixr = value;
4435     return;
4436   case UNW_VE_VL:
4437     _registers.__vl = value;
4438     return;
4439   }
4440   _LIBUNWIND_ABORT("unsupported ve register");
4441 }
4442 
validFloatRegister(int) const4443 inline bool Registers_ve::validFloatRegister(int /* regNum */) const {
4444   return false;
4445 }
4446 
getFloatRegister(int) const4447 inline double Registers_ve::getFloatRegister(int /* regNum */) const {
4448   _LIBUNWIND_ABORT("VE doesn't have float registers");
4449 }
4450 
setFloatRegister(int,double)4451 inline void Registers_ve::setFloatRegister(int /* regNum */,
4452                                            double /* value */) {
4453   _LIBUNWIND_ABORT("VE doesn't have float registers");
4454 }
4455 
validVectorRegister(int) const4456 inline bool Registers_ve::validVectorRegister(int /* regNum */) const {
4457   return false;
4458 }
4459 
getVectorRegister(int) const4460 inline v128 Registers_ve::getVectorRegister(int /* regNum */) const {
4461   _LIBUNWIND_ABORT("VE vector support not implemented");
4462 }
4463 
setVectorRegister(int,v128)4464 inline void Registers_ve::setVectorRegister(int /* regNum */,
4465                                             v128 /* value */) {
4466   _LIBUNWIND_ABORT("VE vector support not implemented");
4467 }
4468 
getRegisterName(int regNum)4469 inline const char *Registers_ve::getRegisterName(int regNum) {
4470   switch (regNum) {
4471   case UNW_REG_IP:
4472     return "ip";
4473   case UNW_REG_SP:
4474     return "sp";
4475   case UNW_VE_VIXR:
4476     return "vixr";
4477   case UNW_VE_VL:
4478     return "vl";
4479   case UNW_VE_S0:
4480     return "s0";
4481   case UNW_VE_S1:
4482     return "s1";
4483   case UNW_VE_S2:
4484     return "s2";
4485   case UNW_VE_S3:
4486     return "s3";
4487   case UNW_VE_S4:
4488     return "s4";
4489   case UNW_VE_S5:
4490     return "s5";
4491   case UNW_VE_S6:
4492     return "s6";
4493   case UNW_VE_S7:
4494     return "s7";
4495   case UNW_VE_S8:
4496     return "s8";
4497   case UNW_VE_S9:
4498     return "s9";
4499   case UNW_VE_S10:
4500     return "s10";
4501   case UNW_VE_S11:
4502     return "s11";
4503   case UNW_VE_S12:
4504     return "s12";
4505   case UNW_VE_S13:
4506     return "s13";
4507   case UNW_VE_S14:
4508     return "s14";
4509   case UNW_VE_S15:
4510     return "s15";
4511   case UNW_VE_S16:
4512     return "s16";
4513   case UNW_VE_S17:
4514     return "s17";
4515   case UNW_VE_S18:
4516     return "s18";
4517   case UNW_VE_S19:
4518     return "s19";
4519   case UNW_VE_S20:
4520     return "s20";
4521   case UNW_VE_S21:
4522     return "s21";
4523   case UNW_VE_S22:
4524     return "s22";
4525   case UNW_VE_S23:
4526     return "s23";
4527   case UNW_VE_S24:
4528     return "s24";
4529   case UNW_VE_S25:
4530     return "s25";
4531   case UNW_VE_S26:
4532     return "s26";
4533   case UNW_VE_S27:
4534     return "s27";
4535   case UNW_VE_S28:
4536     return "s28";
4537   case UNW_VE_S29:
4538     return "s29";
4539   case UNW_VE_S30:
4540     return "s30";
4541   case UNW_VE_S31:
4542     return "s31";
4543   case UNW_VE_S32:
4544     return "s32";
4545   case UNW_VE_S33:
4546     return "s33";
4547   case UNW_VE_S34:
4548     return "s34";
4549   case UNW_VE_S35:
4550     return "s35";
4551   case UNW_VE_S36:
4552     return "s36";
4553   case UNW_VE_S37:
4554     return "s37";
4555   case UNW_VE_S38:
4556     return "s38";
4557   case UNW_VE_S39:
4558     return "s39";
4559   case UNW_VE_S40:
4560     return "s40";
4561   case UNW_VE_S41:
4562     return "s41";
4563   case UNW_VE_S42:
4564     return "s42";
4565   case UNW_VE_S43:
4566     return "s43";
4567   case UNW_VE_S44:
4568     return "s44";
4569   case UNW_VE_S45:
4570     return "s45";
4571   case UNW_VE_S46:
4572     return "s46";
4573   case UNW_VE_S47:
4574     return "s47";
4575   case UNW_VE_S48:
4576     return "s48";
4577   case UNW_VE_S49:
4578     return "s49";
4579   case UNW_VE_S50:
4580     return "s50";
4581   case UNW_VE_S51:
4582     return "s51";
4583   case UNW_VE_S52:
4584     return "s52";
4585   case UNW_VE_S53:
4586     return "s53";
4587   case UNW_VE_S54:
4588     return "s54";
4589   case UNW_VE_S55:
4590     return "s55";
4591   case UNW_VE_S56:
4592     return "s56";
4593   case UNW_VE_S57:
4594     return "s57";
4595   case UNW_VE_S58:
4596     return "s58";
4597   case UNW_VE_S59:
4598     return "s59";
4599   case UNW_VE_S60:
4600     return "s60";
4601   case UNW_VE_S61:
4602     return "s61";
4603   case UNW_VE_S62:
4604     return "s62";
4605   case UNW_VE_S63:
4606     return "s63";
4607   case UNW_VE_V0:
4608     return "v0";
4609   case UNW_VE_V1:
4610     return "v1";
4611   case UNW_VE_V2:
4612     return "v2";
4613   case UNW_VE_V3:
4614     return "v3";
4615   case UNW_VE_V4:
4616     return "v4";
4617   case UNW_VE_V5:
4618     return "v5";
4619   case UNW_VE_V6:
4620     return "v6";
4621   case UNW_VE_V7:
4622     return "v7";
4623   case UNW_VE_V8:
4624     return "v8";
4625   case UNW_VE_V9:
4626     return "v9";
4627   case UNW_VE_V10:
4628     return "v10";
4629   case UNW_VE_V11:
4630     return "v11";
4631   case UNW_VE_V12:
4632     return "v12";
4633   case UNW_VE_V13:
4634     return "v13";
4635   case UNW_VE_V14:
4636     return "v14";
4637   case UNW_VE_V15:
4638     return "v15";
4639   case UNW_VE_V16:
4640     return "v16";
4641   case UNW_VE_V17:
4642     return "v17";
4643   case UNW_VE_V18:
4644     return "v18";
4645   case UNW_VE_V19:
4646     return "v19";
4647   case UNW_VE_V20:
4648     return "v20";
4649   case UNW_VE_V21:
4650     return "v21";
4651   case UNW_VE_V22:
4652     return "v22";
4653   case UNW_VE_V23:
4654     return "v23";
4655   case UNW_VE_V24:
4656     return "v24";
4657   case UNW_VE_V25:
4658     return "v25";
4659   case UNW_VE_V26:
4660     return "v26";
4661   case UNW_VE_V27:
4662     return "v27";
4663   case UNW_VE_V28:
4664     return "v28";
4665   case UNW_VE_V29:
4666     return "v29";
4667   case UNW_VE_V30:
4668     return "v30";
4669   case UNW_VE_V31:
4670     return "v31";
4671   case UNW_VE_V32:
4672     return "v32";
4673   case UNW_VE_V33:
4674     return "v33";
4675   case UNW_VE_V34:
4676     return "v34";
4677   case UNW_VE_V35:
4678     return "v35";
4679   case UNW_VE_V36:
4680     return "v36";
4681   case UNW_VE_V37:
4682     return "v37";
4683   case UNW_VE_V38:
4684     return "v38";
4685   case UNW_VE_V39:
4686     return "v39";
4687   case UNW_VE_V40:
4688     return "v40";
4689   case UNW_VE_V41:
4690     return "v41";
4691   case UNW_VE_V42:
4692     return "v42";
4693   case UNW_VE_V43:
4694     return "v43";
4695   case UNW_VE_V44:
4696     return "v44";
4697   case UNW_VE_V45:
4698     return "v45";
4699   case UNW_VE_V46:
4700     return "v46";
4701   case UNW_VE_V47:
4702     return "v47";
4703   case UNW_VE_V48:
4704     return "v48";
4705   case UNW_VE_V49:
4706     return "v49";
4707   case UNW_VE_V50:
4708     return "v50";
4709   case UNW_VE_V51:
4710     return "v51";
4711   case UNW_VE_V52:
4712     return "v52";
4713   case UNW_VE_V53:
4714     return "v53";
4715   case UNW_VE_V54:
4716     return "v54";
4717   case UNW_VE_V55:
4718     return "v55";
4719   case UNW_VE_V56:
4720     return "v56";
4721   case UNW_VE_V57:
4722     return "v57";
4723   case UNW_VE_V58:
4724     return "v58";
4725   case UNW_VE_V59:
4726     return "v59";
4727   case UNW_VE_V60:
4728     return "v60";
4729   case UNW_VE_V61:
4730     return "v61";
4731   case UNW_VE_V62:
4732     return "v62";
4733   case UNW_VE_V63:
4734     return "v63";
4735   case UNW_VE_VM0:
4736     return "vm0";
4737   case UNW_VE_VM1:
4738     return "vm1";
4739   case UNW_VE_VM2:
4740     return "vm2";
4741   case UNW_VE_VM3:
4742     return "vm3";
4743   case UNW_VE_VM4:
4744     return "vm4";
4745   case UNW_VE_VM5:
4746     return "vm5";
4747   case UNW_VE_VM6:
4748     return "vm6";
4749   case UNW_VE_VM7:
4750     return "vm7";
4751   case UNW_VE_VM8:
4752     return "vm8";
4753   case UNW_VE_VM9:
4754     return "vm9";
4755   case UNW_VE_VM10:
4756     return "vm10";
4757   case UNW_VE_VM11:
4758     return "vm11";
4759   case UNW_VE_VM12:
4760     return "vm12";
4761   case UNW_VE_VM13:
4762     return "vm13";
4763   case UNW_VE_VM14:
4764     return "vm14";
4765   case UNW_VE_VM15:
4766     return "vm15";
4767   }
4768   return "unknown register";
4769 }
4770 #endif // _LIBUNWIND_TARGET_VE
4771 
4772 #if defined(_LIBUNWIND_TARGET_S390X)
4773 /// Registers_s390x holds the register state of a thread in a
4774 /// 64-bit Linux on IBM zSystems process.
4775 class _LIBUNWIND_HIDDEN Registers_s390x {
4776 public:
4777   Registers_s390x();
4778   Registers_s390x(const void *registers);
4779 
4780   bool        validRegister(int num) const;
4781   uint64_t    getRegister(int num) const;
4782   void        setRegister(int num, uint64_t value);
4783   bool        validFloatRegister(int num) const;
4784   double      getFloatRegister(int num) const;
4785   void        setFloatRegister(int num, double value);
4786   bool        validVectorRegister(int num) const;
4787   v128        getVectorRegister(int num) const;
4788   void        setVectorRegister(int num, v128 value);
4789   static const char *getRegisterName(int num);
4790   void        jumpto();
lastDwarfRegNum()4791   static constexpr int lastDwarfRegNum() {
4792     return _LIBUNWIND_HIGHEST_DWARF_REGISTER_S390X;
4793   }
getArch()4794   static int  getArch() { return REGISTERS_S390X; }
4795 
getSP() const4796   uint64_t  getSP() const         { return _registers.__gpr[15]; }
setSP(uint64_t value)4797   void      setSP(uint64_t value) { _registers.__gpr[15] = value; }
getIP() const4798   uint64_t  getIP() const         { return _registers.__pswa; }
setIP(uint64_t value)4799   void      setIP(uint64_t value) { _registers.__pswa = value; }
4800 
4801 private:
4802   struct s390x_thread_state_t {
4803     uint64_t __pswm;    // Problem Status Word: Mask
4804     uint64_t __pswa;    // Problem Status Word: Address (PC)
4805     uint64_t __gpr[16]; // General Purpose Registers
4806     double __fpr[16];   // Floating-Point Registers
4807   };
4808 
4809   s390x_thread_state_t _registers;
4810 };
4811 
Registers_s390x(const void * registers)4812 inline Registers_s390x::Registers_s390x(const void *registers) {
4813   static_assert((check_fit<Registers_s390x, unw_context_t>::does_fit),
4814                 "s390x registers do not fit into unw_context_t");
4815   memcpy(&_registers, static_cast<const uint8_t *>(registers),
4816          sizeof(_registers));
4817 }
4818 
Registers_s390x()4819 inline Registers_s390x::Registers_s390x() {
4820   memset(&_registers, 0, sizeof(_registers));
4821 }
4822 
validRegister(int regNum) const4823 inline bool Registers_s390x::validRegister(int regNum) const {
4824   switch (regNum) {
4825   case UNW_S390X_PSWM:
4826   case UNW_S390X_PSWA:
4827   case UNW_REG_IP:
4828   case UNW_REG_SP:
4829       return true;
4830   }
4831 
4832   if (regNum >= UNW_S390X_R0 && regNum <= UNW_S390X_R15)
4833     return true;
4834 
4835   return false;
4836 }
4837 
getRegister(int regNum) const4838 inline uint64_t Registers_s390x::getRegister(int regNum) const {
4839   if (regNum >= UNW_S390X_R0 && regNum <= UNW_S390X_R15)
4840     return _registers.__gpr[regNum - UNW_S390X_R0];
4841 
4842   switch (regNum) {
4843   case UNW_S390X_PSWM:
4844     return _registers.__pswm;
4845   case UNW_S390X_PSWA:
4846   case UNW_REG_IP:
4847     return _registers.__pswa;
4848   case UNW_REG_SP:
4849     return _registers.__gpr[15];
4850   }
4851   _LIBUNWIND_ABORT("unsupported s390x register");
4852 }
4853 
setRegister(int regNum,uint64_t value)4854 inline void Registers_s390x::setRegister(int regNum, uint64_t value) {
4855   if (regNum >= UNW_S390X_R0 && regNum <= UNW_S390X_R15) {
4856     _registers.__gpr[regNum - UNW_S390X_R0] = value;
4857     return;
4858   }
4859 
4860   switch (regNum) {
4861   case UNW_S390X_PSWM:
4862     _registers.__pswm = value;
4863     return;
4864   case UNW_S390X_PSWA:
4865   case UNW_REG_IP:
4866     _registers.__pswa = value;
4867     return;
4868   case UNW_REG_SP:
4869     _registers.__gpr[15] = value;
4870     return;
4871   }
4872   _LIBUNWIND_ABORT("unsupported s390x register");
4873 }
4874 
validFloatRegister(int regNum) const4875 inline bool Registers_s390x::validFloatRegister(int regNum) const {
4876   return regNum >= UNW_S390X_F0 && regNum <= UNW_S390X_F15;
4877 }
4878 
getFloatRegister(int regNum) const4879 inline double Registers_s390x::getFloatRegister(int regNum) const {
4880   // NOTE: FPR DWARF register numbers are not consecutive.
4881   switch (regNum) {
4882   case UNW_S390X_F0:
4883     return _registers.__fpr[0];
4884   case UNW_S390X_F1:
4885     return _registers.__fpr[1];
4886   case UNW_S390X_F2:
4887     return _registers.__fpr[2];
4888   case UNW_S390X_F3:
4889     return _registers.__fpr[3];
4890   case UNW_S390X_F4:
4891     return _registers.__fpr[4];
4892   case UNW_S390X_F5:
4893     return _registers.__fpr[5];
4894   case UNW_S390X_F6:
4895     return _registers.__fpr[6];
4896   case UNW_S390X_F7:
4897     return _registers.__fpr[7];
4898   case UNW_S390X_F8:
4899     return _registers.__fpr[8];
4900   case UNW_S390X_F9:
4901     return _registers.__fpr[9];
4902   case UNW_S390X_F10:
4903     return _registers.__fpr[10];
4904   case UNW_S390X_F11:
4905     return _registers.__fpr[11];
4906   case UNW_S390X_F12:
4907     return _registers.__fpr[12];
4908   case UNW_S390X_F13:
4909     return _registers.__fpr[13];
4910   case UNW_S390X_F14:
4911     return _registers.__fpr[14];
4912   case UNW_S390X_F15:
4913     return _registers.__fpr[15];
4914   }
4915   _LIBUNWIND_ABORT("unsupported s390x register");
4916 }
4917 
setFloatRegister(int regNum,double value)4918 inline void Registers_s390x::setFloatRegister(int regNum, double value) {
4919   // NOTE: FPR DWARF register numbers are not consecutive.
4920   switch (regNum) {
4921   case UNW_S390X_F0:
4922     _registers.__fpr[0] = value;
4923     return;
4924   case UNW_S390X_F1:
4925     _registers.__fpr[1] = value;
4926     return;
4927   case UNW_S390X_F2:
4928     _registers.__fpr[2] = value;
4929     return;
4930   case UNW_S390X_F3:
4931     _registers.__fpr[3] = value;
4932     return;
4933   case UNW_S390X_F4:
4934     _registers.__fpr[4] = value;
4935     return;
4936   case UNW_S390X_F5:
4937     _registers.__fpr[5] = value;
4938     return;
4939   case UNW_S390X_F6:
4940     _registers.__fpr[6] = value;
4941     return;
4942   case UNW_S390X_F7:
4943     _registers.__fpr[7] = value;
4944     return;
4945   case UNW_S390X_F8:
4946     _registers.__fpr[8] = value;
4947     return;
4948   case UNW_S390X_F9:
4949     _registers.__fpr[9] = value;
4950     return;
4951   case UNW_S390X_F10:
4952     _registers.__fpr[10] = value;
4953     return;
4954   case UNW_S390X_F11:
4955     _registers.__fpr[11] = value;
4956     return;
4957   case UNW_S390X_F12:
4958     _registers.__fpr[12] = value;
4959     return;
4960   case UNW_S390X_F13:
4961     _registers.__fpr[13] = value;
4962     return;
4963   case UNW_S390X_F14:
4964     _registers.__fpr[14] = value;
4965     return;
4966   case UNW_S390X_F15:
4967     _registers.__fpr[15] = value;
4968     return;
4969   }
4970   _LIBUNWIND_ABORT("unsupported s390x register");
4971 }
4972 
validVectorRegister(int) const4973 inline bool Registers_s390x::validVectorRegister(int /*regNum*/) const {
4974   return false;
4975 }
4976 
getVectorRegister(int) const4977 inline v128 Registers_s390x::getVectorRegister(int /*regNum*/) const {
4978   _LIBUNWIND_ABORT("s390x vector support not implemented");
4979 }
4980 
setVectorRegister(int,v128)4981 inline void Registers_s390x::setVectorRegister(int /*regNum*/, v128 /*value*/) {
4982   _LIBUNWIND_ABORT("s390x vector support not implemented");
4983 }
4984 
getRegisterName(int regNum)4985 inline const char *Registers_s390x::getRegisterName(int regNum) {
4986   switch (regNum) {
4987   case UNW_REG_IP:
4988     return "ip";
4989   case UNW_REG_SP:
4990     return "sp";
4991   case UNW_S390X_R0:
4992     return "r0";
4993   case UNW_S390X_R1:
4994     return "r1";
4995   case UNW_S390X_R2:
4996     return "r2";
4997   case UNW_S390X_R3:
4998     return "r3";
4999   case UNW_S390X_R4:
5000     return "r4";
5001   case UNW_S390X_R5:
5002     return "r5";
5003   case UNW_S390X_R6:
5004     return "r6";
5005   case UNW_S390X_R7:
5006     return "r7";
5007   case UNW_S390X_R8:
5008     return "r8";
5009   case UNW_S390X_R9:
5010     return "r9";
5011   case UNW_S390X_R10:
5012     return "r10";
5013   case UNW_S390X_R11:
5014     return "r11";
5015   case UNW_S390X_R12:
5016     return "r12";
5017   case UNW_S390X_R13:
5018     return "r13";
5019   case UNW_S390X_R14:
5020     return "r14";
5021   case UNW_S390X_R15:
5022     return "r15";
5023   case UNW_S390X_F0:
5024     return "f0";
5025   case UNW_S390X_F1:
5026     return "f1";
5027   case UNW_S390X_F2:
5028     return "f2";
5029   case UNW_S390X_F3:
5030     return "f3";
5031   case UNW_S390X_F4:
5032     return "f4";
5033   case UNW_S390X_F5:
5034     return "f5";
5035   case UNW_S390X_F6:
5036     return "f6";
5037   case UNW_S390X_F7:
5038     return "f7";
5039   case UNW_S390X_F8:
5040     return "f8";
5041   case UNW_S390X_F9:
5042     return "f9";
5043   case UNW_S390X_F10:
5044     return "f10";
5045   case UNW_S390X_F11:
5046     return "f11";
5047   case UNW_S390X_F12:
5048     return "f12";
5049   case UNW_S390X_F13:
5050     return "f13";
5051   case UNW_S390X_F14:
5052     return "f14";
5053   case UNW_S390X_F15:
5054     return "f15";
5055   }
5056   return "unknown register";
5057 }
5058 #endif // _LIBUNWIND_TARGET_S390X
5059 
5060 #if defined(_LIBUNWIND_TARGET_LOONGARCH)
5061 /// Registers_loongarch holds the register state of a thread in a 64-bit
5062 /// LoongArch process.
5063 class _LIBUNWIND_HIDDEN Registers_loongarch {
5064 public:
5065   Registers_loongarch();
5066   Registers_loongarch(const void *registers);
5067 
5068   bool validRegister(int num) const;
5069   uint64_t getRegister(int num) const;
5070   void setRegister(int num, uint64_t value);
5071   bool validFloatRegister(int num) const;
5072   double getFloatRegister(int num) const;
5073   void setFloatRegister(int num, double value);
5074   bool validVectorRegister(int num) const;
5075   v128 getVectorRegister(int num) const;
5076   void setVectorRegister(int num, v128 value);
5077   static const char *getRegisterName(int num);
5078   void jumpto();
lastDwarfRegNum()5079   static constexpr int lastDwarfRegNum() {
5080     return _LIBUNWIND_HIGHEST_DWARF_REGISTER_LOONGARCH;
5081   }
getArch()5082   static int getArch() { return REGISTERS_LOONGARCH; }
5083 
getSP() const5084   uint64_t getSP() const { return _registers.__r[3]; }
setSP(uint64_t value)5085   void setSP(uint64_t value) { _registers.__r[3] = value; }
getIP() const5086   uint64_t getIP() const { return _registers.__pc; }
setIP(uint64_t value)5087   void setIP(uint64_t value) { _registers.__pc = value; }
5088 
5089 private:
5090   struct loongarch_thread_state_t {
5091     uint64_t __r[32];
5092     uint64_t __pc;
5093   };
5094 
5095   loongarch_thread_state_t _registers;
5096 #if __loongarch_frlen == 64
5097   double _floats[32];
5098 #endif
5099 };
5100 
Registers_loongarch(const void * registers)5101 inline Registers_loongarch::Registers_loongarch(const void *registers) {
5102   static_assert((check_fit<Registers_loongarch, unw_context_t>::does_fit),
5103                 "loongarch registers do not fit into unw_context_t");
5104   memcpy(&_registers, registers, sizeof(_registers));
5105   static_assert(sizeof(_registers) == 0x108,
5106                 "expected float registers to be at offset 264");
5107 #if __loongarch_frlen == 64
5108   memcpy(_floats, static_cast<const uint8_t *>(registers) + sizeof(_registers),
5109          sizeof(_floats));
5110 #endif
5111 }
5112 
Registers_loongarch()5113 inline Registers_loongarch::Registers_loongarch() {
5114   memset(&_registers, 0, sizeof(_registers));
5115 #if __loongarch_frlen == 64
5116   memset(&_floats, 0, sizeof(_floats));
5117 #endif
5118 }
5119 
validRegister(int regNum) const5120 inline bool Registers_loongarch::validRegister(int regNum) const {
5121   if (regNum == UNW_REG_IP || regNum == UNW_REG_SP)
5122     return true;
5123   if (regNum < 0 || regNum > UNW_LOONGARCH_F31)
5124     return false;
5125   return true;
5126 }
5127 
getRegister(int regNum) const5128 inline uint64_t Registers_loongarch::getRegister(int regNum) const {
5129   if (regNum >= UNW_LOONGARCH_R0 && regNum <= UNW_LOONGARCH_R31)
5130     return _registers.__r[regNum - UNW_LOONGARCH_R0];
5131 
5132   if (regNum == UNW_REG_IP)
5133     return _registers.__pc;
5134   if (regNum == UNW_REG_SP)
5135     return _registers.__r[3];
5136   _LIBUNWIND_ABORT("unsupported loongarch register");
5137 }
5138 
setRegister(int regNum,uint64_t value)5139 inline void Registers_loongarch::setRegister(int regNum, uint64_t value) {
5140   if (regNum >= UNW_LOONGARCH_R0 && regNum <= UNW_LOONGARCH_R31)
5141     _registers.__r[regNum - UNW_LOONGARCH_R0] = value;
5142   else if (regNum == UNW_REG_IP)
5143     _registers.__pc = value;
5144   else if (regNum == UNW_REG_SP)
5145     _registers.__r[3] = value;
5146   else
5147     _LIBUNWIND_ABORT("unsupported loongarch register");
5148 }
5149 
getRegisterName(int regNum)5150 inline const char *Registers_loongarch::getRegisterName(int regNum) {
5151   switch (regNum) {
5152   case UNW_REG_IP:
5153     return "$pc";
5154   case UNW_REG_SP:
5155     return "$sp";
5156   case UNW_LOONGARCH_R0:
5157     return "$r0";
5158   case UNW_LOONGARCH_R1:
5159     return "$r1";
5160   case UNW_LOONGARCH_R2:
5161     return "$r2";
5162   case UNW_LOONGARCH_R3:
5163     return "$r3";
5164   case UNW_LOONGARCH_R4:
5165     return "$r4";
5166   case UNW_LOONGARCH_R5:
5167     return "$r5";
5168   case UNW_LOONGARCH_R6:
5169     return "$r6";
5170   case UNW_LOONGARCH_R7:
5171     return "$r7";
5172   case UNW_LOONGARCH_R8:
5173     return "$r8";
5174   case UNW_LOONGARCH_R9:
5175     return "$r9";
5176   case UNW_LOONGARCH_R10:
5177     return "$r10";
5178   case UNW_LOONGARCH_R11:
5179     return "$r11";
5180   case UNW_LOONGARCH_R12:
5181     return "$r12";
5182   case UNW_LOONGARCH_R13:
5183     return "$r13";
5184   case UNW_LOONGARCH_R14:
5185     return "$r14";
5186   case UNW_LOONGARCH_R15:
5187     return "$r15";
5188   case UNW_LOONGARCH_R16:
5189     return "$r16";
5190   case UNW_LOONGARCH_R17:
5191     return "$r17";
5192   case UNW_LOONGARCH_R18:
5193     return "$r18";
5194   case UNW_LOONGARCH_R19:
5195     return "$r19";
5196   case UNW_LOONGARCH_R20:
5197     return "$r20";
5198   case UNW_LOONGARCH_R21:
5199     return "$r21";
5200   case UNW_LOONGARCH_R22:
5201     return "$r22";
5202   case UNW_LOONGARCH_R23:
5203     return "$r23";
5204   case UNW_LOONGARCH_R24:
5205     return "$r24";
5206   case UNW_LOONGARCH_R25:
5207     return "$r25";
5208   case UNW_LOONGARCH_R26:
5209     return "$r26";
5210   case UNW_LOONGARCH_R27:
5211     return "$r27";
5212   case UNW_LOONGARCH_R28:
5213     return "$r28";
5214   case UNW_LOONGARCH_R29:
5215     return "$r29";
5216   case UNW_LOONGARCH_R30:
5217     return "$r30";
5218   case UNW_LOONGARCH_R31:
5219     return "$r31";
5220   case UNW_LOONGARCH_F0:
5221     return "$f0";
5222   case UNW_LOONGARCH_F1:
5223     return "$f1";
5224   case UNW_LOONGARCH_F2:
5225     return "$f2";
5226   case UNW_LOONGARCH_F3:
5227     return "$f3";
5228   case UNW_LOONGARCH_F4:
5229     return "$f4";
5230   case UNW_LOONGARCH_F5:
5231     return "$f5";
5232   case UNW_LOONGARCH_F6:
5233     return "$f6";
5234   case UNW_LOONGARCH_F7:
5235     return "$f7";
5236   case UNW_LOONGARCH_F8:
5237     return "$f8";
5238   case UNW_LOONGARCH_F9:
5239     return "$f9";
5240   case UNW_LOONGARCH_F10:
5241     return "$f10";
5242   case UNW_LOONGARCH_F11:
5243     return "$f11";
5244   case UNW_LOONGARCH_F12:
5245     return "$f12";
5246   case UNW_LOONGARCH_F13:
5247     return "$f13";
5248   case UNW_LOONGARCH_F14:
5249     return "$f14";
5250   case UNW_LOONGARCH_F15:
5251     return "$f15";
5252   case UNW_LOONGARCH_F16:
5253     return "$f16";
5254   case UNW_LOONGARCH_F17:
5255     return "$f17";
5256   case UNW_LOONGARCH_F18:
5257     return "$f18";
5258   case UNW_LOONGARCH_F19:
5259     return "$f19";
5260   case UNW_LOONGARCH_F20:
5261     return "$f20";
5262   case UNW_LOONGARCH_F21:
5263     return "$f21";
5264   case UNW_LOONGARCH_F22:
5265     return "$f22";
5266   case UNW_LOONGARCH_F23:
5267     return "$f23";
5268   case UNW_LOONGARCH_F24:
5269     return "$f24";
5270   case UNW_LOONGARCH_F25:
5271     return "$f25";
5272   case UNW_LOONGARCH_F26:
5273     return "$f26";
5274   case UNW_LOONGARCH_F27:
5275     return "$f27";
5276   case UNW_LOONGARCH_F28:
5277     return "$f28";
5278   case UNW_LOONGARCH_F29:
5279     return "$f29";
5280   case UNW_LOONGARCH_F30:
5281     return "$f30";
5282   case UNW_LOONGARCH_F31:
5283     return "$f31";
5284   default:
5285     return "unknown register";
5286   }
5287 }
5288 
validFloatRegister(int regNum) const5289 inline bool Registers_loongarch::validFloatRegister(int regNum) const {
5290   if (regNum < UNW_LOONGARCH_F0 || regNum > UNW_LOONGARCH_F31)
5291     return false;
5292   return true;
5293 }
5294 
getFloatRegister(int regNum) const5295 inline double Registers_loongarch::getFloatRegister(int regNum) const {
5296 #if __loongarch_frlen == 64
5297   assert(validFloatRegister(regNum));
5298   return _floats[regNum - UNW_LOONGARCH_F0];
5299 #else
5300   _LIBUNWIND_ABORT("libunwind not built with float support");
5301 #endif
5302 }
5303 
setFloatRegister(int regNum,double value)5304 inline void Registers_loongarch::setFloatRegister(int regNum, double value) {
5305 #if __loongarch_frlen == 64
5306   assert(validFloatRegister(regNum));
5307   _floats[regNum - UNW_LOONGARCH_F0] = value;
5308 #else
5309   _LIBUNWIND_ABORT("libunwind not built with float support");
5310 #endif
5311 }
5312 
validVectorRegister(int) const5313 inline bool Registers_loongarch::validVectorRegister(int) const {
5314   return false;
5315 }
5316 
getVectorRegister(int) const5317 inline v128 Registers_loongarch::getVectorRegister(int) const {
5318   _LIBUNWIND_ABORT("loongarch vector support not implemented");
5319 }
5320 
setVectorRegister(int,v128)5321 inline void Registers_loongarch::setVectorRegister(int, v128) {
5322   _LIBUNWIND_ABORT("loongarch vector support not implemented");
5323 }
5324 #endif //_LIBUNWIND_TARGET_LOONGARCH
5325 
5326 } // namespace libunwind
5327 
5328 #endif // __REGISTERS_HPP__
5329