• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===----------------------------- Registers.hpp --------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //
9 //  Models register sets for supported processors.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef __REGISTERS_HPP__
14 #define __REGISTERS_HPP__
15 
16 #include <stdint.h>
17 #include <strings.h>
18 #include <string.h>
19 
20 #include "libunwind.h"
21 #include "config.h"
22 
23 namespace libunwind {
24 
25 // For emulating 128-bit registers
26 struct v128 { uint32_t vec[4]; };
27 
28 
29 /// Registers_x86 holds the register state of a thread in a 32-bit intel
30 /// process.
31 class _LIBUNWIND_HIDDEN Registers_x86 {
32 public:
33   Registers_x86();
34   Registers_x86(const void *registers);
35 
36   bool        validRegister(int num) const;
37   uint32_t    getRegister(int num) const;
38   void        setRegister(int num, uint32_t value);
validFloatRegister(int) const39   bool        validFloatRegister(int) const { return false; }
40   double      getFloatRegister(int num) const;
41   void        setFloatRegister(int num, double value);
validVectorRegister(int) const42   bool        validVectorRegister(int) const { return false; }
43   v128        getVectorRegister(int num) const;
44   void        setVectorRegister(int num, v128 value);
45   const char *getRegisterName(int num);
46   void        jumpto();
lastDwarfRegNum()47   static int  lastDwarfRegNum() { return 8; }
48 
getSP() const49   uint32_t  getSP() const          { return _registers.__esp; }
setSP(uint32_t value)50   void      setSP(uint32_t value)  { _registers.__esp = value; }
getIP() const51   uint32_t  getIP() const          { return _registers.__eip; }
setIP(uint32_t value)52   void      setIP(uint32_t value)  { _registers.__eip = value; }
getEBP() const53   uint32_t  getEBP() const         { return _registers.__ebp; }
setEBP(uint32_t value)54   void      setEBP(uint32_t value) { _registers.__ebp = value; }
getEBX() const55   uint32_t  getEBX() const         { return _registers.__ebx; }
setEBX(uint32_t value)56   void      setEBX(uint32_t value) { _registers.__ebx = value; }
getECX() const57   uint32_t  getECX() const         { return _registers.__ecx; }
setECX(uint32_t value)58   void      setECX(uint32_t value) { _registers.__ecx = value; }
getEDX() const59   uint32_t  getEDX() const         { return _registers.__edx; }
setEDX(uint32_t value)60   void      setEDX(uint32_t value) { _registers.__edx = value; }
getESI() const61   uint32_t  getESI() const         { return _registers.__esi; }
setESI(uint32_t value)62   void      setESI(uint32_t value) { _registers.__esi = value; }
getEDI() const63   uint32_t  getEDI() const         { return _registers.__edi; }
setEDI(uint32_t value)64   void      setEDI(uint32_t value) { _registers.__edi = value; }
65 
66 private:
67   struct GPRs {
68     unsigned int __eax;
69     unsigned int __ebx;
70     unsigned int __ecx;
71     unsigned int __edx;
72     unsigned int __edi;
73     unsigned int __esi;
74     unsigned int __ebp;
75     unsigned int __esp;
76     unsigned int __ss;
77     unsigned int __eflags;
78     unsigned int __eip;
79     unsigned int __cs;
80     unsigned int __ds;
81     unsigned int __es;
82     unsigned int __fs;
83     unsigned int __gs;
84   };
85 
86   GPRs _registers;
87 };
88 
Registers_x86(const void * registers)89 inline Registers_x86::Registers_x86(const void *registers) {
90   static_assert(sizeof(Registers_x86) < sizeof(unw_context_t),
91                     "x86 registers do not fit into unw_context_t");
92   memcpy(&_registers, registers, sizeof(_registers));
93 }
94 
Registers_x86()95 inline Registers_x86::Registers_x86() {
96   memset(&_registers, 0, sizeof(_registers));
97 }
98 
validRegister(int regNum) const99 inline bool Registers_x86::validRegister(int regNum) const {
100   if (regNum == UNW_REG_IP)
101     return true;
102   if (regNum == UNW_REG_SP)
103     return true;
104   if (regNum < 0)
105     return false;
106   if (regNum > 7)
107     return false;
108   return true;
109 }
110 
getRegister(int regNum) const111 inline uint32_t Registers_x86::getRegister(int regNum) const {
112   switch (regNum) {
113   case UNW_REG_IP:
114     return _registers.__eip;
115   case UNW_REG_SP:
116     return _registers.__esp;
117   case UNW_X86_EAX:
118     return _registers.__eax;
119   case UNW_X86_ECX:
120     return _registers.__ecx;
121   case UNW_X86_EDX:
122     return _registers.__edx;
123   case UNW_X86_EBX:
124     return _registers.__ebx;
125   case UNW_X86_EBP:
126     return _registers.__ebp;
127   case UNW_X86_ESP:
128     return _registers.__esp;
129   case UNW_X86_ESI:
130     return _registers.__esi;
131   case UNW_X86_EDI:
132     return _registers.__edi;
133   }
134   _LIBUNWIND_ABORT("unsupported x86 register");
135 }
136 
setRegister(int regNum,uint32_t value)137 inline void Registers_x86::setRegister(int regNum, uint32_t value) {
138   switch (regNum) {
139   case UNW_REG_IP:
140     _registers.__eip = value;
141     return;
142   case UNW_REG_SP:
143     _registers.__esp = value;
144     return;
145   case UNW_X86_EAX:
146     _registers.__eax = value;
147     return;
148   case UNW_X86_ECX:
149     _registers.__ecx = value;
150     return;
151   case UNW_X86_EDX:
152     _registers.__edx = value;
153     return;
154   case UNW_X86_EBX:
155     _registers.__ebx = value;
156     return;
157   case UNW_X86_EBP:
158     _registers.__ebp = value;
159     return;
160   case UNW_X86_ESP:
161     _registers.__esp = value;
162     return;
163   case UNW_X86_ESI:
164     _registers.__esi = value;
165     return;
166   case UNW_X86_EDI:
167     _registers.__edi = value;
168     return;
169   }
170   _LIBUNWIND_ABORT("unsupported x86 register");
171 }
172 
getRegisterName(int regNum)173 inline const char *Registers_x86::getRegisterName(int regNum) {
174   switch (regNum) {
175   case UNW_REG_IP:
176     return "ip";
177   case UNW_REG_SP:
178     return "esp";
179   case UNW_X86_EAX:
180     return "eax";
181   case UNW_X86_ECX:
182     return "ecx";
183   case UNW_X86_EDX:
184     return "edx";
185   case UNW_X86_EBX:
186     return "ebx";
187   case UNW_X86_EBP:
188     return "ebp";
189   case UNW_X86_ESP:
190     return "esp";
191   case UNW_X86_ESI:
192     return "esi";
193   case UNW_X86_EDI:
194     return "edi";
195   default:
196     return "unknown register";
197   }
198 }
199 
getFloatRegister(int) const200 inline double Registers_x86::getFloatRegister(int) const {
201   _LIBUNWIND_ABORT("no x86 float registers");
202 }
203 
setFloatRegister(int,double)204 inline void Registers_x86::setFloatRegister(int, double) {
205   _LIBUNWIND_ABORT("no x86 float registers");
206 }
207 
getVectorRegister(int) const208 inline v128 Registers_x86::getVectorRegister(int) const {
209   _LIBUNWIND_ABORT("no x86 vector registers");
210 }
211 
setVectorRegister(int,v128)212 inline void Registers_x86::setVectorRegister(int, v128) {
213   _LIBUNWIND_ABORT("no x86 vector registers");
214 }
215 
216 
217 /// Registers_x86_64  holds the register state of a thread in a 64-bit intel
218 /// process.
219 class _LIBUNWIND_HIDDEN Registers_x86_64 {
220 public:
221   Registers_x86_64();
222   Registers_x86_64(const void *registers);
223 
224   bool        validRegister(int num) const;
225   uint64_t    getRegister(int num) const;
226   void        setRegister(int num, uint64_t value);
validFloatRegister(int) const227   bool        validFloatRegister(int) const { return false; }
228   double      getFloatRegister(int num) const;
229   void        setFloatRegister(int num, double value);
validVectorRegister(int) const230   bool        validVectorRegister(int) const { return false; }
231   v128        getVectorRegister(int num) const;
232   void        setVectorRegister(int num, v128 value);
233   const char *getRegisterName(int num);
234   void        jumpto();
lastDwarfRegNum()235   static int  lastDwarfRegNum() { return 16; }
236 
getSP() const237   uint64_t  getSP() const          { return _registers.__rsp; }
setSP(uint64_t value)238   void      setSP(uint64_t value)  { _registers.__rsp = value; }
getIP() const239   uint64_t  getIP() const          { return _registers.__rip; }
setIP(uint64_t value)240   void      setIP(uint64_t value)  { _registers.__rip = value; }
getRBP() const241   uint64_t  getRBP() const         { return _registers.__rbp; }
setRBP(uint64_t value)242   void      setRBP(uint64_t value) { _registers.__rbp = value; }
getRBX() const243   uint64_t  getRBX() const         { return _registers.__rbx; }
setRBX(uint64_t value)244   void      setRBX(uint64_t value) { _registers.__rbx = value; }
getR12() const245   uint64_t  getR12() const         { return _registers.__r12; }
setR12(uint64_t value)246   void      setR12(uint64_t value) { _registers.__r12 = value; }
getR13() const247   uint64_t  getR13() const         { return _registers.__r13; }
setR13(uint64_t value)248   void      setR13(uint64_t value) { _registers.__r13 = value; }
getR14() const249   uint64_t  getR14() const         { return _registers.__r14; }
setR14(uint64_t value)250   void      setR14(uint64_t value) { _registers.__r14 = value; }
getR15() const251   uint64_t  getR15() const         { return _registers.__r15; }
setR15(uint64_t value)252   void      setR15(uint64_t value) { _registers.__r15 = value; }
253 
254 private:
255   struct GPRs {
256     uint64_t __rax;
257     uint64_t __rbx;
258     uint64_t __rcx;
259     uint64_t __rdx;
260     uint64_t __rdi;
261     uint64_t __rsi;
262     uint64_t __rbp;
263     uint64_t __rsp;
264     uint64_t __r8;
265     uint64_t __r9;
266     uint64_t __r10;
267     uint64_t __r11;
268     uint64_t __r12;
269     uint64_t __r13;
270     uint64_t __r14;
271     uint64_t __r15;
272     uint64_t __rip;
273     uint64_t __rflags;
274     uint64_t __cs;
275     uint64_t __fs;
276     uint64_t __gs;
277   };
278   GPRs _registers;
279 };
280 
Registers_x86_64(const void * registers)281 inline Registers_x86_64::Registers_x86_64(const void *registers) {
282   static_assert(sizeof(Registers_x86_64) < sizeof(unw_context_t),
283                     "x86_64 registers do not fit into unw_context_t");
284   memcpy(&_registers, registers, sizeof(_registers));
285 }
286 
Registers_x86_64()287 inline Registers_x86_64::Registers_x86_64() {
288   memset(&_registers, 0, sizeof(_registers));
289 }
290 
validRegister(int regNum) const291 inline bool Registers_x86_64::validRegister(int regNum) const {
292   if (regNum == UNW_REG_IP)
293     return true;
294   if (regNum == UNW_REG_SP)
295     return true;
296   if (regNum < 0)
297     return false;
298   if (regNum > 15)
299     return false;
300   return true;
301 }
302 
getRegister(int regNum) const303 inline uint64_t Registers_x86_64::getRegister(int regNum) const {
304   switch (regNum) {
305   case UNW_REG_IP:
306     return _registers.__rip;
307   case UNW_REG_SP:
308     return _registers.__rsp;
309   case UNW_X86_64_RAX:
310     return _registers.__rax;
311   case UNW_X86_64_RDX:
312     return _registers.__rdx;
313   case UNW_X86_64_RCX:
314     return _registers.__rcx;
315   case UNW_X86_64_RBX:
316     return _registers.__rbx;
317   case UNW_X86_64_RSI:
318     return _registers.__rsi;
319   case UNW_X86_64_RDI:
320     return _registers.__rdi;
321   case UNW_X86_64_RBP:
322     return _registers.__rbp;
323   case UNW_X86_64_RSP:
324     return _registers.__rsp;
325   case UNW_X86_64_R8:
326     return _registers.__r8;
327   case UNW_X86_64_R9:
328     return _registers.__r9;
329   case UNW_X86_64_R10:
330     return _registers.__r10;
331   case UNW_X86_64_R11:
332     return _registers.__r11;
333   case UNW_X86_64_R12:
334     return _registers.__r12;
335   case UNW_X86_64_R13:
336     return _registers.__r13;
337   case UNW_X86_64_R14:
338     return _registers.__r14;
339   case UNW_X86_64_R15:
340     return _registers.__r15;
341   }
342   _LIBUNWIND_ABORT("unsupported x86_64 register");
343 }
344 
setRegister(int regNum,uint64_t value)345 inline void Registers_x86_64::setRegister(int regNum, uint64_t value) {
346   switch (regNum) {
347   case UNW_REG_IP:
348     _registers.__rip = value;
349     return;
350   case UNW_REG_SP:
351     _registers.__rsp = value;
352     return;
353   case UNW_X86_64_RAX:
354     _registers.__rax = value;
355     return;
356   case UNW_X86_64_RDX:
357     _registers.__rdx = value;
358     return;
359   case UNW_X86_64_RCX:
360     _registers.__rcx = value;
361     return;
362   case UNW_X86_64_RBX:
363     _registers.__rbx = value;
364     return;
365   case UNW_X86_64_RSI:
366     _registers.__rsi = value;
367     return;
368   case UNW_X86_64_RDI:
369     _registers.__rdi = value;
370     return;
371   case UNW_X86_64_RBP:
372     _registers.__rbp = value;
373     return;
374   case UNW_X86_64_RSP:
375     _registers.__rsp = value;
376     return;
377   case UNW_X86_64_R8:
378     _registers.__r8 = value;
379     return;
380   case UNW_X86_64_R9:
381     _registers.__r9 = value;
382     return;
383   case UNW_X86_64_R10:
384     _registers.__r10 = value;
385     return;
386   case UNW_X86_64_R11:
387     _registers.__r11 = value;
388     return;
389   case UNW_X86_64_R12:
390     _registers.__r12 = value;
391     return;
392   case UNW_X86_64_R13:
393     _registers.__r13 = value;
394     return;
395   case UNW_X86_64_R14:
396     _registers.__r14 = value;
397     return;
398   case UNW_X86_64_R15:
399     _registers.__r15 = value;
400     return;
401   }
402   _LIBUNWIND_ABORT("unsupported x86_64 register");
403 }
404 
getRegisterName(int regNum)405 inline const char *Registers_x86_64::getRegisterName(int regNum) {
406   switch (regNum) {
407   case UNW_REG_IP:
408     return "rip";
409   case UNW_REG_SP:
410     return "rsp";
411   case UNW_X86_64_RAX:
412     return "rax";
413   case UNW_X86_64_RDX:
414     return "rdx";
415   case UNW_X86_64_RCX:
416     return "rcx";
417   case UNW_X86_64_RBX:
418     return "rbx";
419   case UNW_X86_64_RSI:
420     return "rsi";
421   case UNW_X86_64_RDI:
422     return "rdi";
423   case UNW_X86_64_RBP:
424     return "rbp";
425   case UNW_X86_64_RSP:
426     return "rsp";
427   case UNW_X86_64_R8:
428     return "r8";
429   case UNW_X86_64_R9:
430     return "r9";
431   case UNW_X86_64_R10:
432     return "r10";
433   case UNW_X86_64_R11:
434     return "r11";
435   case UNW_X86_64_R12:
436     return "r12";
437   case UNW_X86_64_R13:
438     return "r13";
439   case UNW_X86_64_R14:
440     return "r14";
441   case UNW_X86_64_R15:
442     return "r15";
443   default:
444     return "unknown register";
445   }
446 }
447 
getFloatRegister(int) const448 inline double Registers_x86_64::getFloatRegister(int) const {
449   _LIBUNWIND_ABORT("no x86_64 float registers");
450 }
451 
setFloatRegister(int,double)452 inline void Registers_x86_64::setFloatRegister(int, double) {
453   _LIBUNWIND_ABORT("no x86_64 float registers");
454 }
455 
getVectorRegister(int) const456 inline v128 Registers_x86_64::getVectorRegister(int) const {
457   _LIBUNWIND_ABORT("no x86_64 vector registers");
458 }
459 
setVectorRegister(int,v128)460 inline void Registers_x86_64::setVectorRegister(int, v128) {
461   _LIBUNWIND_ABORT("no x86_64 vector registers");
462 }
463 
464 
465 /// Registers_ppc holds the register state of a thread in a 32-bit PowerPC
466 /// process.
467 class _LIBUNWIND_HIDDEN Registers_ppc {
468 public:
469   Registers_ppc();
470   Registers_ppc(const void *registers);
471 
472   bool        validRegister(int num) const;
473   uint32_t    getRegister(int num) const;
474   void        setRegister(int num, uint32_t value);
475   bool        validFloatRegister(int num) const;
476   double      getFloatRegister(int num) const;
477   void        setFloatRegister(int num, double value);
478   bool        validVectorRegister(int num) const;
479   v128        getVectorRegister(int num) const;
480   void        setVectorRegister(int num, v128 value);
481   const char *getRegisterName(int num);
482   void        jumpto();
lastDwarfRegNum()483   static int  lastDwarfRegNum() { return 112; }
484 
getSP() const485   uint64_t  getSP() const         { return _registers.__r1; }
setSP(uint32_t value)486   void      setSP(uint32_t value) { _registers.__r1 = value; }
getIP() const487   uint64_t  getIP() const         { return _registers.__srr0; }
setIP(uint32_t value)488   void      setIP(uint32_t value) { _registers.__srr0 = value; }
489 
490 private:
491   struct ppc_thread_state_t {
492     unsigned int __srr0; /* Instruction address register (PC) */
493     unsigned int __srr1; /* Machine state register (supervisor) */
494     unsigned int __r0;
495     unsigned int __r1;
496     unsigned int __r2;
497     unsigned int __r3;
498     unsigned int __r4;
499     unsigned int __r5;
500     unsigned int __r6;
501     unsigned int __r7;
502     unsigned int __r8;
503     unsigned int __r9;
504     unsigned int __r10;
505     unsigned int __r11;
506     unsigned int __r12;
507     unsigned int __r13;
508     unsigned int __r14;
509     unsigned int __r15;
510     unsigned int __r16;
511     unsigned int __r17;
512     unsigned int __r18;
513     unsigned int __r19;
514     unsigned int __r20;
515     unsigned int __r21;
516     unsigned int __r22;
517     unsigned int __r23;
518     unsigned int __r24;
519     unsigned int __r25;
520     unsigned int __r26;
521     unsigned int __r27;
522     unsigned int __r28;
523     unsigned int __r29;
524     unsigned int __r30;
525     unsigned int __r31;
526     unsigned int __cr;     /* Condition register */
527     unsigned int __xer;    /* User's integer exception register */
528     unsigned int __lr;     /* Link register */
529     unsigned int __ctr;    /* Count register */
530     unsigned int __mq;     /* MQ register (601 only) */
531     unsigned int __vrsave; /* Vector Save Register */
532   };
533 
534   struct ppc_float_state_t {
535     double __fpregs[32];
536 
537     unsigned int __fpscr_pad; /* fpscr is 64 bits, 32 bits of rubbish */
538     unsigned int __fpscr;     /* floating point status register */
539   };
540 
541   ppc_thread_state_t _registers;
542   ppc_float_state_t  _floatRegisters;
543   v128               _vectorRegisters[32]; // offset 424
544 };
545 
Registers_ppc(const void * registers)546 inline Registers_ppc::Registers_ppc(const void *registers) {
547   static_assert(sizeof(Registers_ppc) < sizeof(unw_context_t),
548                     "ppc registers do not fit into unw_context_t");
549   memcpy(&_registers, static_cast<const uint8_t *>(registers),
550          sizeof(_registers));
551   static_assert(sizeof(ppc_thread_state_t) == 160,
552                 "expected float register offset to be 160");
553   memcpy(&_floatRegisters,
554          static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t),
555          sizeof(_floatRegisters));
556   static_assert(sizeof(ppc_thread_state_t) + sizeof(ppc_float_state_t) == 424,
557                 "expected vector register offset to be 424 bytes");
558   memcpy(_vectorRegisters,
559          static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t) +
560              sizeof(ppc_float_state_t),
561          sizeof(_vectorRegisters));
562 }
563 
Registers_ppc()564 inline Registers_ppc::Registers_ppc() {
565   memset(&_registers, 0, sizeof(_registers));
566   memset(&_floatRegisters, 0, sizeof(_floatRegisters));
567   memset(&_vectorRegisters, 0, sizeof(_vectorRegisters));
568 }
569 
validRegister(int regNum) const570 inline bool Registers_ppc::validRegister(int regNum) const {
571   if (regNum == UNW_REG_IP)
572     return true;
573   if (regNum == UNW_REG_SP)
574     return true;
575   if (regNum == UNW_PPC_VRSAVE)
576     return true;
577   if (regNum < 0)
578     return false;
579   if (regNum <= UNW_PPC_R31)
580     return true;
581   if (regNum == UNW_PPC_MQ)
582     return true;
583   if (regNum == UNW_PPC_LR)
584     return true;
585   if (regNum == UNW_PPC_CTR)
586     return true;
587   if ((UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7))
588     return true;
589   return false;
590 }
591 
getRegister(int regNum) const592 inline uint32_t Registers_ppc::getRegister(int regNum) const {
593   switch (regNum) {
594   case UNW_REG_IP:
595     return _registers.__srr0;
596   case UNW_REG_SP:
597     return _registers.__r1;
598   case UNW_PPC_R0:
599     return _registers.__r0;
600   case UNW_PPC_R1:
601     return _registers.__r1;
602   case UNW_PPC_R2:
603     return _registers.__r2;
604   case UNW_PPC_R3:
605     return _registers.__r3;
606   case UNW_PPC_R4:
607     return _registers.__r4;
608   case UNW_PPC_R5:
609     return _registers.__r5;
610   case UNW_PPC_R6:
611     return _registers.__r6;
612   case UNW_PPC_R7:
613     return _registers.__r7;
614   case UNW_PPC_R8:
615     return _registers.__r8;
616   case UNW_PPC_R9:
617     return _registers.__r9;
618   case UNW_PPC_R10:
619     return _registers.__r10;
620   case UNW_PPC_R11:
621     return _registers.__r11;
622   case UNW_PPC_R12:
623     return _registers.__r12;
624   case UNW_PPC_R13:
625     return _registers.__r13;
626   case UNW_PPC_R14:
627     return _registers.__r14;
628   case UNW_PPC_R15:
629     return _registers.__r15;
630   case UNW_PPC_R16:
631     return _registers.__r16;
632   case UNW_PPC_R17:
633     return _registers.__r17;
634   case UNW_PPC_R18:
635     return _registers.__r18;
636   case UNW_PPC_R19:
637     return _registers.__r19;
638   case UNW_PPC_R20:
639     return _registers.__r20;
640   case UNW_PPC_R21:
641     return _registers.__r21;
642   case UNW_PPC_R22:
643     return _registers.__r22;
644   case UNW_PPC_R23:
645     return _registers.__r23;
646   case UNW_PPC_R24:
647     return _registers.__r24;
648   case UNW_PPC_R25:
649     return _registers.__r25;
650   case UNW_PPC_R26:
651     return _registers.__r26;
652   case UNW_PPC_R27:
653     return _registers.__r27;
654   case UNW_PPC_R28:
655     return _registers.__r28;
656   case UNW_PPC_R29:
657     return _registers.__r29;
658   case UNW_PPC_R30:
659     return _registers.__r30;
660   case UNW_PPC_R31:
661     return _registers.__r31;
662   case UNW_PPC_LR:
663     return _registers.__lr;
664   case UNW_PPC_CR0:
665     return (_registers.__cr & 0xF0000000);
666   case UNW_PPC_CR1:
667     return (_registers.__cr & 0x0F000000);
668   case UNW_PPC_CR2:
669     return (_registers.__cr & 0x00F00000);
670   case UNW_PPC_CR3:
671     return (_registers.__cr & 0x000F0000);
672   case UNW_PPC_CR4:
673     return (_registers.__cr & 0x0000F000);
674   case UNW_PPC_CR5:
675     return (_registers.__cr & 0x00000F00);
676   case UNW_PPC_CR6:
677     return (_registers.__cr & 0x000000F0);
678   case UNW_PPC_CR7:
679     return (_registers.__cr & 0x0000000F);
680   case UNW_PPC_VRSAVE:
681     return _registers.__vrsave;
682   }
683   _LIBUNWIND_ABORT("unsupported ppc register");
684 }
685 
setRegister(int regNum,uint32_t value)686 inline void Registers_ppc::setRegister(int regNum, uint32_t value) {
687   //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value);
688   switch (regNum) {
689   case UNW_REG_IP:
690     _registers.__srr0 = value;
691     return;
692   case UNW_REG_SP:
693     _registers.__r1 = value;
694     return;
695   case UNW_PPC_R0:
696     _registers.__r0 = value;
697     return;
698   case UNW_PPC_R1:
699     _registers.__r1 = value;
700     return;
701   case UNW_PPC_R2:
702     _registers.__r2 = value;
703     return;
704   case UNW_PPC_R3:
705     _registers.__r3 = value;
706     return;
707   case UNW_PPC_R4:
708     _registers.__r4 = value;
709     return;
710   case UNW_PPC_R5:
711     _registers.__r5 = value;
712     return;
713   case UNW_PPC_R6:
714     _registers.__r6 = value;
715     return;
716   case UNW_PPC_R7:
717     _registers.__r7 = value;
718     return;
719   case UNW_PPC_R8:
720     _registers.__r8 = value;
721     return;
722   case UNW_PPC_R9:
723     _registers.__r9 = value;
724     return;
725   case UNW_PPC_R10:
726     _registers.__r10 = value;
727     return;
728   case UNW_PPC_R11:
729     _registers.__r11 = value;
730     return;
731   case UNW_PPC_R12:
732     _registers.__r12 = value;
733     return;
734   case UNW_PPC_R13:
735     _registers.__r13 = value;
736     return;
737   case UNW_PPC_R14:
738     _registers.__r14 = value;
739     return;
740   case UNW_PPC_R15:
741     _registers.__r15 = value;
742     return;
743   case UNW_PPC_R16:
744     _registers.__r16 = value;
745     return;
746   case UNW_PPC_R17:
747     _registers.__r17 = value;
748     return;
749   case UNW_PPC_R18:
750     _registers.__r18 = value;
751     return;
752   case UNW_PPC_R19:
753     _registers.__r19 = value;
754     return;
755   case UNW_PPC_R20:
756     _registers.__r20 = value;
757     return;
758   case UNW_PPC_R21:
759     _registers.__r21 = value;
760     return;
761   case UNW_PPC_R22:
762     _registers.__r22 = value;
763     return;
764   case UNW_PPC_R23:
765     _registers.__r23 = value;
766     return;
767   case UNW_PPC_R24:
768     _registers.__r24 = value;
769     return;
770   case UNW_PPC_R25:
771     _registers.__r25 = value;
772     return;
773   case UNW_PPC_R26:
774     _registers.__r26 = value;
775     return;
776   case UNW_PPC_R27:
777     _registers.__r27 = value;
778     return;
779   case UNW_PPC_R28:
780     _registers.__r28 = value;
781     return;
782   case UNW_PPC_R29:
783     _registers.__r29 = value;
784     return;
785   case UNW_PPC_R30:
786     _registers.__r30 = value;
787     return;
788   case UNW_PPC_R31:
789     _registers.__r31 = value;
790     return;
791   case UNW_PPC_MQ:
792     _registers.__mq = value;
793     return;
794   case UNW_PPC_LR:
795     _registers.__lr = value;
796     return;
797   case UNW_PPC_CTR:
798     _registers.__ctr = value;
799     return;
800   case UNW_PPC_CR0:
801     _registers.__cr &= 0x0FFFFFFF;
802     _registers.__cr |= (value & 0xF0000000);
803     return;
804   case UNW_PPC_CR1:
805     _registers.__cr &= 0xF0FFFFFF;
806     _registers.__cr |= (value & 0x0F000000);
807     return;
808   case UNW_PPC_CR2:
809     _registers.__cr &= 0xFF0FFFFF;
810     _registers.__cr |= (value & 0x00F00000);
811     return;
812   case UNW_PPC_CR3:
813     _registers.__cr &= 0xFFF0FFFF;
814     _registers.__cr |= (value & 0x000F0000);
815     return;
816   case UNW_PPC_CR4:
817     _registers.__cr &= 0xFFFF0FFF;
818     _registers.__cr |= (value & 0x0000F000);
819     return;
820   case UNW_PPC_CR5:
821     _registers.__cr &= 0xFFFFF0FF;
822     _registers.__cr |= (value & 0x00000F00);
823     return;
824   case UNW_PPC_CR6:
825     _registers.__cr &= 0xFFFFFF0F;
826     _registers.__cr |= (value & 0x000000F0);
827     return;
828   case UNW_PPC_CR7:
829     _registers.__cr &= 0xFFFFFFF0;
830     _registers.__cr |= (value & 0x0000000F);
831     return;
832   case UNW_PPC_VRSAVE:
833     _registers.__vrsave = value;
834     return;
835     // not saved
836     return;
837   case UNW_PPC_XER:
838     _registers.__xer = value;
839     return;
840   case UNW_PPC_AP:
841   case UNW_PPC_VSCR:
842   case UNW_PPC_SPEFSCR:
843     // not saved
844     return;
845   }
846   _LIBUNWIND_ABORT("unsupported ppc register");
847 }
848 
validFloatRegister(int regNum) const849 inline bool Registers_ppc::validFloatRegister(int regNum) const {
850   if (regNum < UNW_PPC_F0)
851     return false;
852   if (regNum > UNW_PPC_F31)
853     return false;
854   return true;
855 }
856 
getFloatRegister(int regNum) const857 inline double Registers_ppc::getFloatRegister(int regNum) const {
858   assert(validFloatRegister(regNum));
859   return _floatRegisters.__fpregs[regNum - UNW_PPC_F0];
860 }
861 
setFloatRegister(int regNum,double value)862 inline void Registers_ppc::setFloatRegister(int regNum, double value) {
863   assert(validFloatRegister(regNum));
864   _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value;
865 }
866 
validVectorRegister(int regNum) const867 inline bool Registers_ppc::validVectorRegister(int regNum) const {
868   if (regNum < UNW_PPC_V0)
869     return false;
870   if (regNum > UNW_PPC_V31)
871     return false;
872   return true;
873 }
874 
getVectorRegister(int regNum) const875 inline v128 Registers_ppc::getVectorRegister(int regNum) const {
876   assert(validVectorRegister(regNum));
877   v128 result = _vectorRegisters[regNum - UNW_PPC_V0];
878   return result;
879 }
880 
setVectorRegister(int regNum,v128 value)881 inline void Registers_ppc::setVectorRegister(int regNum, v128 value) {
882   assert(validVectorRegister(regNum));
883   _vectorRegisters[regNum - UNW_PPC_V0] = value;
884 }
885 
getRegisterName(int regNum)886 inline const char *Registers_ppc::getRegisterName(int regNum) {
887   switch (regNum) {
888   case UNW_REG_IP:
889     return "ip";
890   case UNW_REG_SP:
891     return "sp";
892   case UNW_PPC_R0:
893     return "r0";
894   case UNW_PPC_R1:
895     return "r1";
896   case UNW_PPC_R2:
897     return "r2";
898   case UNW_PPC_R3:
899     return "r3";
900   case UNW_PPC_R4:
901     return "r4";
902   case UNW_PPC_R5:
903     return "r5";
904   case UNW_PPC_R6:
905     return "r6";
906   case UNW_PPC_R7:
907     return "r7";
908   case UNW_PPC_R8:
909     return "r8";
910   case UNW_PPC_R9:
911     return "r9";
912   case UNW_PPC_R10:
913     return "r10";
914   case UNW_PPC_R11:
915     return "r11";
916   case UNW_PPC_R12:
917     return "r12";
918   case UNW_PPC_R13:
919     return "r13";
920   case UNW_PPC_R14:
921     return "r14";
922   case UNW_PPC_R15:
923     return "r15";
924   case UNW_PPC_R16:
925     return "r16";
926   case UNW_PPC_R17:
927     return "r17";
928   case UNW_PPC_R18:
929     return "r18";
930   case UNW_PPC_R19:
931     return "r19";
932   case UNW_PPC_R20:
933     return "r20";
934   case UNW_PPC_R21:
935     return "r21";
936   case UNW_PPC_R22:
937     return "r22";
938   case UNW_PPC_R23:
939     return "r23";
940   case UNW_PPC_R24:
941     return "r24";
942   case UNW_PPC_R25:
943     return "r25";
944   case UNW_PPC_R26:
945     return "r26";
946   case UNW_PPC_R27:
947     return "r27";
948   case UNW_PPC_R28:
949     return "r28";
950   case UNW_PPC_R29:
951     return "r29";
952   case UNW_PPC_R30:
953     return "r30";
954   case UNW_PPC_R31:
955     return "r31";
956   case UNW_PPC_F0:
957     return "fp0";
958   case UNW_PPC_F1:
959     return "fp1";
960   case UNW_PPC_F2:
961     return "fp2";
962   case UNW_PPC_F3:
963     return "fp3";
964   case UNW_PPC_F4:
965     return "fp4";
966   case UNW_PPC_F5:
967     return "fp5";
968   case UNW_PPC_F6:
969     return "fp6";
970   case UNW_PPC_F7:
971     return "fp7";
972   case UNW_PPC_F8:
973     return "fp8";
974   case UNW_PPC_F9:
975     return "fp9";
976   case UNW_PPC_F10:
977     return "fp10";
978   case UNW_PPC_F11:
979     return "fp11";
980   case UNW_PPC_F12:
981     return "fp12";
982   case UNW_PPC_F13:
983     return "fp13";
984   case UNW_PPC_F14:
985     return "fp14";
986   case UNW_PPC_F15:
987     return "fp15";
988   case UNW_PPC_F16:
989     return "fp16";
990   case UNW_PPC_F17:
991     return "fp17";
992   case UNW_PPC_F18:
993     return "fp18";
994   case UNW_PPC_F19:
995     return "fp19";
996   case UNW_PPC_F20:
997     return "fp20";
998   case UNW_PPC_F21:
999     return "fp21";
1000   case UNW_PPC_F22:
1001     return "fp22";
1002   case UNW_PPC_F23:
1003     return "fp23";
1004   case UNW_PPC_F24:
1005     return "fp24";
1006   case UNW_PPC_F25:
1007     return "fp25";
1008   case UNW_PPC_F26:
1009     return "fp26";
1010   case UNW_PPC_F27:
1011     return "fp27";
1012   case UNW_PPC_F28:
1013     return "fp28";
1014   case UNW_PPC_F29:
1015     return "fp29";
1016   case UNW_PPC_F30:
1017     return "fp30";
1018   case UNW_PPC_F31:
1019     return "fp31";
1020   case UNW_PPC_LR:
1021     return "lr";
1022   default:
1023     return "unknown register";
1024   }
1025 
1026 }
1027 
1028 
1029 /// Registers_arm64  holds the register state of a thread in a 64-bit arm
1030 /// process.
1031 class _LIBUNWIND_HIDDEN Registers_arm64 {
1032 public:
1033   Registers_arm64();
1034   Registers_arm64(const void *registers);
1035 
1036   bool        validRegister(int num) const;
1037   uint64_t    getRegister(int num) const;
1038   void        setRegister(int num, uint64_t value);
1039   bool        validFloatRegister(int num) const;
1040   double      getFloatRegister(int num) const;
1041   void        setFloatRegister(int num, double value);
1042   bool        validVectorRegister(int num) const;
1043   v128        getVectorRegister(int num) const;
1044   void        setVectorRegister(int num, v128 value);
1045   const char *getRegisterName(int num);
1046   void        jumpto();
lastDwarfRegNum()1047   static int  lastDwarfRegNum() { return 95; }
1048 
getSP() const1049   uint64_t  getSP() const         { return _registers.__sp; }
setSP(uint64_t value)1050   void      setSP(uint64_t value) { _registers.__sp = value; }
getIP() const1051   uint64_t  getIP() const         { return _registers.__pc; }
setIP(uint64_t value)1052   void      setIP(uint64_t value) { _registers.__pc = value; }
getFP() const1053   uint64_t  getFP() const         { return _registers.__fp; }
setFP(uint64_t value)1054   void      setFP(uint64_t value) { _registers.__fp = value; }
1055 
1056 private:
1057   struct GPRs {
1058     uint64_t __x[29]; // x0-x28
1059     uint64_t __fp;    // Frame pointer x29
1060     uint64_t __lr;    // Link register x30
1061     uint64_t __sp;    // Stack pointer x31
1062     uint64_t __pc;    // Program counter
1063     uint64_t padding; // 16-byte align
1064   };
1065 
1066   GPRs    _registers;
1067   double  _vectorHalfRegisters[32];
1068   // Currently only the lower double in 128-bit vectore registers
1069   // is perserved during unwinding.  We could define new register
1070   // numbers (> 96) which mean whole vector registers, then this
1071   // struct would need to change to contain whole vector registers.
1072 };
1073 
Registers_arm64(const void * registers)1074 inline Registers_arm64::Registers_arm64(const void *registers) {
1075   static_assert(sizeof(Registers_arm64) < sizeof(unw_context_t),
1076                     "arm64 registers do not fit into unw_context_t");
1077   memcpy(&_registers, registers, sizeof(_registers));
1078   static_assert(sizeof(GPRs) == 0x110,
1079                 "expected VFP registers to be at offset 272");
1080   memcpy(_vectorHalfRegisters,
1081          static_cast<const uint8_t *>(registers) + sizeof(GPRs),
1082          sizeof(_vectorHalfRegisters));
1083 }
1084 
Registers_arm64()1085 inline Registers_arm64::Registers_arm64() {
1086   memset(&_registers, 0, sizeof(_registers));
1087   memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
1088 }
1089 
validRegister(int regNum) const1090 inline bool Registers_arm64::validRegister(int regNum) const {
1091   if (regNum == UNW_REG_IP)
1092     return true;
1093   if (regNum == UNW_REG_SP)
1094     return true;
1095   if (regNum < 0)
1096     return false;
1097   if (regNum > 95)
1098     return false;
1099   if ((regNum > 31) && (regNum < 64))
1100     return false;
1101   return true;
1102 }
1103 
getRegister(int regNum) const1104 inline uint64_t Registers_arm64::getRegister(int regNum) const {
1105   if (regNum == UNW_REG_IP)
1106     return _registers.__pc;
1107   if (regNum == UNW_REG_SP)
1108     return _registers.__sp;
1109   if ((regNum >= 0) && (regNum < 32))
1110     return _registers.__x[regNum];
1111   _LIBUNWIND_ABORT("unsupported arm64 register");
1112 }
1113 
setRegister(int regNum,uint64_t value)1114 inline void Registers_arm64::setRegister(int regNum, uint64_t value) {
1115   if (regNum == UNW_REG_IP)
1116     _registers.__pc = value;
1117   else if (regNum == UNW_REG_SP)
1118     _registers.__sp = value;
1119   else if ((regNum >= 0) && (regNum < 32))
1120     _registers.__x[regNum] = value;
1121   else
1122     _LIBUNWIND_ABORT("unsupported arm64 register");
1123 }
1124 
getRegisterName(int regNum)1125 inline const char *Registers_arm64::getRegisterName(int regNum) {
1126   switch (regNum) {
1127   case UNW_REG_IP:
1128     return "pc";
1129   case UNW_REG_SP:
1130     return "sp";
1131   case UNW_ARM64_X0:
1132     return "x0";
1133   case UNW_ARM64_X1:
1134     return "x1";
1135   case UNW_ARM64_X2:
1136     return "x2";
1137   case UNW_ARM64_X3:
1138     return "x3";
1139   case UNW_ARM64_X4:
1140     return "x4";
1141   case UNW_ARM64_X5:
1142     return "x5";
1143   case UNW_ARM64_X6:
1144     return "x6";
1145   case UNW_ARM64_X7:
1146     return "x7";
1147   case UNW_ARM64_X8:
1148     return "x8";
1149   case UNW_ARM64_X9:
1150     return "x9";
1151   case UNW_ARM64_X10:
1152     return "x10";
1153   case UNW_ARM64_X11:
1154     return "x11";
1155   case UNW_ARM64_X12:
1156     return "x12";
1157   case UNW_ARM64_X13:
1158     return "x13";
1159   case UNW_ARM64_X14:
1160     return "x14";
1161   case UNW_ARM64_X15:
1162     return "x15";
1163   case UNW_ARM64_X16:
1164     return "x16";
1165   case UNW_ARM64_X17:
1166     return "x17";
1167   case UNW_ARM64_X18:
1168     return "x18";
1169   case UNW_ARM64_X19:
1170     return "x19";
1171   case UNW_ARM64_X20:
1172     return "x20";
1173   case UNW_ARM64_X21:
1174     return "x21";
1175   case UNW_ARM64_X22:
1176     return "x22";
1177   case UNW_ARM64_X23:
1178     return "x23";
1179   case UNW_ARM64_X24:
1180     return "x24";
1181   case UNW_ARM64_X25:
1182     return "x25";
1183   case UNW_ARM64_X26:
1184     return "x26";
1185   case UNW_ARM64_X27:
1186     return "x27";
1187   case UNW_ARM64_X28:
1188     return "x28";
1189   case UNW_ARM64_X29:
1190     return "fp";
1191   case UNW_ARM64_X30:
1192     return "lr";
1193   case UNW_ARM64_X31:
1194     return "sp";
1195   case UNW_ARM64_D0:
1196     return "d0";
1197   case UNW_ARM64_D1:
1198     return "d1";
1199   case UNW_ARM64_D2:
1200     return "d2";
1201   case UNW_ARM64_D3:
1202     return "d3";
1203   case UNW_ARM64_D4:
1204     return "d4";
1205   case UNW_ARM64_D5:
1206     return "d5";
1207   case UNW_ARM64_D6:
1208     return "d6";
1209   case UNW_ARM64_D7:
1210     return "d7";
1211   case UNW_ARM64_D8:
1212     return "d8";
1213   case UNW_ARM64_D9:
1214     return "d9";
1215   case UNW_ARM64_D10:
1216     return "d10";
1217   case UNW_ARM64_D11:
1218     return "d11";
1219   case UNW_ARM64_D12:
1220     return "d12";
1221   case UNW_ARM64_D13:
1222     return "d13";
1223   case UNW_ARM64_D14:
1224     return "d14";
1225   case UNW_ARM64_D15:
1226     return "d15";
1227   case UNW_ARM64_D16:
1228     return "d16";
1229   case UNW_ARM64_D17:
1230     return "d17";
1231   case UNW_ARM64_D18:
1232     return "d18";
1233   case UNW_ARM64_D19:
1234     return "d19";
1235   case UNW_ARM64_D20:
1236     return "d20";
1237   case UNW_ARM64_D21:
1238     return "d21";
1239   case UNW_ARM64_D22:
1240     return "d22";
1241   case UNW_ARM64_D23:
1242     return "d23";
1243   case UNW_ARM64_D24:
1244     return "d24";
1245   case UNW_ARM64_D25:
1246     return "d25";
1247   case UNW_ARM64_D26:
1248     return "d26";
1249   case UNW_ARM64_D27:
1250     return "d27";
1251   case UNW_ARM64_D28:
1252     return "d28";
1253   case UNW_ARM64_D29:
1254     return "d29";
1255   case UNW_ARM64_D30:
1256     return "d30";
1257   case UNW_ARM64_D31:
1258     return "d31";
1259   default:
1260     return "unknown register";
1261   }
1262 }
1263 
validFloatRegister(int regNum) const1264 inline bool Registers_arm64::validFloatRegister(int regNum) const {
1265   if (regNum < UNW_ARM64_D0)
1266     return false;
1267   if (regNum > UNW_ARM64_D31)
1268     return false;
1269   return true;
1270 }
1271 
getFloatRegister(int regNum) const1272 inline double Registers_arm64::getFloatRegister(int regNum) const {
1273   assert(validFloatRegister(regNum));
1274   return _vectorHalfRegisters[regNum - UNW_ARM64_D0];
1275 }
1276 
setFloatRegister(int regNum,double value)1277 inline void Registers_arm64::setFloatRegister(int regNum, double value) {
1278   assert(validFloatRegister(regNum));
1279   _vectorHalfRegisters[regNum - UNW_ARM64_D0] = value;
1280 }
1281 
validVectorRegister(int) const1282 inline bool Registers_arm64::validVectorRegister(int) const {
1283   return false;
1284 }
1285 
getVectorRegister(int) const1286 inline v128 Registers_arm64::getVectorRegister(int) const {
1287   _LIBUNWIND_ABORT("no arm64 vector register support yet");
1288 }
1289 
setVectorRegister(int,v128)1290 inline void Registers_arm64::setVectorRegister(int, v128) {
1291   _LIBUNWIND_ABORT("no arm64 vector register support yet");
1292 }
1293 
1294 /// Registers_arm holds the register state of a thread in a 32-bit arm
1295 /// process.
1296 ///
1297 /// NOTE: Assumes VFPv3. On ARM processors without a floating point unit,
1298 /// this uses more memory than required.
1299 class _LIBUNWIND_HIDDEN Registers_arm {
1300 public:
1301   Registers_arm();
1302   Registers_arm(const void *registers);
1303 
1304   bool        validRegister(int num) const;
1305   uint32_t    getRegister(int num);
1306   void        setRegister(int num, uint32_t value);
1307   bool        validFloatRegister(int num) const;
1308   unw_fpreg_t getFloatRegister(int num);
1309   void        setFloatRegister(int num, unw_fpreg_t value);
1310   bool        validVectorRegister(int num) const;
1311   v128        getVectorRegister(int num) const;
1312   void        setVectorRegister(int num, v128 value);
1313   const char *getRegisterName(int num);
jumpto()1314   void        jumpto() {
1315     restoreSavedFloatRegisters();
1316     restoreCoreAndJumpTo();
1317   }
1318 
getSP() const1319   uint32_t  getSP() const         { return _registers.__sp; }
setSP(uint32_t value)1320   void      setSP(uint32_t value) { _registers.__sp = value; }
getIP() const1321   uint32_t  getIP() const         { return _registers.__pc; }
setIP(uint32_t value)1322   void      setIP(uint32_t value) { _registers.__pc = value; }
1323 
saveVFPAsX()1324   void saveVFPAsX() {
1325     assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15);
1326     _use_X_for_vfp_save = true;
1327   }
1328 
restoreSavedFloatRegisters()1329   void restoreSavedFloatRegisters() {
1330     if (_saved_vfp_d0_d15) {
1331       if (_use_X_for_vfp_save)
1332         restoreVFPWithFLDMX(_vfp_d0_d15_pad);
1333       else
1334         restoreVFPWithFLDMD(_vfp_d0_d15_pad);
1335     }
1336     if (_saved_vfp_d16_d31)
1337       restoreVFPv3(_vfp_d16_d31);
1338     if (_saved_iwmmx)
1339       restoreiWMMX(_iwmmx);
1340     if (_saved_iwmmx_control)
1341       restoreiWMMXControl(_iwmmx_control);
1342   }
1343 
1344 private:
1345   struct GPRs {
1346     uint32_t __r[13]; // r0-r12
1347     uint32_t __sp;    // Stack pointer r13
1348     uint32_t __lr;    // Link register r14
1349     uint32_t __pc;    // Program counter r15
1350   };
1351 
1352   static void saveVFPWithFSTMD(unw_fpreg_t*);
1353   static void saveVFPWithFSTMX(unw_fpreg_t*);
1354   static void saveVFPv3(unw_fpreg_t*);
1355   static void saveiWMMX(unw_fpreg_t*);
1356   static void saveiWMMXControl(uint32_t*);
1357   static void restoreVFPWithFLDMD(unw_fpreg_t*);
1358   static void restoreVFPWithFLDMX(unw_fpreg_t*);
1359   static void restoreVFPv3(unw_fpreg_t*);
1360   static void restoreiWMMX(unw_fpreg_t*);
1361   static void restoreiWMMXControl(uint32_t*);
1362   void restoreCoreAndJumpTo();
1363 
1364   // ARM registers
1365   GPRs _registers;
1366 
1367   // We save floating point registers lazily because we can't know ahead of
1368   // time which ones are used. See EHABI #4.7.
1369 
1370   // Whether D0-D15 are saved in the FTSMX instead of FSTMD format.
1371   //
1372   // See EHABI #7.5 that explains how matching instruction sequences for load
1373   // and store need to be used to correctly restore the exact register bits.
1374   bool _use_X_for_vfp_save;
1375   // Whether VFP D0-D15 are saved.
1376   bool _saved_vfp_d0_d15;
1377   // Whether VFPv3 D16-D31 are saved.
1378   bool _saved_vfp_d16_d31;
1379   // Whether iWMMX data registers are saved.
1380   bool _saved_iwmmx;
1381   // Whether iWMMX control registers are saved.
1382   bool _saved_iwmmx_control;
1383   // VFP registers D0-D15, + padding if saved using FSTMX
1384   unw_fpreg_t _vfp_d0_d15_pad[17];
1385   // VFPv3 registers D16-D31, always saved using FSTMD
1386   unw_fpreg_t _vfp_d16_d31[16];
1387   // iWMMX registers
1388   unw_fpreg_t _iwmmx[16];
1389   // iWMMX control registers
1390   uint32_t _iwmmx_control[4];
1391 };
1392 
Registers_arm(const void * registers)1393 inline Registers_arm::Registers_arm(const void *registers)
1394   : _use_X_for_vfp_save(false),
1395     _saved_vfp_d0_d15(false),
1396     _saved_vfp_d16_d31(false),
1397     _saved_iwmmx(false),
1398     _saved_iwmmx_control(false) {
1399   static_assert(sizeof(Registers_arm) < sizeof(unw_context_t),
1400                     "arm registers do not fit into unw_context_t");
1401   // See unw_getcontext() note about data.
1402   memcpy(&_registers, registers, sizeof(_registers));
1403   memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
1404   memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
1405   memset(&_iwmmx, 0, sizeof(_iwmmx));
1406   memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
1407 }
1408 
Registers_arm()1409 inline Registers_arm::Registers_arm()
1410   : _use_X_for_vfp_save(false),
1411     _saved_vfp_d0_d15(false),
1412     _saved_vfp_d16_d31(false),
1413     _saved_iwmmx(false),
1414     _saved_iwmmx_control(false) {
1415   memset(&_registers, 0, sizeof(_registers));
1416   memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
1417   memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
1418   memset(&_iwmmx, 0, sizeof(_iwmmx));
1419   memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
1420 }
1421 
validRegister(int regNum) const1422 inline bool Registers_arm::validRegister(int regNum) const {
1423   // Returns true for all non-VFP registers supported by the EHABI
1424   // virtual register set (VRS).
1425   if (regNum == UNW_REG_IP)
1426     return true;
1427   if (regNum == UNW_REG_SP)
1428     return true;
1429   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15)
1430     return true;
1431   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3)
1432     return true;
1433   return false;
1434 }
1435 
getRegister(int regNum)1436 inline uint32_t Registers_arm::getRegister(int regNum) {
1437   if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
1438     return _registers.__sp;
1439   if (regNum == UNW_ARM_LR)
1440     return _registers.__lr;
1441   if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
1442     return _registers.__pc;
1443   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
1444     return _registers.__r[regNum];
1445   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
1446     if (!_saved_iwmmx_control) {
1447       _saved_iwmmx_control = true;
1448       saveiWMMXControl(_iwmmx_control);
1449     }
1450     return _iwmmx_control[regNum - UNW_ARM_WC0];
1451   }
1452   _LIBUNWIND_ABORT("unsupported arm register");
1453 }
1454 
setRegister(int regNum,uint32_t value)1455 inline void Registers_arm::setRegister(int regNum, uint32_t value) {
1456   if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
1457     _registers.__sp = value;
1458   else if (regNum == UNW_ARM_LR)
1459     _registers.__lr = value;
1460   else if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
1461     _registers.__pc = value;
1462   else if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
1463     _registers.__r[regNum] = value;
1464   else if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
1465     if (!_saved_iwmmx_control) {
1466       _saved_iwmmx_control = true;
1467       saveiWMMXControl(_iwmmx_control);
1468     }
1469     _iwmmx_control[regNum - UNW_ARM_WC0] = value;
1470   } else
1471     _LIBUNWIND_ABORT("unsupported arm register");
1472 }
1473 
getRegisterName(int regNum)1474 inline const char *Registers_arm::getRegisterName(int regNum) {
1475   switch (regNum) {
1476   case UNW_REG_IP:
1477   case UNW_ARM_IP: // UNW_ARM_R15 is alias
1478     return "pc";
1479   case UNW_ARM_LR: // UNW_ARM_R14 is alias
1480     return "lr";
1481   case UNW_REG_SP:
1482   case UNW_ARM_SP: // UNW_ARM_R13 is alias
1483     return "sp";
1484   case UNW_ARM_R0:
1485     return "r0";
1486   case UNW_ARM_R1:
1487     return "r1";
1488   case UNW_ARM_R2:
1489     return "r2";
1490   case UNW_ARM_R3:
1491     return "r3";
1492   case UNW_ARM_R4:
1493     return "r4";
1494   case UNW_ARM_R5:
1495     return "r5";
1496   case UNW_ARM_R6:
1497     return "r6";
1498   case UNW_ARM_R7:
1499     return "r7";
1500   case UNW_ARM_R8:
1501     return "r8";
1502   case UNW_ARM_R9:
1503     return "r9";
1504   case UNW_ARM_R10:
1505     return "r10";
1506   case UNW_ARM_R11:
1507     return "r11";
1508   case UNW_ARM_R12:
1509     return "r12";
1510   case UNW_ARM_S0:
1511     return "s0";
1512   case UNW_ARM_S1:
1513     return "s1";
1514   case UNW_ARM_S2:
1515     return "s2";
1516   case UNW_ARM_S3:
1517     return "s3";
1518   case UNW_ARM_S4:
1519     return "s4";
1520   case UNW_ARM_S5:
1521     return "s5";
1522   case UNW_ARM_S6:
1523     return "s6";
1524   case UNW_ARM_S7:
1525     return "s7";
1526   case UNW_ARM_S8:
1527     return "s8";
1528   case UNW_ARM_S9:
1529     return "s9";
1530   case UNW_ARM_S10:
1531     return "s10";
1532   case UNW_ARM_S11:
1533     return "s11";
1534   case UNW_ARM_S12:
1535     return "s12";
1536   case UNW_ARM_S13:
1537     return "s13";
1538   case UNW_ARM_S14:
1539     return "s14";
1540   case UNW_ARM_S15:
1541     return "s15";
1542   case UNW_ARM_S16:
1543     return "s16";
1544   case UNW_ARM_S17:
1545     return "s17";
1546   case UNW_ARM_S18:
1547     return "s18";
1548   case UNW_ARM_S19:
1549     return "s19";
1550   case UNW_ARM_S20:
1551     return "s20";
1552   case UNW_ARM_S21:
1553     return "s21";
1554   case UNW_ARM_S22:
1555     return "s22";
1556   case UNW_ARM_S23:
1557     return "s23";
1558   case UNW_ARM_S24:
1559     return "s24";
1560   case UNW_ARM_S25:
1561     return "s25";
1562   case UNW_ARM_S26:
1563     return "s26";
1564   case UNW_ARM_S27:
1565     return "s27";
1566   case UNW_ARM_S28:
1567     return "s28";
1568   case UNW_ARM_S29:
1569     return "s29";
1570   case UNW_ARM_S30:
1571     return "s30";
1572   case UNW_ARM_S31:
1573     return "s31";
1574   case UNW_ARM_D0:
1575     return "d0";
1576   case UNW_ARM_D1:
1577     return "d1";
1578   case UNW_ARM_D2:
1579     return "d2";
1580   case UNW_ARM_D3:
1581     return "d3";
1582   case UNW_ARM_D4:
1583     return "d4";
1584   case UNW_ARM_D5:
1585     return "d5";
1586   case UNW_ARM_D6:
1587     return "d6";
1588   case UNW_ARM_D7:
1589     return "d7";
1590   case UNW_ARM_D8:
1591     return "d8";
1592   case UNW_ARM_D9:
1593     return "d9";
1594   case UNW_ARM_D10:
1595     return "d10";
1596   case UNW_ARM_D11:
1597     return "d11";
1598   case UNW_ARM_D12:
1599     return "d12";
1600   case UNW_ARM_D13:
1601     return "d13";
1602   case UNW_ARM_D14:
1603     return "d14";
1604   case UNW_ARM_D15:
1605     return "d15";
1606   case UNW_ARM_D16:
1607     return "d16";
1608   case UNW_ARM_D17:
1609     return "d17";
1610   case UNW_ARM_D18:
1611     return "d18";
1612   case UNW_ARM_D19:
1613     return "d19";
1614   case UNW_ARM_D20:
1615     return "d20";
1616   case UNW_ARM_D21:
1617     return "d21";
1618   case UNW_ARM_D22:
1619     return "d22";
1620   case UNW_ARM_D23:
1621     return "d23";
1622   case UNW_ARM_D24:
1623     return "d24";
1624   case UNW_ARM_D25:
1625     return "d25";
1626   case UNW_ARM_D26:
1627     return "d26";
1628   case UNW_ARM_D27:
1629     return "d27";
1630   case UNW_ARM_D28:
1631     return "d28";
1632   case UNW_ARM_D29:
1633     return "d29";
1634   case UNW_ARM_D30:
1635     return "d30";
1636   case UNW_ARM_D31:
1637     return "d31";
1638   default:
1639     return "unknown register";
1640   }
1641 }
1642 
validFloatRegister(int regNum) const1643 inline bool Registers_arm::validFloatRegister(int regNum) const {
1644   // NOTE: Consider the intel MMX registers floating points so the
1645   // unw_get_fpreg can be used to transmit the 64-bit data back.
1646   return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31))
1647       || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15));
1648 }
1649 
getFloatRegister(int regNum)1650 inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) {
1651   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
1652     if (!_saved_vfp_d0_d15) {
1653       _saved_vfp_d0_d15 = true;
1654       if (_use_X_for_vfp_save)
1655         saveVFPWithFSTMX(_vfp_d0_d15_pad);
1656       else
1657         saveVFPWithFSTMD(_vfp_d0_d15_pad);
1658     }
1659     return _vfp_d0_d15_pad[regNum - UNW_ARM_D0];
1660   } else if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
1661     if (!_saved_vfp_d16_d31) {
1662       _saved_vfp_d16_d31 = true;
1663       saveVFPv3(_vfp_d16_d31);
1664     }
1665     return _vfp_d16_d31[regNum - UNW_ARM_D16];
1666   } else if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
1667     if (!_saved_iwmmx) {
1668       _saved_iwmmx = true;
1669       saveiWMMX(_iwmmx);
1670     }
1671     return _iwmmx[regNum - UNW_ARM_WR0];
1672   } else {
1673     _LIBUNWIND_ABORT("Unknown ARM float register");
1674   }
1675 }
1676 
setFloatRegister(int regNum,unw_fpreg_t value)1677 inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) {
1678   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
1679     if (!_saved_vfp_d0_d15) {
1680       _saved_vfp_d0_d15 = true;
1681       if (_use_X_for_vfp_save)
1682         saveVFPWithFSTMX(_vfp_d0_d15_pad);
1683       else
1684         saveVFPWithFSTMD(_vfp_d0_d15_pad);
1685     }
1686     _vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value;
1687   } else if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
1688     if (!_saved_vfp_d16_d31) {
1689       _saved_vfp_d16_d31 = true;
1690       saveVFPv3(_vfp_d16_d31);
1691     }
1692     _vfp_d16_d31[regNum - UNW_ARM_D16] = value;
1693   } else if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
1694     if (!_saved_iwmmx) {
1695       _saved_iwmmx = true;
1696       saveiWMMX(_iwmmx);
1697     }
1698     _iwmmx[regNum - UNW_ARM_WR0] = value;
1699   } else {
1700     _LIBUNWIND_ABORT("Unknown ARM float register");
1701   }
1702 }
1703 
validVectorRegister(int) const1704 inline bool Registers_arm::validVectorRegister(int) const {
1705   return false;
1706 }
1707 
getVectorRegister(int) const1708 inline v128 Registers_arm::getVectorRegister(int) const {
1709   _LIBUNWIND_ABORT("ARM vector support not implemented");
1710 }
1711 
setVectorRegister(int,v128)1712 inline void Registers_arm::setVectorRegister(int, v128) {
1713   _LIBUNWIND_ABORT("ARM vector support not implemented");
1714 }
1715 
1716 } // namespace libunwind
1717 
1718 #endif // __REGISTERS_HPP__
1719