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