• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===----------------------------- Registers.hpp --------------------------===//
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 "libunwind.h"
19 #include "config.h"
20 
21 namespace libunwind {
22 
23 // For emulating 128-bit registers
24 struct v128 { uint32_t vec[4]; };
25 
26 enum {
27   REGISTERS_X86,
28   REGISTERS_X86_64,
29   REGISTERS_PPC,
30   REGISTERS_PPC64,
31   REGISTERS_ARM64,
32   REGISTERS_ARM,
33   REGISTERS_OR1K,
34   REGISTERS_MIPS_O32,
35   REGISTERS_MIPS_NEWABI,
36   REGISTERS_SPARC,
37   REGISTERS_HEXAGON,
38   REGISTERS_RISCV,
39 };
40 
41 #if defined(_LIBUNWIND_TARGET_I386)
42 class _LIBUNWIND_HIDDEN Registers_x86;
43 extern "C" void __libunwind_Registers_x86_jumpto(Registers_x86 *);
44 /// Registers_x86 holds the register state of a thread in a 32-bit intel
45 /// process.
46 class _LIBUNWIND_HIDDEN Registers_x86 {
47 public:
48   Registers_x86();
49   Registers_x86(const void *registers);
50 
51   bool        validRegister(int num) const;
52   uint32_t    getRegister(int num) const;
53   void        setRegister(int num, uint32_t value);
validFloatRegister(int) const54   bool        validFloatRegister(int) const { return false; }
55   double      getFloatRegister(int num) const;
56   void        setFloatRegister(int num, double value);
validVectorRegister(int) const57   bool        validVectorRegister(int) const { return false; }
58   v128        getVectorRegister(int num) const;
59   void        setVectorRegister(int num, v128 value);
60   static const char *getRegisterName(int num);
jumpto()61   void        jumpto() { __libunwind_Registers_x86_jumpto(this); }
lastDwarfRegNum()62   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86; }
getArch()63   static int  getArch() { return REGISTERS_X86; }
64 
getSP() const65   uint32_t  getSP() const          { return _registers.__esp; }
setSP(uint32_t value)66   void      setSP(uint32_t value)  { _registers.__esp = value; }
getIP() const67   uint32_t  getIP() const          { return _registers.__eip; }
setIP(uint32_t value)68   void      setIP(uint32_t value)  { _registers.__eip = value; }
getEBP() const69   uint32_t  getEBP() const         { return _registers.__ebp; }
setEBP(uint32_t value)70   void      setEBP(uint32_t value) { _registers.__ebp = value; }
getEBX() const71   uint32_t  getEBX() const         { return _registers.__ebx; }
setEBX(uint32_t value)72   void      setEBX(uint32_t value) { _registers.__ebx = value; }
getECX() const73   uint32_t  getECX() const         { return _registers.__ecx; }
setECX(uint32_t value)74   void      setECX(uint32_t value) { _registers.__ecx = value; }
getEDX() const75   uint32_t  getEDX() const         { return _registers.__edx; }
setEDX(uint32_t value)76   void      setEDX(uint32_t value) { _registers.__edx = value; }
getESI() const77   uint32_t  getESI() const         { return _registers.__esi; }
setESI(uint32_t value)78   void      setESI(uint32_t value) { _registers.__esi = value; }
getEDI() const79   uint32_t  getEDI() const         { return _registers.__edi; }
setEDI(uint32_t value)80   void      setEDI(uint32_t value) { _registers.__edi = value; }
81 
82 private:
83   struct GPRs {
84     unsigned int __eax;
85     unsigned int __ebx;
86     unsigned int __ecx;
87     unsigned int __edx;
88     unsigned int __edi;
89     unsigned int __esi;
90     unsigned int __ebp;
91     unsigned int __esp;
92     unsigned int __ss;
93     unsigned int __eflags;
94     unsigned int __eip;
95     unsigned int __cs;
96     unsigned int __ds;
97     unsigned int __es;
98     unsigned int __fs;
99     unsigned int __gs;
100   };
101 
102   GPRs _registers;
103 };
104 
Registers_x86(const void * registers)105 inline Registers_x86::Registers_x86(const void *registers) {
106   static_assert((check_fit<Registers_x86, unw_context_t>::does_fit),
107                 "x86 registers do not fit into unw_context_t");
108   memcpy(&_registers, registers, sizeof(_registers));
109 }
110 
Registers_x86()111 inline Registers_x86::Registers_x86() {
112   memset(&_registers, 0, sizeof(_registers));
113 }
114 
validRegister(int regNum) const115 inline bool Registers_x86::validRegister(int regNum) const {
116   if (regNum == UNW_REG_IP)
117     return true;
118   if (regNum == UNW_REG_SP)
119     return true;
120   if (regNum < 0)
121     return false;
122   if (regNum > 7)
123     return false;
124   return true;
125 }
126 
getRegister(int regNum) const127 inline uint32_t Registers_x86::getRegister(int regNum) const {
128   switch (regNum) {
129   case UNW_REG_IP:
130     return _registers.__eip;
131   case UNW_REG_SP:
132     return _registers.__esp;
133   case UNW_X86_EAX:
134     return _registers.__eax;
135   case UNW_X86_ECX:
136     return _registers.__ecx;
137   case UNW_X86_EDX:
138     return _registers.__edx;
139   case UNW_X86_EBX:
140     return _registers.__ebx;
141 #if !defined(__APPLE__)
142   case UNW_X86_ESP:
143 #else
144   case UNW_X86_EBP:
145 #endif
146     return _registers.__ebp;
147 #if !defined(__APPLE__)
148   case UNW_X86_EBP:
149 #else
150   case UNW_X86_ESP:
151 #endif
152     return _registers.__esp;
153   case UNW_X86_ESI:
154     return _registers.__esi;
155   case UNW_X86_EDI:
156     return _registers.__edi;
157   }
158   _LIBUNWIND_ABORT("unsupported x86 register");
159 }
160 
setRegister(int regNum,uint32_t value)161 inline void Registers_x86::setRegister(int regNum, uint32_t value) {
162   switch (regNum) {
163   case UNW_REG_IP:
164     _registers.__eip = value;
165     return;
166   case UNW_REG_SP:
167     _registers.__esp = value;
168     return;
169   case UNW_X86_EAX:
170     _registers.__eax = value;
171     return;
172   case UNW_X86_ECX:
173     _registers.__ecx = value;
174     return;
175   case UNW_X86_EDX:
176     _registers.__edx = value;
177     return;
178   case UNW_X86_EBX:
179     _registers.__ebx = value;
180     return;
181 #if !defined(__APPLE__)
182   case UNW_X86_ESP:
183 #else
184   case UNW_X86_EBP:
185 #endif
186     _registers.__ebp = value;
187     return;
188 #if !defined(__APPLE__)
189   case UNW_X86_EBP:
190 #else
191   case UNW_X86_ESP:
192 #endif
193     _registers.__esp = value;
194     return;
195   case UNW_X86_ESI:
196     _registers.__esi = value;
197     return;
198   case UNW_X86_EDI:
199     _registers.__edi = value;
200     return;
201   }
202   _LIBUNWIND_ABORT("unsupported x86 register");
203 }
204 
getRegisterName(int regNum)205 inline const char *Registers_x86::getRegisterName(int regNum) {
206   switch (regNum) {
207   case UNW_REG_IP:
208     return "ip";
209   case UNW_REG_SP:
210     return "esp";
211   case UNW_X86_EAX:
212     return "eax";
213   case UNW_X86_ECX:
214     return "ecx";
215   case UNW_X86_EDX:
216     return "edx";
217   case UNW_X86_EBX:
218     return "ebx";
219   case UNW_X86_EBP:
220     return "ebp";
221   case UNW_X86_ESP:
222     return "esp";
223   case UNW_X86_ESI:
224     return "esi";
225   case UNW_X86_EDI:
226     return "edi";
227   default:
228     return "unknown register";
229   }
230 }
231 
getFloatRegister(int) const232 inline double Registers_x86::getFloatRegister(int) const {
233   _LIBUNWIND_ABORT("no x86 float registers");
234 }
235 
setFloatRegister(int,double)236 inline void Registers_x86::setFloatRegister(int, double) {
237   _LIBUNWIND_ABORT("no x86 float registers");
238 }
239 
getVectorRegister(int) const240 inline v128 Registers_x86::getVectorRegister(int) const {
241   _LIBUNWIND_ABORT("no x86 vector registers");
242 }
243 
setVectorRegister(int,v128)244 inline void Registers_x86::setVectorRegister(int, v128) {
245   _LIBUNWIND_ABORT("no x86 vector registers");
246 }
247 #endif // _LIBUNWIND_TARGET_I386
248 
249 
250 #if defined(_LIBUNWIND_TARGET_X86_64)
251 /// Registers_x86_64  holds the register state of a thread in a 64-bit intel
252 /// process.
253 class _LIBUNWIND_HIDDEN Registers_x86_64;
254 extern "C" void __libunwind_Registers_x86_64_jumpto(Registers_x86_64 *);
255 class _LIBUNWIND_HIDDEN Registers_x86_64 {
256 public:
257   Registers_x86_64();
258   Registers_x86_64(const void *registers);
259 
260   bool        validRegister(int num) const;
261   uint64_t    getRegister(int num) const;
262   void        setRegister(int num, uint64_t value);
validFloatRegister(int) const263   bool        validFloatRegister(int) const { return false; }
264   double      getFloatRegister(int num) const;
265   void        setFloatRegister(int num, double value);
266   bool        validVectorRegister(int) const;
267   v128        getVectorRegister(int num) const;
268   void        setVectorRegister(int num, v128 value);
269   static const char *getRegisterName(int num);
jumpto()270   void        jumpto() { __libunwind_Registers_x86_64_jumpto(this); }
lastDwarfRegNum()271   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64; }
getArch()272   static int  getArch() { return REGISTERS_X86_64; }
273 
getSP() const274   uint64_t  getSP() const          { return _registers.__rsp; }
setSP(uint64_t value)275   void      setSP(uint64_t value)  { _registers.__rsp = value; }
getIP() const276   uint64_t  getIP() const          { return _registers.__rip; }
setIP(uint64_t value)277   void      setIP(uint64_t value)  { _registers.__rip = value; }
getRBP() const278   uint64_t  getRBP() const         { return _registers.__rbp; }
setRBP(uint64_t value)279   void      setRBP(uint64_t value) { _registers.__rbp = value; }
getRBX() const280   uint64_t  getRBX() const         { return _registers.__rbx; }
setRBX(uint64_t value)281   void      setRBX(uint64_t value) { _registers.__rbx = value; }
getR12() const282   uint64_t  getR12() const         { return _registers.__r12; }
setR12(uint64_t value)283   void      setR12(uint64_t value) { _registers.__r12 = value; }
getR13() const284   uint64_t  getR13() const         { return _registers.__r13; }
setR13(uint64_t value)285   void      setR13(uint64_t value) { _registers.__r13 = value; }
getR14() const286   uint64_t  getR14() const         { return _registers.__r14; }
setR14(uint64_t value)287   void      setR14(uint64_t value) { _registers.__r14 = value; }
getR15() const288   uint64_t  getR15() const         { return _registers.__r15; }
setR15(uint64_t value)289   void      setR15(uint64_t value) { _registers.__r15 = value; }
290 
291 private:
292   struct GPRs {
293     uint64_t __rax;
294     uint64_t __rbx;
295     uint64_t __rcx;
296     uint64_t __rdx;
297     uint64_t __rdi;
298     uint64_t __rsi;
299     uint64_t __rbp;
300     uint64_t __rsp;
301     uint64_t __r8;
302     uint64_t __r9;
303     uint64_t __r10;
304     uint64_t __r11;
305     uint64_t __r12;
306     uint64_t __r13;
307     uint64_t __r14;
308     uint64_t __r15;
309     uint64_t __rip;
310     uint64_t __rflags;
311     uint64_t __cs;
312     uint64_t __fs;
313     uint64_t __gs;
314 #if defined(_WIN64)
315     uint64_t __padding; // 16-byte align
316 #endif
317   };
318   GPRs _registers;
319 #if defined(_WIN64)
320   v128 _xmm[16];
321 #endif
322 };
323 
Registers_x86_64(const void * registers)324 inline Registers_x86_64::Registers_x86_64(const void *registers) {
325   static_assert((check_fit<Registers_x86_64, unw_context_t>::does_fit),
326                 "x86_64 registers do not fit into unw_context_t");
327   memcpy(&_registers, registers, sizeof(_registers));
328 }
329 
Registers_x86_64()330 inline Registers_x86_64::Registers_x86_64() {
331   memset(&_registers, 0, sizeof(_registers));
332 }
333 
validRegister(int regNum) const334 inline bool Registers_x86_64::validRegister(int regNum) const {
335   if (regNum == UNW_REG_IP)
336     return true;
337   if (regNum == UNW_REG_SP)
338     return true;
339   if (regNum < 0)
340     return false;
341   if (regNum > 15)
342     return false;
343   return true;
344 }
345 
getRegister(int regNum) const346 inline uint64_t Registers_x86_64::getRegister(int regNum) const {
347   switch (regNum) {
348   case UNW_REG_IP:
349     return _registers.__rip;
350   case UNW_REG_SP:
351     return _registers.__rsp;
352   case UNW_X86_64_RAX:
353     return _registers.__rax;
354   case UNW_X86_64_RDX:
355     return _registers.__rdx;
356   case UNW_X86_64_RCX:
357     return _registers.__rcx;
358   case UNW_X86_64_RBX:
359     return _registers.__rbx;
360   case UNW_X86_64_RSI:
361     return _registers.__rsi;
362   case UNW_X86_64_RDI:
363     return _registers.__rdi;
364   case UNW_X86_64_RBP:
365     return _registers.__rbp;
366   case UNW_X86_64_RSP:
367     return _registers.__rsp;
368   case UNW_X86_64_R8:
369     return _registers.__r8;
370   case UNW_X86_64_R9:
371     return _registers.__r9;
372   case UNW_X86_64_R10:
373     return _registers.__r10;
374   case UNW_X86_64_R11:
375     return _registers.__r11;
376   case UNW_X86_64_R12:
377     return _registers.__r12;
378   case UNW_X86_64_R13:
379     return _registers.__r13;
380   case UNW_X86_64_R14:
381     return _registers.__r14;
382   case UNW_X86_64_R15:
383     return _registers.__r15;
384   }
385   _LIBUNWIND_ABORT("unsupported x86_64 register");
386 }
387 
setRegister(int regNum,uint64_t value)388 inline void Registers_x86_64::setRegister(int regNum, uint64_t value) {
389   switch (regNum) {
390   case UNW_REG_IP:
391     _registers.__rip = value;
392     return;
393   case UNW_REG_SP:
394     _registers.__rsp = value;
395     return;
396   case UNW_X86_64_RAX:
397     _registers.__rax = value;
398     return;
399   case UNW_X86_64_RDX:
400     _registers.__rdx = value;
401     return;
402   case UNW_X86_64_RCX:
403     _registers.__rcx = value;
404     return;
405   case UNW_X86_64_RBX:
406     _registers.__rbx = value;
407     return;
408   case UNW_X86_64_RSI:
409     _registers.__rsi = value;
410     return;
411   case UNW_X86_64_RDI:
412     _registers.__rdi = value;
413     return;
414   case UNW_X86_64_RBP:
415     _registers.__rbp = value;
416     return;
417   case UNW_X86_64_RSP:
418     _registers.__rsp = value;
419     return;
420   case UNW_X86_64_R8:
421     _registers.__r8 = value;
422     return;
423   case UNW_X86_64_R9:
424     _registers.__r9 = value;
425     return;
426   case UNW_X86_64_R10:
427     _registers.__r10 = value;
428     return;
429   case UNW_X86_64_R11:
430     _registers.__r11 = value;
431     return;
432   case UNW_X86_64_R12:
433     _registers.__r12 = value;
434     return;
435   case UNW_X86_64_R13:
436     _registers.__r13 = value;
437     return;
438   case UNW_X86_64_R14:
439     _registers.__r14 = value;
440     return;
441   case UNW_X86_64_R15:
442     _registers.__r15 = value;
443     return;
444   }
445   _LIBUNWIND_ABORT("unsupported x86_64 register");
446 }
447 
getRegisterName(int regNum)448 inline const char *Registers_x86_64::getRegisterName(int regNum) {
449   switch (regNum) {
450   case UNW_REG_IP:
451     return "rip";
452   case UNW_REG_SP:
453     return "rsp";
454   case UNW_X86_64_RAX:
455     return "rax";
456   case UNW_X86_64_RDX:
457     return "rdx";
458   case UNW_X86_64_RCX:
459     return "rcx";
460   case UNW_X86_64_RBX:
461     return "rbx";
462   case UNW_X86_64_RSI:
463     return "rsi";
464   case UNW_X86_64_RDI:
465     return "rdi";
466   case UNW_X86_64_RBP:
467     return "rbp";
468   case UNW_X86_64_RSP:
469     return "rsp";
470   case UNW_X86_64_R8:
471     return "r8";
472   case UNW_X86_64_R9:
473     return "r9";
474   case UNW_X86_64_R10:
475     return "r10";
476   case UNW_X86_64_R11:
477     return "r11";
478   case UNW_X86_64_R12:
479     return "r12";
480   case UNW_X86_64_R13:
481     return "r13";
482   case UNW_X86_64_R14:
483     return "r14";
484   case UNW_X86_64_R15:
485     return "r15";
486   case UNW_X86_64_XMM0:
487     return "xmm0";
488   case UNW_X86_64_XMM1:
489     return "xmm1";
490   case UNW_X86_64_XMM2:
491     return "xmm2";
492   case UNW_X86_64_XMM3:
493     return "xmm3";
494   case UNW_X86_64_XMM4:
495     return "xmm4";
496   case UNW_X86_64_XMM5:
497     return "xmm5";
498   case UNW_X86_64_XMM6:
499     return "xmm6";
500   case UNW_X86_64_XMM7:
501     return "xmm7";
502   case UNW_X86_64_XMM8:
503     return "xmm8";
504   case UNW_X86_64_XMM9:
505     return "xmm9";
506   case UNW_X86_64_XMM10:
507     return "xmm10";
508   case UNW_X86_64_XMM11:
509     return "xmm11";
510   case UNW_X86_64_XMM12:
511     return "xmm12";
512   case UNW_X86_64_XMM13:
513     return "xmm13";
514   case UNW_X86_64_XMM14:
515     return "xmm14";
516   case UNW_X86_64_XMM15:
517     return "xmm15";
518   default:
519     return "unknown register";
520   }
521 }
522 
getFloatRegister(int) const523 inline double Registers_x86_64::getFloatRegister(int) const {
524   _LIBUNWIND_ABORT("no x86_64 float registers");
525 }
526 
setFloatRegister(int,double)527 inline void Registers_x86_64::setFloatRegister(int, double) {
528   _LIBUNWIND_ABORT("no x86_64 float registers");
529 }
530 
validVectorRegister(int regNum) const531 inline bool Registers_x86_64::validVectorRegister(int regNum) const {
532 #if defined(_WIN64)
533   if (regNum < UNW_X86_64_XMM0)
534     return false;
535   if (regNum > UNW_X86_64_XMM15)
536     return false;
537   return true;
538 #else
539   (void)regNum; // suppress unused parameter warning
540   return false;
541 #endif
542 }
543 
getVectorRegister(int regNum) const544 inline v128 Registers_x86_64::getVectorRegister(int regNum) const {
545 #if defined(_WIN64)
546   assert(validVectorRegister(regNum));
547   return _xmm[regNum - UNW_X86_64_XMM0];
548 #else
549   (void)regNum; // suppress unused parameter warning
550   _LIBUNWIND_ABORT("no x86_64 vector registers");
551 #endif
552 }
553 
setVectorRegister(int regNum,v128 value)554 inline void Registers_x86_64::setVectorRegister(int regNum, v128 value) {
555 #if defined(_WIN64)
556   assert(validVectorRegister(regNum));
557   _xmm[regNum - UNW_X86_64_XMM0] = value;
558 #else
559   (void)regNum; (void)value; // suppress unused parameter warnings
560   _LIBUNWIND_ABORT("no x86_64 vector registers");
561 #endif
562 }
563 #endif // _LIBUNWIND_TARGET_X86_64
564 
565 
566 #if defined(_LIBUNWIND_TARGET_PPC)
567 /// Registers_ppc holds the register state of a thread in a 32-bit PowerPC
568 /// process.
569 class _LIBUNWIND_HIDDEN Registers_ppc {
570 public:
571   Registers_ppc();
572   Registers_ppc(const void *registers);
573 
574   bool        validRegister(int num) const;
575   uint32_t    getRegister(int num) const;
576   void        setRegister(int num, uint32_t value);
577   bool        validFloatRegister(int num) const;
578   double      getFloatRegister(int num) const;
579   void        setFloatRegister(int num, double value);
580   bool        validVectorRegister(int num) const;
581   v128        getVectorRegister(int num) const;
582   void        setVectorRegister(int num, v128 value);
583   static const char *getRegisterName(int num);
584   void        jumpto();
lastDwarfRegNum()585   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC; }
getArch()586   static int  getArch() { return REGISTERS_PPC; }
587 
getSP() const588   uint64_t  getSP() const         { return _registers.__r1; }
setSP(uint32_t value)589   void      setSP(uint32_t value) { _registers.__r1 = value; }
getIP() const590   uint64_t  getIP() const         { return _registers.__srr0; }
setIP(uint32_t value)591   void      setIP(uint32_t value) { _registers.__srr0 = value; }
592 
593 private:
594   struct ppc_thread_state_t {
595     unsigned int __srr0; /* Instruction address register (PC) */
596     unsigned int __srr1; /* Machine state register (supervisor) */
597     unsigned int __r0;
598     unsigned int __r1;
599     unsigned int __r2;
600     unsigned int __r3;
601     unsigned int __r4;
602     unsigned int __r5;
603     unsigned int __r6;
604     unsigned int __r7;
605     unsigned int __r8;
606     unsigned int __r9;
607     unsigned int __r10;
608     unsigned int __r11;
609     unsigned int __r12;
610     unsigned int __r13;
611     unsigned int __r14;
612     unsigned int __r15;
613     unsigned int __r16;
614     unsigned int __r17;
615     unsigned int __r18;
616     unsigned int __r19;
617     unsigned int __r20;
618     unsigned int __r21;
619     unsigned int __r22;
620     unsigned int __r23;
621     unsigned int __r24;
622     unsigned int __r25;
623     unsigned int __r26;
624     unsigned int __r27;
625     unsigned int __r28;
626     unsigned int __r29;
627     unsigned int __r30;
628     unsigned int __r31;
629     unsigned int __cr;     /* Condition register */
630     unsigned int __xer;    /* User's integer exception register */
631     unsigned int __lr;     /* Link register */
632     unsigned int __ctr;    /* Count register */
633     unsigned int __mq;     /* MQ register (601 only) */
634     unsigned int __vrsave; /* Vector Save Register */
635   };
636 
637   struct ppc_float_state_t {
638     double __fpregs[32];
639 
640     unsigned int __fpscr_pad; /* fpscr is 64 bits, 32 bits of rubbish */
641     unsigned int __fpscr;     /* floating point status register */
642   };
643 
644   ppc_thread_state_t _registers;
645   ppc_float_state_t  _floatRegisters;
646   v128               _vectorRegisters[32]; // offset 424
647 };
648 
Registers_ppc(const void * registers)649 inline Registers_ppc::Registers_ppc(const void *registers) {
650   static_assert((check_fit<Registers_ppc, unw_context_t>::does_fit),
651                 "ppc registers do not fit into unw_context_t");
652   memcpy(&_registers, static_cast<const uint8_t *>(registers),
653          sizeof(_registers));
654   static_assert(sizeof(ppc_thread_state_t) == 160,
655                 "expected float register offset to be 160");
656   memcpy(&_floatRegisters,
657          static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t),
658          sizeof(_floatRegisters));
659   static_assert(sizeof(ppc_thread_state_t) + sizeof(ppc_float_state_t) == 424,
660                 "expected vector register offset to be 424 bytes");
661   memcpy(_vectorRegisters,
662          static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t) +
663              sizeof(ppc_float_state_t),
664          sizeof(_vectorRegisters));
665 }
666 
Registers_ppc()667 inline Registers_ppc::Registers_ppc() {
668   memset(&_registers, 0, sizeof(_registers));
669   memset(&_floatRegisters, 0, sizeof(_floatRegisters));
670   memset(&_vectorRegisters, 0, sizeof(_vectorRegisters));
671 }
672 
validRegister(int regNum) const673 inline bool Registers_ppc::validRegister(int regNum) const {
674   if (regNum == UNW_REG_IP)
675     return true;
676   if (regNum == UNW_REG_SP)
677     return true;
678   if (regNum == UNW_PPC_VRSAVE)
679     return true;
680   if (regNum < 0)
681     return false;
682   if (regNum <= UNW_PPC_R31)
683     return true;
684   if (regNum == UNW_PPC_MQ)
685     return true;
686   if (regNum == UNW_PPC_LR)
687     return true;
688   if (regNum == UNW_PPC_CTR)
689     return true;
690   if ((UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7))
691     return true;
692   return false;
693 }
694 
getRegister(int regNum) const695 inline uint32_t Registers_ppc::getRegister(int regNum) const {
696   switch (regNum) {
697   case UNW_REG_IP:
698     return _registers.__srr0;
699   case UNW_REG_SP:
700     return _registers.__r1;
701   case UNW_PPC_R0:
702     return _registers.__r0;
703   case UNW_PPC_R1:
704     return _registers.__r1;
705   case UNW_PPC_R2:
706     return _registers.__r2;
707   case UNW_PPC_R3:
708     return _registers.__r3;
709   case UNW_PPC_R4:
710     return _registers.__r4;
711   case UNW_PPC_R5:
712     return _registers.__r5;
713   case UNW_PPC_R6:
714     return _registers.__r6;
715   case UNW_PPC_R7:
716     return _registers.__r7;
717   case UNW_PPC_R8:
718     return _registers.__r8;
719   case UNW_PPC_R9:
720     return _registers.__r9;
721   case UNW_PPC_R10:
722     return _registers.__r10;
723   case UNW_PPC_R11:
724     return _registers.__r11;
725   case UNW_PPC_R12:
726     return _registers.__r12;
727   case UNW_PPC_R13:
728     return _registers.__r13;
729   case UNW_PPC_R14:
730     return _registers.__r14;
731   case UNW_PPC_R15:
732     return _registers.__r15;
733   case UNW_PPC_R16:
734     return _registers.__r16;
735   case UNW_PPC_R17:
736     return _registers.__r17;
737   case UNW_PPC_R18:
738     return _registers.__r18;
739   case UNW_PPC_R19:
740     return _registers.__r19;
741   case UNW_PPC_R20:
742     return _registers.__r20;
743   case UNW_PPC_R21:
744     return _registers.__r21;
745   case UNW_PPC_R22:
746     return _registers.__r22;
747   case UNW_PPC_R23:
748     return _registers.__r23;
749   case UNW_PPC_R24:
750     return _registers.__r24;
751   case UNW_PPC_R25:
752     return _registers.__r25;
753   case UNW_PPC_R26:
754     return _registers.__r26;
755   case UNW_PPC_R27:
756     return _registers.__r27;
757   case UNW_PPC_R28:
758     return _registers.__r28;
759   case UNW_PPC_R29:
760     return _registers.__r29;
761   case UNW_PPC_R30:
762     return _registers.__r30;
763   case UNW_PPC_R31:
764     return _registers.__r31;
765   case UNW_PPC_LR:
766     return _registers.__lr;
767   case UNW_PPC_CR0:
768     return (_registers.__cr & 0xF0000000);
769   case UNW_PPC_CR1:
770     return (_registers.__cr & 0x0F000000);
771   case UNW_PPC_CR2:
772     return (_registers.__cr & 0x00F00000);
773   case UNW_PPC_CR3:
774     return (_registers.__cr & 0x000F0000);
775   case UNW_PPC_CR4:
776     return (_registers.__cr & 0x0000F000);
777   case UNW_PPC_CR5:
778     return (_registers.__cr & 0x00000F00);
779   case UNW_PPC_CR6:
780     return (_registers.__cr & 0x000000F0);
781   case UNW_PPC_CR7:
782     return (_registers.__cr & 0x0000000F);
783   case UNW_PPC_VRSAVE:
784     return _registers.__vrsave;
785   }
786   _LIBUNWIND_ABORT("unsupported ppc register");
787 }
788 
setRegister(int regNum,uint32_t value)789 inline void Registers_ppc::setRegister(int regNum, uint32_t value) {
790   //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value);
791   switch (regNum) {
792   case UNW_REG_IP:
793     _registers.__srr0 = value;
794     return;
795   case UNW_REG_SP:
796     _registers.__r1 = value;
797     return;
798   case UNW_PPC_R0:
799     _registers.__r0 = value;
800     return;
801   case UNW_PPC_R1:
802     _registers.__r1 = value;
803     return;
804   case UNW_PPC_R2:
805     _registers.__r2 = value;
806     return;
807   case UNW_PPC_R3:
808     _registers.__r3 = value;
809     return;
810   case UNW_PPC_R4:
811     _registers.__r4 = value;
812     return;
813   case UNW_PPC_R5:
814     _registers.__r5 = value;
815     return;
816   case UNW_PPC_R6:
817     _registers.__r6 = value;
818     return;
819   case UNW_PPC_R7:
820     _registers.__r7 = value;
821     return;
822   case UNW_PPC_R8:
823     _registers.__r8 = value;
824     return;
825   case UNW_PPC_R9:
826     _registers.__r9 = value;
827     return;
828   case UNW_PPC_R10:
829     _registers.__r10 = value;
830     return;
831   case UNW_PPC_R11:
832     _registers.__r11 = value;
833     return;
834   case UNW_PPC_R12:
835     _registers.__r12 = value;
836     return;
837   case UNW_PPC_R13:
838     _registers.__r13 = value;
839     return;
840   case UNW_PPC_R14:
841     _registers.__r14 = value;
842     return;
843   case UNW_PPC_R15:
844     _registers.__r15 = value;
845     return;
846   case UNW_PPC_R16:
847     _registers.__r16 = value;
848     return;
849   case UNW_PPC_R17:
850     _registers.__r17 = value;
851     return;
852   case UNW_PPC_R18:
853     _registers.__r18 = value;
854     return;
855   case UNW_PPC_R19:
856     _registers.__r19 = value;
857     return;
858   case UNW_PPC_R20:
859     _registers.__r20 = value;
860     return;
861   case UNW_PPC_R21:
862     _registers.__r21 = value;
863     return;
864   case UNW_PPC_R22:
865     _registers.__r22 = value;
866     return;
867   case UNW_PPC_R23:
868     _registers.__r23 = value;
869     return;
870   case UNW_PPC_R24:
871     _registers.__r24 = value;
872     return;
873   case UNW_PPC_R25:
874     _registers.__r25 = value;
875     return;
876   case UNW_PPC_R26:
877     _registers.__r26 = value;
878     return;
879   case UNW_PPC_R27:
880     _registers.__r27 = value;
881     return;
882   case UNW_PPC_R28:
883     _registers.__r28 = value;
884     return;
885   case UNW_PPC_R29:
886     _registers.__r29 = value;
887     return;
888   case UNW_PPC_R30:
889     _registers.__r30 = value;
890     return;
891   case UNW_PPC_R31:
892     _registers.__r31 = value;
893     return;
894   case UNW_PPC_MQ:
895     _registers.__mq = value;
896     return;
897   case UNW_PPC_LR:
898     _registers.__lr = value;
899     return;
900   case UNW_PPC_CTR:
901     _registers.__ctr = value;
902     return;
903   case UNW_PPC_CR0:
904     _registers.__cr &= 0x0FFFFFFF;
905     _registers.__cr |= (value & 0xF0000000);
906     return;
907   case UNW_PPC_CR1:
908     _registers.__cr &= 0xF0FFFFFF;
909     _registers.__cr |= (value & 0x0F000000);
910     return;
911   case UNW_PPC_CR2:
912     _registers.__cr &= 0xFF0FFFFF;
913     _registers.__cr |= (value & 0x00F00000);
914     return;
915   case UNW_PPC_CR3:
916     _registers.__cr &= 0xFFF0FFFF;
917     _registers.__cr |= (value & 0x000F0000);
918     return;
919   case UNW_PPC_CR4:
920     _registers.__cr &= 0xFFFF0FFF;
921     _registers.__cr |= (value & 0x0000F000);
922     return;
923   case UNW_PPC_CR5:
924     _registers.__cr &= 0xFFFFF0FF;
925     _registers.__cr |= (value & 0x00000F00);
926     return;
927   case UNW_PPC_CR6:
928     _registers.__cr &= 0xFFFFFF0F;
929     _registers.__cr |= (value & 0x000000F0);
930     return;
931   case UNW_PPC_CR7:
932     _registers.__cr &= 0xFFFFFFF0;
933     _registers.__cr |= (value & 0x0000000F);
934     return;
935   case UNW_PPC_VRSAVE:
936     _registers.__vrsave = value;
937     return;
938     // not saved
939     return;
940   case UNW_PPC_XER:
941     _registers.__xer = value;
942     return;
943   case UNW_PPC_AP:
944   case UNW_PPC_VSCR:
945   case UNW_PPC_SPEFSCR:
946     // not saved
947     return;
948   }
949   _LIBUNWIND_ABORT("unsupported ppc register");
950 }
951 
validFloatRegister(int regNum) const952 inline bool Registers_ppc::validFloatRegister(int regNum) const {
953   if (regNum < UNW_PPC_F0)
954     return false;
955   if (regNum > UNW_PPC_F31)
956     return false;
957   return true;
958 }
959 
getFloatRegister(int regNum) const960 inline double Registers_ppc::getFloatRegister(int regNum) const {
961   assert(validFloatRegister(regNum));
962   return _floatRegisters.__fpregs[regNum - UNW_PPC_F0];
963 }
964 
setFloatRegister(int regNum,double value)965 inline void Registers_ppc::setFloatRegister(int regNum, double value) {
966   assert(validFloatRegister(regNum));
967   _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value;
968 }
969 
validVectorRegister(int regNum) const970 inline bool Registers_ppc::validVectorRegister(int regNum) const {
971   if (regNum < UNW_PPC_V0)
972     return false;
973   if (regNum > UNW_PPC_V31)
974     return false;
975   return true;
976 }
977 
getVectorRegister(int regNum) const978 inline v128 Registers_ppc::getVectorRegister(int regNum) const {
979   assert(validVectorRegister(regNum));
980   v128 result = _vectorRegisters[regNum - UNW_PPC_V0];
981   return result;
982 }
983 
setVectorRegister(int regNum,v128 value)984 inline void Registers_ppc::setVectorRegister(int regNum, v128 value) {
985   assert(validVectorRegister(regNum));
986   _vectorRegisters[regNum - UNW_PPC_V0] = value;
987 }
988 
getRegisterName(int regNum)989 inline const char *Registers_ppc::getRegisterName(int regNum) {
990   switch (regNum) {
991   case UNW_REG_IP:
992     return "ip";
993   case UNW_REG_SP:
994     return "sp";
995   case UNW_PPC_R0:
996     return "r0";
997   case UNW_PPC_R1:
998     return "r1";
999   case UNW_PPC_R2:
1000     return "r2";
1001   case UNW_PPC_R3:
1002     return "r3";
1003   case UNW_PPC_R4:
1004     return "r4";
1005   case UNW_PPC_R5:
1006     return "r5";
1007   case UNW_PPC_R6:
1008     return "r6";
1009   case UNW_PPC_R7:
1010     return "r7";
1011   case UNW_PPC_R8:
1012     return "r8";
1013   case UNW_PPC_R9:
1014     return "r9";
1015   case UNW_PPC_R10:
1016     return "r10";
1017   case UNW_PPC_R11:
1018     return "r11";
1019   case UNW_PPC_R12:
1020     return "r12";
1021   case UNW_PPC_R13:
1022     return "r13";
1023   case UNW_PPC_R14:
1024     return "r14";
1025   case UNW_PPC_R15:
1026     return "r15";
1027   case UNW_PPC_R16:
1028     return "r16";
1029   case UNW_PPC_R17:
1030     return "r17";
1031   case UNW_PPC_R18:
1032     return "r18";
1033   case UNW_PPC_R19:
1034     return "r19";
1035   case UNW_PPC_R20:
1036     return "r20";
1037   case UNW_PPC_R21:
1038     return "r21";
1039   case UNW_PPC_R22:
1040     return "r22";
1041   case UNW_PPC_R23:
1042     return "r23";
1043   case UNW_PPC_R24:
1044     return "r24";
1045   case UNW_PPC_R25:
1046     return "r25";
1047   case UNW_PPC_R26:
1048     return "r26";
1049   case UNW_PPC_R27:
1050     return "r27";
1051   case UNW_PPC_R28:
1052     return "r28";
1053   case UNW_PPC_R29:
1054     return "r29";
1055   case UNW_PPC_R30:
1056     return "r30";
1057   case UNW_PPC_R31:
1058     return "r31";
1059   case UNW_PPC_F0:
1060     return "fp0";
1061   case UNW_PPC_F1:
1062     return "fp1";
1063   case UNW_PPC_F2:
1064     return "fp2";
1065   case UNW_PPC_F3:
1066     return "fp3";
1067   case UNW_PPC_F4:
1068     return "fp4";
1069   case UNW_PPC_F5:
1070     return "fp5";
1071   case UNW_PPC_F6:
1072     return "fp6";
1073   case UNW_PPC_F7:
1074     return "fp7";
1075   case UNW_PPC_F8:
1076     return "fp8";
1077   case UNW_PPC_F9:
1078     return "fp9";
1079   case UNW_PPC_F10:
1080     return "fp10";
1081   case UNW_PPC_F11:
1082     return "fp11";
1083   case UNW_PPC_F12:
1084     return "fp12";
1085   case UNW_PPC_F13:
1086     return "fp13";
1087   case UNW_PPC_F14:
1088     return "fp14";
1089   case UNW_PPC_F15:
1090     return "fp15";
1091   case UNW_PPC_F16:
1092     return "fp16";
1093   case UNW_PPC_F17:
1094     return "fp17";
1095   case UNW_PPC_F18:
1096     return "fp18";
1097   case UNW_PPC_F19:
1098     return "fp19";
1099   case UNW_PPC_F20:
1100     return "fp20";
1101   case UNW_PPC_F21:
1102     return "fp21";
1103   case UNW_PPC_F22:
1104     return "fp22";
1105   case UNW_PPC_F23:
1106     return "fp23";
1107   case UNW_PPC_F24:
1108     return "fp24";
1109   case UNW_PPC_F25:
1110     return "fp25";
1111   case UNW_PPC_F26:
1112     return "fp26";
1113   case UNW_PPC_F27:
1114     return "fp27";
1115   case UNW_PPC_F28:
1116     return "fp28";
1117   case UNW_PPC_F29:
1118     return "fp29";
1119   case UNW_PPC_F30:
1120     return "fp30";
1121   case UNW_PPC_F31:
1122     return "fp31";
1123   case UNW_PPC_LR:
1124     return "lr";
1125   default:
1126     return "unknown register";
1127   }
1128 
1129 }
1130 #endif // _LIBUNWIND_TARGET_PPC
1131 
1132 #if defined(_LIBUNWIND_TARGET_PPC64)
1133 /// Registers_ppc64 holds the register state of a thread in a 64-bit PowerPC
1134 /// process.
1135 class _LIBUNWIND_HIDDEN Registers_ppc64 {
1136 public:
1137   Registers_ppc64();
1138   Registers_ppc64(const void *registers);
1139 
1140   bool        validRegister(int num) const;
1141   uint64_t    getRegister(int num) const;
1142   void        setRegister(int num, uint64_t value);
1143   bool        validFloatRegister(int num) const;
1144   double      getFloatRegister(int num) const;
1145   void        setFloatRegister(int num, double value);
1146   bool        validVectorRegister(int num) const;
1147   v128        getVectorRegister(int num) const;
1148   void        setVectorRegister(int num, v128 value);
1149   static const char *getRegisterName(int num);
1150   void        jumpto();
lastDwarfRegNum()1151   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64; }
getArch()1152   static int  getArch() { return REGISTERS_PPC64; }
1153 
getSP() const1154   uint64_t  getSP() const         { return _registers.__r1; }
setSP(uint64_t value)1155   void      setSP(uint64_t value) { _registers.__r1 = value; }
getIP() const1156   uint64_t  getIP() const         { return _registers.__srr0; }
setIP(uint64_t value)1157   void      setIP(uint64_t value) { _registers.__srr0 = value; }
1158 
1159 private:
1160   struct ppc64_thread_state_t {
1161     uint64_t __srr0;    // Instruction address register (PC)
1162     uint64_t __srr1;    // Machine state register (supervisor)
1163     uint64_t __r0;
1164     uint64_t __r1;
1165     uint64_t __r2;
1166     uint64_t __r3;
1167     uint64_t __r4;
1168     uint64_t __r5;
1169     uint64_t __r6;
1170     uint64_t __r7;
1171     uint64_t __r8;
1172     uint64_t __r9;
1173     uint64_t __r10;
1174     uint64_t __r11;
1175     uint64_t __r12;
1176     uint64_t __r13;
1177     uint64_t __r14;
1178     uint64_t __r15;
1179     uint64_t __r16;
1180     uint64_t __r17;
1181     uint64_t __r18;
1182     uint64_t __r19;
1183     uint64_t __r20;
1184     uint64_t __r21;
1185     uint64_t __r22;
1186     uint64_t __r23;
1187     uint64_t __r24;
1188     uint64_t __r25;
1189     uint64_t __r26;
1190     uint64_t __r27;
1191     uint64_t __r28;
1192     uint64_t __r29;
1193     uint64_t __r30;
1194     uint64_t __r31;
1195     uint64_t __cr;      // Condition register
1196     uint64_t __xer;     // User's integer exception register
1197     uint64_t __lr;      // Link register
1198     uint64_t __ctr;     // Count register
1199     uint64_t __vrsave;  // Vector Save Register
1200   };
1201 
1202   union ppc64_vsr_t {
1203     struct asfloat_s {
1204       double f;
1205       uint64_t v2;
1206     } asfloat;
1207     v128 v;
1208   };
1209 
1210   ppc64_thread_state_t _registers;
1211   ppc64_vsr_t          _vectorScalarRegisters[64];
1212 
1213   static int getVectorRegNum(int num);
1214 };
1215 
Registers_ppc64(const void * registers)1216 inline Registers_ppc64::Registers_ppc64(const void *registers) {
1217   static_assert((check_fit<Registers_ppc64, unw_context_t>::does_fit),
1218                 "ppc64 registers do not fit into unw_context_t");
1219   memcpy(&_registers, static_cast<const uint8_t *>(registers),
1220          sizeof(_registers));
1221   static_assert(sizeof(_registers) == 312,
1222                 "expected vector scalar register offset to be 312");
1223   memcpy(&_vectorScalarRegisters,
1224          static_cast<const uint8_t *>(registers) + sizeof(_registers),
1225          sizeof(_vectorScalarRegisters));
1226   static_assert(sizeof(_registers) +
1227                 sizeof(_vectorScalarRegisters) == 1336,
1228                 "expected vector register offset to be 1336 bytes");
1229 }
1230 
Registers_ppc64()1231 inline Registers_ppc64::Registers_ppc64() {
1232   memset(&_registers, 0, sizeof(_registers));
1233   memset(&_vectorScalarRegisters, 0, sizeof(_vectorScalarRegisters));
1234 }
1235 
validRegister(int regNum) const1236 inline bool Registers_ppc64::validRegister(int regNum) const {
1237   switch (regNum) {
1238   case UNW_REG_IP:
1239   case UNW_REG_SP:
1240   case UNW_PPC64_XER:
1241   case UNW_PPC64_LR:
1242   case UNW_PPC64_CTR:
1243   case UNW_PPC64_VRSAVE:
1244       return true;
1245   }
1246 
1247   if (regNum >= UNW_PPC64_R0 && regNum <= UNW_PPC64_R31)
1248     return true;
1249   if (regNum >= UNW_PPC64_CR0 && regNum <= UNW_PPC64_CR7)
1250     return true;
1251 
1252   return false;
1253 }
1254 
getRegister(int regNum) const1255 inline uint64_t Registers_ppc64::getRegister(int regNum) const {
1256   switch (regNum) {
1257   case UNW_REG_IP:
1258     return _registers.__srr0;
1259   case UNW_PPC64_R0:
1260     return _registers.__r0;
1261   case UNW_PPC64_R1:
1262   case UNW_REG_SP:
1263     return _registers.__r1;
1264   case UNW_PPC64_R2:
1265     return _registers.__r2;
1266   case UNW_PPC64_R3:
1267     return _registers.__r3;
1268   case UNW_PPC64_R4:
1269     return _registers.__r4;
1270   case UNW_PPC64_R5:
1271     return _registers.__r5;
1272   case UNW_PPC64_R6:
1273     return _registers.__r6;
1274   case UNW_PPC64_R7:
1275     return _registers.__r7;
1276   case UNW_PPC64_R8:
1277     return _registers.__r8;
1278   case UNW_PPC64_R9:
1279     return _registers.__r9;
1280   case UNW_PPC64_R10:
1281     return _registers.__r10;
1282   case UNW_PPC64_R11:
1283     return _registers.__r11;
1284   case UNW_PPC64_R12:
1285     return _registers.__r12;
1286   case UNW_PPC64_R13:
1287     return _registers.__r13;
1288   case UNW_PPC64_R14:
1289     return _registers.__r14;
1290   case UNW_PPC64_R15:
1291     return _registers.__r15;
1292   case UNW_PPC64_R16:
1293     return _registers.__r16;
1294   case UNW_PPC64_R17:
1295     return _registers.__r17;
1296   case UNW_PPC64_R18:
1297     return _registers.__r18;
1298   case UNW_PPC64_R19:
1299     return _registers.__r19;
1300   case UNW_PPC64_R20:
1301     return _registers.__r20;
1302   case UNW_PPC64_R21:
1303     return _registers.__r21;
1304   case UNW_PPC64_R22:
1305     return _registers.__r22;
1306   case UNW_PPC64_R23:
1307     return _registers.__r23;
1308   case UNW_PPC64_R24:
1309     return _registers.__r24;
1310   case UNW_PPC64_R25:
1311     return _registers.__r25;
1312   case UNW_PPC64_R26:
1313     return _registers.__r26;
1314   case UNW_PPC64_R27:
1315     return _registers.__r27;
1316   case UNW_PPC64_R28:
1317     return _registers.__r28;
1318   case UNW_PPC64_R29:
1319     return _registers.__r29;
1320   case UNW_PPC64_R30:
1321     return _registers.__r30;
1322   case UNW_PPC64_R31:
1323     return _registers.__r31;
1324   case UNW_PPC64_CR0:
1325     return (_registers.__cr & 0xF0000000);
1326   case UNW_PPC64_CR1:
1327     return (_registers.__cr & 0x0F000000);
1328   case UNW_PPC64_CR2:
1329     return (_registers.__cr & 0x00F00000);
1330   case UNW_PPC64_CR3:
1331     return (_registers.__cr & 0x000F0000);
1332   case UNW_PPC64_CR4:
1333     return (_registers.__cr & 0x0000F000);
1334   case UNW_PPC64_CR5:
1335     return (_registers.__cr & 0x00000F00);
1336   case UNW_PPC64_CR6:
1337     return (_registers.__cr & 0x000000F0);
1338   case UNW_PPC64_CR7:
1339     return (_registers.__cr & 0x0000000F);
1340   case UNW_PPC64_XER:
1341     return _registers.__xer;
1342   case UNW_PPC64_LR:
1343     return _registers.__lr;
1344   case UNW_PPC64_CTR:
1345     return _registers.__ctr;
1346   case UNW_PPC64_VRSAVE:
1347     return _registers.__vrsave;
1348   }
1349   _LIBUNWIND_ABORT("unsupported ppc64 register");
1350 }
1351 
setRegister(int regNum,uint64_t value)1352 inline void Registers_ppc64::setRegister(int regNum, uint64_t value) {
1353   switch (regNum) {
1354   case UNW_REG_IP:
1355     _registers.__srr0 = value;
1356     return;
1357   case UNW_PPC64_R0:
1358     _registers.__r0 = value;
1359     return;
1360   case UNW_PPC64_R1:
1361   case UNW_REG_SP:
1362     _registers.__r1 = value;
1363     return;
1364   case UNW_PPC64_R2:
1365     _registers.__r2 = value;
1366     return;
1367   case UNW_PPC64_R3:
1368     _registers.__r3 = value;
1369     return;
1370   case UNW_PPC64_R4:
1371     _registers.__r4 = value;
1372     return;
1373   case UNW_PPC64_R5:
1374     _registers.__r5 = value;
1375     return;
1376   case UNW_PPC64_R6:
1377     _registers.__r6 = value;
1378     return;
1379   case UNW_PPC64_R7:
1380     _registers.__r7 = value;
1381     return;
1382   case UNW_PPC64_R8:
1383     _registers.__r8 = value;
1384     return;
1385   case UNW_PPC64_R9:
1386     _registers.__r9 = value;
1387     return;
1388   case UNW_PPC64_R10:
1389     _registers.__r10 = value;
1390     return;
1391   case UNW_PPC64_R11:
1392     _registers.__r11 = value;
1393     return;
1394   case UNW_PPC64_R12:
1395     _registers.__r12 = value;
1396     return;
1397   case UNW_PPC64_R13:
1398     _registers.__r13 = value;
1399     return;
1400   case UNW_PPC64_R14:
1401     _registers.__r14 = value;
1402     return;
1403   case UNW_PPC64_R15:
1404     _registers.__r15 = value;
1405     return;
1406   case UNW_PPC64_R16:
1407     _registers.__r16 = value;
1408     return;
1409   case UNW_PPC64_R17:
1410     _registers.__r17 = value;
1411     return;
1412   case UNW_PPC64_R18:
1413     _registers.__r18 = value;
1414     return;
1415   case UNW_PPC64_R19:
1416     _registers.__r19 = value;
1417     return;
1418   case UNW_PPC64_R20:
1419     _registers.__r20 = value;
1420     return;
1421   case UNW_PPC64_R21:
1422     _registers.__r21 = value;
1423     return;
1424   case UNW_PPC64_R22:
1425     _registers.__r22 = value;
1426     return;
1427   case UNW_PPC64_R23:
1428     _registers.__r23 = value;
1429     return;
1430   case UNW_PPC64_R24:
1431     _registers.__r24 = value;
1432     return;
1433   case UNW_PPC64_R25:
1434     _registers.__r25 = value;
1435     return;
1436   case UNW_PPC64_R26:
1437     _registers.__r26 = value;
1438     return;
1439   case UNW_PPC64_R27:
1440     _registers.__r27 = value;
1441     return;
1442   case UNW_PPC64_R28:
1443     _registers.__r28 = value;
1444     return;
1445   case UNW_PPC64_R29:
1446     _registers.__r29 = value;
1447     return;
1448   case UNW_PPC64_R30:
1449     _registers.__r30 = value;
1450     return;
1451   case UNW_PPC64_R31:
1452     _registers.__r31 = value;
1453     return;
1454   case UNW_PPC64_CR0:
1455     _registers.__cr &= 0x0FFFFFFF;
1456     _registers.__cr |= (value & 0xF0000000);
1457     return;
1458   case UNW_PPC64_CR1:
1459     _registers.__cr &= 0xF0FFFFFF;
1460     _registers.__cr |= (value & 0x0F000000);
1461     return;
1462   case UNW_PPC64_CR2:
1463     _registers.__cr &= 0xFF0FFFFF;
1464     _registers.__cr |= (value & 0x00F00000);
1465     return;
1466   case UNW_PPC64_CR3:
1467     _registers.__cr &= 0xFFF0FFFF;
1468     _registers.__cr |= (value & 0x000F0000);
1469     return;
1470   case UNW_PPC64_CR4:
1471     _registers.__cr &= 0xFFFF0FFF;
1472     _registers.__cr |= (value & 0x0000F000);
1473     return;
1474   case UNW_PPC64_CR5:
1475     _registers.__cr &= 0xFFFFF0FF;
1476     _registers.__cr |= (value & 0x00000F00);
1477     return;
1478   case UNW_PPC64_CR6:
1479     _registers.__cr &= 0xFFFFFF0F;
1480     _registers.__cr |= (value & 0x000000F0);
1481     return;
1482   case UNW_PPC64_CR7:
1483     _registers.__cr &= 0xFFFFFFF0;
1484     _registers.__cr |= (value & 0x0000000F);
1485     return;
1486   case UNW_PPC64_XER:
1487     _registers.__xer = value;
1488     return;
1489   case UNW_PPC64_LR:
1490     _registers.__lr = value;
1491     return;
1492   case UNW_PPC64_CTR:
1493     _registers.__ctr = value;
1494     return;
1495   case UNW_PPC64_VRSAVE:
1496     _registers.__vrsave = value;
1497     return;
1498   }
1499   _LIBUNWIND_ABORT("unsupported ppc64 register");
1500 }
1501 
validFloatRegister(int regNum) const1502 inline bool Registers_ppc64::validFloatRegister(int regNum) const {
1503   return regNum >= UNW_PPC64_F0 && regNum <= UNW_PPC64_F31;
1504 }
1505 
getFloatRegister(int regNum) const1506 inline double Registers_ppc64::getFloatRegister(int regNum) const {
1507   assert(validFloatRegister(regNum));
1508   return _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f;
1509 }
1510 
setFloatRegister(int regNum,double value)1511 inline void Registers_ppc64::setFloatRegister(int regNum, double value) {
1512   assert(validFloatRegister(regNum));
1513   _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f = value;
1514 }
1515 
validVectorRegister(int regNum) const1516 inline bool Registers_ppc64::validVectorRegister(int regNum) const {
1517 #if defined(__VSX__)
1518   if (regNum >= UNW_PPC64_VS0 && regNum <= UNW_PPC64_VS31)
1519     return true;
1520   if (regNum >= UNW_PPC64_VS32 && regNum <= UNW_PPC64_VS63)
1521     return true;
1522 #elif defined(__ALTIVEC__)
1523   if (regNum >= UNW_PPC64_V0 && regNum <= UNW_PPC64_V31)
1524     return true;
1525 #endif
1526   return false;
1527 }
1528 
getVectorRegNum(int num)1529 inline int Registers_ppc64::getVectorRegNum(int num)
1530 {
1531   if (num >= UNW_PPC64_VS0 && num <= UNW_PPC64_VS31)
1532     return num - UNW_PPC64_VS0;
1533   else
1534     return num - UNW_PPC64_VS32 + 32;
1535 }
1536 
getVectorRegister(int regNum) const1537 inline v128 Registers_ppc64::getVectorRegister(int regNum) const {
1538   assert(validVectorRegister(regNum));
1539   return _vectorScalarRegisters[getVectorRegNum(regNum)].v;
1540 }
1541 
setVectorRegister(int regNum,v128 value)1542 inline void Registers_ppc64::setVectorRegister(int regNum, v128 value) {
1543   assert(validVectorRegister(regNum));
1544   _vectorScalarRegisters[getVectorRegNum(regNum)].v = value;
1545 }
1546 
getRegisterName(int regNum)1547 inline const char *Registers_ppc64::getRegisterName(int regNum) {
1548   switch (regNum) {
1549   case UNW_REG_IP:
1550     return "ip";
1551   case UNW_REG_SP:
1552     return "sp";
1553   case UNW_PPC64_R0:
1554     return "r0";
1555   case UNW_PPC64_R1:
1556     return "r1";
1557   case UNW_PPC64_R2:
1558     return "r2";
1559   case UNW_PPC64_R3:
1560     return "r3";
1561   case UNW_PPC64_R4:
1562     return "r4";
1563   case UNW_PPC64_R5:
1564     return "r5";
1565   case UNW_PPC64_R6:
1566     return "r6";
1567   case UNW_PPC64_R7:
1568     return "r7";
1569   case UNW_PPC64_R8:
1570     return "r8";
1571   case UNW_PPC64_R9:
1572     return "r9";
1573   case UNW_PPC64_R10:
1574     return "r10";
1575   case UNW_PPC64_R11:
1576     return "r11";
1577   case UNW_PPC64_R12:
1578     return "r12";
1579   case UNW_PPC64_R13:
1580     return "r13";
1581   case UNW_PPC64_R14:
1582     return "r14";
1583   case UNW_PPC64_R15:
1584     return "r15";
1585   case UNW_PPC64_R16:
1586     return "r16";
1587   case UNW_PPC64_R17:
1588     return "r17";
1589   case UNW_PPC64_R18:
1590     return "r18";
1591   case UNW_PPC64_R19:
1592     return "r19";
1593   case UNW_PPC64_R20:
1594     return "r20";
1595   case UNW_PPC64_R21:
1596     return "r21";
1597   case UNW_PPC64_R22:
1598     return "r22";
1599   case UNW_PPC64_R23:
1600     return "r23";
1601   case UNW_PPC64_R24:
1602     return "r24";
1603   case UNW_PPC64_R25:
1604     return "r25";
1605   case UNW_PPC64_R26:
1606     return "r26";
1607   case UNW_PPC64_R27:
1608     return "r27";
1609   case UNW_PPC64_R28:
1610     return "r28";
1611   case UNW_PPC64_R29:
1612     return "r29";
1613   case UNW_PPC64_R30:
1614     return "r30";
1615   case UNW_PPC64_R31:
1616     return "r31";
1617   case UNW_PPC64_CR0:
1618     return "cr0";
1619   case UNW_PPC64_CR1:
1620     return "cr1";
1621   case UNW_PPC64_CR2:
1622     return "cr2";
1623   case UNW_PPC64_CR3:
1624     return "cr3";
1625   case UNW_PPC64_CR4:
1626     return "cr4";
1627   case UNW_PPC64_CR5:
1628     return "cr5";
1629   case UNW_PPC64_CR6:
1630     return "cr6";
1631   case UNW_PPC64_CR7:
1632     return "cr7";
1633   case UNW_PPC64_XER:
1634     return "xer";
1635   case UNW_PPC64_LR:
1636     return "lr";
1637   case UNW_PPC64_CTR:
1638     return "ctr";
1639   case UNW_PPC64_VRSAVE:
1640     return "vrsave";
1641   case UNW_PPC64_F0:
1642     return "fp0";
1643   case UNW_PPC64_F1:
1644     return "fp1";
1645   case UNW_PPC64_F2:
1646     return "fp2";
1647   case UNW_PPC64_F3:
1648     return "fp3";
1649   case UNW_PPC64_F4:
1650     return "fp4";
1651   case UNW_PPC64_F5:
1652     return "fp5";
1653   case UNW_PPC64_F6:
1654     return "fp6";
1655   case UNW_PPC64_F7:
1656     return "fp7";
1657   case UNW_PPC64_F8:
1658     return "fp8";
1659   case UNW_PPC64_F9:
1660     return "fp9";
1661   case UNW_PPC64_F10:
1662     return "fp10";
1663   case UNW_PPC64_F11:
1664     return "fp11";
1665   case UNW_PPC64_F12:
1666     return "fp12";
1667   case UNW_PPC64_F13:
1668     return "fp13";
1669   case UNW_PPC64_F14:
1670     return "fp14";
1671   case UNW_PPC64_F15:
1672     return "fp15";
1673   case UNW_PPC64_F16:
1674     return "fp16";
1675   case UNW_PPC64_F17:
1676     return "fp17";
1677   case UNW_PPC64_F18:
1678     return "fp18";
1679   case UNW_PPC64_F19:
1680     return "fp19";
1681   case UNW_PPC64_F20:
1682     return "fp20";
1683   case UNW_PPC64_F21:
1684     return "fp21";
1685   case UNW_PPC64_F22:
1686     return "fp22";
1687   case UNW_PPC64_F23:
1688     return "fp23";
1689   case UNW_PPC64_F24:
1690     return "fp24";
1691   case UNW_PPC64_F25:
1692     return "fp25";
1693   case UNW_PPC64_F26:
1694     return "fp26";
1695   case UNW_PPC64_F27:
1696     return "fp27";
1697   case UNW_PPC64_F28:
1698     return "fp28";
1699   case UNW_PPC64_F29:
1700     return "fp29";
1701   case UNW_PPC64_F30:
1702     return "fp30";
1703   case UNW_PPC64_F31:
1704     return "fp31";
1705   case UNW_PPC64_V0:
1706     return "v0";
1707   case UNW_PPC64_V1:
1708     return "v1";
1709   case UNW_PPC64_V2:
1710     return "v2";
1711   case UNW_PPC64_V3:
1712     return "v3";
1713   case UNW_PPC64_V4:
1714     return "v4";
1715   case UNW_PPC64_V5:
1716     return "v5";
1717   case UNW_PPC64_V6:
1718     return "v6";
1719   case UNW_PPC64_V7:
1720     return "v7";
1721   case UNW_PPC64_V8:
1722     return "v8";
1723   case UNW_PPC64_V9:
1724     return "v9";
1725   case UNW_PPC64_V10:
1726     return "v10";
1727   case UNW_PPC64_V11:
1728     return "v11";
1729   case UNW_PPC64_V12:
1730     return "v12";
1731   case UNW_PPC64_V13:
1732     return "v13";
1733   case UNW_PPC64_V14:
1734     return "v14";
1735   case UNW_PPC64_V15:
1736     return "v15";
1737   case UNW_PPC64_V16:
1738     return "v16";
1739   case UNW_PPC64_V17:
1740     return "v17";
1741   case UNW_PPC64_V18:
1742     return "v18";
1743   case UNW_PPC64_V19:
1744     return "v19";
1745   case UNW_PPC64_V20:
1746     return "v20";
1747   case UNW_PPC64_V21:
1748     return "v21";
1749   case UNW_PPC64_V22:
1750     return "v22";
1751   case UNW_PPC64_V23:
1752     return "v23";
1753   case UNW_PPC64_V24:
1754     return "v24";
1755   case UNW_PPC64_V25:
1756     return "v25";
1757   case UNW_PPC64_V26:
1758     return "v26";
1759   case UNW_PPC64_V27:
1760     return "v27";
1761   case UNW_PPC64_V28:
1762     return "v28";
1763   case UNW_PPC64_V29:
1764     return "v29";
1765   case UNW_PPC64_V30:
1766     return "v30";
1767   case UNW_PPC64_V31:
1768     return "v31";
1769   }
1770   return "unknown register";
1771 }
1772 #endif // _LIBUNWIND_TARGET_PPC64
1773 
1774 
1775 #if defined(_LIBUNWIND_TARGET_AARCH64)
1776 /// Registers_arm64  holds the register state of a thread in a 64-bit arm
1777 /// process.
1778 class _LIBUNWIND_HIDDEN Registers_arm64;
1779 extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *);
1780 class _LIBUNWIND_HIDDEN Registers_arm64 {
1781 public:
1782   Registers_arm64();
1783   Registers_arm64(const void *registers);
1784 
1785   bool        validRegister(int num) const;
1786   uint64_t    getRegister(int num) const;
1787   void        setRegister(int num, uint64_t value);
1788   bool        validFloatRegister(int num) const;
1789   double      getFloatRegister(int num) const;
1790   void        setFloatRegister(int num, double value);
1791   bool        validVectorRegister(int num) const;
1792   v128        getVectorRegister(int num) const;
1793   void        setVectorRegister(int num, v128 value);
1794   static const char *getRegisterName(int num);
jumpto()1795   void        jumpto() { __libunwind_Registers_arm64_jumpto(this); }
lastDwarfRegNum()1796   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64; }
getArch()1797   static int  getArch() { return REGISTERS_ARM64; }
1798 
getSP() const1799   uint64_t  getSP() const         { return _registers.__sp; }
setSP(uint64_t value)1800   void      setSP(uint64_t value) { _registers.__sp = value; }
getIP() const1801   uint64_t  getIP() const         { return _registers.__pc; }
setIP(uint64_t value)1802   void      setIP(uint64_t value) { _registers.__pc = value; }
getFP() const1803   uint64_t  getFP() const         { return _registers.__fp; }
setFP(uint64_t value)1804   void      setFP(uint64_t value) { _registers.__fp = value; }
1805 
1806 private:
1807   struct GPRs {
1808     uint64_t __x[29]; // x0-x28
1809     uint64_t __fp;    // Frame pointer x29
1810     uint64_t __lr;    // Link register x30
1811     uint64_t __sp;    // Stack pointer x31
1812     uint64_t __pc;    // Program counter
1813     uint64_t __ra_sign_state; // RA sign state register
1814   };
1815 
1816   GPRs    _registers;
1817   double  _vectorHalfRegisters[32];
1818   // Currently only the lower double in 128-bit vectore registers
1819   // is perserved during unwinding.  We could define new register
1820   // numbers (> 96) which mean whole vector registers, then this
1821   // struct would need to change to contain whole vector registers.
1822 };
1823 
Registers_arm64(const void * registers)1824 inline Registers_arm64::Registers_arm64(const void *registers) {
1825   static_assert((check_fit<Registers_arm64, unw_context_t>::does_fit),
1826                 "arm64 registers do not fit into unw_context_t");
1827   memcpy(&_registers, registers, sizeof(_registers));
1828   static_assert(sizeof(GPRs) == 0x110,
1829                 "expected VFP registers to be at offset 272");
1830   memcpy(_vectorHalfRegisters,
1831          static_cast<const uint8_t *>(registers) + sizeof(GPRs),
1832          sizeof(_vectorHalfRegisters));
1833 }
1834 
Registers_arm64()1835 inline Registers_arm64::Registers_arm64() {
1836   memset(&_registers, 0, sizeof(_registers));
1837   memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
1838 }
1839 
validRegister(int regNum) const1840 inline bool Registers_arm64::validRegister(int regNum) const {
1841   if (regNum == UNW_REG_IP)
1842     return true;
1843   if (regNum == UNW_REG_SP)
1844     return true;
1845   if (regNum < 0)
1846     return false;
1847   if (regNum > 95)
1848     return false;
1849   if (regNum == UNW_ARM64_RA_SIGN_STATE)
1850     return true;
1851   if ((regNum > 31) && (regNum < 64))
1852     return false;
1853   return true;
1854 }
1855 
getRegister(int regNum) const1856 inline uint64_t Registers_arm64::getRegister(int regNum) const {
1857   if (regNum == UNW_REG_IP)
1858     return _registers.__pc;
1859   if (regNum == UNW_REG_SP)
1860     return _registers.__sp;
1861   if (regNum == UNW_ARM64_RA_SIGN_STATE)
1862     return _registers.__ra_sign_state;
1863   if ((regNum >= 0) && (regNum < 32))
1864     return _registers.__x[regNum];
1865   _LIBUNWIND_ABORT("unsupported arm64 register");
1866 }
1867 
setRegister(int regNum,uint64_t value)1868 inline void Registers_arm64::setRegister(int regNum, uint64_t value) {
1869   if (regNum == UNW_REG_IP)
1870     _registers.__pc = value;
1871   else if (regNum == UNW_REG_SP)
1872     _registers.__sp = value;
1873   else if (regNum == UNW_ARM64_RA_SIGN_STATE)
1874     _registers.__ra_sign_state = value;
1875   else if ((regNum >= 0) && (regNum < 32))
1876     _registers.__x[regNum] = value;
1877   else
1878     _LIBUNWIND_ABORT("unsupported arm64 register");
1879 }
1880 
getRegisterName(int regNum)1881 inline const char *Registers_arm64::getRegisterName(int regNum) {
1882   switch (regNum) {
1883   case UNW_REG_IP:
1884     return "pc";
1885   case UNW_REG_SP:
1886     return "sp";
1887   case UNW_ARM64_X0:
1888     return "x0";
1889   case UNW_ARM64_X1:
1890     return "x1";
1891   case UNW_ARM64_X2:
1892     return "x2";
1893   case UNW_ARM64_X3:
1894     return "x3";
1895   case UNW_ARM64_X4:
1896     return "x4";
1897   case UNW_ARM64_X5:
1898     return "x5";
1899   case UNW_ARM64_X6:
1900     return "x6";
1901   case UNW_ARM64_X7:
1902     return "x7";
1903   case UNW_ARM64_X8:
1904     return "x8";
1905   case UNW_ARM64_X9:
1906     return "x9";
1907   case UNW_ARM64_X10:
1908     return "x10";
1909   case UNW_ARM64_X11:
1910     return "x11";
1911   case UNW_ARM64_X12:
1912     return "x12";
1913   case UNW_ARM64_X13:
1914     return "x13";
1915   case UNW_ARM64_X14:
1916     return "x14";
1917   case UNW_ARM64_X15:
1918     return "x15";
1919   case UNW_ARM64_X16:
1920     return "x16";
1921   case UNW_ARM64_X17:
1922     return "x17";
1923   case UNW_ARM64_X18:
1924     return "x18";
1925   case UNW_ARM64_X19:
1926     return "x19";
1927   case UNW_ARM64_X20:
1928     return "x20";
1929   case UNW_ARM64_X21:
1930     return "x21";
1931   case UNW_ARM64_X22:
1932     return "x22";
1933   case UNW_ARM64_X23:
1934     return "x23";
1935   case UNW_ARM64_X24:
1936     return "x24";
1937   case UNW_ARM64_X25:
1938     return "x25";
1939   case UNW_ARM64_X26:
1940     return "x26";
1941   case UNW_ARM64_X27:
1942     return "x27";
1943   case UNW_ARM64_X28:
1944     return "x28";
1945   case UNW_ARM64_X29:
1946     return "fp";
1947   case UNW_ARM64_X30:
1948     return "lr";
1949   case UNW_ARM64_X31:
1950     return "sp";
1951   case UNW_ARM64_D0:
1952     return "d0";
1953   case UNW_ARM64_D1:
1954     return "d1";
1955   case UNW_ARM64_D2:
1956     return "d2";
1957   case UNW_ARM64_D3:
1958     return "d3";
1959   case UNW_ARM64_D4:
1960     return "d4";
1961   case UNW_ARM64_D5:
1962     return "d5";
1963   case UNW_ARM64_D6:
1964     return "d6";
1965   case UNW_ARM64_D7:
1966     return "d7";
1967   case UNW_ARM64_D8:
1968     return "d8";
1969   case UNW_ARM64_D9:
1970     return "d9";
1971   case UNW_ARM64_D10:
1972     return "d10";
1973   case UNW_ARM64_D11:
1974     return "d11";
1975   case UNW_ARM64_D12:
1976     return "d12";
1977   case UNW_ARM64_D13:
1978     return "d13";
1979   case UNW_ARM64_D14:
1980     return "d14";
1981   case UNW_ARM64_D15:
1982     return "d15";
1983   case UNW_ARM64_D16:
1984     return "d16";
1985   case UNW_ARM64_D17:
1986     return "d17";
1987   case UNW_ARM64_D18:
1988     return "d18";
1989   case UNW_ARM64_D19:
1990     return "d19";
1991   case UNW_ARM64_D20:
1992     return "d20";
1993   case UNW_ARM64_D21:
1994     return "d21";
1995   case UNW_ARM64_D22:
1996     return "d22";
1997   case UNW_ARM64_D23:
1998     return "d23";
1999   case UNW_ARM64_D24:
2000     return "d24";
2001   case UNW_ARM64_D25:
2002     return "d25";
2003   case UNW_ARM64_D26:
2004     return "d26";
2005   case UNW_ARM64_D27:
2006     return "d27";
2007   case UNW_ARM64_D28:
2008     return "d28";
2009   case UNW_ARM64_D29:
2010     return "d29";
2011   case UNW_ARM64_D30:
2012     return "d30";
2013   case UNW_ARM64_D31:
2014     return "d31";
2015   default:
2016     return "unknown register";
2017   }
2018 }
2019 
validFloatRegister(int regNum) const2020 inline bool Registers_arm64::validFloatRegister(int regNum) const {
2021   if (regNum < UNW_ARM64_D0)
2022     return false;
2023   if (regNum > UNW_ARM64_D31)
2024     return false;
2025   return true;
2026 }
2027 
getFloatRegister(int regNum) const2028 inline double Registers_arm64::getFloatRegister(int regNum) const {
2029   assert(validFloatRegister(regNum));
2030   return _vectorHalfRegisters[regNum - UNW_ARM64_D0];
2031 }
2032 
setFloatRegister(int regNum,double value)2033 inline void Registers_arm64::setFloatRegister(int regNum, double value) {
2034   assert(validFloatRegister(regNum));
2035   _vectorHalfRegisters[regNum - UNW_ARM64_D0] = value;
2036 }
2037 
validVectorRegister(int) const2038 inline bool Registers_arm64::validVectorRegister(int) const {
2039   return false;
2040 }
2041 
getVectorRegister(int) const2042 inline v128 Registers_arm64::getVectorRegister(int) const {
2043   _LIBUNWIND_ABORT("no arm64 vector register support yet");
2044 }
2045 
setVectorRegister(int,v128)2046 inline void Registers_arm64::setVectorRegister(int, v128) {
2047   _LIBUNWIND_ABORT("no arm64 vector register support yet");
2048 }
2049 #endif // _LIBUNWIND_TARGET_AARCH64
2050 
2051 #if defined(_LIBUNWIND_TARGET_ARM)
2052 /// Registers_arm holds the register state of a thread in a 32-bit arm
2053 /// process.
2054 ///
2055 /// NOTE: Assumes VFPv3. On ARM processors without a floating point unit,
2056 /// this uses more memory than required.
2057 class _LIBUNWIND_HIDDEN Registers_arm {
2058 public:
2059   Registers_arm();
2060   Registers_arm(const void *registers);
2061 
2062   bool        validRegister(int num) const;
2063   uint32_t    getRegister(int num) const;
2064   void        setRegister(int num, uint32_t value);
2065   bool        validFloatRegister(int num) const;
2066   unw_fpreg_t getFloatRegister(int num);
2067   void        setFloatRegister(int num, unw_fpreg_t value);
2068   bool        validVectorRegister(int num) const;
2069   v128        getVectorRegister(int num) const;
2070   void        setVectorRegister(int num, v128 value);
2071   static const char *getRegisterName(int num);
jumpto()2072   void        jumpto() {
2073     restoreSavedFloatRegisters();
2074     restoreCoreAndJumpTo();
2075   }
lastDwarfRegNum()2076   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM; }
getArch()2077   static int  getArch() { return REGISTERS_ARM; }
2078 
getSP() const2079   uint32_t  getSP() const         { return _registers.__sp; }
setSP(uint32_t value)2080   void      setSP(uint32_t value) { _registers.__sp = value; }
getIP() const2081   uint32_t  getIP() const         { return _registers.__pc; }
setIP(uint32_t value)2082   void      setIP(uint32_t value) { _registers.__pc = value; }
2083 
saveVFPAsX()2084   void saveVFPAsX() {
2085     assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15);
2086     _use_X_for_vfp_save = true;
2087   }
2088 
restoreSavedFloatRegisters()2089   void restoreSavedFloatRegisters() {
2090     if (_saved_vfp_d0_d15) {
2091       if (_use_X_for_vfp_save)
2092         restoreVFPWithFLDMX(_vfp_d0_d15_pad);
2093       else
2094         restoreVFPWithFLDMD(_vfp_d0_d15_pad);
2095     }
2096     if (_saved_vfp_d16_d31)
2097       restoreVFPv3(_vfp_d16_d31);
2098 #if defined(__ARM_WMMX)
2099     if (_saved_iwmmx)
2100       restoreiWMMX(_iwmmx);
2101     if (_saved_iwmmx_control)
2102       restoreiWMMXControl(_iwmmx_control);
2103 #endif
2104   }
2105 
2106 private:
2107   struct GPRs {
2108     uint32_t __r[13]; // r0-r12
2109     uint32_t __sp;    // Stack pointer r13
2110     uint32_t __lr;    // Link register r14
2111     uint32_t __pc;    // Program counter r15
2112   };
2113 
2114   static void saveVFPWithFSTMD(void*);
2115   static void saveVFPWithFSTMX(void*);
2116   static void saveVFPv3(void*);
2117   static void restoreVFPWithFLDMD(void*);
2118   static void restoreVFPWithFLDMX(void*);
2119   static void restoreVFPv3(void*);
2120 #if defined(__ARM_WMMX)
2121   static void saveiWMMX(void*);
2122   static void saveiWMMXControl(uint32_t*);
2123   static void restoreiWMMX(void*);
2124   static void restoreiWMMXControl(uint32_t*);
2125 #endif
2126   void restoreCoreAndJumpTo();
2127 
2128   // ARM registers
2129   GPRs _registers;
2130 
2131   // We save floating point registers lazily because we can't know ahead of
2132   // time which ones are used. See EHABI #4.7.
2133 
2134   // Whether D0-D15 are saved in the FTSMX instead of FSTMD format.
2135   //
2136   // See EHABI #7.5 that explains how matching instruction sequences for load
2137   // and store need to be used to correctly restore the exact register bits.
2138   bool _use_X_for_vfp_save;
2139   // Whether VFP D0-D15 are saved.
2140   bool _saved_vfp_d0_d15;
2141   // Whether VFPv3 D16-D31 are saved.
2142   bool _saved_vfp_d16_d31;
2143   // VFP registers D0-D15, + padding if saved using FSTMX
2144   unw_fpreg_t _vfp_d0_d15_pad[17];
2145   // VFPv3 registers D16-D31, always saved using FSTMD
2146   unw_fpreg_t _vfp_d16_d31[16];
2147 #if defined(__ARM_WMMX)
2148   // Whether iWMMX data registers are saved.
2149   bool _saved_iwmmx;
2150   // Whether iWMMX control registers are saved.
2151   mutable bool _saved_iwmmx_control;
2152   // iWMMX registers
2153   unw_fpreg_t _iwmmx[16];
2154   // iWMMX control registers
2155   mutable uint32_t _iwmmx_control[4];
2156 #endif
2157 };
2158 
Registers_arm(const void * registers)2159 inline Registers_arm::Registers_arm(const void *registers)
2160   : _use_X_for_vfp_save(false),
2161     _saved_vfp_d0_d15(false),
2162     _saved_vfp_d16_d31(false) {
2163   static_assert((check_fit<Registers_arm, unw_context_t>::does_fit),
2164                 "arm registers do not fit into unw_context_t");
2165   // See __unw_getcontext() note about data.
2166   memcpy(&_registers, registers, sizeof(_registers));
2167   memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
2168   memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
2169 #if defined(__ARM_WMMX)
2170   _saved_iwmmx = false;
2171   _saved_iwmmx_control = false;
2172   memset(&_iwmmx, 0, sizeof(_iwmmx));
2173   memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
2174 #endif
2175 }
2176 
Registers_arm()2177 inline Registers_arm::Registers_arm()
2178   : _use_X_for_vfp_save(false),
2179     _saved_vfp_d0_d15(false),
2180     _saved_vfp_d16_d31(false) {
2181   memset(&_registers, 0, sizeof(_registers));
2182   memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
2183   memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
2184 #if defined(__ARM_WMMX)
2185   _saved_iwmmx = false;
2186   _saved_iwmmx_control = false;
2187   memset(&_iwmmx, 0, sizeof(_iwmmx));
2188   memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
2189 #endif
2190 }
2191 
validRegister(int regNum) const2192 inline bool Registers_arm::validRegister(int regNum) const {
2193   // Returns true for all non-VFP registers supported by the EHABI
2194   // virtual register set (VRS).
2195   if (regNum == UNW_REG_IP)
2196     return true;
2197 
2198   if (regNum == UNW_REG_SP)
2199     return true;
2200 
2201   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15)
2202     return true;
2203 
2204 #if defined(__ARM_WMMX)
2205   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3)
2206     return true;
2207 #endif
2208 
2209   return false;
2210 }
2211 
getRegister(int regNum) const2212 inline uint32_t Registers_arm::getRegister(int regNum) const {
2213   if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
2214     return _registers.__sp;
2215 
2216   if (regNum == UNW_ARM_LR)
2217     return _registers.__lr;
2218 
2219   if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
2220     return _registers.__pc;
2221 
2222   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
2223     return _registers.__r[regNum];
2224 
2225 #if defined(__ARM_WMMX)
2226   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
2227     if (!_saved_iwmmx_control) {
2228       _saved_iwmmx_control = true;
2229       saveiWMMXControl(_iwmmx_control);
2230     }
2231     return _iwmmx_control[regNum - UNW_ARM_WC0];
2232   }
2233 #endif
2234 
2235   _LIBUNWIND_ABORT("unsupported arm register");
2236 }
2237 
setRegister(int regNum,uint32_t value)2238 inline void Registers_arm::setRegister(int regNum, uint32_t value) {
2239   if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) {
2240     _registers.__sp = value;
2241     return;
2242   }
2243 
2244   if (regNum == UNW_ARM_LR) {
2245     _registers.__lr = value;
2246     return;
2247   }
2248 
2249   if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) {
2250     _registers.__pc = value;
2251     return;
2252   }
2253 
2254   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) {
2255     _registers.__r[regNum] = value;
2256     return;
2257   }
2258 
2259 #if defined(__ARM_WMMX)
2260   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
2261     if (!_saved_iwmmx_control) {
2262       _saved_iwmmx_control = true;
2263       saveiWMMXControl(_iwmmx_control);
2264     }
2265     _iwmmx_control[regNum - UNW_ARM_WC0] = value;
2266     return;
2267   }
2268 #endif
2269 
2270   _LIBUNWIND_ABORT("unsupported arm register");
2271 }
2272 
getRegisterName(int regNum)2273 inline const char *Registers_arm::getRegisterName(int regNum) {
2274   switch (regNum) {
2275   case UNW_REG_IP:
2276   case UNW_ARM_IP: // UNW_ARM_R15 is alias
2277     return "pc";
2278   case UNW_ARM_LR: // UNW_ARM_R14 is alias
2279     return "lr";
2280   case UNW_REG_SP:
2281   case UNW_ARM_SP: // UNW_ARM_R13 is alias
2282     return "sp";
2283   case UNW_ARM_R0:
2284     return "r0";
2285   case UNW_ARM_R1:
2286     return "r1";
2287   case UNW_ARM_R2:
2288     return "r2";
2289   case UNW_ARM_R3:
2290     return "r3";
2291   case UNW_ARM_R4:
2292     return "r4";
2293   case UNW_ARM_R5:
2294     return "r5";
2295   case UNW_ARM_R6:
2296     return "r6";
2297   case UNW_ARM_R7:
2298     return "r7";
2299   case UNW_ARM_R8:
2300     return "r8";
2301   case UNW_ARM_R9:
2302     return "r9";
2303   case UNW_ARM_R10:
2304     return "r10";
2305   case UNW_ARM_R11:
2306     return "r11";
2307   case UNW_ARM_R12:
2308     return "r12";
2309   case UNW_ARM_S0:
2310     return "s0";
2311   case UNW_ARM_S1:
2312     return "s1";
2313   case UNW_ARM_S2:
2314     return "s2";
2315   case UNW_ARM_S3:
2316     return "s3";
2317   case UNW_ARM_S4:
2318     return "s4";
2319   case UNW_ARM_S5:
2320     return "s5";
2321   case UNW_ARM_S6:
2322     return "s6";
2323   case UNW_ARM_S7:
2324     return "s7";
2325   case UNW_ARM_S8:
2326     return "s8";
2327   case UNW_ARM_S9:
2328     return "s9";
2329   case UNW_ARM_S10:
2330     return "s10";
2331   case UNW_ARM_S11:
2332     return "s11";
2333   case UNW_ARM_S12:
2334     return "s12";
2335   case UNW_ARM_S13:
2336     return "s13";
2337   case UNW_ARM_S14:
2338     return "s14";
2339   case UNW_ARM_S15:
2340     return "s15";
2341   case UNW_ARM_S16:
2342     return "s16";
2343   case UNW_ARM_S17:
2344     return "s17";
2345   case UNW_ARM_S18:
2346     return "s18";
2347   case UNW_ARM_S19:
2348     return "s19";
2349   case UNW_ARM_S20:
2350     return "s20";
2351   case UNW_ARM_S21:
2352     return "s21";
2353   case UNW_ARM_S22:
2354     return "s22";
2355   case UNW_ARM_S23:
2356     return "s23";
2357   case UNW_ARM_S24:
2358     return "s24";
2359   case UNW_ARM_S25:
2360     return "s25";
2361   case UNW_ARM_S26:
2362     return "s26";
2363   case UNW_ARM_S27:
2364     return "s27";
2365   case UNW_ARM_S28:
2366     return "s28";
2367   case UNW_ARM_S29:
2368     return "s29";
2369   case UNW_ARM_S30:
2370     return "s30";
2371   case UNW_ARM_S31:
2372     return "s31";
2373   case UNW_ARM_D0:
2374     return "d0";
2375   case UNW_ARM_D1:
2376     return "d1";
2377   case UNW_ARM_D2:
2378     return "d2";
2379   case UNW_ARM_D3:
2380     return "d3";
2381   case UNW_ARM_D4:
2382     return "d4";
2383   case UNW_ARM_D5:
2384     return "d5";
2385   case UNW_ARM_D6:
2386     return "d6";
2387   case UNW_ARM_D7:
2388     return "d7";
2389   case UNW_ARM_D8:
2390     return "d8";
2391   case UNW_ARM_D9:
2392     return "d9";
2393   case UNW_ARM_D10:
2394     return "d10";
2395   case UNW_ARM_D11:
2396     return "d11";
2397   case UNW_ARM_D12:
2398     return "d12";
2399   case UNW_ARM_D13:
2400     return "d13";
2401   case UNW_ARM_D14:
2402     return "d14";
2403   case UNW_ARM_D15:
2404     return "d15";
2405   case UNW_ARM_D16:
2406     return "d16";
2407   case UNW_ARM_D17:
2408     return "d17";
2409   case UNW_ARM_D18:
2410     return "d18";
2411   case UNW_ARM_D19:
2412     return "d19";
2413   case UNW_ARM_D20:
2414     return "d20";
2415   case UNW_ARM_D21:
2416     return "d21";
2417   case UNW_ARM_D22:
2418     return "d22";
2419   case UNW_ARM_D23:
2420     return "d23";
2421   case UNW_ARM_D24:
2422     return "d24";
2423   case UNW_ARM_D25:
2424     return "d25";
2425   case UNW_ARM_D26:
2426     return "d26";
2427   case UNW_ARM_D27:
2428     return "d27";
2429   case UNW_ARM_D28:
2430     return "d28";
2431   case UNW_ARM_D29:
2432     return "d29";
2433   case UNW_ARM_D30:
2434     return "d30";
2435   case UNW_ARM_D31:
2436     return "d31";
2437   default:
2438     return "unknown register";
2439   }
2440 }
2441 
validFloatRegister(int regNum) const2442 inline bool Registers_arm::validFloatRegister(int regNum) const {
2443   // NOTE: Consider the intel MMX registers floating points so the
2444   // __unw_get_fpreg can be used to transmit the 64-bit data back.
2445   return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31))
2446 #if defined(__ARM_WMMX)
2447       || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15))
2448 #endif
2449       ;
2450 }
2451 
getFloatRegister(int regNum)2452 inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) {
2453   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
2454     if (!_saved_vfp_d0_d15) {
2455       _saved_vfp_d0_d15 = true;
2456       if (_use_X_for_vfp_save)
2457         saveVFPWithFSTMX(_vfp_d0_d15_pad);
2458       else
2459         saveVFPWithFSTMD(_vfp_d0_d15_pad);
2460     }
2461     return _vfp_d0_d15_pad[regNum - UNW_ARM_D0];
2462   }
2463 
2464   if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
2465     if (!_saved_vfp_d16_d31) {
2466       _saved_vfp_d16_d31 = true;
2467       saveVFPv3(_vfp_d16_d31);
2468     }
2469     return _vfp_d16_d31[regNum - UNW_ARM_D16];
2470   }
2471 
2472 #if defined(__ARM_WMMX)
2473   if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
2474     if (!_saved_iwmmx) {
2475       _saved_iwmmx = true;
2476       saveiWMMX(_iwmmx);
2477     }
2478     return _iwmmx[regNum - UNW_ARM_WR0];
2479   }
2480 #endif
2481 
2482   _LIBUNWIND_ABORT("Unknown ARM float register");
2483 }
2484 
setFloatRegister(int regNum,unw_fpreg_t value)2485 inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) {
2486   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
2487     if (!_saved_vfp_d0_d15) {
2488       _saved_vfp_d0_d15 = true;
2489       if (_use_X_for_vfp_save)
2490         saveVFPWithFSTMX(_vfp_d0_d15_pad);
2491       else
2492         saveVFPWithFSTMD(_vfp_d0_d15_pad);
2493     }
2494     _vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value;
2495     return;
2496   }
2497 
2498   if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
2499     if (!_saved_vfp_d16_d31) {
2500       _saved_vfp_d16_d31 = true;
2501       saveVFPv3(_vfp_d16_d31);
2502     }
2503     _vfp_d16_d31[regNum - UNW_ARM_D16] = value;
2504     return;
2505   }
2506 
2507 #if defined(__ARM_WMMX)
2508   if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
2509     if (!_saved_iwmmx) {
2510       _saved_iwmmx = true;
2511       saveiWMMX(_iwmmx);
2512     }
2513     _iwmmx[regNum - UNW_ARM_WR0] = value;
2514     return;
2515   }
2516 #endif
2517 
2518   _LIBUNWIND_ABORT("Unknown ARM float register");
2519 }
2520 
validVectorRegister(int) const2521 inline bool Registers_arm::validVectorRegister(int) const {
2522   return false;
2523 }
2524 
getVectorRegister(int) const2525 inline v128 Registers_arm::getVectorRegister(int) const {
2526   _LIBUNWIND_ABORT("ARM vector support not implemented");
2527 }
2528 
setVectorRegister(int,v128)2529 inline void Registers_arm::setVectorRegister(int, v128) {
2530   _LIBUNWIND_ABORT("ARM vector support not implemented");
2531 }
2532 #endif // _LIBUNWIND_TARGET_ARM
2533 
2534 
2535 #if defined(_LIBUNWIND_TARGET_OR1K)
2536 /// Registers_or1k holds the register state of a thread in an OpenRISC1000
2537 /// process.
2538 class _LIBUNWIND_HIDDEN Registers_or1k {
2539 public:
2540   Registers_or1k();
2541   Registers_or1k(const void *registers);
2542 
2543   bool        validRegister(int num) const;
2544   uint32_t    getRegister(int num) const;
2545   void        setRegister(int num, uint32_t value);
2546   bool        validFloatRegister(int num) const;
2547   double      getFloatRegister(int num) const;
2548   void        setFloatRegister(int num, double value);
2549   bool        validVectorRegister(int num) const;
2550   v128        getVectorRegister(int num) const;
2551   void        setVectorRegister(int num, v128 value);
2552   static const char *getRegisterName(int num);
2553   void        jumpto();
lastDwarfRegNum()2554   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K; }
getArch()2555   static int  getArch() { return REGISTERS_OR1K; }
2556 
getSP() const2557   uint64_t  getSP() const         { return _registers.__r[1]; }
setSP(uint32_t value)2558   void      setSP(uint32_t value) { _registers.__r[1] = value; }
getIP() const2559   uint64_t  getIP() const         { return _registers.__pc; }
setIP(uint32_t value)2560   void      setIP(uint32_t value) { _registers.__pc = value; }
2561 
2562 private:
2563   struct or1k_thread_state_t {
2564     unsigned int __r[32]; // r0-r31
2565     unsigned int __pc;    // Program counter
2566     unsigned int __epcr;  // Program counter at exception
2567   };
2568 
2569   or1k_thread_state_t _registers;
2570 };
2571 
Registers_or1k(const void * registers)2572 inline Registers_or1k::Registers_or1k(const void *registers) {
2573   static_assert((check_fit<Registers_or1k, unw_context_t>::does_fit),
2574                 "or1k registers do not fit into unw_context_t");
2575   memcpy(&_registers, static_cast<const uint8_t *>(registers),
2576          sizeof(_registers));
2577 }
2578 
Registers_or1k()2579 inline Registers_or1k::Registers_or1k() {
2580   memset(&_registers, 0, sizeof(_registers));
2581 }
2582 
validRegister(int regNum) const2583 inline bool Registers_or1k::validRegister(int regNum) const {
2584   if (regNum == UNW_REG_IP)
2585     return true;
2586   if (regNum == UNW_REG_SP)
2587     return true;
2588   if (regNum < 0)
2589     return false;
2590   if (regNum <= UNW_OR1K_R31)
2591     return true;
2592   if (regNum == UNW_OR1K_EPCR)
2593     return true;
2594   return false;
2595 }
2596 
getRegister(int regNum) const2597 inline uint32_t Registers_or1k::getRegister(int regNum) const {
2598   if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31)
2599     return _registers.__r[regNum - UNW_OR1K_R0];
2600 
2601   switch (regNum) {
2602   case UNW_REG_IP:
2603     return _registers.__pc;
2604   case UNW_REG_SP:
2605     return _registers.__r[1];
2606   case UNW_OR1K_EPCR:
2607     return _registers.__epcr;
2608   }
2609   _LIBUNWIND_ABORT("unsupported or1k register");
2610 }
2611 
setRegister(int regNum,uint32_t value)2612 inline void Registers_or1k::setRegister(int regNum, uint32_t value) {
2613   if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) {
2614     _registers.__r[regNum - UNW_OR1K_R0] = value;
2615     return;
2616   }
2617 
2618   switch (regNum) {
2619   case UNW_REG_IP:
2620     _registers.__pc = value;
2621     return;
2622   case UNW_REG_SP:
2623     _registers.__r[1] = value;
2624     return;
2625   case UNW_OR1K_EPCR:
2626     _registers.__epcr = value;
2627     return;
2628   }
2629   _LIBUNWIND_ABORT("unsupported or1k register");
2630 }
2631 
validFloatRegister(int) const2632 inline bool Registers_or1k::validFloatRegister(int /* regNum */) const {
2633   return false;
2634 }
2635 
getFloatRegister(int) const2636 inline double Registers_or1k::getFloatRegister(int /* regNum */) const {
2637   _LIBUNWIND_ABORT("or1k float support not implemented");
2638 }
2639 
setFloatRegister(int,double)2640 inline void Registers_or1k::setFloatRegister(int /* regNum */,
2641                                              double /* value */) {
2642   _LIBUNWIND_ABORT("or1k float support not implemented");
2643 }
2644 
validVectorRegister(int) const2645 inline bool Registers_or1k::validVectorRegister(int /* regNum */) const {
2646   return false;
2647 }
2648 
getVectorRegister(int) const2649 inline v128 Registers_or1k::getVectorRegister(int /* regNum */) const {
2650   _LIBUNWIND_ABORT("or1k vector support not implemented");
2651 }
2652 
setVectorRegister(int,v128)2653 inline void Registers_or1k::setVectorRegister(int /* regNum */, v128 /* value */) {
2654   _LIBUNWIND_ABORT("or1k vector support not implemented");
2655 }
2656 
getRegisterName(int regNum)2657 inline const char *Registers_or1k::getRegisterName(int regNum) {
2658   switch (regNum) {
2659   case UNW_OR1K_R0:
2660     return "r0";
2661   case UNW_OR1K_R1:
2662     return "r1";
2663   case UNW_OR1K_R2:
2664     return "r2";
2665   case UNW_OR1K_R3:
2666     return "r3";
2667   case UNW_OR1K_R4:
2668     return "r4";
2669   case UNW_OR1K_R5:
2670     return "r5";
2671   case UNW_OR1K_R6:
2672     return "r6";
2673   case UNW_OR1K_R7:
2674     return "r7";
2675   case UNW_OR1K_R8:
2676     return "r8";
2677   case UNW_OR1K_R9:
2678     return "r9";
2679   case UNW_OR1K_R10:
2680     return "r10";
2681   case UNW_OR1K_R11:
2682     return "r11";
2683   case UNW_OR1K_R12:
2684     return "r12";
2685   case UNW_OR1K_R13:
2686     return "r13";
2687   case UNW_OR1K_R14:
2688     return "r14";
2689   case UNW_OR1K_R15:
2690     return "r15";
2691   case UNW_OR1K_R16:
2692     return "r16";
2693   case UNW_OR1K_R17:
2694     return "r17";
2695   case UNW_OR1K_R18:
2696     return "r18";
2697   case UNW_OR1K_R19:
2698     return "r19";
2699   case UNW_OR1K_R20:
2700     return "r20";
2701   case UNW_OR1K_R21:
2702     return "r21";
2703   case UNW_OR1K_R22:
2704     return "r22";
2705   case UNW_OR1K_R23:
2706     return "r23";
2707   case UNW_OR1K_R24:
2708     return "r24";
2709   case UNW_OR1K_R25:
2710     return "r25";
2711   case UNW_OR1K_R26:
2712     return "r26";
2713   case UNW_OR1K_R27:
2714     return "r27";
2715   case UNW_OR1K_R28:
2716     return "r28";
2717   case UNW_OR1K_R29:
2718     return "r29";
2719   case UNW_OR1K_R30:
2720     return "r30";
2721   case UNW_OR1K_R31:
2722     return "r31";
2723   case UNW_OR1K_EPCR:
2724     return "EPCR";
2725   default:
2726     return "unknown register";
2727   }
2728 
2729 }
2730 #endif // _LIBUNWIND_TARGET_OR1K
2731 
2732 #if defined(_LIBUNWIND_TARGET_MIPS_O32)
2733 /// Registers_mips_o32 holds the register state of a thread in a 32-bit MIPS
2734 /// process.
2735 class _LIBUNWIND_HIDDEN Registers_mips_o32 {
2736 public:
2737   Registers_mips_o32();
2738   Registers_mips_o32(const void *registers);
2739 
2740   bool        validRegister(int num) const;
2741   uint32_t    getRegister(int num) const;
2742   void        setRegister(int num, uint32_t value);
2743   bool        validFloatRegister(int num) const;
2744   double      getFloatRegister(int num) const;
2745   void        setFloatRegister(int num, double value);
2746   bool        validVectorRegister(int num) const;
2747   v128        getVectorRegister(int num) const;
2748   void        setVectorRegister(int num, v128 value);
2749   static const char *getRegisterName(int num);
2750   void        jumpto();
lastDwarfRegNum()2751   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
getArch()2752   static int  getArch() { return REGISTERS_MIPS_O32; }
2753 
getSP() const2754   uint32_t  getSP() const         { return _registers.__r[29]; }
setSP(uint32_t value)2755   void      setSP(uint32_t value) { _registers.__r[29] = value; }
getIP() const2756   uint32_t  getIP() const         { return _registers.__pc; }
setIP(uint32_t value)2757   void      setIP(uint32_t value) { _registers.__pc = value; }
2758 
2759 private:
2760   struct mips_o32_thread_state_t {
2761     uint32_t __r[32];
2762     uint32_t __pc;
2763     uint32_t __hi;
2764     uint32_t __lo;
2765   };
2766 
2767   mips_o32_thread_state_t _registers;
2768 #ifdef __mips_hard_float
2769   /// O32 with 32-bit floating point registers only uses half of this
2770   /// space.  However, using the same layout for 32-bit vs 64-bit
2771   /// floating point registers results in a single context size for
2772   /// O32 with hard float.
2773   uint32_t _padding;
2774   double _floats[32];
2775 #endif
2776 };
2777 
Registers_mips_o32(const void * registers)2778 inline Registers_mips_o32::Registers_mips_o32(const void *registers) {
2779   static_assert((check_fit<Registers_mips_o32, unw_context_t>::does_fit),
2780                 "mips_o32 registers do not fit into unw_context_t");
2781   memcpy(&_registers, static_cast<const uint8_t *>(registers),
2782          sizeof(_registers));
2783 }
2784 
Registers_mips_o32()2785 inline Registers_mips_o32::Registers_mips_o32() {
2786   memset(&_registers, 0, sizeof(_registers));
2787 }
2788 
validRegister(int regNum) const2789 inline bool Registers_mips_o32::validRegister(int regNum) const {
2790   if (regNum == UNW_REG_IP)
2791     return true;
2792   if (regNum == UNW_REG_SP)
2793     return true;
2794   if (regNum < 0)
2795     return false;
2796   if (regNum <= UNW_MIPS_R31)
2797     return true;
2798 #if __mips_isa_rev != 6
2799   if (regNum == UNW_MIPS_HI)
2800     return true;
2801   if (regNum == UNW_MIPS_LO)
2802     return true;
2803 #endif
2804 #if defined(__mips_hard_float) && __mips_fpr == 32
2805   if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
2806     return true;
2807 #endif
2808   // FIXME: DSP accumulator registers, MSA registers
2809   return false;
2810 }
2811 
getRegister(int regNum) const2812 inline uint32_t Registers_mips_o32::getRegister(int regNum) const {
2813   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
2814     return _registers.__r[regNum - UNW_MIPS_R0];
2815 #if defined(__mips_hard_float) && __mips_fpr == 32
2816   if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
2817     uint32_t *p;
2818 
2819     if (regNum % 2 == 0)
2820       p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
2821     else
2822       p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
2823     return *p;
2824   }
2825 #endif
2826 
2827   switch (regNum) {
2828   case UNW_REG_IP:
2829     return _registers.__pc;
2830   case UNW_REG_SP:
2831     return _registers.__r[29];
2832   case UNW_MIPS_HI:
2833     return _registers.__hi;
2834   case UNW_MIPS_LO:
2835     return _registers.__lo;
2836   }
2837   _LIBUNWIND_ABORT("unsupported mips_o32 register");
2838 }
2839 
setRegister(int regNum,uint32_t value)2840 inline void Registers_mips_o32::setRegister(int regNum, uint32_t value) {
2841   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
2842     _registers.__r[regNum - UNW_MIPS_R0] = value;
2843     return;
2844   }
2845 #if defined(__mips_hard_float) && __mips_fpr == 32
2846   if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
2847     uint32_t *p;
2848 
2849     if (regNum % 2 == 0)
2850       p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
2851     else
2852       p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
2853     *p = value;
2854     return;
2855   }
2856 #endif
2857 
2858   switch (regNum) {
2859   case UNW_REG_IP:
2860     _registers.__pc = value;
2861     return;
2862   case UNW_REG_SP:
2863     _registers.__r[29] = value;
2864     return;
2865   case UNW_MIPS_HI:
2866     _registers.__hi = value;
2867     return;
2868   case UNW_MIPS_LO:
2869     _registers.__lo = value;
2870     return;
2871   }
2872   _LIBUNWIND_ABORT("unsupported mips_o32 register");
2873 }
2874 
validFloatRegister(int regNum) const2875 inline bool Registers_mips_o32::validFloatRegister(int regNum) const {
2876 #if defined(__mips_hard_float) && __mips_fpr == 64
2877   if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
2878     return true;
2879 #else
2880   (void)regNum;
2881 #endif
2882   return false;
2883 }
2884 
getFloatRegister(int regNum) const2885 inline double Registers_mips_o32::getFloatRegister(int regNum) const {
2886 #if defined(__mips_hard_float) && __mips_fpr == 64
2887   assert(validFloatRegister(regNum));
2888   return _floats[regNum - UNW_MIPS_F0];
2889 #else
2890   (void)regNum;
2891   _LIBUNWIND_ABORT("mips_o32 float support not implemented");
2892 #endif
2893 }
2894 
setFloatRegister(int regNum,double value)2895 inline void Registers_mips_o32::setFloatRegister(int regNum,
2896                                                  double value) {
2897 #if defined(__mips_hard_float) && __mips_fpr == 64
2898   assert(validFloatRegister(regNum));
2899   _floats[regNum - UNW_MIPS_F0] = value;
2900 #else
2901   (void)regNum;
2902   (void)value;
2903   _LIBUNWIND_ABORT("mips_o32 float support not implemented");
2904 #endif
2905 }
2906 
validVectorRegister(int) const2907 inline bool Registers_mips_o32::validVectorRegister(int /* regNum */) const {
2908   return false;
2909 }
2910 
getVectorRegister(int) const2911 inline v128 Registers_mips_o32::getVectorRegister(int /* regNum */) const {
2912   _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
2913 }
2914 
setVectorRegister(int,v128)2915 inline void Registers_mips_o32::setVectorRegister(int /* regNum */, v128 /* value */) {
2916   _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
2917 }
2918 
getRegisterName(int regNum)2919 inline const char *Registers_mips_o32::getRegisterName(int regNum) {
2920   switch (regNum) {
2921   case UNW_MIPS_R0:
2922     return "$0";
2923   case UNW_MIPS_R1:
2924     return "$1";
2925   case UNW_MIPS_R2:
2926     return "$2";
2927   case UNW_MIPS_R3:
2928     return "$3";
2929   case UNW_MIPS_R4:
2930     return "$4";
2931   case UNW_MIPS_R5:
2932     return "$5";
2933   case UNW_MIPS_R6:
2934     return "$6";
2935   case UNW_MIPS_R7:
2936     return "$7";
2937   case UNW_MIPS_R8:
2938     return "$8";
2939   case UNW_MIPS_R9:
2940     return "$9";
2941   case UNW_MIPS_R10:
2942     return "$10";
2943   case UNW_MIPS_R11:
2944     return "$11";
2945   case UNW_MIPS_R12:
2946     return "$12";
2947   case UNW_MIPS_R13:
2948     return "$13";
2949   case UNW_MIPS_R14:
2950     return "$14";
2951   case UNW_MIPS_R15:
2952     return "$15";
2953   case UNW_MIPS_R16:
2954     return "$16";
2955   case UNW_MIPS_R17:
2956     return "$17";
2957   case UNW_MIPS_R18:
2958     return "$18";
2959   case UNW_MIPS_R19:
2960     return "$19";
2961   case UNW_MIPS_R20:
2962     return "$20";
2963   case UNW_MIPS_R21:
2964     return "$21";
2965   case UNW_MIPS_R22:
2966     return "$22";
2967   case UNW_MIPS_R23:
2968     return "$23";
2969   case UNW_MIPS_R24:
2970     return "$24";
2971   case UNW_MIPS_R25:
2972     return "$25";
2973   case UNW_MIPS_R26:
2974     return "$26";
2975   case UNW_MIPS_R27:
2976     return "$27";
2977   case UNW_MIPS_R28:
2978     return "$28";
2979   case UNW_MIPS_R29:
2980     return "$29";
2981   case UNW_MIPS_R30:
2982     return "$30";
2983   case UNW_MIPS_R31:
2984     return "$31";
2985   case UNW_MIPS_F0:
2986     return "$f0";
2987   case UNW_MIPS_F1:
2988     return "$f1";
2989   case UNW_MIPS_F2:
2990     return "$f2";
2991   case UNW_MIPS_F3:
2992     return "$f3";
2993   case UNW_MIPS_F4:
2994     return "$f4";
2995   case UNW_MIPS_F5:
2996     return "$f5";
2997   case UNW_MIPS_F6:
2998     return "$f6";
2999   case UNW_MIPS_F7:
3000     return "$f7";
3001   case UNW_MIPS_F8:
3002     return "$f8";
3003   case UNW_MIPS_F9:
3004     return "$f9";
3005   case UNW_MIPS_F10:
3006     return "$f10";
3007   case UNW_MIPS_F11:
3008     return "$f11";
3009   case UNW_MIPS_F12:
3010     return "$f12";
3011   case UNW_MIPS_F13:
3012     return "$f13";
3013   case UNW_MIPS_F14:
3014     return "$f14";
3015   case UNW_MIPS_F15:
3016     return "$f15";
3017   case UNW_MIPS_F16:
3018     return "$f16";
3019   case UNW_MIPS_F17:
3020     return "$f17";
3021   case UNW_MIPS_F18:
3022     return "$f18";
3023   case UNW_MIPS_F19:
3024     return "$f19";
3025   case UNW_MIPS_F20:
3026     return "$f20";
3027   case UNW_MIPS_F21:
3028     return "$f21";
3029   case UNW_MIPS_F22:
3030     return "$f22";
3031   case UNW_MIPS_F23:
3032     return "$f23";
3033   case UNW_MIPS_F24:
3034     return "$f24";
3035   case UNW_MIPS_F25:
3036     return "$f25";
3037   case UNW_MIPS_F26:
3038     return "$f26";
3039   case UNW_MIPS_F27:
3040     return "$f27";
3041   case UNW_MIPS_F28:
3042     return "$f28";
3043   case UNW_MIPS_F29:
3044     return "$f29";
3045   case UNW_MIPS_F30:
3046     return "$f30";
3047   case UNW_MIPS_F31:
3048     return "$f31";
3049   case UNW_MIPS_HI:
3050     return "$hi";
3051   case UNW_MIPS_LO:
3052     return "$lo";
3053   default:
3054     return "unknown register";
3055   }
3056 }
3057 #endif // _LIBUNWIND_TARGET_MIPS_O32
3058 
3059 #if defined(_LIBUNWIND_TARGET_MIPS_NEWABI)
3060 /// Registers_mips_newabi holds the register state of a thread in a
3061 /// MIPS process using NEWABI (the N32 or N64 ABIs).
3062 class _LIBUNWIND_HIDDEN Registers_mips_newabi {
3063 public:
3064   Registers_mips_newabi();
3065   Registers_mips_newabi(const void *registers);
3066 
3067   bool        validRegister(int num) const;
3068   uint64_t    getRegister(int num) const;
3069   void        setRegister(int num, uint64_t value);
3070   bool        validFloatRegister(int num) const;
3071   double      getFloatRegister(int num) const;
3072   void        setFloatRegister(int num, double value);
3073   bool        validVectorRegister(int num) const;
3074   v128        getVectorRegister(int num) const;
3075   void        setVectorRegister(int num, v128 value);
3076   static const char *getRegisterName(int num);
3077   void        jumpto();
lastDwarfRegNum()3078   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
getArch()3079   static int  getArch() { return REGISTERS_MIPS_NEWABI; }
3080 
getSP() const3081   uint64_t  getSP() const         { return _registers.__r[29]; }
setSP(uint64_t value)3082   void      setSP(uint64_t value) { _registers.__r[29] = value; }
getIP() const3083   uint64_t  getIP() const         { return _registers.__pc; }
setIP(uint64_t value)3084   void      setIP(uint64_t value) { _registers.__pc = value; }
3085 
3086 private:
3087   struct mips_newabi_thread_state_t {
3088     uint64_t __r[32];
3089     uint64_t __pc;
3090     uint64_t __hi;
3091     uint64_t __lo;
3092   };
3093 
3094   mips_newabi_thread_state_t _registers;
3095 #ifdef __mips_hard_float
3096   double _floats[32];
3097 #endif
3098 };
3099 
Registers_mips_newabi(const void * registers)3100 inline Registers_mips_newabi::Registers_mips_newabi(const void *registers) {
3101   static_assert((check_fit<Registers_mips_newabi, unw_context_t>::does_fit),
3102                 "mips_newabi registers do not fit into unw_context_t");
3103   memcpy(&_registers, static_cast<const uint8_t *>(registers),
3104          sizeof(_registers));
3105 }
3106 
Registers_mips_newabi()3107 inline Registers_mips_newabi::Registers_mips_newabi() {
3108   memset(&_registers, 0, sizeof(_registers));
3109 }
3110 
validRegister(int regNum) const3111 inline bool Registers_mips_newabi::validRegister(int regNum) const {
3112   if (regNum == UNW_REG_IP)
3113     return true;
3114   if (regNum == UNW_REG_SP)
3115     return true;
3116   if (regNum < 0)
3117     return false;
3118   if (regNum <= UNW_MIPS_R31)
3119     return true;
3120 #if __mips_isa_rev != 6
3121   if (regNum == UNW_MIPS_HI)
3122     return true;
3123   if (regNum == UNW_MIPS_LO)
3124     return true;
3125 #endif
3126   // FIXME: Hard float, DSP accumulator registers, MSA registers
3127   return false;
3128 }
3129 
getRegister(int regNum) const3130 inline uint64_t Registers_mips_newabi::getRegister(int regNum) const {
3131   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
3132     return _registers.__r[regNum - UNW_MIPS_R0];
3133 
3134   switch (regNum) {
3135   case UNW_REG_IP:
3136     return _registers.__pc;
3137   case UNW_REG_SP:
3138     return _registers.__r[29];
3139   case UNW_MIPS_HI:
3140     return _registers.__hi;
3141   case UNW_MIPS_LO:
3142     return _registers.__lo;
3143   }
3144   _LIBUNWIND_ABORT("unsupported mips_newabi register");
3145 }
3146 
setRegister(int regNum,uint64_t value)3147 inline void Registers_mips_newabi::setRegister(int regNum, uint64_t value) {
3148   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
3149     _registers.__r[regNum - UNW_MIPS_R0] = value;
3150     return;
3151   }
3152 
3153   switch (regNum) {
3154   case UNW_REG_IP:
3155     _registers.__pc = value;
3156     return;
3157   case UNW_REG_SP:
3158     _registers.__r[29] = value;
3159     return;
3160   case UNW_MIPS_HI:
3161     _registers.__hi = value;
3162     return;
3163   case UNW_MIPS_LO:
3164     _registers.__lo = value;
3165     return;
3166   }
3167   _LIBUNWIND_ABORT("unsupported mips_newabi register");
3168 }
3169 
validFloatRegister(int regNum) const3170 inline bool Registers_mips_newabi::validFloatRegister(int regNum) const {
3171 #ifdef __mips_hard_float
3172   if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
3173     return true;
3174 #else
3175   (void)regNum;
3176 #endif
3177   return false;
3178 }
3179 
getFloatRegister(int regNum) const3180 inline double Registers_mips_newabi::getFloatRegister(int regNum) const {
3181 #ifdef __mips_hard_float
3182   assert(validFloatRegister(regNum));
3183   return _floats[regNum - UNW_MIPS_F0];
3184 #else
3185   (void)regNum;
3186   _LIBUNWIND_ABORT("mips_newabi float support not implemented");
3187 #endif
3188 }
3189 
setFloatRegister(int regNum,double value)3190 inline void Registers_mips_newabi::setFloatRegister(int regNum,
3191                                                     double value) {
3192 #ifdef __mips_hard_float
3193   assert(validFloatRegister(regNum));
3194   _floats[regNum - UNW_MIPS_F0] = value;
3195 #else
3196   (void)regNum;
3197   (void)value;
3198   _LIBUNWIND_ABORT("mips_newabi float support not implemented");
3199 #endif
3200 }
3201 
validVectorRegister(int) const3202 inline bool Registers_mips_newabi::validVectorRegister(int /* regNum */) const {
3203   return false;
3204 }
3205 
getVectorRegister(int) const3206 inline v128 Registers_mips_newabi::getVectorRegister(int /* regNum */) const {
3207   _LIBUNWIND_ABORT("mips_newabi vector support not implemented");
3208 }
3209 
setVectorRegister(int,v128)3210 inline void Registers_mips_newabi::setVectorRegister(int /* regNum */, v128 /* value */) {
3211   _LIBUNWIND_ABORT("mips_newabi vector support not implemented");
3212 }
3213 
getRegisterName(int regNum)3214 inline const char *Registers_mips_newabi::getRegisterName(int regNum) {
3215   switch (regNum) {
3216   case UNW_MIPS_R0:
3217     return "$0";
3218   case UNW_MIPS_R1:
3219     return "$1";
3220   case UNW_MIPS_R2:
3221     return "$2";
3222   case UNW_MIPS_R3:
3223     return "$3";
3224   case UNW_MIPS_R4:
3225     return "$4";
3226   case UNW_MIPS_R5:
3227     return "$5";
3228   case UNW_MIPS_R6:
3229     return "$6";
3230   case UNW_MIPS_R7:
3231     return "$7";
3232   case UNW_MIPS_R8:
3233     return "$8";
3234   case UNW_MIPS_R9:
3235     return "$9";
3236   case UNW_MIPS_R10:
3237     return "$10";
3238   case UNW_MIPS_R11:
3239     return "$11";
3240   case UNW_MIPS_R12:
3241     return "$12";
3242   case UNW_MIPS_R13:
3243     return "$13";
3244   case UNW_MIPS_R14:
3245     return "$14";
3246   case UNW_MIPS_R15:
3247     return "$15";
3248   case UNW_MIPS_R16:
3249     return "$16";
3250   case UNW_MIPS_R17:
3251     return "$17";
3252   case UNW_MIPS_R18:
3253     return "$18";
3254   case UNW_MIPS_R19:
3255     return "$19";
3256   case UNW_MIPS_R20:
3257     return "$20";
3258   case UNW_MIPS_R21:
3259     return "$21";
3260   case UNW_MIPS_R22:
3261     return "$22";
3262   case UNW_MIPS_R23:
3263     return "$23";
3264   case UNW_MIPS_R24:
3265     return "$24";
3266   case UNW_MIPS_R25:
3267     return "$25";
3268   case UNW_MIPS_R26:
3269     return "$26";
3270   case UNW_MIPS_R27:
3271     return "$27";
3272   case UNW_MIPS_R28:
3273     return "$28";
3274   case UNW_MIPS_R29:
3275     return "$29";
3276   case UNW_MIPS_R30:
3277     return "$30";
3278   case UNW_MIPS_R31:
3279     return "$31";
3280   case UNW_MIPS_F0:
3281     return "$f0";
3282   case UNW_MIPS_F1:
3283     return "$f1";
3284   case UNW_MIPS_F2:
3285     return "$f2";
3286   case UNW_MIPS_F3:
3287     return "$f3";
3288   case UNW_MIPS_F4:
3289     return "$f4";
3290   case UNW_MIPS_F5:
3291     return "$f5";
3292   case UNW_MIPS_F6:
3293     return "$f6";
3294   case UNW_MIPS_F7:
3295     return "$f7";
3296   case UNW_MIPS_F8:
3297     return "$f8";
3298   case UNW_MIPS_F9:
3299     return "$f9";
3300   case UNW_MIPS_F10:
3301     return "$f10";
3302   case UNW_MIPS_F11:
3303     return "$f11";
3304   case UNW_MIPS_F12:
3305     return "$f12";
3306   case UNW_MIPS_F13:
3307     return "$f13";
3308   case UNW_MIPS_F14:
3309     return "$f14";
3310   case UNW_MIPS_F15:
3311     return "$f15";
3312   case UNW_MIPS_F16:
3313     return "$f16";
3314   case UNW_MIPS_F17:
3315     return "$f17";
3316   case UNW_MIPS_F18:
3317     return "$f18";
3318   case UNW_MIPS_F19:
3319     return "$f19";
3320   case UNW_MIPS_F20:
3321     return "$f20";
3322   case UNW_MIPS_F21:
3323     return "$f21";
3324   case UNW_MIPS_F22:
3325     return "$f22";
3326   case UNW_MIPS_F23:
3327     return "$f23";
3328   case UNW_MIPS_F24:
3329     return "$f24";
3330   case UNW_MIPS_F25:
3331     return "$f25";
3332   case UNW_MIPS_F26:
3333     return "$f26";
3334   case UNW_MIPS_F27:
3335     return "$f27";
3336   case UNW_MIPS_F28:
3337     return "$f28";
3338   case UNW_MIPS_F29:
3339     return "$f29";
3340   case UNW_MIPS_F30:
3341     return "$f30";
3342   case UNW_MIPS_F31:
3343     return "$f31";
3344   case UNW_MIPS_HI:
3345     return "$hi";
3346   case UNW_MIPS_LO:
3347     return "$lo";
3348   default:
3349     return "unknown register";
3350   }
3351 }
3352 #endif // _LIBUNWIND_TARGET_MIPS_NEWABI
3353 
3354 #if defined(_LIBUNWIND_TARGET_SPARC)
3355 /// Registers_sparc holds the register state of a thread in a 32-bit Sparc
3356 /// process.
3357 class _LIBUNWIND_HIDDEN Registers_sparc {
3358 public:
3359   Registers_sparc();
3360   Registers_sparc(const void *registers);
3361 
3362   bool        validRegister(int num) const;
3363   uint32_t    getRegister(int num) const;
3364   void        setRegister(int num, uint32_t value);
3365   bool        validFloatRegister(int num) const;
3366   double      getFloatRegister(int num) const;
3367   void        setFloatRegister(int num, double value);
3368   bool        validVectorRegister(int num) const;
3369   v128        getVectorRegister(int num) const;
3370   void        setVectorRegister(int num, v128 value);
3371   static const char *getRegisterName(int num);
3372   void        jumpto();
lastDwarfRegNum()3373   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC; }
getArch()3374   static int  getArch() { return REGISTERS_SPARC; }
3375 
getSP() const3376   uint64_t  getSP() const         { return _registers.__regs[UNW_SPARC_O6]; }
setSP(uint32_t value)3377   void      setSP(uint32_t value) { _registers.__regs[UNW_SPARC_O6] = value; }
getIP() const3378   uint64_t  getIP() const         { return _registers.__regs[UNW_SPARC_O7]; }
setIP(uint32_t value)3379   void      setIP(uint32_t value) { _registers.__regs[UNW_SPARC_O7] = value; }
3380 
3381 private:
3382   struct sparc_thread_state_t {
3383     unsigned int __regs[32];
3384   };
3385 
3386   sparc_thread_state_t _registers;
3387 };
3388 
Registers_sparc(const void * registers)3389 inline Registers_sparc::Registers_sparc(const void *registers) {
3390   static_assert((check_fit<Registers_sparc, unw_context_t>::does_fit),
3391                 "sparc registers do not fit into unw_context_t");
3392   memcpy(&_registers, static_cast<const uint8_t *>(registers),
3393          sizeof(_registers));
3394 }
3395 
Registers_sparc()3396 inline Registers_sparc::Registers_sparc() {
3397   memset(&_registers, 0, sizeof(_registers));
3398 }
3399 
validRegister(int regNum) const3400 inline bool Registers_sparc::validRegister(int regNum) const {
3401   if (regNum == UNW_REG_IP)
3402     return true;
3403   if (regNum == UNW_REG_SP)
3404     return true;
3405   if (regNum < 0)
3406     return false;
3407   if (regNum <= UNW_SPARC_I7)
3408     return true;
3409   return false;
3410 }
3411 
getRegister(int regNum) const3412 inline uint32_t Registers_sparc::getRegister(int regNum) const {
3413   if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) {
3414     return _registers.__regs[regNum];
3415   }
3416 
3417   switch (regNum) {
3418   case UNW_REG_IP:
3419     return _registers.__regs[UNW_SPARC_O7];
3420   case UNW_REG_SP:
3421     return _registers.__regs[UNW_SPARC_O6];
3422   }
3423   _LIBUNWIND_ABORT("unsupported sparc register");
3424 }
3425 
setRegister(int regNum,uint32_t value)3426 inline void Registers_sparc::setRegister(int regNum, uint32_t value) {
3427   if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) {
3428     _registers.__regs[regNum] = value;
3429     return;
3430   }
3431 
3432   switch (regNum) {
3433   case UNW_REG_IP:
3434     _registers.__regs[UNW_SPARC_O7] = value;
3435     return;
3436   case UNW_REG_SP:
3437     _registers.__regs[UNW_SPARC_O6] = value;
3438     return;
3439   }
3440   _LIBUNWIND_ABORT("unsupported sparc register");
3441 }
3442 
validFloatRegister(int) const3443 inline bool Registers_sparc::validFloatRegister(int) const { return false; }
3444 
getFloatRegister(int) const3445 inline double Registers_sparc::getFloatRegister(int) const {
3446   _LIBUNWIND_ABORT("no Sparc float registers");
3447 }
3448 
setFloatRegister(int,double)3449 inline void Registers_sparc::setFloatRegister(int, double) {
3450   _LIBUNWIND_ABORT("no Sparc float registers");
3451 }
3452 
validVectorRegister(int) const3453 inline bool Registers_sparc::validVectorRegister(int) const { return false; }
3454 
getVectorRegister(int) const3455 inline v128 Registers_sparc::getVectorRegister(int) const {
3456   _LIBUNWIND_ABORT("no Sparc vector registers");
3457 }
3458 
setVectorRegister(int,v128)3459 inline void Registers_sparc::setVectorRegister(int, v128) {
3460   _LIBUNWIND_ABORT("no Sparc vector registers");
3461 }
3462 
getRegisterName(int regNum)3463 inline const char *Registers_sparc::getRegisterName(int regNum) {
3464   switch (regNum) {
3465   case UNW_REG_IP:
3466     return "pc";
3467   case UNW_SPARC_G0:
3468     return "g0";
3469   case UNW_SPARC_G1:
3470     return "g1";
3471   case UNW_SPARC_G2:
3472     return "g2";
3473   case UNW_SPARC_G3:
3474     return "g3";
3475   case UNW_SPARC_G4:
3476     return "g4";
3477   case UNW_SPARC_G5:
3478     return "g5";
3479   case UNW_SPARC_G6:
3480     return "g6";
3481   case UNW_SPARC_G7:
3482     return "g7";
3483   case UNW_SPARC_O0:
3484     return "o0";
3485   case UNW_SPARC_O1:
3486     return "o1";
3487   case UNW_SPARC_O2:
3488     return "o2";
3489   case UNW_SPARC_O3:
3490     return "o3";
3491   case UNW_SPARC_O4:
3492     return "o4";
3493   case UNW_SPARC_O5:
3494     return "o5";
3495   case UNW_REG_SP:
3496   case UNW_SPARC_O6:
3497     return "sp";
3498   case UNW_SPARC_O7:
3499     return "o7";
3500   case UNW_SPARC_L0:
3501     return "l0";
3502   case UNW_SPARC_L1:
3503     return "l1";
3504   case UNW_SPARC_L2:
3505     return "l2";
3506   case UNW_SPARC_L3:
3507     return "l3";
3508   case UNW_SPARC_L4:
3509     return "l4";
3510   case UNW_SPARC_L5:
3511     return "l5";
3512   case UNW_SPARC_L6:
3513     return "l6";
3514   case UNW_SPARC_L7:
3515     return "l7";
3516   case UNW_SPARC_I0:
3517     return "i0";
3518   case UNW_SPARC_I1:
3519     return "i1";
3520   case UNW_SPARC_I2:
3521     return "i2";
3522   case UNW_SPARC_I3:
3523     return "i3";
3524   case UNW_SPARC_I4:
3525     return "i4";
3526   case UNW_SPARC_I5:
3527     return "i5";
3528   case UNW_SPARC_I6:
3529     return "fp";
3530   case UNW_SPARC_I7:
3531     return "i7";
3532   default:
3533     return "unknown register";
3534   }
3535 }
3536 #endif // _LIBUNWIND_TARGET_SPARC
3537 
3538 #if defined(_LIBUNWIND_TARGET_HEXAGON)
3539 /// Registers_hexagon holds the register state of a thread in a Hexagon QDSP6
3540 /// process.
3541 class _LIBUNWIND_HIDDEN Registers_hexagon {
3542 public:
3543   Registers_hexagon();
3544   Registers_hexagon(const void *registers);
3545 
3546   bool        validRegister(int num) const;
3547   uint32_t    getRegister(int num) const;
3548   void        setRegister(int num, uint32_t value);
3549   bool        validFloatRegister(int num) const;
3550   double      getFloatRegister(int num) const;
3551   void        setFloatRegister(int num, double value);
3552   bool        validVectorRegister(int num) const;
3553   v128        getVectorRegister(int num) const;
3554   void        setVectorRegister(int num, v128 value);
3555   const char *getRegisterName(int num);
3556   void        jumpto();
lastDwarfRegNum()3557   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON; }
getArch()3558   static int  getArch() { return REGISTERS_HEXAGON; }
3559 
getSP() const3560   uint32_t  getSP() const         { return _registers.__r[UNW_HEXAGON_R29]; }
setSP(uint32_t value)3561   void      setSP(uint32_t value) { _registers.__r[UNW_HEXAGON_R29] = value; }
getIP() const3562   uint32_t  getIP() const         { return _registers.__r[UNW_HEXAGON_PC]; }
setIP(uint32_t value)3563   void      setIP(uint32_t value) { _registers.__r[UNW_HEXAGON_PC] = value; }
3564 
3565 private:
3566   struct hexagon_thread_state_t {
3567     unsigned int __r[35];
3568   };
3569 
3570   hexagon_thread_state_t _registers;
3571 };
3572 
Registers_hexagon(const void * registers)3573 inline Registers_hexagon::Registers_hexagon(const void *registers) {
3574   static_assert((check_fit<Registers_hexagon, unw_context_t>::does_fit),
3575                 "hexagon registers do not fit into unw_context_t");
3576   memcpy(&_registers, static_cast<const uint8_t *>(registers),
3577          sizeof(_registers));
3578 }
3579 
Registers_hexagon()3580 inline Registers_hexagon::Registers_hexagon() {
3581   memset(&_registers, 0, sizeof(_registers));
3582 }
3583 
validRegister(int regNum) const3584 inline bool Registers_hexagon::validRegister(int regNum) const {
3585   if (regNum <= UNW_HEXAGON_R31)
3586     return true;
3587   return false;
3588 }
3589 
getRegister(int regNum) const3590 inline uint32_t Registers_hexagon::getRegister(int regNum) const {
3591   if (regNum >= UNW_HEXAGON_R0 && regNum <= UNW_HEXAGON_R31)
3592     return _registers.__r[regNum - UNW_HEXAGON_R0];
3593 
3594   switch (regNum) {
3595   case UNW_REG_IP:
3596     return _registers.__r[UNW_HEXAGON_PC];
3597   case UNW_REG_SP:
3598     return _registers.__r[UNW_HEXAGON_R29];
3599   }
3600   _LIBUNWIND_ABORT("unsupported hexagon register");
3601 }
3602 
setRegister(int regNum,uint32_t value)3603 inline void Registers_hexagon::setRegister(int regNum, uint32_t value) {
3604   if (regNum >= UNW_HEXAGON_R0 && regNum <= UNW_HEXAGON_R31) {
3605     _registers.__r[regNum - UNW_HEXAGON_R0] = value;
3606     return;
3607   }
3608 
3609   switch (regNum) {
3610   case UNW_REG_IP:
3611     _registers.__r[UNW_HEXAGON_PC] = value;
3612     return;
3613   case UNW_REG_SP:
3614     _registers.__r[UNW_HEXAGON_R29] = value;
3615     return;
3616   }
3617   _LIBUNWIND_ABORT("unsupported hexagon register");
3618 }
3619 
validFloatRegister(int) const3620 inline bool Registers_hexagon::validFloatRegister(int /* regNum */) const {
3621   return false;
3622 }
3623 
getFloatRegister(int) const3624 inline double Registers_hexagon::getFloatRegister(int /* regNum */) const {
3625   _LIBUNWIND_ABORT("hexagon float support not implemented");
3626 }
3627 
setFloatRegister(int,double)3628 inline void Registers_hexagon::setFloatRegister(int /* regNum */,
3629                                              double /* value */) {
3630   _LIBUNWIND_ABORT("hexagon float support not implemented");
3631 }
3632 
validVectorRegister(int) const3633 inline bool Registers_hexagon::validVectorRegister(int /* regNum */) const {
3634   return false;
3635 }
3636 
getVectorRegister(int) const3637 inline v128 Registers_hexagon::getVectorRegister(int /* regNum */) const {
3638   _LIBUNWIND_ABORT("hexagon vector support not implemented");
3639 }
3640 
setVectorRegister(int,v128)3641 inline void Registers_hexagon::setVectorRegister(int /* regNum */, v128 /* value */) {
3642   _LIBUNWIND_ABORT("hexagon vector support not implemented");
3643 }
3644 
getRegisterName(int regNum)3645 inline const char *Registers_hexagon::getRegisterName(int regNum) {
3646   switch (regNum) {
3647   case UNW_HEXAGON_R0:
3648     return "r0";
3649   case UNW_HEXAGON_R1:
3650     return "r1";
3651   case UNW_HEXAGON_R2:
3652     return "r2";
3653   case UNW_HEXAGON_R3:
3654     return "r3";
3655   case UNW_HEXAGON_R4:
3656     return "r4";
3657   case UNW_HEXAGON_R5:
3658     return "r5";
3659   case UNW_HEXAGON_R6:
3660     return "r6";
3661   case UNW_HEXAGON_R7:
3662     return "r7";
3663   case UNW_HEXAGON_R8:
3664     return "r8";
3665   case UNW_HEXAGON_R9:
3666     return "r9";
3667   case UNW_HEXAGON_R10:
3668     return "r10";
3669   case UNW_HEXAGON_R11:
3670     return "r11";
3671   case UNW_HEXAGON_R12:
3672     return "r12";
3673   case UNW_HEXAGON_R13:
3674     return "r13";
3675   case UNW_HEXAGON_R14:
3676     return "r14";
3677   case UNW_HEXAGON_R15:
3678     return "r15";
3679   case UNW_HEXAGON_R16:
3680     return "r16";
3681   case UNW_HEXAGON_R17:
3682     return "r17";
3683   case UNW_HEXAGON_R18:
3684     return "r18";
3685   case UNW_HEXAGON_R19:
3686     return "r19";
3687   case UNW_HEXAGON_R20:
3688     return "r20";
3689   case UNW_HEXAGON_R21:
3690     return "r21";
3691   case UNW_HEXAGON_R22:
3692     return "r22";
3693   case UNW_HEXAGON_R23:
3694     return "r23";
3695   case UNW_HEXAGON_R24:
3696     return "r24";
3697   case UNW_HEXAGON_R25:
3698     return "r25";
3699   case UNW_HEXAGON_R26:
3700     return "r26";
3701   case UNW_HEXAGON_R27:
3702     return "r27";
3703   case UNW_HEXAGON_R28:
3704     return "r28";
3705   case UNW_HEXAGON_R29:
3706     return "r29";
3707   case UNW_HEXAGON_R30:
3708     return "r30";
3709   case UNW_HEXAGON_R31:
3710     return "r31";
3711   default:
3712     return "unknown register";
3713   }
3714 
3715 }
3716 #endif // _LIBUNWIND_TARGET_HEXAGON
3717 
3718 
3719 #if defined(_LIBUNWIND_TARGET_RISCV)
3720 /// Registers_riscv holds the register state of a thread in a 64-bit RISC-V
3721 /// process.
3722 class _LIBUNWIND_HIDDEN Registers_riscv {
3723 public:
3724   Registers_riscv();
3725   Registers_riscv(const void *registers);
3726 
3727   bool        validRegister(int num) const;
3728   uint64_t    getRegister(int num) const;
3729   void        setRegister(int num, uint64_t value);
3730   bool        validFloatRegister(int num) const;
3731   double      getFloatRegister(int num) const;
3732   void        setFloatRegister(int num, double value);
3733   bool        validVectorRegister(int num) const;
3734   v128        getVectorRegister(int num) const;
3735   void        setVectorRegister(int num, v128 value);
3736   static const char *getRegisterName(int num);
3737   void        jumpto();
lastDwarfRegNum()3738   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV; }
getArch()3739   static int  getArch() { return REGISTERS_RISCV; }
3740 
getSP() const3741   uint64_t  getSP() const         { return _registers[2]; }
setSP(uint64_t value)3742   void      setSP(uint64_t value) { _registers[2] = value; }
getIP() const3743   uint64_t  getIP() const         { return _registers[0]; }
setIP(uint64_t value)3744   void      setIP(uint64_t value) { _registers[0] = value; }
3745 
3746 private:
3747   // _registers[0] holds the pc
3748   uint64_t _registers[32];
3749   double   _floats[32];
3750 };
3751 
Registers_riscv(const void * registers)3752 inline Registers_riscv::Registers_riscv(const void *registers) {
3753   static_assert((check_fit<Registers_riscv, unw_context_t>::does_fit),
3754                 "riscv registers do not fit into unw_context_t");
3755   memcpy(&_registers, registers, sizeof(_registers));
3756   static_assert(sizeof(_registers) == 0x100,
3757                 "expected float registers to be at offset 256");
3758   memcpy(_floats,
3759          static_cast<const uint8_t *>(registers) + sizeof(_registers),
3760          sizeof(_floats));
3761 }
3762 
Registers_riscv()3763 inline Registers_riscv::Registers_riscv() {
3764   memset(&_registers, 0, sizeof(_registers));
3765   memset(&_floats, 0, sizeof(_floats));
3766 }
3767 
validRegister(int regNum) const3768 inline bool Registers_riscv::validRegister(int regNum) const {
3769   if (regNum == UNW_REG_IP)
3770     return true;
3771   if (regNum == UNW_REG_SP)
3772     return true;
3773   if (regNum < 0)
3774     return false;
3775   if (regNum > UNW_RISCV_F31)
3776     return false;
3777   return true;
3778 }
3779 
getRegister(int regNum) const3780 inline uint64_t Registers_riscv::getRegister(int regNum) const {
3781   if (regNum == UNW_REG_IP)
3782     return _registers[0];
3783   if (regNum == UNW_REG_SP)
3784     return _registers[2];
3785   if (regNum == UNW_RISCV_X0)
3786     return 0;
3787   if ((regNum > 0) && (regNum < 32))
3788     return _registers[regNum];
3789   _LIBUNWIND_ABORT("unsupported riscv register");
3790 }
3791 
setRegister(int regNum,uint64_t value)3792 inline void Registers_riscv::setRegister(int regNum, uint64_t value) {
3793   if (regNum == UNW_REG_IP)
3794     _registers[0] = value;
3795   else if (regNum == UNW_REG_SP)
3796     _registers[2] = value;
3797   else if (regNum == UNW_RISCV_X0)
3798     /* x0 is hardwired to zero */
3799     return;
3800   else if ((regNum > 0) && (regNum < 32))
3801     _registers[regNum] = value;
3802   else
3803     _LIBUNWIND_ABORT("unsupported riscv register");
3804 }
3805 
getRegisterName(int regNum)3806 inline const char *Registers_riscv::getRegisterName(int regNum) {
3807   switch (regNum) {
3808   case UNW_REG_IP:
3809     return "pc";
3810   case UNW_REG_SP:
3811     return "sp";
3812   case UNW_RISCV_X0:
3813     return "zero";
3814   case UNW_RISCV_X1:
3815     return "ra";
3816   case UNW_RISCV_X2:
3817     return "sp";
3818   case UNW_RISCV_X3:
3819     return "gp";
3820   case UNW_RISCV_X4:
3821     return "tp";
3822   case UNW_RISCV_X5:
3823     return "t0";
3824   case UNW_RISCV_X6:
3825     return "t1";
3826   case UNW_RISCV_X7:
3827     return "t2";
3828   case UNW_RISCV_X8:
3829     return "s0";
3830   case UNW_RISCV_X9:
3831     return "s1";
3832   case UNW_RISCV_X10:
3833     return "a0";
3834   case UNW_RISCV_X11:
3835     return "a1";
3836   case UNW_RISCV_X12:
3837     return "a2";
3838   case UNW_RISCV_X13:
3839     return "a3";
3840   case UNW_RISCV_X14:
3841     return "a4";
3842   case UNW_RISCV_X15:
3843     return "a5";
3844   case UNW_RISCV_X16:
3845     return "a6";
3846   case UNW_RISCV_X17:
3847     return "a7";
3848   case UNW_RISCV_X18:
3849     return "s2";
3850   case UNW_RISCV_X19:
3851     return "s3";
3852   case UNW_RISCV_X20:
3853     return "s4";
3854   case UNW_RISCV_X21:
3855     return "s5";
3856   case UNW_RISCV_X22:
3857     return "s6";
3858   case UNW_RISCV_X23:
3859     return "s7";
3860   case UNW_RISCV_X24:
3861     return "s8";
3862   case UNW_RISCV_X25:
3863     return "s9";
3864   case UNW_RISCV_X26:
3865     return "s10";
3866   case UNW_RISCV_X27:
3867     return "s11";
3868   case UNW_RISCV_X28:
3869     return "t3";
3870   case UNW_RISCV_X29:
3871     return "t4";
3872   case UNW_RISCV_X30:
3873     return "t5";
3874   case UNW_RISCV_X31:
3875     return "t6";
3876   case UNW_RISCV_F0:
3877     return "ft0";
3878   case UNW_RISCV_F1:
3879     return "ft1";
3880   case UNW_RISCV_F2:
3881     return "ft2";
3882   case UNW_RISCV_F3:
3883     return "ft3";
3884   case UNW_RISCV_F4:
3885     return "ft4";
3886   case UNW_RISCV_F5:
3887     return "ft5";
3888   case UNW_RISCV_F6:
3889     return "ft6";
3890   case UNW_RISCV_F7:
3891     return "ft7";
3892   case UNW_RISCV_F8:
3893     return "fs0";
3894   case UNW_RISCV_F9:
3895     return "fs1";
3896   case UNW_RISCV_F10:
3897     return "fa0";
3898   case UNW_RISCV_F11:
3899     return "fa1";
3900   case UNW_RISCV_F12:
3901     return "fa2";
3902   case UNW_RISCV_F13:
3903     return "fa3";
3904   case UNW_RISCV_F14:
3905     return "fa4";
3906   case UNW_RISCV_F15:
3907     return "fa5";
3908   case UNW_RISCV_F16:
3909     return "fa6";
3910   case UNW_RISCV_F17:
3911     return "fa7";
3912   case UNW_RISCV_F18:
3913     return "fs2";
3914   case UNW_RISCV_F19:
3915     return "fs3";
3916   case UNW_RISCV_F20:
3917     return "fs4";
3918   case UNW_RISCV_F21:
3919     return "fs5";
3920   case UNW_RISCV_F22:
3921     return "fs6";
3922   case UNW_RISCV_F23:
3923     return "fs7";
3924   case UNW_RISCV_F24:
3925     return "fs8";
3926   case UNW_RISCV_F25:
3927     return "fs9";
3928   case UNW_RISCV_F26:
3929     return "fs10";
3930   case UNW_RISCV_F27:
3931     return "fs11";
3932   case UNW_RISCV_F28:
3933     return "ft8";
3934   case UNW_RISCV_F29:
3935     return "ft9";
3936   case UNW_RISCV_F30:
3937     return "ft10";
3938   case UNW_RISCV_F31:
3939     return "ft11";
3940   default:
3941     return "unknown register";
3942   }
3943 }
3944 
validFloatRegister(int regNum) const3945 inline bool Registers_riscv::validFloatRegister(int regNum) const {
3946   if (regNum < UNW_RISCV_F0)
3947     return false;
3948   if (regNum > UNW_RISCV_F31)
3949     return false;
3950   return true;
3951 }
3952 
getFloatRegister(int regNum) const3953 inline double Registers_riscv::getFloatRegister(int regNum) const {
3954 #if defined(__riscv_flen) && __riscv_flen == 64
3955   assert(validFloatRegister(regNum));
3956   return _floats[regNum - UNW_RISCV_F0];
3957 #else
3958   (void)regNum;
3959   _LIBUNWIND_ABORT("libunwind not built with float support");
3960 #endif
3961 }
3962 
setFloatRegister(int regNum,double value)3963 inline void Registers_riscv::setFloatRegister(int regNum, double value) {
3964 #if defined(__riscv_flen) && __riscv_flen == 64
3965   assert(validFloatRegister(regNum));
3966   _floats[regNum - UNW_RISCV_F0] = value;
3967 #else
3968   (void)regNum;
3969   (void)value;
3970   _LIBUNWIND_ABORT("libunwind not built with float support");
3971 #endif
3972 }
3973 
validVectorRegister(int) const3974 inline bool Registers_riscv::validVectorRegister(int) const {
3975   return false;
3976 }
3977 
getVectorRegister(int) const3978 inline v128 Registers_riscv::getVectorRegister(int) const {
3979   _LIBUNWIND_ABORT("no riscv vector register support yet");
3980 }
3981 
setVectorRegister(int,v128)3982 inline void Registers_riscv::setVectorRegister(int, v128) {
3983   _LIBUNWIND_ABORT("no riscv vector register support yet");
3984 }
3985 #endif // _LIBUNWIND_TARGET_RISCV
3986 } // namespace libunwind
3987 
3988 #endif // __REGISTERS_HPP__
3989