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