• Home
  • History
  • Annotate
  • 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