1 //===----------------------------- Registers.hpp --------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //
9 //  Models register sets for supported processors.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef __REGISTERS_HPP__
14 #define __REGISTERS_HPP__
15 
16 #include <stdint.h>
17 #include <string.h>
18 
19 #include "libunwind.h"
20 #include "config.h"
21 
22 namespace libunwind {
23 
24 // For emulating 128-bit registers
25 struct v128 { uint32_t vec[4]; };
26 
27 
28 #if defined(_LIBUNWIND_TARGET_I386)
29 /// Registers_x86 holds the register state of a thread in a 32-bit intel
30 /// process.
31 class _LIBUNWIND_HIDDEN Registers_x86 {
32 public:
33   Registers_x86();
34   Registers_x86(const void *registers);
35 
36   bool        validRegister(int num) const;
37   uint32_t    getRegister(int num) const;
38   void        setRegister(int num, uint32_t value);
validFloatRegister(int) const39   bool        validFloatRegister(int) const { return false; }
40   double      getFloatRegister(int num) const;
41   void        setFloatRegister(int num, double value);
validVectorRegister(int) const42   bool        validVectorRegister(int) const { return false; }
43   v128        getVectorRegister(int num) const;
44   void        setVectorRegister(int num, v128 value);
45   const char *getRegisterName(int num);
46   void        jumpto();
lastDwarfRegNum()47   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86; }
48 
getSP() const49   uint32_t  getSP() const          { return _registers.__esp; }
setSP(uint32_t value)50   void      setSP(uint32_t value)  { _registers.__esp = value; }
getIP() const51   uint32_t  getIP() const          { return _registers.__eip; }
setIP(uint32_t value)52   void      setIP(uint32_t value)  { _registers.__eip = value; }
getEBP() const53   uint32_t  getEBP() const         { return _registers.__ebp; }
setEBP(uint32_t value)54   void      setEBP(uint32_t value) { _registers.__ebp = value; }
getEBX() const55   uint32_t  getEBX() const         { return _registers.__ebx; }
setEBX(uint32_t value)56   void      setEBX(uint32_t value) { _registers.__ebx = value; }
getECX() const57   uint32_t  getECX() const         { return _registers.__ecx; }
setECX(uint32_t value)58   void      setECX(uint32_t value) { _registers.__ecx = value; }
getEDX() const59   uint32_t  getEDX() const         { return _registers.__edx; }
setEDX(uint32_t value)60   void      setEDX(uint32_t value) { _registers.__edx = value; }
getESI() const61   uint32_t  getESI() const         { return _registers.__esi; }
setESI(uint32_t value)62   void      setESI(uint32_t value) { _registers.__esi = value; }
getEDI() const63   uint32_t  getEDI() const         { return _registers.__edi; }
setEDI(uint32_t value)64   void      setEDI(uint32_t value) { _registers.__edi = value; }
65 
66 private:
67   struct GPRs {
68     unsigned int __eax;
69     unsigned int __ebx;
70     unsigned int __ecx;
71     unsigned int __edx;
72     unsigned int __edi;
73     unsigned int __esi;
74     unsigned int __ebp;
75     unsigned int __esp;
76     unsigned int __ss;
77     unsigned int __eflags;
78     unsigned int __eip;
79     unsigned int __cs;
80     unsigned int __ds;
81     unsigned int __es;
82     unsigned int __fs;
83     unsigned int __gs;
84   };
85 
86   GPRs _registers;
87 };
88 
Registers_x86(const void * registers)89 inline Registers_x86::Registers_x86(const void *registers) {
90   static_assert((check_fit<Registers_x86, unw_context_t>::does_fit),
91                 "x86 registers do not fit into unw_context_t");
92   memcpy(&_registers, registers, sizeof(_registers));
93 }
94 
Registers_x86()95 inline Registers_x86::Registers_x86() {
96   memset(&_registers, 0, sizeof(_registers));
97 }
98 
validRegister(int regNum) const99 inline bool Registers_x86::validRegister(int regNum) const {
100   if (regNum == UNW_REG_IP)
101     return true;
102   if (regNum == UNW_REG_SP)
103     return true;
104   if (regNum < 0)
105     return false;
106   if (regNum > 7)
107     return false;
108   return true;
109 }
110 
getRegister(int regNum) const111 inline uint32_t Registers_x86::getRegister(int regNum) const {
112   switch (regNum) {
113   case UNW_REG_IP:
114     return _registers.__eip;
115   case UNW_REG_SP:
116     return _registers.__esp;
117   case UNW_X86_EAX:
118     return _registers.__eax;
119   case UNW_X86_ECX:
120     return _registers.__ecx;
121   case UNW_X86_EDX:
122     return _registers.__edx;
123   case UNW_X86_EBX:
124     return _registers.__ebx;
125 #if !defined(__APPLE__)
126   case UNW_X86_ESP:
127 #else
128   case UNW_X86_EBP:
129 #endif
130     return _registers.__ebp;
131 #if !defined(__APPLE__)
132   case UNW_X86_EBP:
133 #else
134   case UNW_X86_ESP:
135 #endif
136     return _registers.__esp;
137   case UNW_X86_ESI:
138     return _registers.__esi;
139   case UNW_X86_EDI:
140     return _registers.__edi;
141   }
142   _LIBUNWIND_ABORT("unsupported x86 register");
143 }
144 
setRegister(int regNum,uint32_t value)145 inline void Registers_x86::setRegister(int regNum, uint32_t value) {
146   switch (regNum) {
147   case UNW_REG_IP:
148     _registers.__eip = value;
149     return;
150   case UNW_REG_SP:
151     _registers.__esp = value;
152     return;
153   case UNW_X86_EAX:
154     _registers.__eax = value;
155     return;
156   case UNW_X86_ECX:
157     _registers.__ecx = value;
158     return;
159   case UNW_X86_EDX:
160     _registers.__edx = value;
161     return;
162   case UNW_X86_EBX:
163     _registers.__ebx = value;
164     return;
165 #if !defined(__APPLE__)
166   case UNW_X86_ESP:
167 #else
168   case UNW_X86_EBP:
169 #endif
170     _registers.__ebp = value;
171     return;
172 #if !defined(__APPLE__)
173   case UNW_X86_EBP:
174 #else
175   case UNW_X86_ESP:
176 #endif
177     _registers.__esp = value;
178     return;
179   case UNW_X86_ESI:
180     _registers.__esi = value;
181     return;
182   case UNW_X86_EDI:
183     _registers.__edi = value;
184     return;
185   }
186   _LIBUNWIND_ABORT("unsupported x86 register");
187 }
188 
getRegisterName(int regNum)189 inline const char *Registers_x86::getRegisterName(int regNum) {
190   switch (regNum) {
191   case UNW_REG_IP:
192     return "ip";
193   case UNW_REG_SP:
194     return "esp";
195   case UNW_X86_EAX:
196     return "eax";
197   case UNW_X86_ECX:
198     return "ecx";
199   case UNW_X86_EDX:
200     return "edx";
201   case UNW_X86_EBX:
202     return "ebx";
203   case UNW_X86_EBP:
204     return "ebp";
205   case UNW_X86_ESP:
206     return "esp";
207   case UNW_X86_ESI:
208     return "esi";
209   case UNW_X86_EDI:
210     return "edi";
211   default:
212     return "unknown register";
213   }
214 }
215 
getFloatRegister(int) const216 inline double Registers_x86::getFloatRegister(int) const {
217   _LIBUNWIND_ABORT("no x86 float registers");
218 }
219 
setFloatRegister(int,double)220 inline void Registers_x86::setFloatRegister(int, double) {
221   _LIBUNWIND_ABORT("no x86 float registers");
222 }
223 
getVectorRegister(int) const224 inline v128 Registers_x86::getVectorRegister(int) const {
225   _LIBUNWIND_ABORT("no x86 vector registers");
226 }
227 
setVectorRegister(int,v128)228 inline void Registers_x86::setVectorRegister(int, v128) {
229   _LIBUNWIND_ABORT("no x86 vector registers");
230 }
231 #endif // _LIBUNWIND_TARGET_I386
232 
233 
234 #if defined(_LIBUNWIND_TARGET_X86_64)
235 /// Registers_x86_64  holds the register state of a thread in a 64-bit intel
236 /// process.
237 class _LIBUNWIND_HIDDEN Registers_x86_64 {
238 public:
239   Registers_x86_64();
240   Registers_x86_64(const void *registers);
241 
242   bool        validRegister(int num) const;
243   uint64_t    getRegister(int num) const;
244   void        setRegister(int num, uint64_t value);
validFloatRegister(int) const245   bool        validFloatRegister(int) const { return false; }
246   double      getFloatRegister(int num) const;
247   void        setFloatRegister(int num, double value);
248   bool        validVectorRegister(int) const;
249   v128        getVectorRegister(int num) const;
250   void        setVectorRegister(int num, v128 value);
251   const char *getRegisterName(int num);
252   void        jumpto();
lastDwarfRegNum()253   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64; }
254 
getSP() const255   uint64_t  getSP() const          { return _registers.__rsp; }
setSP(uint64_t value)256   void      setSP(uint64_t value)  { _registers.__rsp = value; }
getIP() const257   uint64_t  getIP() const          { return _registers.__rip; }
setIP(uint64_t value)258   void      setIP(uint64_t value)  { _registers.__rip = value; }
getRBP() const259   uint64_t  getRBP() const         { return _registers.__rbp; }
setRBP(uint64_t value)260   void      setRBP(uint64_t value) { _registers.__rbp = value; }
getRBX() const261   uint64_t  getRBX() const         { return _registers.__rbx; }
setRBX(uint64_t value)262   void      setRBX(uint64_t value) { _registers.__rbx = value; }
getR12() const263   uint64_t  getR12() const         { return _registers.__r12; }
setR12(uint64_t value)264   void      setR12(uint64_t value) { _registers.__r12 = value; }
getR13() const265   uint64_t  getR13() const         { return _registers.__r13; }
setR13(uint64_t value)266   void      setR13(uint64_t value) { _registers.__r13 = value; }
getR14() const267   uint64_t  getR14() const         { return _registers.__r14; }
setR14(uint64_t value)268   void      setR14(uint64_t value) { _registers.__r14 = value; }
getR15() const269   uint64_t  getR15() const         { return _registers.__r15; }
setR15(uint64_t value)270   void      setR15(uint64_t value) { _registers.__r15 = value; }
271 
272 private:
273   struct GPRs {
274     uint64_t __rax;
275     uint64_t __rbx;
276     uint64_t __rcx;
277     uint64_t __rdx;
278     uint64_t __rdi;
279     uint64_t __rsi;
280     uint64_t __rbp;
281     uint64_t __rsp;
282     uint64_t __r8;
283     uint64_t __r9;
284     uint64_t __r10;
285     uint64_t __r11;
286     uint64_t __r12;
287     uint64_t __r13;
288     uint64_t __r14;
289     uint64_t __r15;
290     uint64_t __rip;
291     uint64_t __rflags;
292     uint64_t __cs;
293     uint64_t __fs;
294     uint64_t __gs;
295 #if defined(_WIN64)
296     uint64_t __padding; // 16-byte align
297 #endif
298   };
299   GPRs _registers;
300 #if defined(_WIN64)
301   v128 _xmm[16];
302 #endif
303 };
304 
Registers_x86_64(const void * registers)305 inline Registers_x86_64::Registers_x86_64(const void *registers) {
306   static_assert((check_fit<Registers_x86_64, unw_context_t>::does_fit),
307                 "x86_64 registers do not fit into unw_context_t");
308   memcpy(&_registers, registers, sizeof(_registers));
309 }
310 
Registers_x86_64()311 inline Registers_x86_64::Registers_x86_64() {
312   memset(&_registers, 0, sizeof(_registers));
313 }
314 
validRegister(int regNum) const315 inline bool Registers_x86_64::validRegister(int regNum) const {
316   if (regNum == UNW_REG_IP)
317     return true;
318   if (regNum == UNW_REG_SP)
319     return true;
320   if (regNum < 0)
321     return false;
322   if (regNum > 15)
323     return false;
324   return true;
325 }
326 
getRegister(int regNum) const327 inline uint64_t Registers_x86_64::getRegister(int regNum) const {
328   switch (regNum) {
329   case UNW_REG_IP:
330     return _registers.__rip;
331   case UNW_REG_SP:
332     return _registers.__rsp;
333   case UNW_X86_64_RAX:
334     return _registers.__rax;
335   case UNW_X86_64_RDX:
336     return _registers.__rdx;
337   case UNW_X86_64_RCX:
338     return _registers.__rcx;
339   case UNW_X86_64_RBX:
340     return _registers.__rbx;
341   case UNW_X86_64_RSI:
342     return _registers.__rsi;
343   case UNW_X86_64_RDI:
344     return _registers.__rdi;
345   case UNW_X86_64_RBP:
346     return _registers.__rbp;
347   case UNW_X86_64_RSP:
348     return _registers.__rsp;
349   case UNW_X86_64_R8:
350     return _registers.__r8;
351   case UNW_X86_64_R9:
352     return _registers.__r9;
353   case UNW_X86_64_R10:
354     return _registers.__r10;
355   case UNW_X86_64_R11:
356     return _registers.__r11;
357   case UNW_X86_64_R12:
358     return _registers.__r12;
359   case UNW_X86_64_R13:
360     return _registers.__r13;
361   case UNW_X86_64_R14:
362     return _registers.__r14;
363   case UNW_X86_64_R15:
364     return _registers.__r15;
365   }
366   _LIBUNWIND_ABORT("unsupported x86_64 register");
367 }
368 
setRegister(int regNum,uint64_t value)369 inline void Registers_x86_64::setRegister(int regNum, uint64_t value) {
370   switch (regNum) {
371   case UNW_REG_IP:
372     _registers.__rip = value;
373     return;
374   case UNW_REG_SP:
375     _registers.__rsp = value;
376     return;
377   case UNW_X86_64_RAX:
378     _registers.__rax = value;
379     return;
380   case UNW_X86_64_RDX:
381     _registers.__rdx = value;
382     return;
383   case UNW_X86_64_RCX:
384     _registers.__rcx = value;
385     return;
386   case UNW_X86_64_RBX:
387     _registers.__rbx = value;
388     return;
389   case UNW_X86_64_RSI:
390     _registers.__rsi = value;
391     return;
392   case UNW_X86_64_RDI:
393     _registers.__rdi = value;
394     return;
395   case UNW_X86_64_RBP:
396     _registers.__rbp = value;
397     return;
398   case UNW_X86_64_RSP:
399     _registers.__rsp = value;
400     return;
401   case UNW_X86_64_R8:
402     _registers.__r8 = value;
403     return;
404   case UNW_X86_64_R9:
405     _registers.__r9 = value;
406     return;
407   case UNW_X86_64_R10:
408     _registers.__r10 = value;
409     return;
410   case UNW_X86_64_R11:
411     _registers.__r11 = value;
412     return;
413   case UNW_X86_64_R12:
414     _registers.__r12 = value;
415     return;
416   case UNW_X86_64_R13:
417     _registers.__r13 = value;
418     return;
419   case UNW_X86_64_R14:
420     _registers.__r14 = value;
421     return;
422   case UNW_X86_64_R15:
423     _registers.__r15 = value;
424     return;
425   }
426   _LIBUNWIND_ABORT("unsupported x86_64 register");
427 }
428 
getRegisterName(int regNum)429 inline const char *Registers_x86_64::getRegisterName(int regNum) {
430   switch (regNum) {
431   case UNW_REG_IP:
432     return "rip";
433   case UNW_REG_SP:
434     return "rsp";
435   case UNW_X86_64_RAX:
436     return "rax";
437   case UNW_X86_64_RDX:
438     return "rdx";
439   case UNW_X86_64_RCX:
440     return "rcx";
441   case UNW_X86_64_RBX:
442     return "rbx";
443   case UNW_X86_64_RSI:
444     return "rsi";
445   case UNW_X86_64_RDI:
446     return "rdi";
447   case UNW_X86_64_RBP:
448     return "rbp";
449   case UNW_X86_64_RSP:
450     return "rsp";
451   case UNW_X86_64_R8:
452     return "r8";
453   case UNW_X86_64_R9:
454     return "r9";
455   case UNW_X86_64_R10:
456     return "r10";
457   case UNW_X86_64_R11:
458     return "r11";
459   case UNW_X86_64_R12:
460     return "r12";
461   case UNW_X86_64_R13:
462     return "r13";
463   case UNW_X86_64_R14:
464     return "r14";
465   case UNW_X86_64_R15:
466     return "r15";
467   case UNW_X86_64_XMM0:
468     return "xmm0";
469   case UNW_X86_64_XMM1:
470     return "xmm1";
471   case UNW_X86_64_XMM2:
472     return "xmm2";
473   case UNW_X86_64_XMM3:
474     return "xmm3";
475   case UNW_X86_64_XMM4:
476     return "xmm4";
477   case UNW_X86_64_XMM5:
478     return "xmm5";
479   case UNW_X86_64_XMM6:
480     return "xmm6";
481   case UNW_X86_64_XMM7:
482     return "xmm7";
483   case UNW_X86_64_XMM8:
484     return "xmm8";
485   case UNW_X86_64_XMM9:
486     return "xmm9";
487   case UNW_X86_64_XMM10:
488     return "xmm10";
489   case UNW_X86_64_XMM11:
490     return "xmm11";
491   case UNW_X86_64_XMM12:
492     return "xmm12";
493   case UNW_X86_64_XMM13:
494     return "xmm13";
495   case UNW_X86_64_XMM14:
496     return "xmm14";
497   case UNW_X86_64_XMM15:
498     return "xmm15";
499   default:
500     return "unknown register";
501   }
502 }
503 
getFloatRegister(int) const504 inline double Registers_x86_64::getFloatRegister(int) const {
505   _LIBUNWIND_ABORT("no x86_64 float registers");
506 }
507 
setFloatRegister(int,double)508 inline void Registers_x86_64::setFloatRegister(int, double) {
509   _LIBUNWIND_ABORT("no x86_64 float registers");
510 }
511 
validVectorRegister(int regNum) const512 inline bool Registers_x86_64::validVectorRegister(int regNum) const {
513 #if defined(_WIN64)
514   if (regNum < UNW_X86_64_XMM0)
515     return false;
516   if (regNum > UNW_X86_64_XMM15)
517     return false;
518   return true;
519 #else
520   return false;
521 #endif
522 }
523 
getVectorRegister(int regNum) const524 inline v128 Registers_x86_64::getVectorRegister(int regNum) const {
525 #if defined(_WIN64)
526   assert(validVectorRegister(regNum));
527   return _xmm[regNum - UNW_X86_64_XMM0];
528 #else
529   _LIBUNWIND_ABORT("no x86_64 vector registers");
530 #endif
531 }
532 
setVectorRegister(int regNum,v128 value)533 inline void Registers_x86_64::setVectorRegister(int regNum, v128 value) {
534 #if defined(_WIN64)
535   assert(validVectorRegister(regNum));
536   _xmm[regNum - UNW_X86_64_XMM0] = value;
537 #else
538   _LIBUNWIND_ABORT("no x86_64 vector registers");
539 #endif
540 }
541 #endif // _LIBUNWIND_TARGET_X86_64
542 
543 
544 #if defined(_LIBUNWIND_TARGET_PPC)
545 /// Registers_ppc holds the register state of a thread in a 32-bit PowerPC
546 /// process.
547 class _LIBUNWIND_HIDDEN Registers_ppc {
548 public:
549   Registers_ppc();
550   Registers_ppc(const void *registers);
551 
552   bool        validRegister(int num) const;
553   uint32_t    getRegister(int num) const;
554   void        setRegister(int num, uint32_t value);
555   bool        validFloatRegister(int num) const;
556   double      getFloatRegister(int num) const;
557   void        setFloatRegister(int num, double value);
558   bool        validVectorRegister(int num) const;
559   v128        getVectorRegister(int num) const;
560   void        setVectorRegister(int num, v128 value);
561   const char *getRegisterName(int num);
562   void        jumpto();
lastDwarfRegNum()563   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC; }
564 
getSP() const565   uint64_t  getSP() const         { return _registers.__r1; }
setSP(uint32_t value)566   void      setSP(uint32_t value) { _registers.__r1 = value; }
getIP() const567   uint64_t  getIP() const         { return _registers.__srr0; }
setIP(uint32_t value)568   void      setIP(uint32_t value) { _registers.__srr0 = value; }
569 
570 private:
571   struct ppc_thread_state_t {
572     unsigned int __srr0; /* Instruction address register (PC) */
573     unsigned int __srr1; /* Machine state register (supervisor) */
574     unsigned int __r0;
575     unsigned int __r1;
576     unsigned int __r2;
577     unsigned int __r3;
578     unsigned int __r4;
579     unsigned int __r5;
580     unsigned int __r6;
581     unsigned int __r7;
582     unsigned int __r8;
583     unsigned int __r9;
584     unsigned int __r10;
585     unsigned int __r11;
586     unsigned int __r12;
587     unsigned int __r13;
588     unsigned int __r14;
589     unsigned int __r15;
590     unsigned int __r16;
591     unsigned int __r17;
592     unsigned int __r18;
593     unsigned int __r19;
594     unsigned int __r20;
595     unsigned int __r21;
596     unsigned int __r22;
597     unsigned int __r23;
598     unsigned int __r24;
599     unsigned int __r25;
600     unsigned int __r26;
601     unsigned int __r27;
602     unsigned int __r28;
603     unsigned int __r29;
604     unsigned int __r30;
605     unsigned int __r31;
606     unsigned int __cr;     /* Condition register */
607     unsigned int __xer;    /* User's integer exception register */
608     unsigned int __lr;     /* Link register */
609     unsigned int __ctr;    /* Count register */
610     unsigned int __mq;     /* MQ register (601 only) */
611     unsigned int __vrsave; /* Vector Save Register */
612   };
613 
614   struct ppc_float_state_t {
615     double __fpregs[32];
616 
617     unsigned int __fpscr_pad; /* fpscr is 64 bits, 32 bits of rubbish */
618     unsigned int __fpscr;     /* floating point status register */
619   };
620 
621   ppc_thread_state_t _registers;
622   ppc_float_state_t  _floatRegisters;
623   v128               _vectorRegisters[32]; // offset 424
624 };
625 
Registers_ppc(const void * registers)626 inline Registers_ppc::Registers_ppc(const void *registers) {
627   static_assert((check_fit<Registers_ppc, unw_context_t>::does_fit),
628                 "ppc registers do not fit into unw_context_t");
629   memcpy(&_registers, static_cast<const uint8_t *>(registers),
630          sizeof(_registers));
631   static_assert(sizeof(ppc_thread_state_t) == 160,
632                 "expected float register offset to be 160");
633   memcpy(&_floatRegisters,
634          static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t),
635          sizeof(_floatRegisters));
636   static_assert(sizeof(ppc_thread_state_t) + sizeof(ppc_float_state_t) == 424,
637                 "expected vector register offset to be 424 bytes");
638   memcpy(_vectorRegisters,
639          static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t) +
640              sizeof(ppc_float_state_t),
641          sizeof(_vectorRegisters));
642 }
643 
Registers_ppc()644 inline Registers_ppc::Registers_ppc() {
645   memset(&_registers, 0, sizeof(_registers));
646   memset(&_floatRegisters, 0, sizeof(_floatRegisters));
647   memset(&_vectorRegisters, 0, sizeof(_vectorRegisters));
648 }
649 
validRegister(int regNum) const650 inline bool Registers_ppc::validRegister(int regNum) const {
651   if (regNum == UNW_REG_IP)
652     return true;
653   if (regNum == UNW_REG_SP)
654     return true;
655   if (regNum == UNW_PPC_VRSAVE)
656     return true;
657   if (regNum < 0)
658     return false;
659   if (regNum <= UNW_PPC_R31)
660     return true;
661   if (regNum == UNW_PPC_MQ)
662     return true;
663   if (regNum == UNW_PPC_LR)
664     return true;
665   if (regNum == UNW_PPC_CTR)
666     return true;
667   if ((UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7))
668     return true;
669   return false;
670 }
671 
getRegister(int regNum) const672 inline uint32_t Registers_ppc::getRegister(int regNum) const {
673   switch (regNum) {
674   case UNW_REG_IP:
675     return _registers.__srr0;
676   case UNW_REG_SP:
677     return _registers.__r1;
678   case UNW_PPC_R0:
679     return _registers.__r0;
680   case UNW_PPC_R1:
681     return _registers.__r1;
682   case UNW_PPC_R2:
683     return _registers.__r2;
684   case UNW_PPC_R3:
685     return _registers.__r3;
686   case UNW_PPC_R4:
687     return _registers.__r4;
688   case UNW_PPC_R5:
689     return _registers.__r5;
690   case UNW_PPC_R6:
691     return _registers.__r6;
692   case UNW_PPC_R7:
693     return _registers.__r7;
694   case UNW_PPC_R8:
695     return _registers.__r8;
696   case UNW_PPC_R9:
697     return _registers.__r9;
698   case UNW_PPC_R10:
699     return _registers.__r10;
700   case UNW_PPC_R11:
701     return _registers.__r11;
702   case UNW_PPC_R12:
703     return _registers.__r12;
704   case UNW_PPC_R13:
705     return _registers.__r13;
706   case UNW_PPC_R14:
707     return _registers.__r14;
708   case UNW_PPC_R15:
709     return _registers.__r15;
710   case UNW_PPC_R16:
711     return _registers.__r16;
712   case UNW_PPC_R17:
713     return _registers.__r17;
714   case UNW_PPC_R18:
715     return _registers.__r18;
716   case UNW_PPC_R19:
717     return _registers.__r19;
718   case UNW_PPC_R20:
719     return _registers.__r20;
720   case UNW_PPC_R21:
721     return _registers.__r21;
722   case UNW_PPC_R22:
723     return _registers.__r22;
724   case UNW_PPC_R23:
725     return _registers.__r23;
726   case UNW_PPC_R24:
727     return _registers.__r24;
728   case UNW_PPC_R25:
729     return _registers.__r25;
730   case UNW_PPC_R26:
731     return _registers.__r26;
732   case UNW_PPC_R27:
733     return _registers.__r27;
734   case UNW_PPC_R28:
735     return _registers.__r28;
736   case UNW_PPC_R29:
737     return _registers.__r29;
738   case UNW_PPC_R30:
739     return _registers.__r30;
740   case UNW_PPC_R31:
741     return _registers.__r31;
742   case UNW_PPC_LR:
743     return _registers.__lr;
744   case UNW_PPC_CR0:
745     return (_registers.__cr & 0xF0000000);
746   case UNW_PPC_CR1:
747     return (_registers.__cr & 0x0F000000);
748   case UNW_PPC_CR2:
749     return (_registers.__cr & 0x00F00000);
750   case UNW_PPC_CR3:
751     return (_registers.__cr & 0x000F0000);
752   case UNW_PPC_CR4:
753     return (_registers.__cr & 0x0000F000);
754   case UNW_PPC_CR5:
755     return (_registers.__cr & 0x00000F00);
756   case UNW_PPC_CR6:
757     return (_registers.__cr & 0x000000F0);
758   case UNW_PPC_CR7:
759     return (_registers.__cr & 0x0000000F);
760   case UNW_PPC_VRSAVE:
761     return _registers.__vrsave;
762   }
763   _LIBUNWIND_ABORT("unsupported ppc register");
764 }
765 
setRegister(int regNum,uint32_t value)766 inline void Registers_ppc::setRegister(int regNum, uint32_t value) {
767   //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value);
768   switch (regNum) {
769   case UNW_REG_IP:
770     _registers.__srr0 = value;
771     return;
772   case UNW_REG_SP:
773     _registers.__r1 = value;
774     return;
775   case UNW_PPC_R0:
776     _registers.__r0 = value;
777     return;
778   case UNW_PPC_R1:
779     _registers.__r1 = value;
780     return;
781   case UNW_PPC_R2:
782     _registers.__r2 = value;
783     return;
784   case UNW_PPC_R3:
785     _registers.__r3 = value;
786     return;
787   case UNW_PPC_R4:
788     _registers.__r4 = value;
789     return;
790   case UNW_PPC_R5:
791     _registers.__r5 = value;
792     return;
793   case UNW_PPC_R6:
794     _registers.__r6 = value;
795     return;
796   case UNW_PPC_R7:
797     _registers.__r7 = value;
798     return;
799   case UNW_PPC_R8:
800     _registers.__r8 = value;
801     return;
802   case UNW_PPC_R9:
803     _registers.__r9 = value;
804     return;
805   case UNW_PPC_R10:
806     _registers.__r10 = value;
807     return;
808   case UNW_PPC_R11:
809     _registers.__r11 = value;
810     return;
811   case UNW_PPC_R12:
812     _registers.__r12 = value;
813     return;
814   case UNW_PPC_R13:
815     _registers.__r13 = value;
816     return;
817   case UNW_PPC_R14:
818     _registers.__r14 = value;
819     return;
820   case UNW_PPC_R15:
821     _registers.__r15 = value;
822     return;
823   case UNW_PPC_R16:
824     _registers.__r16 = value;
825     return;
826   case UNW_PPC_R17:
827     _registers.__r17 = value;
828     return;
829   case UNW_PPC_R18:
830     _registers.__r18 = value;
831     return;
832   case UNW_PPC_R19:
833     _registers.__r19 = value;
834     return;
835   case UNW_PPC_R20:
836     _registers.__r20 = value;
837     return;
838   case UNW_PPC_R21:
839     _registers.__r21 = value;
840     return;
841   case UNW_PPC_R22:
842     _registers.__r22 = value;
843     return;
844   case UNW_PPC_R23:
845     _registers.__r23 = value;
846     return;
847   case UNW_PPC_R24:
848     _registers.__r24 = value;
849     return;
850   case UNW_PPC_R25:
851     _registers.__r25 = value;
852     return;
853   case UNW_PPC_R26:
854     _registers.__r26 = value;
855     return;
856   case UNW_PPC_R27:
857     _registers.__r27 = value;
858     return;
859   case UNW_PPC_R28:
860     _registers.__r28 = value;
861     return;
862   case UNW_PPC_R29:
863     _registers.__r29 = value;
864     return;
865   case UNW_PPC_R30:
866     _registers.__r30 = value;
867     return;
868   case UNW_PPC_R31:
869     _registers.__r31 = value;
870     return;
871   case UNW_PPC_MQ:
872     _registers.__mq = value;
873     return;
874   case UNW_PPC_LR:
875     _registers.__lr = value;
876     return;
877   case UNW_PPC_CTR:
878     _registers.__ctr = value;
879     return;
880   case UNW_PPC_CR0:
881     _registers.__cr &= 0x0FFFFFFF;
882     _registers.__cr |= (value & 0xF0000000);
883     return;
884   case UNW_PPC_CR1:
885     _registers.__cr &= 0xF0FFFFFF;
886     _registers.__cr |= (value & 0x0F000000);
887     return;
888   case UNW_PPC_CR2:
889     _registers.__cr &= 0xFF0FFFFF;
890     _registers.__cr |= (value & 0x00F00000);
891     return;
892   case UNW_PPC_CR3:
893     _registers.__cr &= 0xFFF0FFFF;
894     _registers.__cr |= (value & 0x000F0000);
895     return;
896   case UNW_PPC_CR4:
897     _registers.__cr &= 0xFFFF0FFF;
898     _registers.__cr |= (value & 0x0000F000);
899     return;
900   case UNW_PPC_CR5:
901     _registers.__cr &= 0xFFFFF0FF;
902     _registers.__cr |= (value & 0x00000F00);
903     return;
904   case UNW_PPC_CR6:
905     _registers.__cr &= 0xFFFFFF0F;
906     _registers.__cr |= (value & 0x000000F0);
907     return;
908   case UNW_PPC_CR7:
909     _registers.__cr &= 0xFFFFFFF0;
910     _registers.__cr |= (value & 0x0000000F);
911     return;
912   case UNW_PPC_VRSAVE:
913     _registers.__vrsave = value;
914     return;
915     // not saved
916     return;
917   case UNW_PPC_XER:
918     _registers.__xer = value;
919     return;
920   case UNW_PPC_AP:
921   case UNW_PPC_VSCR:
922   case UNW_PPC_SPEFSCR:
923     // not saved
924     return;
925   }
926   _LIBUNWIND_ABORT("unsupported ppc register");
927 }
928 
validFloatRegister(int regNum) const929 inline bool Registers_ppc::validFloatRegister(int regNum) const {
930   if (regNum < UNW_PPC_F0)
931     return false;
932   if (regNum > UNW_PPC_F31)
933     return false;
934   return true;
935 }
936 
getFloatRegister(int regNum) const937 inline double Registers_ppc::getFloatRegister(int regNum) const {
938   assert(validFloatRegister(regNum));
939   return _floatRegisters.__fpregs[regNum - UNW_PPC_F0];
940 }
941 
setFloatRegister(int regNum,double value)942 inline void Registers_ppc::setFloatRegister(int regNum, double value) {
943   assert(validFloatRegister(regNum));
944   _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value;
945 }
946 
validVectorRegister(int regNum) const947 inline bool Registers_ppc::validVectorRegister(int regNum) const {
948   if (regNum < UNW_PPC_V0)
949     return false;
950   if (regNum > UNW_PPC_V31)
951     return false;
952   return true;
953 }
954 
getVectorRegister(int regNum) const955 inline v128 Registers_ppc::getVectorRegister(int regNum) const {
956   assert(validVectorRegister(regNum));
957   v128 result = _vectorRegisters[regNum - UNW_PPC_V0];
958   return result;
959 }
960 
setVectorRegister(int regNum,v128 value)961 inline void Registers_ppc::setVectorRegister(int regNum, v128 value) {
962   assert(validVectorRegister(regNum));
963   _vectorRegisters[regNum - UNW_PPC_V0] = value;
964 }
965 
getRegisterName(int regNum)966 inline const char *Registers_ppc::getRegisterName(int regNum) {
967   switch (regNum) {
968   case UNW_REG_IP:
969     return "ip";
970   case UNW_REG_SP:
971     return "sp";
972   case UNW_PPC_R0:
973     return "r0";
974   case UNW_PPC_R1:
975     return "r1";
976   case UNW_PPC_R2:
977     return "r2";
978   case UNW_PPC_R3:
979     return "r3";
980   case UNW_PPC_R4:
981     return "r4";
982   case UNW_PPC_R5:
983     return "r5";
984   case UNW_PPC_R6:
985     return "r6";
986   case UNW_PPC_R7:
987     return "r7";
988   case UNW_PPC_R8:
989     return "r8";
990   case UNW_PPC_R9:
991     return "r9";
992   case UNW_PPC_R10:
993     return "r10";
994   case UNW_PPC_R11:
995     return "r11";
996   case UNW_PPC_R12:
997     return "r12";
998   case UNW_PPC_R13:
999     return "r13";
1000   case UNW_PPC_R14:
1001     return "r14";
1002   case UNW_PPC_R15:
1003     return "r15";
1004   case UNW_PPC_R16:
1005     return "r16";
1006   case UNW_PPC_R17:
1007     return "r17";
1008   case UNW_PPC_R18:
1009     return "r18";
1010   case UNW_PPC_R19:
1011     return "r19";
1012   case UNW_PPC_R20:
1013     return "r20";
1014   case UNW_PPC_R21:
1015     return "r21";
1016   case UNW_PPC_R22:
1017     return "r22";
1018   case UNW_PPC_R23:
1019     return "r23";
1020   case UNW_PPC_R24:
1021     return "r24";
1022   case UNW_PPC_R25:
1023     return "r25";
1024   case UNW_PPC_R26:
1025     return "r26";
1026   case UNW_PPC_R27:
1027     return "r27";
1028   case UNW_PPC_R28:
1029     return "r28";
1030   case UNW_PPC_R29:
1031     return "r29";
1032   case UNW_PPC_R30:
1033     return "r30";
1034   case UNW_PPC_R31:
1035     return "r31";
1036   case UNW_PPC_F0:
1037     return "fp0";
1038   case UNW_PPC_F1:
1039     return "fp1";
1040   case UNW_PPC_F2:
1041     return "fp2";
1042   case UNW_PPC_F3:
1043     return "fp3";
1044   case UNW_PPC_F4:
1045     return "fp4";
1046   case UNW_PPC_F5:
1047     return "fp5";
1048   case UNW_PPC_F6:
1049     return "fp6";
1050   case UNW_PPC_F7:
1051     return "fp7";
1052   case UNW_PPC_F8:
1053     return "fp8";
1054   case UNW_PPC_F9:
1055     return "fp9";
1056   case UNW_PPC_F10:
1057     return "fp10";
1058   case UNW_PPC_F11:
1059     return "fp11";
1060   case UNW_PPC_F12:
1061     return "fp12";
1062   case UNW_PPC_F13:
1063     return "fp13";
1064   case UNW_PPC_F14:
1065     return "fp14";
1066   case UNW_PPC_F15:
1067     return "fp15";
1068   case UNW_PPC_F16:
1069     return "fp16";
1070   case UNW_PPC_F17:
1071     return "fp17";
1072   case UNW_PPC_F18:
1073     return "fp18";
1074   case UNW_PPC_F19:
1075     return "fp19";
1076   case UNW_PPC_F20:
1077     return "fp20";
1078   case UNW_PPC_F21:
1079     return "fp21";
1080   case UNW_PPC_F22:
1081     return "fp22";
1082   case UNW_PPC_F23:
1083     return "fp23";
1084   case UNW_PPC_F24:
1085     return "fp24";
1086   case UNW_PPC_F25:
1087     return "fp25";
1088   case UNW_PPC_F26:
1089     return "fp26";
1090   case UNW_PPC_F27:
1091     return "fp27";
1092   case UNW_PPC_F28:
1093     return "fp28";
1094   case UNW_PPC_F29:
1095     return "fp29";
1096   case UNW_PPC_F30:
1097     return "fp30";
1098   case UNW_PPC_F31:
1099     return "fp31";
1100   case UNW_PPC_LR:
1101     return "lr";
1102   default:
1103     return "unknown register";
1104   }
1105 
1106 }
1107 #endif // _LIBUNWIND_TARGET_PPC
1108 
1109 
1110 #if defined(_LIBUNWIND_TARGET_AARCH64)
1111 /// Registers_arm64  holds the register state of a thread in a 64-bit arm
1112 /// process.
1113 class _LIBUNWIND_HIDDEN Registers_arm64 {
1114 public:
1115   Registers_arm64();
1116   Registers_arm64(const void *registers);
1117 
1118   bool        validRegister(int num) const;
1119   uint64_t    getRegister(int num) const;
1120   void        setRegister(int num, uint64_t value);
1121   bool        validFloatRegister(int num) const;
1122   double      getFloatRegister(int num) const;
1123   void        setFloatRegister(int num, double value);
1124   bool        validVectorRegister(int num) const;
1125   v128        getVectorRegister(int num) const;
1126   void        setVectorRegister(int num, v128 value);
1127   const char *getRegisterName(int num);
1128   void        jumpto();
lastDwarfRegNum()1129   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64; }
1130 
getSP() const1131   uint64_t  getSP() const         { return _registers.__sp; }
setSP(uint64_t value)1132   void      setSP(uint64_t value) { _registers.__sp = value; }
getIP() const1133   uint64_t  getIP() const         { return _registers.__pc; }
setIP(uint64_t value)1134   void      setIP(uint64_t value) { _registers.__pc = value; }
getFP() const1135   uint64_t  getFP() const         { return _registers.__fp; }
setFP(uint64_t value)1136   void      setFP(uint64_t value) { _registers.__fp = value; }
1137 
1138 private:
1139   struct GPRs {
1140     uint64_t __x[29]; // x0-x28
1141     uint64_t __fp;    // Frame pointer x29
1142     uint64_t __lr;    // Link register x30
1143     uint64_t __sp;    // Stack pointer x31
1144     uint64_t __pc;    // Program counter
1145     uint64_t padding; // 16-byte align
1146   };
1147 
1148   GPRs    _registers;
1149   double  _vectorHalfRegisters[32];
1150   // Currently only the lower double in 128-bit vectore registers
1151   // is perserved during unwinding.  We could define new register
1152   // numbers (> 96) which mean whole vector registers, then this
1153   // struct would need to change to contain whole vector registers.
1154 };
1155 
Registers_arm64(const void * registers)1156 inline Registers_arm64::Registers_arm64(const void *registers) {
1157   static_assert((check_fit<Registers_arm64, unw_context_t>::does_fit),
1158                 "arm64 registers do not fit into unw_context_t");
1159   memcpy(&_registers, registers, sizeof(_registers));
1160   static_assert(sizeof(GPRs) == 0x110,
1161                 "expected VFP registers to be at offset 272");
1162   memcpy(_vectorHalfRegisters,
1163          static_cast<const uint8_t *>(registers) + sizeof(GPRs),
1164          sizeof(_vectorHalfRegisters));
1165 }
1166 
Registers_arm64()1167 inline Registers_arm64::Registers_arm64() {
1168   memset(&_registers, 0, sizeof(_registers));
1169   memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
1170 }
1171 
validRegister(int regNum) const1172 inline bool Registers_arm64::validRegister(int regNum) const {
1173   if (regNum == UNW_REG_IP)
1174     return true;
1175   if (regNum == UNW_REG_SP)
1176     return true;
1177   if (regNum < 0)
1178     return false;
1179   if (regNum > 95)
1180     return false;
1181   if ((regNum > 31) && (regNum < 64))
1182     return false;
1183   return true;
1184 }
1185 
getRegister(int regNum) const1186 inline uint64_t Registers_arm64::getRegister(int regNum) const {
1187   if (regNum == UNW_REG_IP)
1188     return _registers.__pc;
1189   if (regNum == UNW_REG_SP)
1190     return _registers.__sp;
1191   if ((regNum >= 0) && (regNum < 32))
1192     return _registers.__x[regNum];
1193   _LIBUNWIND_ABORT("unsupported arm64 register");
1194 }
1195 
setRegister(int regNum,uint64_t value)1196 inline void Registers_arm64::setRegister(int regNum, uint64_t value) {
1197   if (regNum == UNW_REG_IP)
1198     _registers.__pc = value;
1199   else if (regNum == UNW_REG_SP)
1200     _registers.__sp = value;
1201   else if ((regNum >= 0) && (regNum < 32))
1202     _registers.__x[regNum] = value;
1203   else
1204     _LIBUNWIND_ABORT("unsupported arm64 register");
1205 }
1206 
getRegisterName(int regNum)1207 inline const char *Registers_arm64::getRegisterName(int regNum) {
1208   switch (regNum) {
1209   case UNW_REG_IP:
1210     return "pc";
1211   case UNW_REG_SP:
1212     return "sp";
1213   case UNW_ARM64_X0:
1214     return "x0";
1215   case UNW_ARM64_X1:
1216     return "x1";
1217   case UNW_ARM64_X2:
1218     return "x2";
1219   case UNW_ARM64_X3:
1220     return "x3";
1221   case UNW_ARM64_X4:
1222     return "x4";
1223   case UNW_ARM64_X5:
1224     return "x5";
1225   case UNW_ARM64_X6:
1226     return "x6";
1227   case UNW_ARM64_X7:
1228     return "x7";
1229   case UNW_ARM64_X8:
1230     return "x8";
1231   case UNW_ARM64_X9:
1232     return "x9";
1233   case UNW_ARM64_X10:
1234     return "x10";
1235   case UNW_ARM64_X11:
1236     return "x11";
1237   case UNW_ARM64_X12:
1238     return "x12";
1239   case UNW_ARM64_X13:
1240     return "x13";
1241   case UNW_ARM64_X14:
1242     return "x14";
1243   case UNW_ARM64_X15:
1244     return "x15";
1245   case UNW_ARM64_X16:
1246     return "x16";
1247   case UNW_ARM64_X17:
1248     return "x17";
1249   case UNW_ARM64_X18:
1250     return "x18";
1251   case UNW_ARM64_X19:
1252     return "x19";
1253   case UNW_ARM64_X20:
1254     return "x20";
1255   case UNW_ARM64_X21:
1256     return "x21";
1257   case UNW_ARM64_X22:
1258     return "x22";
1259   case UNW_ARM64_X23:
1260     return "x23";
1261   case UNW_ARM64_X24:
1262     return "x24";
1263   case UNW_ARM64_X25:
1264     return "x25";
1265   case UNW_ARM64_X26:
1266     return "x26";
1267   case UNW_ARM64_X27:
1268     return "x27";
1269   case UNW_ARM64_X28:
1270     return "x28";
1271   case UNW_ARM64_X29:
1272     return "fp";
1273   case UNW_ARM64_X30:
1274     return "lr";
1275   case UNW_ARM64_X31:
1276     return "sp";
1277   case UNW_ARM64_D0:
1278     return "d0";
1279   case UNW_ARM64_D1:
1280     return "d1";
1281   case UNW_ARM64_D2:
1282     return "d2";
1283   case UNW_ARM64_D3:
1284     return "d3";
1285   case UNW_ARM64_D4:
1286     return "d4";
1287   case UNW_ARM64_D5:
1288     return "d5";
1289   case UNW_ARM64_D6:
1290     return "d6";
1291   case UNW_ARM64_D7:
1292     return "d7";
1293   case UNW_ARM64_D8:
1294     return "d8";
1295   case UNW_ARM64_D9:
1296     return "d9";
1297   case UNW_ARM64_D10:
1298     return "d10";
1299   case UNW_ARM64_D11:
1300     return "d11";
1301   case UNW_ARM64_D12:
1302     return "d12";
1303   case UNW_ARM64_D13:
1304     return "d13";
1305   case UNW_ARM64_D14:
1306     return "d14";
1307   case UNW_ARM64_D15:
1308     return "d15";
1309   case UNW_ARM64_D16:
1310     return "d16";
1311   case UNW_ARM64_D17:
1312     return "d17";
1313   case UNW_ARM64_D18:
1314     return "d18";
1315   case UNW_ARM64_D19:
1316     return "d19";
1317   case UNW_ARM64_D20:
1318     return "d20";
1319   case UNW_ARM64_D21:
1320     return "d21";
1321   case UNW_ARM64_D22:
1322     return "d22";
1323   case UNW_ARM64_D23:
1324     return "d23";
1325   case UNW_ARM64_D24:
1326     return "d24";
1327   case UNW_ARM64_D25:
1328     return "d25";
1329   case UNW_ARM64_D26:
1330     return "d26";
1331   case UNW_ARM64_D27:
1332     return "d27";
1333   case UNW_ARM64_D28:
1334     return "d28";
1335   case UNW_ARM64_D29:
1336     return "d29";
1337   case UNW_ARM64_D30:
1338     return "d30";
1339   case UNW_ARM64_D31:
1340     return "d31";
1341   default:
1342     return "unknown register";
1343   }
1344 }
1345 
validFloatRegister(int regNum) const1346 inline bool Registers_arm64::validFloatRegister(int regNum) const {
1347   if (regNum < UNW_ARM64_D0)
1348     return false;
1349   if (regNum > UNW_ARM64_D31)
1350     return false;
1351   return true;
1352 }
1353 
getFloatRegister(int regNum) const1354 inline double Registers_arm64::getFloatRegister(int regNum) const {
1355   assert(validFloatRegister(regNum));
1356   return _vectorHalfRegisters[regNum - UNW_ARM64_D0];
1357 }
1358 
setFloatRegister(int regNum,double value)1359 inline void Registers_arm64::setFloatRegister(int regNum, double value) {
1360   assert(validFloatRegister(regNum));
1361   _vectorHalfRegisters[regNum - UNW_ARM64_D0] = value;
1362 }
1363 
validVectorRegister(int) const1364 inline bool Registers_arm64::validVectorRegister(int) const {
1365   return false;
1366 }
1367 
getVectorRegister(int) const1368 inline v128 Registers_arm64::getVectorRegister(int) const {
1369   _LIBUNWIND_ABORT("no arm64 vector register support yet");
1370 }
1371 
setVectorRegister(int,v128)1372 inline void Registers_arm64::setVectorRegister(int, v128) {
1373   _LIBUNWIND_ABORT("no arm64 vector register support yet");
1374 }
1375 #endif // _LIBUNWIND_TARGET_AARCH64
1376 
1377 #if defined(_LIBUNWIND_TARGET_ARM)
1378 /// Registers_arm holds the register state of a thread in a 32-bit arm
1379 /// process.
1380 ///
1381 /// NOTE: Assumes VFPv3. On ARM processors without a floating point unit,
1382 /// this uses more memory than required.
1383 class _LIBUNWIND_HIDDEN Registers_arm {
1384 public:
1385   Registers_arm();
1386   Registers_arm(const void *registers);
1387 
1388   bool        validRegister(int num) const;
1389   uint32_t    getRegister(int num) const;
1390   void        setRegister(int num, uint32_t value);
1391   bool        validFloatRegister(int num) const;
1392   unw_fpreg_t getFloatRegister(int num);
1393   void        setFloatRegister(int num, unw_fpreg_t value);
1394   bool        validVectorRegister(int num) const;
1395   v128        getVectorRegister(int num) const;
1396   void        setVectorRegister(int num, v128 value);
1397   const char *getRegisterName(int num);
jumpto()1398   void        jumpto() {
1399     restoreSavedFloatRegisters();
1400     restoreCoreAndJumpTo();
1401   }
lastDwarfRegNum()1402   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM; }
1403 
getSP() const1404   uint32_t  getSP() const         { return _registers.__sp; }
setSP(uint32_t value)1405   void      setSP(uint32_t value) { _registers.__sp = value; }
getIP() const1406   uint32_t  getIP() const         { return _registers.__pc; }
setIP(uint32_t value)1407   void      setIP(uint32_t value) { _registers.__pc = value; }
1408 
saveVFPAsX()1409   void saveVFPAsX() {
1410     assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15);
1411     _use_X_for_vfp_save = true;
1412   }
1413 
restoreSavedFloatRegisters()1414   void restoreSavedFloatRegisters() {
1415     if (_saved_vfp_d0_d15) {
1416       if (_use_X_for_vfp_save)
1417         restoreVFPWithFLDMX(_vfp_d0_d15_pad);
1418       else
1419         restoreVFPWithFLDMD(_vfp_d0_d15_pad);
1420     }
1421     if (_saved_vfp_d16_d31)
1422       restoreVFPv3(_vfp_d16_d31);
1423 #if defined(__ARM_WMMX)
1424     if (_saved_iwmmx)
1425       restoreiWMMX(_iwmmx);
1426     if (_saved_iwmmx_control)
1427       restoreiWMMXControl(_iwmmx_control);
1428 #endif
1429   }
1430 
1431 private:
1432   struct GPRs {
1433     uint32_t __r[13]; // r0-r12
1434     uint32_t __sp;    // Stack pointer r13
1435     uint32_t __lr;    // Link register r14
1436     uint32_t __pc;    // Program counter r15
1437   };
1438 
1439   static void saveVFPWithFSTMD(unw_fpreg_t*);
1440   static void saveVFPWithFSTMX(unw_fpreg_t*);
1441   static void saveVFPv3(unw_fpreg_t*);
1442   static void restoreVFPWithFLDMD(unw_fpreg_t*);
1443   static void restoreVFPWithFLDMX(unw_fpreg_t*);
1444   static void restoreVFPv3(unw_fpreg_t*);
1445 #if defined(__ARM_WMMX)
1446   static void saveiWMMX(unw_fpreg_t*);
1447   static void saveiWMMXControl(uint32_t*);
1448   static void restoreiWMMX(unw_fpreg_t*);
1449   static void restoreiWMMXControl(uint32_t*);
1450 #endif
1451   void restoreCoreAndJumpTo();
1452 
1453   // ARM registers
1454   GPRs _registers;
1455 
1456   // We save floating point registers lazily because we can't know ahead of
1457   // time which ones are used. See EHABI #4.7.
1458 
1459   // Whether D0-D15 are saved in the FTSMX instead of FSTMD format.
1460   //
1461   // See EHABI #7.5 that explains how matching instruction sequences for load
1462   // and store need to be used to correctly restore the exact register bits.
1463   bool _use_X_for_vfp_save;
1464   // Whether VFP D0-D15 are saved.
1465   bool _saved_vfp_d0_d15;
1466   // Whether VFPv3 D16-D31 are saved.
1467   bool _saved_vfp_d16_d31;
1468   // VFP registers D0-D15, + padding if saved using FSTMX
1469   unw_fpreg_t _vfp_d0_d15_pad[17];
1470   // VFPv3 registers D16-D31, always saved using FSTMD
1471   unw_fpreg_t _vfp_d16_d31[16];
1472 #if defined(__ARM_WMMX)
1473   // Whether iWMMX data registers are saved.
1474   bool _saved_iwmmx;
1475   // Whether iWMMX control registers are saved.
1476   mutable bool _saved_iwmmx_control;
1477   // iWMMX registers
1478   unw_fpreg_t _iwmmx[16];
1479   // iWMMX control registers
1480   mutable uint32_t _iwmmx_control[4];
1481 #endif
1482 };
1483 
Registers_arm(const void * registers)1484 inline Registers_arm::Registers_arm(const void *registers)
1485   : _use_X_for_vfp_save(false),
1486     _saved_vfp_d0_d15(false),
1487     _saved_vfp_d16_d31(false) {
1488   static_assert((check_fit<Registers_arm, unw_context_t>::does_fit),
1489                 "arm registers do not fit into unw_context_t");
1490   // See unw_getcontext() note about data.
1491   memcpy(&_registers, registers, sizeof(_registers));
1492   memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
1493   memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
1494 #if defined(__ARM_WMMX)
1495   _saved_iwmmx = false;
1496   _saved_iwmmx_control = false;
1497   memset(&_iwmmx, 0, sizeof(_iwmmx));
1498   memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
1499 #endif
1500 }
1501 
Registers_arm()1502 inline Registers_arm::Registers_arm()
1503   : _use_X_for_vfp_save(false),
1504     _saved_vfp_d0_d15(false),
1505     _saved_vfp_d16_d31(false) {
1506   memset(&_registers, 0, sizeof(_registers));
1507   memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
1508   memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
1509 #if defined(__ARM_WMMX)
1510   _saved_iwmmx = false;
1511   _saved_iwmmx_control = false;
1512   memset(&_iwmmx, 0, sizeof(_iwmmx));
1513   memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
1514 #endif
1515 }
1516 
validRegister(int regNum) const1517 inline bool Registers_arm::validRegister(int regNum) const {
1518   // Returns true for all non-VFP registers supported by the EHABI
1519   // virtual register set (VRS).
1520   if (regNum == UNW_REG_IP)
1521     return true;
1522 
1523   if (regNum == UNW_REG_SP)
1524     return true;
1525 
1526   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15)
1527     return true;
1528 
1529 #if defined(__ARM_WMMX)
1530   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3)
1531     return true;
1532 #endif
1533 
1534   return false;
1535 }
1536 
getRegister(int regNum) const1537 inline uint32_t Registers_arm::getRegister(int regNum) const {
1538   if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
1539     return _registers.__sp;
1540 
1541   if (regNum == UNW_ARM_LR)
1542     return _registers.__lr;
1543 
1544   if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
1545     return _registers.__pc;
1546 
1547   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
1548     return _registers.__r[regNum];
1549 
1550 #if defined(__ARM_WMMX)
1551   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
1552     if (!_saved_iwmmx_control) {
1553       _saved_iwmmx_control = true;
1554       saveiWMMXControl(_iwmmx_control);
1555     }
1556     return _iwmmx_control[regNum - UNW_ARM_WC0];
1557   }
1558 #endif
1559 
1560   _LIBUNWIND_ABORT("unsupported arm register");
1561 }
1562 
setRegister(int regNum,uint32_t value)1563 inline void Registers_arm::setRegister(int regNum, uint32_t value) {
1564   if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) {
1565     _registers.__sp = value;
1566     return;
1567   }
1568 
1569   if (regNum == UNW_ARM_LR) {
1570     _registers.__lr = value;
1571     return;
1572   }
1573 
1574   if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) {
1575     _registers.__pc = value;
1576     return;
1577   }
1578 
1579   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) {
1580     _registers.__r[regNum] = value;
1581     return;
1582   }
1583 
1584 #if defined(__ARM_WMMX)
1585   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
1586     if (!_saved_iwmmx_control) {
1587       _saved_iwmmx_control = true;
1588       saveiWMMXControl(_iwmmx_control);
1589     }
1590     _iwmmx_control[regNum - UNW_ARM_WC0] = value;
1591     return;
1592   }
1593 #endif
1594 
1595   _LIBUNWIND_ABORT("unsupported arm register");
1596 }
1597 
getRegisterName(int regNum)1598 inline const char *Registers_arm::getRegisterName(int regNum) {
1599   switch (regNum) {
1600   case UNW_REG_IP:
1601   case UNW_ARM_IP: // UNW_ARM_R15 is alias
1602     return "pc";
1603   case UNW_ARM_LR: // UNW_ARM_R14 is alias
1604     return "lr";
1605   case UNW_REG_SP:
1606   case UNW_ARM_SP: // UNW_ARM_R13 is alias
1607     return "sp";
1608   case UNW_ARM_R0:
1609     return "r0";
1610   case UNW_ARM_R1:
1611     return "r1";
1612   case UNW_ARM_R2:
1613     return "r2";
1614   case UNW_ARM_R3:
1615     return "r3";
1616   case UNW_ARM_R4:
1617     return "r4";
1618   case UNW_ARM_R5:
1619     return "r5";
1620   case UNW_ARM_R6:
1621     return "r6";
1622   case UNW_ARM_R7:
1623     return "r7";
1624   case UNW_ARM_R8:
1625     return "r8";
1626   case UNW_ARM_R9:
1627     return "r9";
1628   case UNW_ARM_R10:
1629     return "r10";
1630   case UNW_ARM_R11:
1631     return "r11";
1632   case UNW_ARM_R12:
1633     return "r12";
1634   case UNW_ARM_S0:
1635     return "s0";
1636   case UNW_ARM_S1:
1637     return "s1";
1638   case UNW_ARM_S2:
1639     return "s2";
1640   case UNW_ARM_S3:
1641     return "s3";
1642   case UNW_ARM_S4:
1643     return "s4";
1644   case UNW_ARM_S5:
1645     return "s5";
1646   case UNW_ARM_S6:
1647     return "s6";
1648   case UNW_ARM_S7:
1649     return "s7";
1650   case UNW_ARM_S8:
1651     return "s8";
1652   case UNW_ARM_S9:
1653     return "s9";
1654   case UNW_ARM_S10:
1655     return "s10";
1656   case UNW_ARM_S11:
1657     return "s11";
1658   case UNW_ARM_S12:
1659     return "s12";
1660   case UNW_ARM_S13:
1661     return "s13";
1662   case UNW_ARM_S14:
1663     return "s14";
1664   case UNW_ARM_S15:
1665     return "s15";
1666   case UNW_ARM_S16:
1667     return "s16";
1668   case UNW_ARM_S17:
1669     return "s17";
1670   case UNW_ARM_S18:
1671     return "s18";
1672   case UNW_ARM_S19:
1673     return "s19";
1674   case UNW_ARM_S20:
1675     return "s20";
1676   case UNW_ARM_S21:
1677     return "s21";
1678   case UNW_ARM_S22:
1679     return "s22";
1680   case UNW_ARM_S23:
1681     return "s23";
1682   case UNW_ARM_S24:
1683     return "s24";
1684   case UNW_ARM_S25:
1685     return "s25";
1686   case UNW_ARM_S26:
1687     return "s26";
1688   case UNW_ARM_S27:
1689     return "s27";
1690   case UNW_ARM_S28:
1691     return "s28";
1692   case UNW_ARM_S29:
1693     return "s29";
1694   case UNW_ARM_S30:
1695     return "s30";
1696   case UNW_ARM_S31:
1697     return "s31";
1698   case UNW_ARM_D0:
1699     return "d0";
1700   case UNW_ARM_D1:
1701     return "d1";
1702   case UNW_ARM_D2:
1703     return "d2";
1704   case UNW_ARM_D3:
1705     return "d3";
1706   case UNW_ARM_D4:
1707     return "d4";
1708   case UNW_ARM_D5:
1709     return "d5";
1710   case UNW_ARM_D6:
1711     return "d6";
1712   case UNW_ARM_D7:
1713     return "d7";
1714   case UNW_ARM_D8:
1715     return "d8";
1716   case UNW_ARM_D9:
1717     return "d9";
1718   case UNW_ARM_D10:
1719     return "d10";
1720   case UNW_ARM_D11:
1721     return "d11";
1722   case UNW_ARM_D12:
1723     return "d12";
1724   case UNW_ARM_D13:
1725     return "d13";
1726   case UNW_ARM_D14:
1727     return "d14";
1728   case UNW_ARM_D15:
1729     return "d15";
1730   case UNW_ARM_D16:
1731     return "d16";
1732   case UNW_ARM_D17:
1733     return "d17";
1734   case UNW_ARM_D18:
1735     return "d18";
1736   case UNW_ARM_D19:
1737     return "d19";
1738   case UNW_ARM_D20:
1739     return "d20";
1740   case UNW_ARM_D21:
1741     return "d21";
1742   case UNW_ARM_D22:
1743     return "d22";
1744   case UNW_ARM_D23:
1745     return "d23";
1746   case UNW_ARM_D24:
1747     return "d24";
1748   case UNW_ARM_D25:
1749     return "d25";
1750   case UNW_ARM_D26:
1751     return "d26";
1752   case UNW_ARM_D27:
1753     return "d27";
1754   case UNW_ARM_D28:
1755     return "d28";
1756   case UNW_ARM_D29:
1757     return "d29";
1758   case UNW_ARM_D30:
1759     return "d30";
1760   case UNW_ARM_D31:
1761     return "d31";
1762   default:
1763     return "unknown register";
1764   }
1765 }
1766 
validFloatRegister(int regNum) const1767 inline bool Registers_arm::validFloatRegister(int regNum) const {
1768   // NOTE: Consider the intel MMX registers floating points so the
1769   // unw_get_fpreg can be used to transmit the 64-bit data back.
1770   return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31))
1771 #if defined(__ARM_WMMX)
1772       || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15))
1773 #endif
1774       ;
1775 }
1776 
getFloatRegister(int regNum)1777 inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) {
1778   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
1779     if (!_saved_vfp_d0_d15) {
1780       _saved_vfp_d0_d15 = true;
1781       if (_use_X_for_vfp_save)
1782         saveVFPWithFSTMX(_vfp_d0_d15_pad);
1783       else
1784         saveVFPWithFSTMD(_vfp_d0_d15_pad);
1785     }
1786     return _vfp_d0_d15_pad[regNum - UNW_ARM_D0];
1787   }
1788 
1789   if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
1790     if (!_saved_vfp_d16_d31) {
1791       _saved_vfp_d16_d31 = true;
1792       saveVFPv3(_vfp_d16_d31);
1793     }
1794     return _vfp_d16_d31[regNum - UNW_ARM_D16];
1795   }
1796 
1797 #if defined(__ARM_WMMX)
1798   if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
1799     if (!_saved_iwmmx) {
1800       _saved_iwmmx = true;
1801       saveiWMMX(_iwmmx);
1802     }
1803     return _iwmmx[regNum - UNW_ARM_WR0];
1804   }
1805 #endif
1806 
1807   _LIBUNWIND_ABORT("Unknown ARM float register");
1808 }
1809 
setFloatRegister(int regNum,unw_fpreg_t value)1810 inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) {
1811   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
1812     if (!_saved_vfp_d0_d15) {
1813       _saved_vfp_d0_d15 = true;
1814       if (_use_X_for_vfp_save)
1815         saveVFPWithFSTMX(_vfp_d0_d15_pad);
1816       else
1817         saveVFPWithFSTMD(_vfp_d0_d15_pad);
1818     }
1819     _vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value;
1820     return;
1821   }
1822 
1823   if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
1824     if (!_saved_vfp_d16_d31) {
1825       _saved_vfp_d16_d31 = true;
1826       saveVFPv3(_vfp_d16_d31);
1827     }
1828     _vfp_d16_d31[regNum - UNW_ARM_D16] = value;
1829     return;
1830   }
1831 
1832 #if defined(__ARM_WMMX)
1833   if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
1834     if (!_saved_iwmmx) {
1835       _saved_iwmmx = true;
1836       saveiWMMX(_iwmmx);
1837     }
1838     _iwmmx[regNum - UNW_ARM_WR0] = value;
1839     return;
1840   }
1841 #endif
1842 
1843   _LIBUNWIND_ABORT("Unknown ARM float register");
1844 }
1845 
validVectorRegister(int) const1846 inline bool Registers_arm::validVectorRegister(int) const {
1847   return false;
1848 }
1849 
getVectorRegister(int) const1850 inline v128 Registers_arm::getVectorRegister(int) const {
1851   _LIBUNWIND_ABORT("ARM vector support not implemented");
1852 }
1853 
setVectorRegister(int,v128)1854 inline void Registers_arm::setVectorRegister(int, v128) {
1855   _LIBUNWIND_ABORT("ARM vector support not implemented");
1856 }
1857 #endif // _LIBUNWIND_TARGET_ARM
1858 
1859 
1860 #if defined(_LIBUNWIND_TARGET_OR1K)
1861 /// Registers_or1k holds the register state of a thread in an OpenRISC1000
1862 /// process.
1863 class _LIBUNWIND_HIDDEN Registers_or1k {
1864 public:
1865   Registers_or1k();
1866   Registers_or1k(const void *registers);
1867 
1868   bool        validRegister(int num) const;
1869   uint32_t    getRegister(int num) const;
1870   void        setRegister(int num, uint32_t value);
1871   bool        validFloatRegister(int num) const;
1872   double      getFloatRegister(int num) const;
1873   void        setFloatRegister(int num, double value);
1874   bool        validVectorRegister(int num) const;
1875   v128        getVectorRegister(int num) const;
1876   void        setVectorRegister(int num, v128 value);
1877   const char *getRegisterName(int num);
1878   void        jumpto();
lastDwarfRegNum()1879   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K; }
1880 
getSP() const1881   uint64_t  getSP() const         { return _registers.__r[1]; }
setSP(uint32_t value)1882   void      setSP(uint32_t value) { _registers.__r[1] = value; }
getIP() const1883   uint64_t  getIP() const         { return _registers.__r[9]; }
setIP(uint32_t value)1884   void      setIP(uint32_t value) { _registers.__r[9] = value; }
1885 
1886 private:
1887   struct or1k_thread_state_t {
1888     unsigned int __r[32];
1889   };
1890 
1891   or1k_thread_state_t _registers;
1892 };
1893 
Registers_or1k(const void * registers)1894 inline Registers_or1k::Registers_or1k(const void *registers) {
1895   static_assert((check_fit<Registers_or1k, unw_context_t>::does_fit),
1896                 "or1k registers do not fit into unw_context_t");
1897   memcpy(&_registers, static_cast<const uint8_t *>(registers),
1898          sizeof(_registers));
1899 }
1900 
Registers_or1k()1901 inline Registers_or1k::Registers_or1k() {
1902   memset(&_registers, 0, sizeof(_registers));
1903 }
1904 
validRegister(int regNum) const1905 inline bool Registers_or1k::validRegister(int regNum) const {
1906   if (regNum == UNW_REG_IP)
1907     return true;
1908   if (regNum == UNW_REG_SP)
1909     return true;
1910   if (regNum < 0)
1911     return false;
1912   if (regNum <= UNW_OR1K_R31)
1913     return true;
1914   return false;
1915 }
1916 
getRegister(int regNum) const1917 inline uint32_t Registers_or1k::getRegister(int regNum) const {
1918   if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31)
1919     return _registers.__r[regNum - UNW_OR1K_R0];
1920 
1921   switch (regNum) {
1922   case UNW_REG_IP:
1923     return _registers.__r[9];
1924   case UNW_REG_SP:
1925     return _registers.__r[1];
1926   }
1927   _LIBUNWIND_ABORT("unsupported or1k register");
1928 }
1929 
setRegister(int regNum,uint32_t value)1930 inline void Registers_or1k::setRegister(int regNum, uint32_t value) {
1931   if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) {
1932     _registers.__r[regNum - UNW_OR1K_R0] = value;
1933     return;
1934   }
1935 
1936   switch (regNum) {
1937   case UNW_REG_IP:
1938     _registers.__r[9] = value;
1939     return;
1940   case UNW_REG_SP:
1941     _registers.__r[1] = value;
1942     return;
1943   }
1944   _LIBUNWIND_ABORT("unsupported or1k register");
1945 }
1946 
validFloatRegister(int) const1947 inline bool Registers_or1k::validFloatRegister(int /* regNum */) const {
1948   return false;
1949 }
1950 
getFloatRegister(int) const1951 inline double Registers_or1k::getFloatRegister(int /* regNum */) const {
1952   _LIBUNWIND_ABORT("or1k float support not implemented");
1953 }
1954 
setFloatRegister(int,double)1955 inline void Registers_or1k::setFloatRegister(int /* regNum */,
1956                                              double /* value */) {
1957   _LIBUNWIND_ABORT("or1k float support not implemented");
1958 }
1959 
validVectorRegister(int) const1960 inline bool Registers_or1k::validVectorRegister(int /* regNum */) const {
1961   return false;
1962 }
1963 
getVectorRegister(int) const1964 inline v128 Registers_or1k::getVectorRegister(int /* regNum */) const {
1965   _LIBUNWIND_ABORT("or1k vector support not implemented");
1966 }
1967 
setVectorRegister(int,v128)1968 inline void Registers_or1k::setVectorRegister(int /* regNum */, v128 /* value */) {
1969   _LIBUNWIND_ABORT("or1k vector support not implemented");
1970 }
1971 
getRegisterName(int regNum)1972 inline const char *Registers_or1k::getRegisterName(int regNum) {
1973   switch (regNum) {
1974   case UNW_OR1K_R0:
1975     return "r0";
1976   case UNW_OR1K_R1:
1977     return "r1";
1978   case UNW_OR1K_R2:
1979     return "r2";
1980   case UNW_OR1K_R3:
1981     return "r3";
1982   case UNW_OR1K_R4:
1983     return "r4";
1984   case UNW_OR1K_R5:
1985     return "r5";
1986   case UNW_OR1K_R6:
1987     return "r6";
1988   case UNW_OR1K_R7:
1989     return "r7";
1990   case UNW_OR1K_R8:
1991     return "r8";
1992   case UNW_OR1K_R9:
1993     return "r9";
1994   case UNW_OR1K_R10:
1995     return "r10";
1996   case UNW_OR1K_R11:
1997     return "r11";
1998   case UNW_OR1K_R12:
1999     return "r12";
2000   case UNW_OR1K_R13:
2001     return "r13";
2002   case UNW_OR1K_R14:
2003     return "r14";
2004   case UNW_OR1K_R15:
2005     return "r15";
2006   case UNW_OR1K_R16:
2007     return "r16";
2008   case UNW_OR1K_R17:
2009     return "r17";
2010   case UNW_OR1K_R18:
2011     return "r18";
2012   case UNW_OR1K_R19:
2013     return "r19";
2014   case UNW_OR1K_R20:
2015     return "r20";
2016   case UNW_OR1K_R21:
2017     return "r21";
2018   case UNW_OR1K_R22:
2019     return "r22";
2020   case UNW_OR1K_R23:
2021     return "r23";
2022   case UNW_OR1K_R24:
2023     return "r24";
2024   case UNW_OR1K_R25:
2025     return "r25";
2026   case UNW_OR1K_R26:
2027     return "r26";
2028   case UNW_OR1K_R27:
2029     return "r27";
2030   case UNW_OR1K_R28:
2031     return "r28";
2032   case UNW_OR1K_R29:
2033     return "r29";
2034   case UNW_OR1K_R30:
2035     return "r30";
2036   case UNW_OR1K_R31:
2037     return "r31";
2038   default:
2039     return "unknown register";
2040   }
2041 
2042 }
2043 #endif // _LIBUNWIND_TARGET_OR1K
2044 
2045 #if defined(_LIBUNWIND_TARGET_MIPS_O32)
2046 /// Registers_mips_o32 holds the register state of a thread in a 32-bit MIPS
2047 /// process.
2048 class _LIBUNWIND_HIDDEN Registers_mips_o32 {
2049 public:
2050   Registers_mips_o32();
2051   Registers_mips_o32(const void *registers);
2052 
2053   bool        validRegister(int num) const;
2054   uint32_t    getRegister(int num) const;
2055   void        setRegister(int num, uint32_t value);
2056   bool        validFloatRegister(int num) const;
2057   double      getFloatRegister(int num) const;
2058   void        setFloatRegister(int num, double value);
2059   bool        validVectorRegister(int num) const;
2060   v128        getVectorRegister(int num) const;
2061   void        setVectorRegister(int num, v128 value);
2062   const char *getRegisterName(int num);
2063   void        jumpto();
lastDwarfRegNum()2064   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
2065 
getSP() const2066   uint32_t  getSP() const         { return _registers.__r[29]; }
setSP(uint32_t value)2067   void      setSP(uint32_t value) { _registers.__r[29] = value; }
getIP() const2068   uint32_t  getIP() const         { return _registers.__pc; }
setIP(uint32_t value)2069   void      setIP(uint32_t value) { _registers.__pc = value; }
2070 
2071 private:
2072   struct mips_o32_thread_state_t {
2073     uint32_t __r[32];
2074     uint32_t __pc;
2075     uint32_t __hi;
2076     uint32_t __lo;
2077   };
2078 
2079   mips_o32_thread_state_t _registers;
2080 };
2081 
Registers_mips_o32(const void * registers)2082 inline Registers_mips_o32::Registers_mips_o32(const void *registers) {
2083   static_assert((check_fit<Registers_mips_o32, unw_context_t>::does_fit),
2084                 "mips_o32 registers do not fit into unw_context_t");
2085   memcpy(&_registers, static_cast<const uint8_t *>(registers),
2086          sizeof(_registers));
2087 }
2088 
Registers_mips_o32()2089 inline Registers_mips_o32::Registers_mips_o32() {
2090   memset(&_registers, 0, sizeof(_registers));
2091 }
2092 
validRegister(int regNum) const2093 inline bool Registers_mips_o32::validRegister(int regNum) const {
2094   if (regNum == UNW_REG_IP)
2095     return true;
2096   if (regNum == UNW_REG_SP)
2097     return true;
2098   if (regNum < 0)
2099     return false;
2100   if (regNum <= UNW_MIPS_R31)
2101     return true;
2102   if (regNum == UNW_MIPS_HI)
2103     return true;
2104   if (regNum == UNW_MIPS_LO)
2105     return true;
2106   // FIXME: Hard float, DSP accumulator registers, MSA registers
2107   return false;
2108 }
2109 
getRegister(int regNum) const2110 inline uint32_t Registers_mips_o32::getRegister(int regNum) const {
2111   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
2112     return _registers.__r[regNum - UNW_MIPS_R0];
2113 
2114   switch (regNum) {
2115   case UNW_REG_IP:
2116     return _registers.__pc;
2117   case UNW_REG_SP:
2118     return _registers.__r[29];
2119   case UNW_MIPS_HI:
2120     return _registers.__hi;
2121   case UNW_MIPS_LO:
2122     return _registers.__lo;
2123   }
2124   _LIBUNWIND_ABORT("unsupported mips_o32 register");
2125 }
2126 
setRegister(int regNum,uint32_t value)2127 inline void Registers_mips_o32::setRegister(int regNum, uint32_t value) {
2128   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
2129     _registers.__r[regNum - UNW_MIPS_R0] = value;
2130     return;
2131   }
2132 
2133   switch (regNum) {
2134   case UNW_REG_IP:
2135     _registers.__pc = value;
2136     return;
2137   case UNW_REG_SP:
2138     _registers.__r[29] = value;
2139     return;
2140   case UNW_MIPS_HI:
2141     _registers.__hi = value;
2142     return;
2143   case UNW_MIPS_LO:
2144     _registers.__lo = value;
2145     return;
2146   }
2147   _LIBUNWIND_ABORT("unsupported mips_o32 register");
2148 }
2149 
validFloatRegister(int) const2150 inline bool Registers_mips_o32::validFloatRegister(int /* regNum */) const {
2151   return false;
2152 }
2153 
getFloatRegister(int) const2154 inline double Registers_mips_o32::getFloatRegister(int /* regNum */) const {
2155   _LIBUNWIND_ABORT("mips_o32 float support not implemented");
2156 }
2157 
setFloatRegister(int,double)2158 inline void Registers_mips_o32::setFloatRegister(int /* regNum */,
2159                                                  double /* value */) {
2160   _LIBUNWIND_ABORT("mips_o32 float support not implemented");
2161 }
2162 
validVectorRegister(int) const2163 inline bool Registers_mips_o32::validVectorRegister(int /* regNum */) const {
2164   return false;
2165 }
2166 
getVectorRegister(int) const2167 inline v128 Registers_mips_o32::getVectorRegister(int /* regNum */) const {
2168   _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
2169 }
2170 
setVectorRegister(int,v128)2171 inline void Registers_mips_o32::setVectorRegister(int /* regNum */, v128 /* value */) {
2172   _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
2173 }
2174 
getRegisterName(int regNum)2175 inline const char *Registers_mips_o32::getRegisterName(int regNum) {
2176   switch (regNum) {
2177   case UNW_MIPS_R0:
2178     return "$0";
2179   case UNW_MIPS_R1:
2180     return "$1";
2181   case UNW_MIPS_R2:
2182     return "$2";
2183   case UNW_MIPS_R3:
2184     return "$3";
2185   case UNW_MIPS_R4:
2186     return "$4";
2187   case UNW_MIPS_R5:
2188     return "$5";
2189   case UNW_MIPS_R6:
2190     return "$6";
2191   case UNW_MIPS_R7:
2192     return "$7";
2193   case UNW_MIPS_R8:
2194     return "$8";
2195   case UNW_MIPS_R9:
2196     return "$9";
2197   case UNW_MIPS_R10:
2198     return "$10";
2199   case UNW_MIPS_R11:
2200     return "$11";
2201   case UNW_MIPS_R12:
2202     return "$12";
2203   case UNW_MIPS_R13:
2204     return "$13";
2205   case UNW_MIPS_R14:
2206     return "$14";
2207   case UNW_MIPS_R15:
2208     return "$15";
2209   case UNW_MIPS_R16:
2210     return "$16";
2211   case UNW_MIPS_R17:
2212     return "$17";
2213   case UNW_MIPS_R18:
2214     return "$18";
2215   case UNW_MIPS_R19:
2216     return "$19";
2217   case UNW_MIPS_R20:
2218     return "$20";
2219   case UNW_MIPS_R21:
2220     return "$21";
2221   case UNW_MIPS_R22:
2222     return "$22";
2223   case UNW_MIPS_R23:
2224     return "$23";
2225   case UNW_MIPS_R24:
2226     return "$24";
2227   case UNW_MIPS_R25:
2228     return "$25";
2229   case UNW_MIPS_R26:
2230     return "$26";
2231   case UNW_MIPS_R27:
2232     return "$27";
2233   case UNW_MIPS_R28:
2234     return "$28";
2235   case UNW_MIPS_R29:
2236     return "$29";
2237   case UNW_MIPS_R30:
2238     return "$30";
2239   case UNW_MIPS_R31:
2240     return "$31";
2241   case UNW_MIPS_HI:
2242     return "$hi";
2243   case UNW_MIPS_LO:
2244     return "$lo";
2245   default:
2246     return "unknown register";
2247   }
2248 }
2249 #endif // _LIBUNWIND_TARGET_MIPS_O32
2250 
2251 #if defined(_LIBUNWIND_TARGET_MIPS_N64)
2252 /// Registers_mips_n64 holds the register state of a thread in a 64-bit MIPS
2253 /// process.
2254 class _LIBUNWIND_HIDDEN Registers_mips_n64 {
2255 public:
2256   Registers_mips_n64();
2257   Registers_mips_n64(const void *registers);
2258 
2259   bool        validRegister(int num) const;
2260   uint64_t    getRegister(int num) const;
2261   void        setRegister(int num, uint64_t value);
2262   bool        validFloatRegister(int num) const;
2263   double      getFloatRegister(int num) const;
2264   void        setFloatRegister(int num, double value);
2265   bool        validVectorRegister(int num) const;
2266   v128        getVectorRegister(int num) const;
2267   void        setVectorRegister(int num, v128 value);
2268   const char *getRegisterName(int num);
2269   void        jumpto();
lastDwarfRegNum()2270   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
2271 
getSP() const2272   uint64_t  getSP() const         { return _registers.__r[29]; }
setSP(uint64_t value)2273   void      setSP(uint64_t value) { _registers.__r[29] = value; }
getIP() const2274   uint64_t  getIP() const         { return _registers.__pc; }
setIP(uint64_t value)2275   void      setIP(uint64_t value) { _registers.__pc = value; }
2276 
2277 private:
2278   struct mips_n64_thread_state_t {
2279     uint64_t __r[32];
2280     uint64_t __pc;
2281     uint64_t __hi;
2282     uint64_t __lo;
2283   };
2284 
2285   mips_n64_thread_state_t _registers;
2286 };
2287 
Registers_mips_n64(const void * registers)2288 inline Registers_mips_n64::Registers_mips_n64(const void *registers) {
2289   static_assert((check_fit<Registers_mips_n64, unw_context_t>::does_fit),
2290                 "mips_n64 registers do not fit into unw_context_t");
2291   memcpy(&_registers, static_cast<const uint8_t *>(registers),
2292          sizeof(_registers));
2293 }
2294 
Registers_mips_n64()2295 inline Registers_mips_n64::Registers_mips_n64() {
2296   memset(&_registers, 0, sizeof(_registers));
2297 }
2298 
validRegister(int regNum) const2299 inline bool Registers_mips_n64::validRegister(int regNum) const {
2300   if (regNum == UNW_REG_IP)
2301     return true;
2302   if (regNum == UNW_REG_SP)
2303     return true;
2304   if (regNum < 0)
2305     return false;
2306   if (regNum <= UNW_MIPS_R31)
2307     return true;
2308   if (regNum == UNW_MIPS_HI)
2309     return true;
2310   if (regNum == UNW_MIPS_LO)
2311     return true;
2312   // FIXME: Hard float, DSP accumulator registers, MSA registers
2313   return false;
2314 }
2315 
getRegister(int regNum) const2316 inline uint64_t Registers_mips_n64::getRegister(int regNum) const {
2317   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
2318     return _registers.__r[regNum - UNW_MIPS_R0];
2319 
2320   switch (regNum) {
2321   case UNW_REG_IP:
2322     return _registers.__pc;
2323   case UNW_REG_SP:
2324     return _registers.__r[29];
2325   case UNW_MIPS_HI:
2326     return _registers.__hi;
2327   case UNW_MIPS_LO:
2328     return _registers.__lo;
2329   }
2330   _LIBUNWIND_ABORT("unsupported mips_n64 register");
2331 }
2332 
setRegister(int regNum,uint64_t value)2333 inline void Registers_mips_n64::setRegister(int regNum, uint64_t value) {
2334   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
2335     _registers.__r[regNum - UNW_MIPS_R0] = value;
2336     return;
2337   }
2338 
2339   switch (regNum) {
2340   case UNW_REG_IP:
2341     _registers.__pc = value;
2342     return;
2343   case UNW_REG_SP:
2344     _registers.__r[29] = value;
2345     return;
2346   case UNW_MIPS_HI:
2347     _registers.__hi = value;
2348     return;
2349   case UNW_MIPS_LO:
2350     _registers.__lo = value;
2351     return;
2352   }
2353   _LIBUNWIND_ABORT("unsupported mips_n64 register");
2354 }
2355 
validFloatRegister(int) const2356 inline bool Registers_mips_n64::validFloatRegister(int /* regNum */) const {
2357   return false;
2358 }
2359 
getFloatRegister(int) const2360 inline double Registers_mips_n64::getFloatRegister(int /* regNum */) const {
2361   _LIBUNWIND_ABORT("mips_n64 float support not implemented");
2362 }
2363 
setFloatRegister(int,double)2364 inline void Registers_mips_n64::setFloatRegister(int /* regNum */,
2365                                                  double /* value */) {
2366   _LIBUNWIND_ABORT("mips_n64 float support not implemented");
2367 }
2368 
validVectorRegister(int) const2369 inline bool Registers_mips_n64::validVectorRegister(int /* regNum */) const {
2370   return false;
2371 }
2372 
getVectorRegister(int) const2373 inline v128 Registers_mips_n64::getVectorRegister(int /* regNum */) const {
2374   _LIBUNWIND_ABORT("mips_n64 vector support not implemented");
2375 }
2376 
setVectorRegister(int,v128)2377 inline void Registers_mips_n64::setVectorRegister(int /* regNum */, v128 /* value */) {
2378   _LIBUNWIND_ABORT("mips_n64 vector support not implemented");
2379 }
2380 
getRegisterName(int regNum)2381 inline const char *Registers_mips_n64::getRegisterName(int regNum) {
2382   switch (regNum) {
2383   case UNW_MIPS_R0:
2384     return "$0";
2385   case UNW_MIPS_R1:
2386     return "$1";
2387   case UNW_MIPS_R2:
2388     return "$2";
2389   case UNW_MIPS_R3:
2390     return "$3";
2391   case UNW_MIPS_R4:
2392     return "$4";
2393   case UNW_MIPS_R5:
2394     return "$5";
2395   case UNW_MIPS_R6:
2396     return "$6";
2397   case UNW_MIPS_R7:
2398     return "$7";
2399   case UNW_MIPS_R8:
2400     return "$8";
2401   case UNW_MIPS_R9:
2402     return "$9";
2403   case UNW_MIPS_R10:
2404     return "$10";
2405   case UNW_MIPS_R11:
2406     return "$11";
2407   case UNW_MIPS_R12:
2408     return "$12";
2409   case UNW_MIPS_R13:
2410     return "$13";
2411   case UNW_MIPS_R14:
2412     return "$14";
2413   case UNW_MIPS_R15:
2414     return "$15";
2415   case UNW_MIPS_R16:
2416     return "$16";
2417   case UNW_MIPS_R17:
2418     return "$17";
2419   case UNW_MIPS_R18:
2420     return "$18";
2421   case UNW_MIPS_R19:
2422     return "$19";
2423   case UNW_MIPS_R20:
2424     return "$20";
2425   case UNW_MIPS_R21:
2426     return "$21";
2427   case UNW_MIPS_R22:
2428     return "$22";
2429   case UNW_MIPS_R23:
2430     return "$23";
2431   case UNW_MIPS_R24:
2432     return "$24";
2433   case UNW_MIPS_R25:
2434     return "$25";
2435   case UNW_MIPS_R26:
2436     return "$26";
2437   case UNW_MIPS_R27:
2438     return "$27";
2439   case UNW_MIPS_R28:
2440     return "$28";
2441   case UNW_MIPS_R29:
2442     return "$29";
2443   case UNW_MIPS_R30:
2444     return "$30";
2445   case UNW_MIPS_R31:
2446     return "$31";
2447   case UNW_MIPS_HI:
2448     return "$hi";
2449   case UNW_MIPS_LO:
2450     return "$lo";
2451   default:
2452     return "unknown register";
2453   }
2454 }
2455 #endif // _LIBUNWIND_TARGET_MIPS_N64
2456 } // namespace libunwind
2457 
2458 #endif // __REGISTERS_HPP__
2459