brintos

brintos / llvm-project-archived public Read only

0
0
Text · 136.8 KiB · 45a2b09 Raw
5508 lines · plain
1//===----------------------------------------------------------------------===//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-exception6//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 "config.h"19#include "libunwind.h"20#include "libunwind_ext.h"21#include "shadow_stack_unwind.h"22 23#if __has_include(<sys/auxv.h>)24#include <sys/auxv.h>25#define HAVE_SYS_AUXV_H26#endif27 28namespace libunwind {29 30// For emulating 128-bit registers31struct v128 { uint32_t vec[4]; };32 33enum {34  REGISTERS_X86,35  REGISTERS_X86_64,36  REGISTERS_PPC,37  REGISTERS_PPC64,38  REGISTERS_ARM64,39  REGISTERS_ARM,40  REGISTERS_OR1K,41  REGISTERS_MIPS_O32,42  REGISTERS_MIPS_NEWABI,43  REGISTERS_SPARC,44  REGISTERS_SPARC64,45  REGISTERS_HEXAGON,46  REGISTERS_RISCV,47  REGISTERS_VE,48  REGISTERS_S390X,49  REGISTERS_LOONGARCH,50};51 52#if defined(_LIBUNWIND_TARGET_I386)53class _LIBUNWIND_HIDDEN Registers_x86;54extern "C" void __libunwind_Registers_x86_jumpto(Registers_x86 *);55 56#if defined(_LIBUNWIND_USE_CET)57extern "C" void *__libunwind_shstk_get_jump_target() {58  return reinterpret_cast<void *>(&__libunwind_Registers_x86_jumpto);59}60#endif61 62/// Registers_x86 holds the register state of a thread in a 32-bit intel63/// process.64class _LIBUNWIND_HIDDEN Registers_x86 {65public:66  Registers_x86();67  Registers_x86(const void *registers);68 69  typedef uint32_t reg_t;70  typedef uint32_t link_reg_t;71 72  bool        validRegister(int num) const;73  uint32_t    getRegister(int num) const;74  void        setRegister(int num, uint32_t value);75  bool        validFloatRegister(int) const { return false; }76  double      getFloatRegister(int num) const;77  void        setFloatRegister(int num, double value);78  bool        validVectorRegister(int) const { return false; }79  v128        getVectorRegister(int num) const;80  void        setVectorRegister(int num, v128 value);81  static const char *getRegisterName(int num);82  void        jumpto() { __libunwind_Registers_x86_jumpto(this); }83  static constexpr int lastDwarfRegNum() {84    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86;85  }86  static int  getArch() { return REGISTERS_X86; }87 88  uint32_t  getSP() const          { return _registers.__esp; }89  void      setSP(uint32_t value)  { _registers.__esp = value; }90  uint32_t  getIP() const          { return _registers.__eip; }91  void      setIP(uint32_t value)  { _registers.__eip = value; }92  uint32_t  getEBP() const         { return _registers.__ebp; }93  void      setEBP(uint32_t value) { _registers.__ebp = value; }94  uint32_t  getEBX() const         { return _registers.__ebx; }95  void      setEBX(uint32_t value) { _registers.__ebx = value; }96  uint32_t  getECX() const         { return _registers.__ecx; }97  void      setECX(uint32_t value) { _registers.__ecx = value; }98  uint32_t  getEDX() const         { return _registers.__edx; }99  void      setEDX(uint32_t value) { _registers.__edx = value; }100  uint32_t  getESI() const         { return _registers.__esi; }101  void      setESI(uint32_t value) { _registers.__esi = value; }102  uint32_t  getEDI() const         { return _registers.__edi; }103  void      setEDI(uint32_t value) { _registers.__edi = value; }104 105private:106  struct GPRs {107    unsigned int __eax;108    unsigned int __ebx;109    unsigned int __ecx;110    unsigned int __edx;111    unsigned int __edi;112    unsigned int __esi;113    unsigned int __ebp;114    unsigned int __esp;115    unsigned int __ss;116    unsigned int __eflags;117    unsigned int __eip;118    unsigned int __cs;119    unsigned int __ds;120    unsigned int __es;121    unsigned int __fs;122    unsigned int __gs;123  };124 125  GPRs _registers;126};127 128inline Registers_x86::Registers_x86(const void *registers) {129  static_assert((check_fit<Registers_x86, unw_context_t>::does_fit),130                "x86 registers do not fit into unw_context_t");131  memcpy(&_registers, registers, sizeof(_registers));132}133 134inline Registers_x86::Registers_x86() {135  memset(&_registers, 0, sizeof(_registers));136}137 138inline bool Registers_x86::validRegister(int regNum) const {139  if (regNum == UNW_REG_IP)140    return true;141  if (regNum == UNW_REG_SP)142    return true;143  if (regNum < 0)144    return false;145  if (regNum > 7)146    return false;147  return true;148}149 150inline uint32_t Registers_x86::getRegister(int regNum) const {151  switch (regNum) {152  case UNW_REG_IP:153    return _registers.__eip;154  case UNW_REG_SP:155    return _registers.__esp;156  case UNW_X86_EAX:157    return _registers.__eax;158  case UNW_X86_ECX:159    return _registers.__ecx;160  case UNW_X86_EDX:161    return _registers.__edx;162  case UNW_X86_EBX:163    return _registers.__ebx;164#if !defined(__APPLE__)165  case UNW_X86_ESP:166#else167  case UNW_X86_EBP:168#endif169    return _registers.__ebp;170#if !defined(__APPLE__)171  case UNW_X86_EBP:172#else173  case UNW_X86_ESP:174#endif175    return _registers.__esp;176  case UNW_X86_ESI:177    return _registers.__esi;178  case UNW_X86_EDI:179    return _registers.__edi;180  }181  _LIBUNWIND_ABORT("unsupported x86 register");182}183 184inline void Registers_x86::setRegister(int regNum, uint32_t value) {185  switch (regNum) {186  case UNW_REG_IP:187    _registers.__eip = value;188    return;189  case UNW_REG_SP:190    _registers.__esp = value;191    return;192  case UNW_X86_EAX:193    _registers.__eax = value;194    return;195  case UNW_X86_ECX:196    _registers.__ecx = value;197    return;198  case UNW_X86_EDX:199    _registers.__edx = value;200    return;201  case UNW_X86_EBX:202    _registers.__ebx = value;203    return;204#if !defined(__APPLE__)205  case UNW_X86_ESP:206#else207  case UNW_X86_EBP:208#endif209    _registers.__ebp = value;210    return;211#if !defined(__APPLE__)212  case UNW_X86_EBP:213#else214  case UNW_X86_ESP:215#endif216    _registers.__esp = value;217    return;218  case UNW_X86_ESI:219    _registers.__esi = value;220    return;221  case UNW_X86_EDI:222    _registers.__edi = value;223    return;224  }225  _LIBUNWIND_ABORT("unsupported x86 register");226}227 228inline const char *Registers_x86::getRegisterName(int regNum) {229  switch (regNum) {230  case UNW_REG_IP:231    return "ip";232  case UNW_REG_SP:233    return "esp";234  case UNW_X86_EAX:235    return "eax";236  case UNW_X86_ECX:237    return "ecx";238  case UNW_X86_EDX:239    return "edx";240  case UNW_X86_EBX:241    return "ebx";242  case UNW_X86_EBP:243    return "ebp";244  case UNW_X86_ESP:245    return "esp";246  case UNW_X86_ESI:247    return "esi";248  case UNW_X86_EDI:249    return "edi";250  default:251    return "unknown register";252  }253}254 255inline double Registers_x86::getFloatRegister(int) const {256  _LIBUNWIND_ABORT("no x86 float registers");257}258 259inline void Registers_x86::setFloatRegister(int, double) {260  _LIBUNWIND_ABORT("no x86 float registers");261}262 263inline v128 Registers_x86::getVectorRegister(int) const {264  _LIBUNWIND_ABORT("no x86 vector registers");265}266 267inline void Registers_x86::setVectorRegister(int, v128) {268  _LIBUNWIND_ABORT("no x86 vector registers");269}270#endif // _LIBUNWIND_TARGET_I386271 272 273#if defined(_LIBUNWIND_TARGET_X86_64)274/// Registers_x86_64  holds the register state of a thread in a 64-bit intel275/// process.276class _LIBUNWIND_HIDDEN Registers_x86_64;277extern "C" void __libunwind_Registers_x86_64_jumpto(Registers_x86_64 *);278 279#if defined(_LIBUNWIND_USE_CET)280extern "C" void *__libunwind_shstk_get_jump_target() {281  return reinterpret_cast<void *>(&__libunwind_Registers_x86_64_jumpto);282}283#endif284 285class _LIBUNWIND_HIDDEN Registers_x86_64 {286public:287  Registers_x86_64();288  Registers_x86_64(const void *registers);289 290  typedef uint64_t reg_t;291  typedef uint64_t link_reg_t;292 293  bool        validRegister(int num) const;294  uint64_t    getRegister(int num) const;295  void        setRegister(int num, uint64_t value);296  bool        validFloatRegister(int) const { return false; }297  double      getFloatRegister(int num) const;298  void        setFloatRegister(int num, double value);299  bool        validVectorRegister(int) const;300  v128        getVectorRegister(int num) const;301  void        setVectorRegister(int num, v128 value);302  static const char *getRegisterName(int num);303  void        jumpto() { __libunwind_Registers_x86_64_jumpto(this); }304  static constexpr int lastDwarfRegNum() {305    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64;306  }307  static int  getArch() { return REGISTERS_X86_64; }308 309  uint64_t  getSP() const          { return _registers.__rsp; }310  void      setSP(uint64_t value)  { _registers.__rsp = value; }311  uint64_t  getIP() const          { return _registers.__rip; }312  void      setIP(uint64_t value)  { _registers.__rip = value; }313  uint64_t  getRBP() const         { return _registers.__rbp; }314  void      setRBP(uint64_t value) { _registers.__rbp = value; }315  uint64_t  getRBX() const         { return _registers.__rbx; }316  void      setRBX(uint64_t value) { _registers.__rbx = value; }317  uint64_t  getR12() const         { return _registers.__r12; }318  void      setR12(uint64_t value) { _registers.__r12 = value; }319  uint64_t  getR13() const         { return _registers.__r13; }320  void      setR13(uint64_t value) { _registers.__r13 = value; }321  uint64_t  getR14() const         { return _registers.__r14; }322  void      setR14(uint64_t value) { _registers.__r14 = value; }323  uint64_t  getR15() const         { return _registers.__r15; }324  void      setR15(uint64_t value) { _registers.__r15 = value; }325 326private:327  struct GPRs {328    uint64_t __rax;329    uint64_t __rbx;330    uint64_t __rcx;331    uint64_t __rdx;332    uint64_t __rdi;333    uint64_t __rsi;334    uint64_t __rbp;335    uint64_t __rsp;336    uint64_t __r8;337    uint64_t __r9;338    uint64_t __r10;339    uint64_t __r11;340    uint64_t __r12;341    uint64_t __r13;342    uint64_t __r14;343    uint64_t __r15;344    uint64_t __rip;345    uint64_t __rflags;346    uint64_t __cs;347    uint64_t __fs;348    uint64_t __gs;349#if defined(_WIN64)350    uint64_t __padding; // 16-byte align351#endif352  };353  GPRs _registers;354#if defined(_WIN64)355  v128 _xmm[16];356#endif357};358 359inline Registers_x86_64::Registers_x86_64(const void *registers) {360  static_assert((check_fit<Registers_x86_64, unw_context_t>::does_fit),361                "x86_64 registers do not fit into unw_context_t");362  memcpy(&_registers, registers, sizeof(_registers));363}364 365inline Registers_x86_64::Registers_x86_64() {366  memset(&_registers, 0, sizeof(_registers));367}368 369inline bool Registers_x86_64::validRegister(int regNum) const {370  if (regNum == UNW_REG_IP)371    return true;372  if (regNum == UNW_REG_SP)373    return true;374  if (regNum < 0)375    return false;376  if (regNum > 16)377    return false;378  return true;379}380 381inline uint64_t Registers_x86_64::getRegister(int regNum) const {382  switch (regNum) {383  case UNW_REG_IP:384  case UNW_X86_64_RIP:385    return _registers.__rip;386  case UNW_REG_SP:387    return _registers.__rsp;388  case UNW_X86_64_RAX:389    return _registers.__rax;390  case UNW_X86_64_RDX:391    return _registers.__rdx;392  case UNW_X86_64_RCX:393    return _registers.__rcx;394  case UNW_X86_64_RBX:395    return _registers.__rbx;396  case UNW_X86_64_RSI:397    return _registers.__rsi;398  case UNW_X86_64_RDI:399    return _registers.__rdi;400  case UNW_X86_64_RBP:401    return _registers.__rbp;402  case UNW_X86_64_RSP:403    return _registers.__rsp;404  case UNW_X86_64_R8:405    return _registers.__r8;406  case UNW_X86_64_R9:407    return _registers.__r9;408  case UNW_X86_64_R10:409    return _registers.__r10;410  case UNW_X86_64_R11:411    return _registers.__r11;412  case UNW_X86_64_R12:413    return _registers.__r12;414  case UNW_X86_64_R13:415    return _registers.__r13;416  case UNW_X86_64_R14:417    return _registers.__r14;418  case UNW_X86_64_R15:419    return _registers.__r15;420  }421  _LIBUNWIND_ABORT("unsupported x86_64 register");422}423 424inline void Registers_x86_64::setRegister(int regNum, uint64_t value) {425  switch (regNum) {426  case UNW_REG_IP:427  case UNW_X86_64_RIP:428    _registers.__rip = value;429    return;430  case UNW_REG_SP:431    _registers.__rsp = value;432    return;433  case UNW_X86_64_RAX:434    _registers.__rax = value;435    return;436  case UNW_X86_64_RDX:437    _registers.__rdx = value;438    return;439  case UNW_X86_64_RCX:440    _registers.__rcx = value;441    return;442  case UNW_X86_64_RBX:443    _registers.__rbx = value;444    return;445  case UNW_X86_64_RSI:446    _registers.__rsi = value;447    return;448  case UNW_X86_64_RDI:449    _registers.__rdi = value;450    return;451  case UNW_X86_64_RBP:452    _registers.__rbp = value;453    return;454  case UNW_X86_64_RSP:455    _registers.__rsp = value;456    return;457  case UNW_X86_64_R8:458    _registers.__r8 = value;459    return;460  case UNW_X86_64_R9:461    _registers.__r9 = value;462    return;463  case UNW_X86_64_R10:464    _registers.__r10 = value;465    return;466  case UNW_X86_64_R11:467    _registers.__r11 = value;468    return;469  case UNW_X86_64_R12:470    _registers.__r12 = value;471    return;472  case UNW_X86_64_R13:473    _registers.__r13 = value;474    return;475  case UNW_X86_64_R14:476    _registers.__r14 = value;477    return;478  case UNW_X86_64_R15:479    _registers.__r15 = value;480    return;481  }482  _LIBUNWIND_ABORT("unsupported x86_64 register");483}484 485inline const char *Registers_x86_64::getRegisterName(int regNum) {486  switch (regNum) {487  case UNW_REG_IP:488  case UNW_X86_64_RIP:489    return "rip";490  case UNW_REG_SP:491    return "rsp";492  case UNW_X86_64_RAX:493    return "rax";494  case UNW_X86_64_RDX:495    return "rdx";496  case UNW_X86_64_RCX:497    return "rcx";498  case UNW_X86_64_RBX:499    return "rbx";500  case UNW_X86_64_RSI:501    return "rsi";502  case UNW_X86_64_RDI:503    return "rdi";504  case UNW_X86_64_RBP:505    return "rbp";506  case UNW_X86_64_RSP:507    return "rsp";508  case UNW_X86_64_R8:509    return "r8";510  case UNW_X86_64_R9:511    return "r9";512  case UNW_X86_64_R10:513    return "r10";514  case UNW_X86_64_R11:515    return "r11";516  case UNW_X86_64_R12:517    return "r12";518  case UNW_X86_64_R13:519    return "r13";520  case UNW_X86_64_R14:521    return "r14";522  case UNW_X86_64_R15:523    return "r15";524  case UNW_X86_64_XMM0:525    return "xmm0";526  case UNW_X86_64_XMM1:527    return "xmm1";528  case UNW_X86_64_XMM2:529    return "xmm2";530  case UNW_X86_64_XMM3:531    return "xmm3";532  case UNW_X86_64_XMM4:533    return "xmm4";534  case UNW_X86_64_XMM5:535    return "xmm5";536  case UNW_X86_64_XMM6:537    return "xmm6";538  case UNW_X86_64_XMM7:539    return "xmm7";540  case UNW_X86_64_XMM8:541    return "xmm8";542  case UNW_X86_64_XMM9:543    return "xmm9";544  case UNW_X86_64_XMM10:545    return "xmm10";546  case UNW_X86_64_XMM11:547    return "xmm11";548  case UNW_X86_64_XMM12:549    return "xmm12";550  case UNW_X86_64_XMM13:551    return "xmm13";552  case UNW_X86_64_XMM14:553    return "xmm14";554  case UNW_X86_64_XMM15:555    return "xmm15";556  default:557    return "unknown register";558  }559}560 561inline double Registers_x86_64::getFloatRegister(int) const {562  _LIBUNWIND_ABORT("no x86_64 float registers");563}564 565inline void Registers_x86_64::setFloatRegister(int, double) {566  _LIBUNWIND_ABORT("no x86_64 float registers");567}568 569inline bool Registers_x86_64::validVectorRegister(int regNum) const {570#if defined(_WIN64)571  if (regNum < UNW_X86_64_XMM0)572    return false;573  if (regNum > UNW_X86_64_XMM15)574    return false;575  return true;576#else577  (void)regNum; // suppress unused parameter warning578  return false;579#endif580}581 582inline v128 Registers_x86_64::getVectorRegister(int regNum) const {583#if defined(_WIN64)584  assert(validVectorRegister(regNum));585  return _xmm[regNum - UNW_X86_64_XMM0];586#else587  (void)regNum; // suppress unused parameter warning588  _LIBUNWIND_ABORT("no x86_64 vector registers");589#endif590}591 592inline void Registers_x86_64::setVectorRegister(int regNum, v128 value) {593#if defined(_WIN64)594  assert(validVectorRegister(regNum));595  _xmm[regNum - UNW_X86_64_XMM0] = value;596#else597  (void)regNum; (void)value; // suppress unused parameter warnings598  _LIBUNWIND_ABORT("no x86_64 vector registers");599#endif600}601#endif // _LIBUNWIND_TARGET_X86_64602 603 604#if defined(_LIBUNWIND_TARGET_PPC)605/// Registers_ppc holds the register state of a thread in a 32-bit PowerPC606/// process.607class _LIBUNWIND_HIDDEN Registers_ppc {608public:609  Registers_ppc();610  Registers_ppc(const void *registers);611 612  typedef uint32_t reg_t;613  typedef uint32_t link_reg_t;614 615  bool        validRegister(int num) const;616  uint32_t    getRegister(int num) const;617  void        setRegister(int num, uint32_t value);618  bool        validFloatRegister(int num) const;619  double      getFloatRegister(int num) const;620  void        setFloatRegister(int num, double value);621  bool        validVectorRegister(int num) const;622  v128        getVectorRegister(int num) const;623  void        setVectorRegister(int num, v128 value);624  static const char *getRegisterName(int num);625  void        jumpto();626  static constexpr int lastDwarfRegNum() {627    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC;628  }629  static int  getArch() { return REGISTERS_PPC; }630 631  uint64_t  getSP() const         { return _registers.__r1; }632  void      setSP(uint32_t value) { _registers.__r1 = value; }633  uint64_t  getIP() const         { return _registers.__srr0; }634  void      setIP(uint32_t value) { _registers.__srr0 = value; }635  uint64_t  getCR() const         { return _registers.__cr; }636  void      setCR(uint32_t value) { _registers.__cr = value; }637  uint64_t  getLR() const         { return _registers.__lr; }638  void      setLR(uint32_t value) { _registers.__lr = value; }639 640private:641  struct ppc_thread_state_t {642    unsigned int __srr0; /* Instruction address register (PC) */643    unsigned int __srr1; /* Machine state register (supervisor) */644    unsigned int __r0;645    unsigned int __r1;646    unsigned int __r2;647    unsigned int __r3;648    unsigned int __r4;649    unsigned int __r5;650    unsigned int __r6;651    unsigned int __r7;652    unsigned int __r8;653    unsigned int __r9;654    unsigned int __r10;655    unsigned int __r11;656    unsigned int __r12;657    unsigned int __r13;658    unsigned int __r14;659    unsigned int __r15;660    unsigned int __r16;661    unsigned int __r17;662    unsigned int __r18;663    unsigned int __r19;664    unsigned int __r20;665    unsigned int __r21;666    unsigned int __r22;667    unsigned int __r23;668    unsigned int __r24;669    unsigned int __r25;670    unsigned int __r26;671    unsigned int __r27;672    unsigned int __r28;673    unsigned int __r29;674    unsigned int __r30;675    unsigned int __r31;676    unsigned int __cr;     /* Condition register */677    unsigned int __xer;    /* User's integer exception register */678    unsigned int __lr;     /* Link register */679    unsigned int __ctr;    /* Count register */680    unsigned int __mq;     /* MQ register (601 only) */681    unsigned int __vrsave; /* Vector Save Register */682  };683 684  struct ppc_float_state_t {685    double __fpregs[32];686 687    unsigned int __fpscr_pad; /* fpscr is 64 bits, 32 bits of rubbish */688    unsigned int __fpscr;     /* floating point status register */689  };690 691  ppc_thread_state_t _registers;692  ppc_float_state_t  _floatRegisters;693  v128               _vectorRegisters[32]; // offset 424694};695 696inline Registers_ppc::Registers_ppc(const void *registers) {697  static_assert((check_fit<Registers_ppc, unw_context_t>::does_fit),698                "ppc registers do not fit into unw_context_t");699  memcpy(&_registers, static_cast<const uint8_t *>(registers),700         sizeof(_registers));701  static_assert(sizeof(ppc_thread_state_t) == 160,702                "expected float register offset to be 160");703  memcpy(&_floatRegisters,704         static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t),705         sizeof(_floatRegisters));706  static_assert(sizeof(ppc_thread_state_t) + sizeof(ppc_float_state_t) == 424,707                "expected vector register offset to be 424 bytes");708  memcpy(_vectorRegisters,709         static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t) +710             sizeof(ppc_float_state_t),711         sizeof(_vectorRegisters));712}713 714inline Registers_ppc::Registers_ppc() {715  memset(&_registers, 0, sizeof(_registers));716  memset(&_floatRegisters, 0, sizeof(_floatRegisters));717  memset(&_vectorRegisters, 0, sizeof(_vectorRegisters));718}719 720inline bool Registers_ppc::validRegister(int regNum) const {721  if (regNum == UNW_REG_IP)722    return true;723  if (regNum == UNW_REG_SP)724    return true;725  if (regNum == UNW_PPC_VRSAVE)726    return true;727  if (regNum < 0)728    return false;729  if (regNum <= UNW_PPC_R31)730    return true;731  if (regNum == UNW_PPC_MQ)732    return true;733  if (regNum == UNW_PPC_LR)734    return true;735  if (regNum == UNW_PPC_CTR)736    return true;737  if ((UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7))738    return true;739  return false;740}741 742inline uint32_t Registers_ppc::getRegister(int regNum) const {743  switch (regNum) {744  case UNW_REG_IP:745    return _registers.__srr0;746  case UNW_REG_SP:747    return _registers.__r1;748  case UNW_PPC_R0:749    return _registers.__r0;750  case UNW_PPC_R1:751    return _registers.__r1;752  case UNW_PPC_R2:753    return _registers.__r2;754  case UNW_PPC_R3:755    return _registers.__r3;756  case UNW_PPC_R4:757    return _registers.__r4;758  case UNW_PPC_R5:759    return _registers.__r5;760  case UNW_PPC_R6:761    return _registers.__r6;762  case UNW_PPC_R7:763    return _registers.__r7;764  case UNW_PPC_R8:765    return _registers.__r8;766  case UNW_PPC_R9:767    return _registers.__r9;768  case UNW_PPC_R10:769    return _registers.__r10;770  case UNW_PPC_R11:771    return _registers.__r11;772  case UNW_PPC_R12:773    return _registers.__r12;774  case UNW_PPC_R13:775    return _registers.__r13;776  case UNW_PPC_R14:777    return _registers.__r14;778  case UNW_PPC_R15:779    return _registers.__r15;780  case UNW_PPC_R16:781    return _registers.__r16;782  case UNW_PPC_R17:783    return _registers.__r17;784  case UNW_PPC_R18:785    return _registers.__r18;786  case UNW_PPC_R19:787    return _registers.__r19;788  case UNW_PPC_R20:789    return _registers.__r20;790  case UNW_PPC_R21:791    return _registers.__r21;792  case UNW_PPC_R22:793    return _registers.__r22;794  case UNW_PPC_R23:795    return _registers.__r23;796  case UNW_PPC_R24:797    return _registers.__r24;798  case UNW_PPC_R25:799    return _registers.__r25;800  case UNW_PPC_R26:801    return _registers.__r26;802  case UNW_PPC_R27:803    return _registers.__r27;804  case UNW_PPC_R28:805    return _registers.__r28;806  case UNW_PPC_R29:807    return _registers.__r29;808  case UNW_PPC_R30:809    return _registers.__r30;810  case UNW_PPC_R31:811    return _registers.__r31;812  case UNW_PPC_LR:813    return _registers.__lr;814  case UNW_PPC_CR0:815    return (_registers.__cr & 0xF0000000);816  case UNW_PPC_CR1:817    return (_registers.__cr & 0x0F000000);818  case UNW_PPC_CR2:819    return (_registers.__cr & 0x00F00000);820  case UNW_PPC_CR3:821    return (_registers.__cr & 0x000F0000);822  case UNW_PPC_CR4:823    return (_registers.__cr & 0x0000F000);824  case UNW_PPC_CR5:825    return (_registers.__cr & 0x00000F00);826  case UNW_PPC_CR6:827    return (_registers.__cr & 0x000000F0);828  case UNW_PPC_CR7:829    return (_registers.__cr & 0x0000000F);830  case UNW_PPC_VRSAVE:831    return _registers.__vrsave;832  }833  _LIBUNWIND_ABORT("unsupported ppc register");834}835 836inline void Registers_ppc::setRegister(int regNum, uint32_t value) {837  //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value);838  switch (regNum) {839  case UNW_REG_IP:840    _registers.__srr0 = value;841    return;842  case UNW_REG_SP:843    _registers.__r1 = value;844    return;845  case UNW_PPC_R0:846    _registers.__r0 = value;847    return;848  case UNW_PPC_R1:849    _registers.__r1 = value;850    return;851  case UNW_PPC_R2:852    _registers.__r2 = value;853    return;854  case UNW_PPC_R3:855    _registers.__r3 = value;856    return;857  case UNW_PPC_R4:858    _registers.__r4 = value;859    return;860  case UNW_PPC_R5:861    _registers.__r5 = value;862    return;863  case UNW_PPC_R6:864    _registers.__r6 = value;865    return;866  case UNW_PPC_R7:867    _registers.__r7 = value;868    return;869  case UNW_PPC_R8:870    _registers.__r8 = value;871    return;872  case UNW_PPC_R9:873    _registers.__r9 = value;874    return;875  case UNW_PPC_R10:876    _registers.__r10 = value;877    return;878  case UNW_PPC_R11:879    _registers.__r11 = value;880    return;881  case UNW_PPC_R12:882    _registers.__r12 = value;883    return;884  case UNW_PPC_R13:885    _registers.__r13 = value;886    return;887  case UNW_PPC_R14:888    _registers.__r14 = value;889    return;890  case UNW_PPC_R15:891    _registers.__r15 = value;892    return;893  case UNW_PPC_R16:894    _registers.__r16 = value;895    return;896  case UNW_PPC_R17:897    _registers.__r17 = value;898    return;899  case UNW_PPC_R18:900    _registers.__r18 = value;901    return;902  case UNW_PPC_R19:903    _registers.__r19 = value;904    return;905  case UNW_PPC_R20:906    _registers.__r20 = value;907    return;908  case UNW_PPC_R21:909    _registers.__r21 = value;910    return;911  case UNW_PPC_R22:912    _registers.__r22 = value;913    return;914  case UNW_PPC_R23:915    _registers.__r23 = value;916    return;917  case UNW_PPC_R24:918    _registers.__r24 = value;919    return;920  case UNW_PPC_R25:921    _registers.__r25 = value;922    return;923  case UNW_PPC_R26:924    _registers.__r26 = value;925    return;926  case UNW_PPC_R27:927    _registers.__r27 = value;928    return;929  case UNW_PPC_R28:930    _registers.__r28 = value;931    return;932  case UNW_PPC_R29:933    _registers.__r29 = value;934    return;935  case UNW_PPC_R30:936    _registers.__r30 = value;937    return;938  case UNW_PPC_R31:939    _registers.__r31 = value;940    return;941  case UNW_PPC_MQ:942    _registers.__mq = value;943    return;944  case UNW_PPC_LR:945    _registers.__lr = value;946    return;947  case UNW_PPC_CTR:948    _registers.__ctr = value;949    return;950  case UNW_PPC_CR0:951    _registers.__cr &= 0x0FFFFFFF;952    _registers.__cr |= (value & 0xF0000000);953    return;954  case UNW_PPC_CR1:955    _registers.__cr &= 0xF0FFFFFF;956    _registers.__cr |= (value & 0x0F000000);957    return;958  case UNW_PPC_CR2:959    _registers.__cr &= 0xFF0FFFFF;960    _registers.__cr |= (value & 0x00F00000);961    return;962  case UNW_PPC_CR3:963    _registers.__cr &= 0xFFF0FFFF;964    _registers.__cr |= (value & 0x000F0000);965    return;966  case UNW_PPC_CR4:967    _registers.__cr &= 0xFFFF0FFF;968    _registers.__cr |= (value & 0x0000F000);969    return;970  case UNW_PPC_CR5:971    _registers.__cr &= 0xFFFFF0FF;972    _registers.__cr |= (value & 0x00000F00);973    return;974  case UNW_PPC_CR6:975    _registers.__cr &= 0xFFFFFF0F;976    _registers.__cr |= (value & 0x000000F0);977    return;978  case UNW_PPC_CR7:979    _registers.__cr &= 0xFFFFFFF0;980    _registers.__cr |= (value & 0x0000000F);981    return;982  case UNW_PPC_VRSAVE:983    _registers.__vrsave = value;984    return;985    // not saved986    return;987  case UNW_PPC_XER:988    _registers.__xer = value;989    return;990  case UNW_PPC_AP:991  case UNW_PPC_VSCR:992  case UNW_PPC_SPEFSCR:993    // not saved994    return;995  }996  _LIBUNWIND_ABORT("unsupported ppc register");997}998 999inline bool Registers_ppc::validFloatRegister(int regNum) const {1000  if (regNum < UNW_PPC_F0)1001    return false;1002  if (regNum > UNW_PPC_F31)1003    return false;1004  return true;1005}1006 1007inline double Registers_ppc::getFloatRegister(int regNum) const {1008  assert(validFloatRegister(regNum));1009  return _floatRegisters.__fpregs[regNum - UNW_PPC_F0];1010}1011 1012inline void Registers_ppc::setFloatRegister(int regNum, double value) {1013  assert(validFloatRegister(regNum));1014  _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value;1015}1016 1017inline bool Registers_ppc::validVectorRegister(int regNum) const {1018  if (regNum < UNW_PPC_V0)1019    return false;1020  if (regNum > UNW_PPC_V31)1021    return false;1022  return true;1023}1024 1025inline v128 Registers_ppc::getVectorRegister(int regNum) const {1026  assert(validVectorRegister(regNum));1027  v128 result = _vectorRegisters[regNum - UNW_PPC_V0];1028  return result;1029}1030 1031inline void Registers_ppc::setVectorRegister(int regNum, v128 value) {1032  assert(validVectorRegister(regNum));1033  _vectorRegisters[regNum - UNW_PPC_V0] = value;1034}1035 1036inline const char *Registers_ppc::getRegisterName(int regNum) {1037  switch (regNum) {1038  case UNW_REG_IP:1039    return "ip";1040  case UNW_REG_SP:1041    return "sp";1042  case UNW_PPC_R0:1043    return "r0";1044  case UNW_PPC_R1:1045    return "r1";1046  case UNW_PPC_R2:1047    return "r2";1048  case UNW_PPC_R3:1049    return "r3";1050  case UNW_PPC_R4:1051    return "r4";1052  case UNW_PPC_R5:1053    return "r5";1054  case UNW_PPC_R6:1055    return "r6";1056  case UNW_PPC_R7:1057    return "r7";1058  case UNW_PPC_R8:1059    return "r8";1060  case UNW_PPC_R9:1061    return "r9";1062  case UNW_PPC_R10:1063    return "r10";1064  case UNW_PPC_R11:1065    return "r11";1066  case UNW_PPC_R12:1067    return "r12";1068  case UNW_PPC_R13:1069    return "r13";1070  case UNW_PPC_R14:1071    return "r14";1072  case UNW_PPC_R15:1073    return "r15";1074  case UNW_PPC_R16:1075    return "r16";1076  case UNW_PPC_R17:1077    return "r17";1078  case UNW_PPC_R18:1079    return "r18";1080  case UNW_PPC_R19:1081    return "r19";1082  case UNW_PPC_R20:1083    return "r20";1084  case UNW_PPC_R21:1085    return "r21";1086  case UNW_PPC_R22:1087    return "r22";1088  case UNW_PPC_R23:1089    return "r23";1090  case UNW_PPC_R24:1091    return "r24";1092  case UNW_PPC_R25:1093    return "r25";1094  case UNW_PPC_R26:1095    return "r26";1096  case UNW_PPC_R27:1097    return "r27";1098  case UNW_PPC_R28:1099    return "r28";1100  case UNW_PPC_R29:1101    return "r29";1102  case UNW_PPC_R30:1103    return "r30";1104  case UNW_PPC_R31:1105    return "r31";1106  case UNW_PPC_F0:1107    return "fp0";1108  case UNW_PPC_F1:1109    return "fp1";1110  case UNW_PPC_F2:1111    return "fp2";1112  case UNW_PPC_F3:1113    return "fp3";1114  case UNW_PPC_F4:1115    return "fp4";1116  case UNW_PPC_F5:1117    return "fp5";1118  case UNW_PPC_F6:1119    return "fp6";1120  case UNW_PPC_F7:1121    return "fp7";1122  case UNW_PPC_F8:1123    return "fp8";1124  case UNW_PPC_F9:1125    return "fp9";1126  case UNW_PPC_F10:1127    return "fp10";1128  case UNW_PPC_F11:1129    return "fp11";1130  case UNW_PPC_F12:1131    return "fp12";1132  case UNW_PPC_F13:1133    return "fp13";1134  case UNW_PPC_F14:1135    return "fp14";1136  case UNW_PPC_F15:1137    return "fp15";1138  case UNW_PPC_F16:1139    return "fp16";1140  case UNW_PPC_F17:1141    return "fp17";1142  case UNW_PPC_F18:1143    return "fp18";1144  case UNW_PPC_F19:1145    return "fp19";1146  case UNW_PPC_F20:1147    return "fp20";1148  case UNW_PPC_F21:1149    return "fp21";1150  case UNW_PPC_F22:1151    return "fp22";1152  case UNW_PPC_F23:1153    return "fp23";1154  case UNW_PPC_F24:1155    return "fp24";1156  case UNW_PPC_F25:1157    return "fp25";1158  case UNW_PPC_F26:1159    return "fp26";1160  case UNW_PPC_F27:1161    return "fp27";1162  case UNW_PPC_F28:1163    return "fp28";1164  case UNW_PPC_F29:1165    return "fp29";1166  case UNW_PPC_F30:1167    return "fp30";1168  case UNW_PPC_F31:1169    return "fp31";1170  case UNW_PPC_LR:1171    return "lr";1172  default:1173    return "unknown register";1174  }1175 1176}1177#endif // _LIBUNWIND_TARGET_PPC1178 1179#if defined(_LIBUNWIND_TARGET_PPC64)1180/// Registers_ppc64 holds the register state of a thread in a 64-bit PowerPC1181/// process.1182class _LIBUNWIND_HIDDEN Registers_ppc64 {1183public:1184  Registers_ppc64();1185  Registers_ppc64(const void *registers);1186 1187  typedef uint64_t reg_t;1188  typedef uint64_t link_reg_t;1189 1190  bool        validRegister(int num) const;1191  uint64_t    getRegister(int num) const;1192  void        setRegister(int num, uint64_t value);1193  bool        validFloatRegister(int num) const;1194  double      getFloatRegister(int num) const;1195  void        setFloatRegister(int num, double value);1196  bool        validVectorRegister(int num) const;1197  v128        getVectorRegister(int num) const;1198  void        setVectorRegister(int num, v128 value);1199  static const char *getRegisterName(int num);1200  void        jumpto();1201  static constexpr int lastDwarfRegNum() {1202    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64;1203  }1204  static int  getArch() { return REGISTERS_PPC64; }1205 1206  uint64_t  getSP() const         { return _registers.__r1; }1207  void      setSP(uint64_t value) { _registers.__r1 = value; }1208  uint64_t  getIP() const         { return _registers.__srr0; }1209  void      setIP(uint64_t value) { _registers.__srr0 = value; }1210  uint64_t  getCR() const         { return _registers.__cr; }1211  void      setCR(uint64_t value) { _registers.__cr = value; }1212  uint64_t  getLR() const         { return _registers.__lr; }1213  void      setLR(uint64_t value) { _registers.__lr = value; }1214 1215private:1216  struct ppc64_thread_state_t {1217    uint64_t __srr0;    // Instruction address register (PC)1218    uint64_t __srr1;    // Machine state register (supervisor)1219    uint64_t __r0;1220    uint64_t __r1;1221    uint64_t __r2;1222    uint64_t __r3;1223    uint64_t __r4;1224    uint64_t __r5;1225    uint64_t __r6;1226    uint64_t __r7;1227    uint64_t __r8;1228    uint64_t __r9;1229    uint64_t __r10;1230    uint64_t __r11;1231    uint64_t __r12;1232    uint64_t __r13;1233    uint64_t __r14;1234    uint64_t __r15;1235    uint64_t __r16;1236    uint64_t __r17;1237    uint64_t __r18;1238    uint64_t __r19;1239    uint64_t __r20;1240    uint64_t __r21;1241    uint64_t __r22;1242    uint64_t __r23;1243    uint64_t __r24;1244    uint64_t __r25;1245    uint64_t __r26;1246    uint64_t __r27;1247    uint64_t __r28;1248    uint64_t __r29;1249    uint64_t __r30;1250    uint64_t __r31;1251    uint64_t __cr;      // Condition register1252    uint64_t __xer;     // User's integer exception register1253    uint64_t __lr;      // Link register1254    uint64_t __ctr;     // Count register1255    uint64_t __vrsave;  // Vector Save Register1256  };1257 1258  union ppc64_vsr_t {1259    struct asfloat_s {1260      double f;1261      uint64_t v2;1262    } asfloat;1263    v128 v;1264  };1265 1266  ppc64_thread_state_t _registers;1267  ppc64_vsr_t          _vectorScalarRegisters[64];1268 1269  static int getVectorRegNum(int num);1270};1271 1272inline Registers_ppc64::Registers_ppc64(const void *registers) {1273  static_assert((check_fit<Registers_ppc64, unw_context_t>::does_fit),1274                "ppc64 registers do not fit into unw_context_t");1275  memcpy(&_registers, static_cast<const uint8_t *>(registers),1276         sizeof(_registers));1277  static_assert(sizeof(_registers) == 312,1278                "expected vector scalar register offset to be 312");1279  memcpy(&_vectorScalarRegisters,1280         static_cast<const uint8_t *>(registers) + sizeof(_registers),1281         sizeof(_vectorScalarRegisters));1282  static_assert(sizeof(_registers) +1283                sizeof(_vectorScalarRegisters) == 1336,1284                "expected vector register offset to be 1336 bytes");1285}1286 1287inline Registers_ppc64::Registers_ppc64() {1288  memset(&_registers, 0, sizeof(_registers));1289  memset(&_vectorScalarRegisters, 0, sizeof(_vectorScalarRegisters));1290}1291 1292inline bool Registers_ppc64::validRegister(int regNum) const {1293  switch (regNum) {1294  case UNW_REG_IP:1295  case UNW_REG_SP:1296  case UNW_PPC64_XER:1297  case UNW_PPC64_LR:1298  case UNW_PPC64_CTR:1299  case UNW_PPC64_VRSAVE:1300      return true;1301  }1302 1303  if (regNum >= UNW_PPC64_R0 && regNum <= UNW_PPC64_R31)1304    return true;1305  if (regNum >= UNW_PPC64_CR0 && regNum <= UNW_PPC64_CR7)1306    return true;1307 1308  return false;1309}1310 1311inline uint64_t Registers_ppc64::getRegister(int regNum) const {1312  switch (regNum) {1313  case UNW_REG_IP:1314    return _registers.__srr0;1315  case UNW_PPC64_R0:1316    return _registers.__r0;1317  case UNW_PPC64_R1:1318  case UNW_REG_SP:1319    return _registers.__r1;1320  case UNW_PPC64_R2:1321    return _registers.__r2;1322  case UNW_PPC64_R3:1323    return _registers.__r3;1324  case UNW_PPC64_R4:1325    return _registers.__r4;1326  case UNW_PPC64_R5:1327    return _registers.__r5;1328  case UNW_PPC64_R6:1329    return _registers.__r6;1330  case UNW_PPC64_R7:1331    return _registers.__r7;1332  case UNW_PPC64_R8:1333    return _registers.__r8;1334  case UNW_PPC64_R9:1335    return _registers.__r9;1336  case UNW_PPC64_R10:1337    return _registers.__r10;1338  case UNW_PPC64_R11:1339    return _registers.__r11;1340  case UNW_PPC64_R12:1341    return _registers.__r12;1342  case UNW_PPC64_R13:1343    return _registers.__r13;1344  case UNW_PPC64_R14:1345    return _registers.__r14;1346  case UNW_PPC64_R15:1347    return _registers.__r15;1348  case UNW_PPC64_R16:1349    return _registers.__r16;1350  case UNW_PPC64_R17:1351    return _registers.__r17;1352  case UNW_PPC64_R18:1353    return _registers.__r18;1354  case UNW_PPC64_R19:1355    return _registers.__r19;1356  case UNW_PPC64_R20:1357    return _registers.__r20;1358  case UNW_PPC64_R21:1359    return _registers.__r21;1360  case UNW_PPC64_R22:1361    return _registers.__r22;1362  case UNW_PPC64_R23:1363    return _registers.__r23;1364  case UNW_PPC64_R24:1365    return _registers.__r24;1366  case UNW_PPC64_R25:1367    return _registers.__r25;1368  case UNW_PPC64_R26:1369    return _registers.__r26;1370  case UNW_PPC64_R27:1371    return _registers.__r27;1372  case UNW_PPC64_R28:1373    return _registers.__r28;1374  case UNW_PPC64_R29:1375    return _registers.__r29;1376  case UNW_PPC64_R30:1377    return _registers.__r30;1378  case UNW_PPC64_R31:1379    return _registers.__r31;1380  case UNW_PPC64_CR0:1381    return (_registers.__cr & 0xF0000000);1382  case UNW_PPC64_CR1:1383    return (_registers.__cr & 0x0F000000);1384  case UNW_PPC64_CR2:1385    return (_registers.__cr & 0x00F00000);1386  case UNW_PPC64_CR3:1387    return (_registers.__cr & 0x000F0000);1388  case UNW_PPC64_CR4:1389    return (_registers.__cr & 0x0000F000);1390  case UNW_PPC64_CR5:1391    return (_registers.__cr & 0x00000F00);1392  case UNW_PPC64_CR6:1393    return (_registers.__cr & 0x000000F0);1394  case UNW_PPC64_CR7:1395    return (_registers.__cr & 0x0000000F);1396  case UNW_PPC64_XER:1397    return _registers.__xer;1398  case UNW_PPC64_LR:1399    return _registers.__lr;1400  case UNW_PPC64_CTR:1401    return _registers.__ctr;1402  case UNW_PPC64_VRSAVE:1403    return _registers.__vrsave;1404  }1405  _LIBUNWIND_ABORT("unsupported ppc64 register");1406}1407 1408inline void Registers_ppc64::setRegister(int regNum, uint64_t value) {1409  switch (regNum) {1410  case UNW_REG_IP:1411    _registers.__srr0 = value;1412    return;1413  case UNW_PPC64_R0:1414    _registers.__r0 = value;1415    return;1416  case UNW_PPC64_R1:1417  case UNW_REG_SP:1418    _registers.__r1 = value;1419    return;1420  case UNW_PPC64_R2:1421    _registers.__r2 = value;1422    return;1423  case UNW_PPC64_R3:1424    _registers.__r3 = value;1425    return;1426  case UNW_PPC64_R4:1427    _registers.__r4 = value;1428    return;1429  case UNW_PPC64_R5:1430    _registers.__r5 = value;1431    return;1432  case UNW_PPC64_R6:1433    _registers.__r6 = value;1434    return;1435  case UNW_PPC64_R7:1436    _registers.__r7 = value;1437    return;1438  case UNW_PPC64_R8:1439    _registers.__r8 = value;1440    return;1441  case UNW_PPC64_R9:1442    _registers.__r9 = value;1443    return;1444  case UNW_PPC64_R10:1445    _registers.__r10 = value;1446    return;1447  case UNW_PPC64_R11:1448    _registers.__r11 = value;1449    return;1450  case UNW_PPC64_R12:1451    _registers.__r12 = value;1452    return;1453  case UNW_PPC64_R13:1454    _registers.__r13 = value;1455    return;1456  case UNW_PPC64_R14:1457    _registers.__r14 = value;1458    return;1459  case UNW_PPC64_R15:1460    _registers.__r15 = value;1461    return;1462  case UNW_PPC64_R16:1463    _registers.__r16 = value;1464    return;1465  case UNW_PPC64_R17:1466    _registers.__r17 = value;1467    return;1468  case UNW_PPC64_R18:1469    _registers.__r18 = value;1470    return;1471  case UNW_PPC64_R19:1472    _registers.__r19 = value;1473    return;1474  case UNW_PPC64_R20:1475    _registers.__r20 = value;1476    return;1477  case UNW_PPC64_R21:1478    _registers.__r21 = value;1479    return;1480  case UNW_PPC64_R22:1481    _registers.__r22 = value;1482    return;1483  case UNW_PPC64_R23:1484    _registers.__r23 = value;1485    return;1486  case UNW_PPC64_R24:1487    _registers.__r24 = value;1488    return;1489  case UNW_PPC64_R25:1490    _registers.__r25 = value;1491    return;1492  case UNW_PPC64_R26:1493    _registers.__r26 = value;1494    return;1495  case UNW_PPC64_R27:1496    _registers.__r27 = value;1497    return;1498  case UNW_PPC64_R28:1499    _registers.__r28 = value;1500    return;1501  case UNW_PPC64_R29:1502    _registers.__r29 = value;1503    return;1504  case UNW_PPC64_R30:1505    _registers.__r30 = value;1506    return;1507  case UNW_PPC64_R31:1508    _registers.__r31 = value;1509    return;1510  case UNW_PPC64_CR0:1511    _registers.__cr &= 0x0FFFFFFF;1512    _registers.__cr |= (value & 0xF0000000);1513    return;1514  case UNW_PPC64_CR1:1515    _registers.__cr &= 0xF0FFFFFF;1516    _registers.__cr |= (value & 0x0F000000);1517    return;1518  case UNW_PPC64_CR2:1519    _registers.__cr &= 0xFF0FFFFF;1520    _registers.__cr |= (value & 0x00F00000);1521    return;1522  case UNW_PPC64_CR3:1523    _registers.__cr &= 0xFFF0FFFF;1524    _registers.__cr |= (value & 0x000F0000);1525    return;1526  case UNW_PPC64_CR4:1527    _registers.__cr &= 0xFFFF0FFF;1528    _registers.__cr |= (value & 0x0000F000);1529    return;1530  case UNW_PPC64_CR5:1531    _registers.__cr &= 0xFFFFF0FF;1532    _registers.__cr |= (value & 0x00000F00);1533    return;1534  case UNW_PPC64_CR6:1535    _registers.__cr &= 0xFFFFFF0F;1536    _registers.__cr |= (value & 0x000000F0);1537    return;1538  case UNW_PPC64_CR7:1539    _registers.__cr &= 0xFFFFFFF0;1540    _registers.__cr |= (value & 0x0000000F);1541    return;1542  case UNW_PPC64_XER:1543    _registers.__xer = value;1544    return;1545  case UNW_PPC64_LR:1546    _registers.__lr = value;1547    return;1548  case UNW_PPC64_CTR:1549    _registers.__ctr = value;1550    return;1551  case UNW_PPC64_VRSAVE:1552    _registers.__vrsave = value;1553    return;1554  }1555  _LIBUNWIND_ABORT("unsupported ppc64 register");1556}1557 1558inline bool Registers_ppc64::validFloatRegister(int regNum) const {1559  return regNum >= UNW_PPC64_F0 && regNum <= UNW_PPC64_F31;1560}1561 1562inline double Registers_ppc64::getFloatRegister(int regNum) const {1563  assert(validFloatRegister(regNum));1564  return _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f;1565}1566 1567inline void Registers_ppc64::setFloatRegister(int regNum, double value) {1568  assert(validFloatRegister(regNum));1569  _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f = value;1570}1571 1572inline bool Registers_ppc64::validVectorRegister(int regNum) const {1573#if defined(__VSX__)1574  if (regNum >= UNW_PPC64_VS0 && regNum <= UNW_PPC64_VS31)1575    return true;1576  if (regNum >= UNW_PPC64_VS32 && regNum <= UNW_PPC64_VS63)1577    return true;1578#elif defined(__ALTIVEC__)1579  if (regNum >= UNW_PPC64_V0 && regNum <= UNW_PPC64_V31)1580    return true;1581#endif1582  return false;1583}1584 1585inline int Registers_ppc64::getVectorRegNum(int num)1586{1587  if (num >= UNW_PPC64_VS0 && num <= UNW_PPC64_VS31)1588    return num - UNW_PPC64_VS0;1589  else1590    return num - UNW_PPC64_VS32 + 32;1591}1592 1593inline v128 Registers_ppc64::getVectorRegister(int regNum) const {1594  assert(validVectorRegister(regNum));1595  return _vectorScalarRegisters[getVectorRegNum(regNum)].v;1596}1597 1598inline void Registers_ppc64::setVectorRegister(int regNum, v128 value) {1599  assert(validVectorRegister(regNum));1600  _vectorScalarRegisters[getVectorRegNum(regNum)].v = value;1601}1602 1603inline const char *Registers_ppc64::getRegisterName(int regNum) {1604  switch (regNum) {1605  case UNW_REG_IP:1606    return "ip";1607  case UNW_REG_SP:1608    return "sp";1609  case UNW_PPC64_R0:1610    return "r0";1611  case UNW_PPC64_R1:1612    return "r1";1613  case UNW_PPC64_R2:1614    return "r2";1615  case UNW_PPC64_R3:1616    return "r3";1617  case UNW_PPC64_R4:1618    return "r4";1619  case UNW_PPC64_R5:1620    return "r5";1621  case UNW_PPC64_R6:1622    return "r6";1623  case UNW_PPC64_R7:1624    return "r7";1625  case UNW_PPC64_R8:1626    return "r8";1627  case UNW_PPC64_R9:1628    return "r9";1629  case UNW_PPC64_R10:1630    return "r10";1631  case UNW_PPC64_R11:1632    return "r11";1633  case UNW_PPC64_R12:1634    return "r12";1635  case UNW_PPC64_R13:1636    return "r13";1637  case UNW_PPC64_R14:1638    return "r14";1639  case UNW_PPC64_R15:1640    return "r15";1641  case UNW_PPC64_R16:1642    return "r16";1643  case UNW_PPC64_R17:1644    return "r17";1645  case UNW_PPC64_R18:1646    return "r18";1647  case UNW_PPC64_R19:1648    return "r19";1649  case UNW_PPC64_R20:1650    return "r20";1651  case UNW_PPC64_R21:1652    return "r21";1653  case UNW_PPC64_R22:1654    return "r22";1655  case UNW_PPC64_R23:1656    return "r23";1657  case UNW_PPC64_R24:1658    return "r24";1659  case UNW_PPC64_R25:1660    return "r25";1661  case UNW_PPC64_R26:1662    return "r26";1663  case UNW_PPC64_R27:1664    return "r27";1665  case UNW_PPC64_R28:1666    return "r28";1667  case UNW_PPC64_R29:1668    return "r29";1669  case UNW_PPC64_R30:1670    return "r30";1671  case UNW_PPC64_R31:1672    return "r31";1673  case UNW_PPC64_CR0:1674    return "cr0";1675  case UNW_PPC64_CR1:1676    return "cr1";1677  case UNW_PPC64_CR2:1678    return "cr2";1679  case UNW_PPC64_CR3:1680    return "cr3";1681  case UNW_PPC64_CR4:1682    return "cr4";1683  case UNW_PPC64_CR5:1684    return "cr5";1685  case UNW_PPC64_CR6:1686    return "cr6";1687  case UNW_PPC64_CR7:1688    return "cr7";1689  case UNW_PPC64_XER:1690    return "xer";1691  case UNW_PPC64_LR:1692    return "lr";1693  case UNW_PPC64_CTR:1694    return "ctr";1695  case UNW_PPC64_VRSAVE:1696    return "vrsave";1697  case UNW_PPC64_F0:1698    return "fp0";1699  case UNW_PPC64_F1:1700    return "fp1";1701  case UNW_PPC64_F2:1702    return "fp2";1703  case UNW_PPC64_F3:1704    return "fp3";1705  case UNW_PPC64_F4:1706    return "fp4";1707  case UNW_PPC64_F5:1708    return "fp5";1709  case UNW_PPC64_F6:1710    return "fp6";1711  case UNW_PPC64_F7:1712    return "fp7";1713  case UNW_PPC64_F8:1714    return "fp8";1715  case UNW_PPC64_F9:1716    return "fp9";1717  case UNW_PPC64_F10:1718    return "fp10";1719  case UNW_PPC64_F11:1720    return "fp11";1721  case UNW_PPC64_F12:1722    return "fp12";1723  case UNW_PPC64_F13:1724    return "fp13";1725  case UNW_PPC64_F14:1726    return "fp14";1727  case UNW_PPC64_F15:1728    return "fp15";1729  case UNW_PPC64_F16:1730    return "fp16";1731  case UNW_PPC64_F17:1732    return "fp17";1733  case UNW_PPC64_F18:1734    return "fp18";1735  case UNW_PPC64_F19:1736    return "fp19";1737  case UNW_PPC64_F20:1738    return "fp20";1739  case UNW_PPC64_F21:1740    return "fp21";1741  case UNW_PPC64_F22:1742    return "fp22";1743  case UNW_PPC64_F23:1744    return "fp23";1745  case UNW_PPC64_F24:1746    return "fp24";1747  case UNW_PPC64_F25:1748    return "fp25";1749  case UNW_PPC64_F26:1750    return "fp26";1751  case UNW_PPC64_F27:1752    return "fp27";1753  case UNW_PPC64_F28:1754    return "fp28";1755  case UNW_PPC64_F29:1756    return "fp29";1757  case UNW_PPC64_F30:1758    return "fp30";1759  case UNW_PPC64_F31:1760    return "fp31";1761  case UNW_PPC64_V0:1762    return "v0";1763  case UNW_PPC64_V1:1764    return "v1";1765  case UNW_PPC64_V2:1766    return "v2";1767  case UNW_PPC64_V3:1768    return "v3";1769  case UNW_PPC64_V4:1770    return "v4";1771  case UNW_PPC64_V5:1772    return "v5";1773  case UNW_PPC64_V6:1774    return "v6";1775  case UNW_PPC64_V7:1776    return "v7";1777  case UNW_PPC64_V8:1778    return "v8";1779  case UNW_PPC64_V9:1780    return "v9";1781  case UNW_PPC64_V10:1782    return "v10";1783  case UNW_PPC64_V11:1784    return "v11";1785  case UNW_PPC64_V12:1786    return "v12";1787  case UNW_PPC64_V13:1788    return "v13";1789  case UNW_PPC64_V14:1790    return "v14";1791  case UNW_PPC64_V15:1792    return "v15";1793  case UNW_PPC64_V16:1794    return "v16";1795  case UNW_PPC64_V17:1796    return "v17";1797  case UNW_PPC64_V18:1798    return "v18";1799  case UNW_PPC64_V19:1800    return "v19";1801  case UNW_PPC64_V20:1802    return "v20";1803  case UNW_PPC64_V21:1804    return "v21";1805  case UNW_PPC64_V22:1806    return "v22";1807  case UNW_PPC64_V23:1808    return "v23";1809  case UNW_PPC64_V24:1810    return "v24";1811  case UNW_PPC64_V25:1812    return "v25";1813  case UNW_PPC64_V26:1814    return "v26";1815  case UNW_PPC64_V27:1816    return "v27";1817  case UNW_PPC64_V28:1818    return "v28";1819  case UNW_PPC64_V29:1820    return "v29";1821  case UNW_PPC64_V30:1822    return "v30";1823  case UNW_PPC64_V31:1824    return "v31";1825  }1826  return "unknown register";1827}1828#endif // _LIBUNWIND_TARGET_PPC641829 1830 1831#if defined(_LIBUNWIND_TARGET_AARCH64)1832/// Registers_arm64  holds the register state of a thread in a 64-bit arm1833/// process.1834class _LIBUNWIND_HIDDEN Registers_arm64;1835extern "C" int64_t __libunwind_Registers_arm64_za_disable();1836extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *,1837                                                   unsigned walkedFrames);1838 1839#if defined(_LIBUNWIND_USE_GCS)1840extern "C" void *__libunwind_shstk_get_jump_target() {1841  return reinterpret_cast<void *>(&__libunwind_Registers_arm64_jumpto);1842}1843#endif1844 1845class _LIBUNWIND_HIDDEN Registers_arm64 {1846public:1847  Registers_arm64() = default;1848  Registers_arm64(const void *registers);1849  Registers_arm64(const Registers_arm64 &);1850  Registers_arm64 &operator=(const Registers_arm64 &);1851 1852  typedef uint64_t reg_t;1853  typedef uint64_t __ptrauth_unwind_registers_arm64_link_reg link_reg_t;1854 1855  bool        validRegister(int num) const;1856  uint64_t    getRegister(int num) const;1857  void        setRegister(int num, uint64_t value);1858  bool        validFloatRegister(int num) const;1859  double      getFloatRegister(int num) const;1860  void        setFloatRegister(int num, double value);1861  bool        validVectorRegister(int num) const;1862  v128        getVectorRegister(int num) const;1863  void        setVectorRegister(int num, v128 value);1864  static const char *getRegisterName(int num);1865  void        jumpto(unsigned walkedFrames = 0) {1866    zaDisable();1867    __libunwind_Registers_arm64_jumpto(this, walkedFrames);1868  }1869#ifdef _LIBUNWIND_TRACE_RET_INJECT1870  _LIBUNWIND_TRACE_NO_INLINE1871  void        returnto(unsigned walkedFrames) { jumpto(walkedFrames); }1872#endif1873  static constexpr int lastDwarfRegNum() {1874    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64;1875  }1876  static int  getArch() { return REGISTERS_ARM64; }1877 1878  uint64_t  getSP() const         { return _registers.__sp; }1879  void      setSP(uint64_t value) { _registers.__sp = value; }1880  uint64_t  getIP() const {1881    uint64_t value = _registers.__pc;1882#if defined(_LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING)1883    // Note the value of the PC was signed to its address in the register state1884    // but everyone else expects it to be sign by the SP, so convert on return.1885    value = (uint64_t)ptrauth_auth_and_resign((void *)_registers.__pc,1886                                              ptrauth_key_return_address,1887                                              &_registers.__pc,1888                                              ptrauth_key_return_address,1889                                              getSP());1890#endif1891    return value;1892  }1893  void      setIP(uint64_t value) {1894#if defined(_LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING)1895    // Note the value which was set should have been signed with the SP.1896    // We then resign with the slot we are being stored in to so that both SP1897    // and LR can't be spoofed at the same time.1898    value = (uint64_t)ptrauth_auth_and_resign((void *)value,1899                                              ptrauth_key_return_address,1900                                              getSP(),1901                                              ptrauth_key_return_address,1902                                              &_registers.__pc);1903#endif1904    _registers.__pc = value;1905  }1906  uint64_t getFP() const { return _registers.__fp; }1907  void setFP(uint64_t value) { _registers.__fp = value; }1908 1909#if defined(_LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING)1910  void1911  loadAndAuthenticateLinkRegister(reg_t inplaceAuthedLinkRegister,1912                                  link_reg_t *referenceAuthedLinkRegister) {1913    // If we are in an arm64/arm64e frame, then the PC should have been signed1914    // with the SP1915    *referenceAuthedLinkRegister =1916      (uint64_t)ptrauth_auth_data((void *)inplaceAuthedLinkRegister,1917                                  ptrauth_key_return_address,1918                                  _registers.__sp);1919  }1920#endif1921 1922private:1923  uint64_t lazyGetVG() const;1924 1925  void zaDisable() const {1926    if (!_misc_registers.__has_sme)1927      return;1928    if (__libunwind_Registers_arm64_za_disable() != 0)1929      _LIBUNWIND_ABORT("SME ZA disable failed");1930  }1931 1932  static bool checkHasSME() {1933#if defined(HAVE_SYS_AUXV_H)1934    constexpr int hwcap2_sme = (1 << 23);1935    unsigned long hwcap2 = getauxval(AT_HWCAP2);1936    return (hwcap2 & hwcap2_sme) != 0;1937#endif1938    // TODO: Support other platforms.1939    return false;1940  }1941 1942  struct GPRs {1943    uint64_t __x[29] = {};        // x0-x281944    uint64_t __fp = 0;            // Frame pointer x291945    uint64_t __lr = 0;            // Link register x301946    uint64_t __sp = 0;            // Stack pointer x311947    uint64_t __pc = 0;            // Program counter1948    uint64_t __ra_sign_state = 0; // RA sign state register1949  };1950 1951  struct Misc {1952    mutable uint32_t __vg = 0; // Vector Granule1953    bool __has_sme = checkHasSME();1954  };1955 1956  GPRs _registers = {};1957  // Currently only the lower double in 128-bit vectore registers1958  // is perserved during unwinding.  We could define new register1959  // numbers (> 96) which mean whole vector registers, then this1960  // struct would need to change to contain whole vector registers.1961  double _vectorHalfRegisters[32] = {};1962 1963  // Miscellaneous/virtual registers. These are stored below the GPRs and FPRs1964  // as they do not correspond to physical registers, so do not need to be1965  // saved/restored in UnwindRegistersRestore.S and UnwindRegistersSave.S, and1966  // we don't want to modify the existing offsets for GPRs and FPRs.1967  Misc _misc_registers;1968};1969 1970inline Registers_arm64::Registers_arm64(const void *registers) {1971  static_assert((check_fit<Registers_arm64, unw_context_t>::does_fit),1972                "arm64 registers do not fit into unw_context_t");1973  memcpy(&_registers, registers, sizeof(_registers));1974  static_assert(sizeof(GPRs) == 0x110,1975                "expected VFP registers to be at offset 272");1976  memcpy(_vectorHalfRegisters,1977         static_cast<const uint8_t *>(registers) + sizeof(GPRs),1978         sizeof(_vectorHalfRegisters));1979  _misc_registers.__vg = 0;1980 1981#if defined(_LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING)1982  // We have to do some pointer authentication fixups after this copy,1983  // and as part of that we need to load the source pc without1984  // authenticating so that we maintain the signature for the resigning1985  // performed by setIP.1986  uint64_t pcRegister = 0;1987  memmove(&pcRegister, ((uint8_t *)&_registers) + offsetof(GPRs, __pc),1988          sizeof(pcRegister));1989  setIP(pcRegister);1990#endif1991}1992 1993inline Registers_arm64::Registers_arm64(const Registers_arm64 &other) {1994  *this = other;1995}1996 1997inline Registers_arm64 &1998Registers_arm64::operator=(const Registers_arm64 &other) {1999  memmove(static_cast<void *>(this), &other, sizeof(*this));2000  // We perform this step to ensure that we correctly authenticate and re-sign2001  // the pc after the bitwise copy.2002  setIP(other.getIP());2003  return *this;2004}2005 2006inline bool Registers_arm64::validRegister(int regNum) const {2007  if (regNum == UNW_REG_IP)2008    return true;2009  if (regNum == UNW_REG_SP)2010    return true;2011  if (regNum < 0)2012    return false;2013  if (regNum > 95)2014    return false;2015  if (regNum == UNW_AARCH64_RA_SIGN_STATE)2016    return true;2017  if (regNum == UNW_AARCH64_VG)2018    return true;2019  if ((regNum > 32) && (regNum < 64))2020    return false;2021  return true;2022}2023 2024inline uint64_t Registers_arm64::lazyGetVG() const {2025  if (!_misc_registers.__vg) {2026#if defined(__aarch64__)2027    register uint64_t vg asm("x0");2028    asm(".inst 0x04e0e3e0" // CNTD x02029        : "=r"(vg));2030    _misc_registers.__vg = vg;2031#else2032    _LIBUNWIND_ABORT("arm64 VG undefined");2033#endif2034  }2035  return _misc_registers.__vg;2036}2037 2038inline uint64_t Registers_arm64::getRegister(int regNum) const {2039  if (regNum == UNW_REG_IP || regNum == UNW_AARCH64_PC)2040    return getIP();2041  if (regNum == UNW_REG_SP || regNum == UNW_AARCH64_SP)2042    return _registers.__sp;2043  if (regNum == UNW_AARCH64_RA_SIGN_STATE)2044    return _registers.__ra_sign_state;2045  if (regNum == UNW_AARCH64_FP)2046    return getFP();2047  if (regNum == UNW_AARCH64_LR)2048    return _registers.__lr;2049  if (regNum == UNW_AARCH64_VG)2050    return lazyGetVG();2051  if ((regNum >= 0) && (regNum < 29))2052    return _registers.__x[regNum];2053  _LIBUNWIND_ABORT("unsupported arm64 register");2054}2055 2056inline void Registers_arm64::setRegister(int regNum, uint64_t value) {2057  if (regNum == UNW_REG_IP || regNum == UNW_AARCH64_PC)2058    setIP(value);2059  else if (regNum == UNW_REG_SP || regNum == UNW_AARCH64_SP)2060    _registers.__sp = value;2061  else if (regNum == UNW_AARCH64_RA_SIGN_STATE)2062    _registers.__ra_sign_state = value;2063  else if (regNum == UNW_AARCH64_FP)2064    setFP(value);2065  else if (regNum == UNW_AARCH64_LR)2066    _registers.__lr = value;2067  else if (regNum == UNW_AARCH64_VG)2068    _misc_registers.__vg = value;2069  else if ((regNum >= 0) && (regNum < 29))2070    _registers.__x[regNum] = value;2071  else2072    _LIBUNWIND_ABORT("unsupported arm64 register");2073}2074 2075inline const char *Registers_arm64::getRegisterName(int regNum) {2076  switch (regNum) {2077  case UNW_REG_IP:2078    return "pc";2079  case UNW_REG_SP:2080    return "sp";2081  case UNW_AARCH64_X0:2082    return "x0";2083  case UNW_AARCH64_X1:2084    return "x1";2085  case UNW_AARCH64_X2:2086    return "x2";2087  case UNW_AARCH64_X3:2088    return "x3";2089  case UNW_AARCH64_X4:2090    return "x4";2091  case UNW_AARCH64_X5:2092    return "x5";2093  case UNW_AARCH64_X6:2094    return "x6";2095  case UNW_AARCH64_X7:2096    return "x7";2097  case UNW_AARCH64_X8:2098    return "x8";2099  case UNW_AARCH64_X9:2100    return "x9";2101  case UNW_AARCH64_X10:2102    return "x10";2103  case UNW_AARCH64_X11:2104    return "x11";2105  case UNW_AARCH64_X12:2106    return "x12";2107  case UNW_AARCH64_X13:2108    return "x13";2109  case UNW_AARCH64_X14:2110    return "x14";2111  case UNW_AARCH64_X15:2112    return "x15";2113  case UNW_AARCH64_X16:2114    return "x16";2115  case UNW_AARCH64_X17:2116    return "x17";2117  case UNW_AARCH64_X18:2118    return "x18";2119  case UNW_AARCH64_X19:2120    return "x19";2121  case UNW_AARCH64_X20:2122    return "x20";2123  case UNW_AARCH64_X21:2124    return "x21";2125  case UNW_AARCH64_X22:2126    return "x22";2127  case UNW_AARCH64_X23:2128    return "x23";2129  case UNW_AARCH64_X24:2130    return "x24";2131  case UNW_AARCH64_X25:2132    return "x25";2133  case UNW_AARCH64_X26:2134    return "x26";2135  case UNW_AARCH64_X27:2136    return "x27";2137  case UNW_AARCH64_X28:2138    return "x28";2139  case UNW_AARCH64_FP:2140    return "fp";2141  case UNW_AARCH64_LR:2142    return "lr";2143  case UNW_AARCH64_SP:2144    return "sp";2145  case UNW_AARCH64_PC:2146    return "pc";2147  case UNW_AARCH64_V0:2148    return "d0";2149  case UNW_AARCH64_V1:2150    return "d1";2151  case UNW_AARCH64_V2:2152    return "d2";2153  case UNW_AARCH64_V3:2154    return "d3";2155  case UNW_AARCH64_V4:2156    return "d4";2157  case UNW_AARCH64_V5:2158    return "d5";2159  case UNW_AARCH64_V6:2160    return "d6";2161  case UNW_AARCH64_V7:2162    return "d7";2163  case UNW_AARCH64_V8:2164    return "d8";2165  case UNW_AARCH64_V9:2166    return "d9";2167  case UNW_AARCH64_V10:2168    return "d10";2169  case UNW_AARCH64_V11:2170    return "d11";2171  case UNW_AARCH64_V12:2172    return "d12";2173  case UNW_AARCH64_V13:2174    return "d13";2175  case UNW_AARCH64_V14:2176    return "d14";2177  case UNW_AARCH64_V15:2178    return "d15";2179  case UNW_AARCH64_V16:2180    return "d16";2181  case UNW_AARCH64_V17:2182    return "d17";2183  case UNW_AARCH64_V18:2184    return "d18";2185  case UNW_AARCH64_V19:2186    return "d19";2187  case UNW_AARCH64_V20:2188    return "d20";2189  case UNW_AARCH64_V21:2190    return "d21";2191  case UNW_AARCH64_V22:2192    return "d22";2193  case UNW_AARCH64_V23:2194    return "d23";2195  case UNW_AARCH64_V24:2196    return "d24";2197  case UNW_AARCH64_V25:2198    return "d25";2199  case UNW_AARCH64_V26:2200    return "d26";2201  case UNW_AARCH64_V27:2202    return "d27";2203  case UNW_AARCH64_V28:2204    return "d28";2205  case UNW_AARCH64_V29:2206    return "d29";2207  case UNW_AARCH64_V30:2208    return "d30";2209  case UNW_AARCH64_V31:2210    return "d31";2211  default:2212    return "unknown register";2213  }2214}2215 2216inline bool Registers_arm64::validFloatRegister(int regNum) const {2217  if (regNum < UNW_AARCH64_V0)2218    return false;2219  if (regNum > UNW_AARCH64_V31)2220    return false;2221  return true;2222}2223 2224inline double Registers_arm64::getFloatRegister(int regNum) const {2225  assert(validFloatRegister(regNum));2226  return _vectorHalfRegisters[regNum - UNW_AARCH64_V0];2227}2228 2229inline void Registers_arm64::setFloatRegister(int regNum, double value) {2230  assert(validFloatRegister(regNum));2231  _vectorHalfRegisters[regNum - UNW_AARCH64_V0] = value;2232}2233 2234inline bool Registers_arm64::validVectorRegister(int) const {2235  return false;2236}2237 2238inline v128 Registers_arm64::getVectorRegister(int) const {2239  _LIBUNWIND_ABORT("no arm64 vector register support yet");2240}2241 2242inline void Registers_arm64::setVectorRegister(int, v128) {2243  _LIBUNWIND_ABORT("no arm64 vector register support yet");2244}2245#endif // _LIBUNWIND_TARGET_AARCH642246 2247#if defined(_LIBUNWIND_TARGET_ARM)2248/// Registers_arm holds the register state of a thread in a 32-bit arm2249/// process.2250///2251/// NOTE: Assumes VFPv3. On ARM processors without a floating point unit,2252/// this uses more memory than required.2253class _LIBUNWIND_HIDDEN Registers_arm {2254public:2255  Registers_arm();2256  Registers_arm(const void *registers);2257 2258  typedef uint32_t reg_t;2259  typedef uint32_t link_reg_t;2260 2261  bool        validRegister(int num) const;2262  uint32_t    getRegister(int num) const;2263  void        setRegister(int num, uint32_t value);2264  bool        validFloatRegister(int num) const;2265  unw_fpreg_t getFloatRegister(int num);2266  void        setFloatRegister(int num, unw_fpreg_t value);2267  bool        validVectorRegister(int num) const;2268  v128        getVectorRegister(int num) const;2269  void        setVectorRegister(int num, v128 value);2270  static const char *getRegisterName(int num);2271  void        jumpto() {2272    restoreSavedFloatRegisters();2273    restoreCoreAndJumpTo();2274  }2275  static constexpr int lastDwarfRegNum() {2276    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM;2277  }2278  static int  getArch() { return REGISTERS_ARM; }2279 2280  uint32_t  getSP() const         { return _registers.__sp; }2281  void      setSP(uint32_t value) { _registers.__sp = value; }2282  uint32_t  getIP() const         { return _registers.__pc; }2283  void      setIP(uint32_t value) { _registers.__pc = value; }2284 2285  void saveVFPAsX() {2286    assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15);2287    _use_X_for_vfp_save = true;2288  }2289 2290  void restoreSavedFloatRegisters() {2291    if (_saved_vfp_d0_d15) {2292      if (_use_X_for_vfp_save)2293        restoreVFPWithFLDMX(_vfp_d0_d15_pad);2294      else2295        restoreVFPWithFLDMD(_vfp_d0_d15_pad);2296    }2297    if (_saved_vfp_d16_d31)2298      restoreVFPv3(_vfp_d16_d31);2299#if defined(__ARM_WMMX)2300    if (_saved_iwmmx)2301      restoreiWMMX(_iwmmx);2302    if (_saved_iwmmx_control)2303      restoreiWMMXControl(_iwmmx_control);2304#endif2305  }2306 2307private:2308  struct GPRs {2309    uint32_t __r[13]; // r0-r122310    uint32_t __sp;    // Stack pointer r132311    uint32_t __lr;    // Link register r142312    uint32_t __pc;    // Program counter r152313  };2314 2315  struct PseudoRegisters {2316    uint32_t __pac; // Return Authentication Code (PAC)2317  };2318 2319  static void saveVFPWithFSTMD(void*);2320  static void saveVFPWithFSTMX(void*);2321  static void saveVFPv3(void*);2322  static void restoreVFPWithFLDMD(void*);2323  static void restoreVFPWithFLDMX(void*);2324  static void restoreVFPv3(void*);2325#if defined(__ARM_WMMX)2326  static void saveiWMMX(void*);2327  static void saveiWMMXControl(uint32_t*);2328  static void restoreiWMMX(void*);2329  static void restoreiWMMXControl(uint32_t*);2330#endif2331  void restoreCoreAndJumpTo();2332 2333  // ARM registers2334  GPRs _registers;2335  PseudoRegisters _pseudo_registers;2336 2337  // We save floating point registers lazily because we can't know ahead of2338  // time which ones are used. See EHABI #4.7.2339 2340  // Whether D0-D15 are saved in the FTSMX instead of FSTMD format.2341  //2342  // See EHABI #7.5 that explains how matching instruction sequences for load2343  // and store need to be used to correctly restore the exact register bits.2344  bool _use_X_for_vfp_save;2345  // Whether VFP D0-D15 are saved.2346  bool _saved_vfp_d0_d15;2347  // Whether VFPv3 D16-D31 are saved.2348  bool _saved_vfp_d16_d31;2349  // VFP registers D0-D15, + padding if saved using FSTMX2350  unw_fpreg_t _vfp_d0_d15_pad[17];2351  // VFPv3 registers D16-D31, always saved using FSTMD2352  unw_fpreg_t _vfp_d16_d31[16];2353#if defined(__ARM_WMMX)2354  // Whether iWMMX data registers are saved.2355  bool _saved_iwmmx;2356  // Whether iWMMX control registers are saved.2357  mutable bool _saved_iwmmx_control;2358  // iWMMX registers2359  unw_fpreg_t _iwmmx[16];2360  // iWMMX control registers2361  mutable uint32_t _iwmmx_control[4];2362#endif2363};2364 2365inline Registers_arm::Registers_arm(const void *registers)2366  : _use_X_for_vfp_save(false),2367    _saved_vfp_d0_d15(false),2368    _saved_vfp_d16_d31(false) {2369  static_assert((check_fit<Registers_arm, unw_context_t>::does_fit),2370                "arm registers do not fit into unw_context_t");2371  // See __unw_getcontext() note about data.2372  memcpy(&_registers, registers, sizeof(_registers));2373  memset(&_pseudo_registers, 0, sizeof(_pseudo_registers));2374  memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));2375  memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));2376#if defined(__ARM_WMMX)2377  _saved_iwmmx = false;2378  _saved_iwmmx_control = false;2379  memset(&_iwmmx, 0, sizeof(_iwmmx));2380  memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));2381#endif2382}2383 2384inline Registers_arm::Registers_arm()2385  : _use_X_for_vfp_save(false),2386    _saved_vfp_d0_d15(false),2387    _saved_vfp_d16_d31(false) {2388  memset(&_registers, 0, sizeof(_registers));2389  memset(&_pseudo_registers, 0, sizeof(_pseudo_registers));2390  memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));2391  memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));2392#if defined(__ARM_WMMX)2393  _saved_iwmmx = false;2394  _saved_iwmmx_control = false;2395  memset(&_iwmmx, 0, sizeof(_iwmmx));2396  memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));2397#endif2398}2399 2400inline bool Registers_arm::validRegister(int regNum) const {2401  // Returns true for all non-VFP registers supported by the EHABI2402  // virtual register set (VRS).2403  if (regNum == UNW_REG_IP)2404    return true;2405 2406  if (regNum == UNW_REG_SP)2407    return true;2408 2409  if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15)2410    return true;2411 2412#if defined(__ARM_WMMX)2413  if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3)2414    return true;2415#endif2416 2417#ifdef __ARM_FEATURE_PAUTH2418  if (regNum == UNW_ARM_RA_AUTH_CODE)2419    return true;2420#endif2421 2422  return false;2423}2424 2425inline uint32_t Registers_arm::getRegister(int regNum) const {2426  if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)2427    return _registers.__sp;2428 2429  if (regNum == UNW_ARM_LR)2430    return _registers.__lr;2431 2432  if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)2433    return _registers.__pc;2434 2435  if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)2436    return _registers.__r[regNum];2437 2438#if defined(__ARM_WMMX)2439  if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {2440    if (!_saved_iwmmx_control) {2441      _saved_iwmmx_control = true;2442      saveiWMMXControl(_iwmmx_control);2443    }2444    return _iwmmx_control[regNum - UNW_ARM_WC0];2445  }2446#endif2447 2448#ifdef __ARM_FEATURE_PAUTH2449  if (regNum == UNW_ARM_RA_AUTH_CODE)2450    return _pseudo_registers.__pac;2451#endif2452 2453  _LIBUNWIND_ABORT("unsupported arm register");2454}2455 2456inline void Registers_arm::setRegister(int regNum, uint32_t value) {2457  if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) {2458    _registers.__sp = value;2459    return;2460  }2461 2462  if (regNum == UNW_ARM_LR) {2463    _registers.__lr = value;2464    return;2465  }2466 2467  if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) {2468    _registers.__pc = value;2469    return;2470  }2471 2472  if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) {2473    _registers.__r[regNum] = value;2474    return;2475  }2476 2477#if defined(__ARM_WMMX)2478  if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {2479    if (!_saved_iwmmx_control) {2480      _saved_iwmmx_control = true;2481      saveiWMMXControl(_iwmmx_control);2482    }2483    _iwmmx_control[regNum - UNW_ARM_WC0] = value;2484    return;2485  }2486#endif2487 2488  if (regNum == UNW_ARM_RA_AUTH_CODE) {2489    _pseudo_registers.__pac = value;2490    return;2491  }2492 2493  _LIBUNWIND_ABORT("unsupported arm register");2494}2495 2496inline const char *Registers_arm::getRegisterName(int regNum) {2497  switch (regNum) {2498  case UNW_REG_IP:2499  case UNW_ARM_IP: // UNW_ARM_R15 is alias2500    return "pc";2501  case UNW_ARM_LR: // UNW_ARM_R14 is alias2502    return "lr";2503  case UNW_REG_SP:2504  case UNW_ARM_SP: // UNW_ARM_R13 is alias2505    return "sp";2506  case UNW_ARM_R0:2507    return "r0";2508  case UNW_ARM_R1:2509    return "r1";2510  case UNW_ARM_R2:2511    return "r2";2512  case UNW_ARM_R3:2513    return "r3";2514  case UNW_ARM_R4:2515    return "r4";2516  case UNW_ARM_R5:2517    return "r5";2518  case UNW_ARM_R6:2519    return "r6";2520  case UNW_ARM_R7:2521    return "r7";2522  case UNW_ARM_R8:2523    return "r8";2524  case UNW_ARM_R9:2525    return "r9";2526  case UNW_ARM_R10:2527    return "r10";2528  case UNW_ARM_R11:2529    return "r11";2530  case UNW_ARM_R12:2531    return "r12";2532  case UNW_ARM_S0:2533    return "s0";2534  case UNW_ARM_S1:2535    return "s1";2536  case UNW_ARM_S2:2537    return "s2";2538  case UNW_ARM_S3:2539    return "s3";2540  case UNW_ARM_S4:2541    return "s4";2542  case UNW_ARM_S5:2543    return "s5";2544  case UNW_ARM_S6:2545    return "s6";2546  case UNW_ARM_S7:2547    return "s7";2548  case UNW_ARM_S8:2549    return "s8";2550  case UNW_ARM_S9:2551    return "s9";2552  case UNW_ARM_S10:2553    return "s10";2554  case UNW_ARM_S11:2555    return "s11";2556  case UNW_ARM_S12:2557    return "s12";2558  case UNW_ARM_S13:2559    return "s13";2560  case UNW_ARM_S14:2561    return "s14";2562  case UNW_ARM_S15:2563    return "s15";2564  case UNW_ARM_S16:2565    return "s16";2566  case UNW_ARM_S17:2567    return "s17";2568  case UNW_ARM_S18:2569    return "s18";2570  case UNW_ARM_S19:2571    return "s19";2572  case UNW_ARM_S20:2573    return "s20";2574  case UNW_ARM_S21:2575    return "s21";2576  case UNW_ARM_S22:2577    return "s22";2578  case UNW_ARM_S23:2579    return "s23";2580  case UNW_ARM_S24:2581    return "s24";2582  case UNW_ARM_S25:2583    return "s25";2584  case UNW_ARM_S26:2585    return "s26";2586  case UNW_ARM_S27:2587    return "s27";2588  case UNW_ARM_S28:2589    return "s28";2590  case UNW_ARM_S29:2591    return "s29";2592  case UNW_ARM_S30:2593    return "s30";2594  case UNW_ARM_S31:2595    return "s31";2596  case UNW_ARM_D0:2597    return "d0";2598  case UNW_ARM_D1:2599    return "d1";2600  case UNW_ARM_D2:2601    return "d2";2602  case UNW_ARM_D3:2603    return "d3";2604  case UNW_ARM_D4:2605    return "d4";2606  case UNW_ARM_D5:2607    return "d5";2608  case UNW_ARM_D6:2609    return "d6";2610  case UNW_ARM_D7:2611    return "d7";2612  case UNW_ARM_D8:2613    return "d8";2614  case UNW_ARM_D9:2615    return "d9";2616  case UNW_ARM_D10:2617    return "d10";2618  case UNW_ARM_D11:2619    return "d11";2620  case UNW_ARM_D12:2621    return "d12";2622  case UNW_ARM_D13:2623    return "d13";2624  case UNW_ARM_D14:2625    return "d14";2626  case UNW_ARM_D15:2627    return "d15";2628  case UNW_ARM_D16:2629    return "d16";2630  case UNW_ARM_D17:2631    return "d17";2632  case UNW_ARM_D18:2633    return "d18";2634  case UNW_ARM_D19:2635    return "d19";2636  case UNW_ARM_D20:2637    return "d20";2638  case UNW_ARM_D21:2639    return "d21";2640  case UNW_ARM_D22:2641    return "d22";2642  case UNW_ARM_D23:2643    return "d23";2644  case UNW_ARM_D24:2645    return "d24";2646  case UNW_ARM_D25:2647    return "d25";2648  case UNW_ARM_D26:2649    return "d26";2650  case UNW_ARM_D27:2651    return "d27";2652  case UNW_ARM_D28:2653    return "d28";2654  case UNW_ARM_D29:2655    return "d29";2656  case UNW_ARM_D30:2657    return "d30";2658  case UNW_ARM_D31:2659    return "d31";2660  default:2661    return "unknown register";2662  }2663}2664 2665inline bool Registers_arm::validFloatRegister(int regNum) const {2666  // NOTE: Consider the intel MMX registers floating points so the2667  // __unw_get_fpreg can be used to transmit the 64-bit data back.2668  return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31))2669#if defined(__ARM_WMMX)2670      || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15))2671#endif2672      ;2673}2674 2675inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) {2676  if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {2677    if (!_saved_vfp_d0_d15) {2678      _saved_vfp_d0_d15 = true;2679      if (_use_X_for_vfp_save)2680        saveVFPWithFSTMX(_vfp_d0_d15_pad);2681      else2682        saveVFPWithFSTMD(_vfp_d0_d15_pad);2683    }2684    return _vfp_d0_d15_pad[regNum - UNW_ARM_D0];2685  }2686 2687  if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {2688    if (!_saved_vfp_d16_d31) {2689      _saved_vfp_d16_d31 = true;2690      saveVFPv3(_vfp_d16_d31);2691    }2692    return _vfp_d16_d31[regNum - UNW_ARM_D16];2693  }2694 2695#if defined(__ARM_WMMX)2696  if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {2697    if (!_saved_iwmmx) {2698      _saved_iwmmx = true;2699      saveiWMMX(_iwmmx);2700    }2701    return _iwmmx[regNum - UNW_ARM_WR0];2702  }2703#endif2704 2705  _LIBUNWIND_ABORT("Unknown ARM float register");2706}2707 2708inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) {2709  if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {2710    if (!_saved_vfp_d0_d15) {2711      _saved_vfp_d0_d15 = true;2712      if (_use_X_for_vfp_save)2713        saveVFPWithFSTMX(_vfp_d0_d15_pad);2714      else2715        saveVFPWithFSTMD(_vfp_d0_d15_pad);2716    }2717    _vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value;2718    return;2719  }2720 2721  if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {2722    if (!_saved_vfp_d16_d31) {2723      _saved_vfp_d16_d31 = true;2724      saveVFPv3(_vfp_d16_d31);2725    }2726    _vfp_d16_d31[regNum - UNW_ARM_D16] = value;2727    return;2728  }2729 2730#if defined(__ARM_WMMX)2731  if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {2732    if (!_saved_iwmmx) {2733      _saved_iwmmx = true;2734      saveiWMMX(_iwmmx);2735    }2736    _iwmmx[regNum - UNW_ARM_WR0] = value;2737    return;2738  }2739#endif2740 2741  _LIBUNWIND_ABORT("Unknown ARM float register");2742}2743 2744inline bool Registers_arm::validVectorRegister(int) const {2745  return false;2746}2747 2748inline v128 Registers_arm::getVectorRegister(int) const {2749  _LIBUNWIND_ABORT("ARM vector support not implemented");2750}2751 2752inline void Registers_arm::setVectorRegister(int, v128) {2753  _LIBUNWIND_ABORT("ARM vector support not implemented");2754}2755#endif // _LIBUNWIND_TARGET_ARM2756 2757 2758#if defined(_LIBUNWIND_TARGET_OR1K)2759/// Registers_or1k holds the register state of a thread in an OpenRISC10002760/// process.2761class _LIBUNWIND_HIDDEN Registers_or1k {2762public:2763  Registers_or1k();2764  Registers_or1k(const void *registers);2765 2766  typedef uint32_t reg_t;2767  typedef uint32_t link_reg_t;2768 2769  bool        validRegister(int num) const;2770  uint32_t    getRegister(int num) const;2771  void        setRegister(int num, uint32_t value);2772  bool        validFloatRegister(int num) const;2773  double      getFloatRegister(int num) const;2774  void        setFloatRegister(int num, double value);2775  bool        validVectorRegister(int num) const;2776  v128        getVectorRegister(int num) const;2777  void        setVectorRegister(int num, v128 value);2778  static const char *getRegisterName(int num);2779  void        jumpto();2780  static constexpr int lastDwarfRegNum() {2781    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K;2782  }2783  static int  getArch() { return REGISTERS_OR1K; }2784 2785  uint64_t  getSP() const         { return _registers.__r[1]; }2786  void      setSP(uint32_t value) { _registers.__r[1] = value; }2787  uint64_t  getIP() const         { return _registers.__pc; }2788  void      setIP(uint32_t value) { _registers.__pc = value; }2789 2790private:2791  struct or1k_thread_state_t {2792    unsigned int __r[32]; // r0-r312793    unsigned int __pc;    // Program counter2794    unsigned int __epcr;  // Program counter at exception2795  };2796 2797  or1k_thread_state_t _registers;2798};2799 2800inline Registers_or1k::Registers_or1k(const void *registers) {2801  static_assert((check_fit<Registers_or1k, unw_context_t>::does_fit),2802                "or1k registers do not fit into unw_context_t");2803  memcpy(&_registers, static_cast<const uint8_t *>(registers),2804         sizeof(_registers));2805}2806 2807inline Registers_or1k::Registers_or1k() {2808  memset(&_registers, 0, sizeof(_registers));2809}2810 2811inline bool Registers_or1k::validRegister(int regNum) const {2812  if (regNum == UNW_REG_IP)2813    return true;2814  if (regNum == UNW_REG_SP)2815    return true;2816  if (regNum < 0)2817    return false;2818  if (regNum <= UNW_OR1K_R31)2819    return true;2820  if (regNum == UNW_OR1K_EPCR)2821    return true;2822  return false;2823}2824 2825inline uint32_t Registers_or1k::getRegister(int regNum) const {2826  if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31)2827    return _registers.__r[regNum - UNW_OR1K_R0];2828 2829  switch (regNum) {2830  case UNW_REG_IP:2831    return _registers.__pc;2832  case UNW_REG_SP:2833    return _registers.__r[1];2834  case UNW_OR1K_EPCR:2835    return _registers.__epcr;2836  }2837  _LIBUNWIND_ABORT("unsupported or1k register");2838}2839 2840inline void Registers_or1k::setRegister(int regNum, uint32_t value) {2841  if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) {2842    _registers.__r[regNum - UNW_OR1K_R0] = value;2843    return;2844  }2845 2846  switch (regNum) {2847  case UNW_REG_IP:2848    _registers.__pc = value;2849    return;2850  case UNW_REG_SP:2851    _registers.__r[1] = value;2852    return;2853  case UNW_OR1K_EPCR:2854    _registers.__epcr = value;2855    return;2856  }2857  _LIBUNWIND_ABORT("unsupported or1k register");2858}2859 2860inline bool Registers_or1k::validFloatRegister(int /* regNum */) const {2861  return false;2862}2863 2864inline double Registers_or1k::getFloatRegister(int /* regNum */) const {2865  _LIBUNWIND_ABORT("or1k float support not implemented");2866}2867 2868inline void Registers_or1k::setFloatRegister(int /* regNum */,2869                                             double /* value */) {2870  _LIBUNWIND_ABORT("or1k float support not implemented");2871}2872 2873inline bool Registers_or1k::validVectorRegister(int /* regNum */) const {2874  return false;2875}2876 2877inline v128 Registers_or1k::getVectorRegister(int /* regNum */) const {2878  _LIBUNWIND_ABORT("or1k vector support not implemented");2879}2880 2881inline void Registers_or1k::setVectorRegister(int /* regNum */, v128 /* value */) {2882  _LIBUNWIND_ABORT("or1k vector support not implemented");2883}2884 2885inline const char *Registers_or1k::getRegisterName(int regNum) {2886  switch (regNum) {2887  case UNW_OR1K_R0:2888    return "r0";2889  case UNW_OR1K_R1:2890    return "r1";2891  case UNW_OR1K_R2:2892    return "r2";2893  case UNW_OR1K_R3:2894    return "r3";2895  case UNW_OR1K_R4:2896    return "r4";2897  case UNW_OR1K_R5:2898    return "r5";2899  case UNW_OR1K_R6:2900    return "r6";2901  case UNW_OR1K_R7:2902    return "r7";2903  case UNW_OR1K_R8:2904    return "r8";2905  case UNW_OR1K_R9:2906    return "r9";2907  case UNW_OR1K_R10:2908    return "r10";2909  case UNW_OR1K_R11:2910    return "r11";2911  case UNW_OR1K_R12:2912    return "r12";2913  case UNW_OR1K_R13:2914    return "r13";2915  case UNW_OR1K_R14:2916    return "r14";2917  case UNW_OR1K_R15:2918    return "r15";2919  case UNW_OR1K_R16:2920    return "r16";2921  case UNW_OR1K_R17:2922    return "r17";2923  case UNW_OR1K_R18:2924    return "r18";2925  case UNW_OR1K_R19:2926    return "r19";2927  case UNW_OR1K_R20:2928    return "r20";2929  case UNW_OR1K_R21:2930    return "r21";2931  case UNW_OR1K_R22:2932    return "r22";2933  case UNW_OR1K_R23:2934    return "r23";2935  case UNW_OR1K_R24:2936    return "r24";2937  case UNW_OR1K_R25:2938    return "r25";2939  case UNW_OR1K_R26:2940    return "r26";2941  case UNW_OR1K_R27:2942    return "r27";2943  case UNW_OR1K_R28:2944    return "r28";2945  case UNW_OR1K_R29:2946    return "r29";2947  case UNW_OR1K_R30:2948    return "r30";2949  case UNW_OR1K_R31:2950    return "r31";2951  case UNW_OR1K_EPCR:2952    return "EPCR";2953  default:2954    return "unknown register";2955  }2956 2957}2958#endif // _LIBUNWIND_TARGET_OR1K2959 2960#if defined(_LIBUNWIND_TARGET_MIPS_O32)2961/// Registers_mips_o32 holds the register state of a thread in a 32-bit MIPS2962/// process.2963class _LIBUNWIND_HIDDEN Registers_mips_o32 {2964public:2965  Registers_mips_o32();2966  Registers_mips_o32(const void *registers);2967 2968  typedef uint32_t reg_t;2969  typedef uint32_t link_reg_t;2970 2971  bool        validRegister(int num) const;2972  uint32_t    getRegister(int num) const;2973  void        setRegister(int num, uint32_t value);2974  bool        validFloatRegister(int num) const;2975  double      getFloatRegister(int num) const;2976  void        setFloatRegister(int num, double value);2977  bool        validVectorRegister(int num) const;2978  v128        getVectorRegister(int num) const;2979  void        setVectorRegister(int num, v128 value);2980  static const char *getRegisterName(int num);2981  void        jumpto();2982  static constexpr int lastDwarfRegNum() {2983    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS;2984  }2985  static int  getArch() { return REGISTERS_MIPS_O32; }2986 2987  uint32_t  getSP() const         { return _registers.__r[29]; }2988  void      setSP(uint32_t value) { _registers.__r[29] = value; }2989  uint32_t  getIP() const         { return _registers.__pc; }2990  void      setIP(uint32_t value) { _registers.__pc = value; }2991 2992private:2993  struct mips_o32_thread_state_t {2994    uint32_t __r[32];2995    uint32_t __pc;2996    uint32_t __hi;2997    uint32_t __lo;2998  };2999 3000  mips_o32_thread_state_t _registers;3001#ifdef __mips_hard_float3002  /// O32 with 32-bit floating point registers only uses half of this3003  /// space.  However, using the same layout for 32-bit vs 64-bit3004  /// floating point registers results in a single context size for3005  /// O32 with hard float.3006  uint32_t _padding;3007  double _floats[32];3008#endif3009};3010 3011inline Registers_mips_o32::Registers_mips_o32(const void *registers) {3012  static_assert((check_fit<Registers_mips_o32, unw_context_t>::does_fit),3013                "mips_o32 registers do not fit into unw_context_t");3014  memcpy(&_registers, static_cast<const uint8_t *>(registers),3015         sizeof(_registers));3016}3017 3018inline Registers_mips_o32::Registers_mips_o32() {3019  memset(&_registers, 0, sizeof(_registers));3020}3021 3022inline bool Registers_mips_o32::validRegister(int regNum) const {3023  if (regNum == UNW_REG_IP)3024    return true;3025  if (regNum == UNW_REG_SP)3026    return true;3027  if (regNum < 0)3028    return false;3029  if (regNum <= UNW_MIPS_R31)3030    return true;3031#if __mips_isa_rev < 63032  if (regNum == UNW_MIPS_HI)3033    return true;3034  if (regNum == UNW_MIPS_LO)3035    return true;3036#endif3037#if defined(__mips_hard_float) && __mips_fpr == 323038  if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)3039    return true;3040#endif3041  // FIXME: DSP accumulator registers, MSA registers3042  return false;3043}3044 3045inline uint32_t Registers_mips_o32::getRegister(int regNum) const {3046  if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)3047    return _registers.__r[regNum - UNW_MIPS_R0];3048#if defined(__mips_hard_float) && __mips_fpr == 323049  if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {3050    uint32_t *p;3051 3052    if (regNum % 2 == 0)3053      p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];3054    else3055      p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;3056    return *p;3057  }3058#endif3059 3060  switch (regNum) {3061  case UNW_REG_IP:3062    return _registers.__pc;3063  case UNW_REG_SP:3064    return _registers.__r[29];3065#if __mips_isa_rev < 63066  case UNW_MIPS_HI:3067    return _registers.__hi;3068  case UNW_MIPS_LO:3069    return _registers.__lo;3070#endif3071  }3072  _LIBUNWIND_ABORT("unsupported mips_o32 register");3073}3074 3075inline void Registers_mips_o32::setRegister(int regNum, uint32_t value) {3076  if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {3077    _registers.__r[regNum - UNW_MIPS_R0] = value;3078    return;3079  }3080#if defined(__mips_hard_float) && __mips_fpr == 323081  if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {3082    uint32_t *p;3083 3084    if (regNum % 2 == 0)3085      p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];3086    else3087      p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;3088    *p = value;3089    return;3090  }3091#endif3092 3093  switch (regNum) {3094  case UNW_REG_IP:3095    _registers.__pc = value;3096    return;3097  case UNW_REG_SP:3098    _registers.__r[29] = value;3099    return;3100#if __mips_isa_rev < 63101  case UNW_MIPS_HI:3102    _registers.__hi = value;3103    return;3104  case UNW_MIPS_LO:3105    _registers.__lo = value;3106#endif3107    return;3108  }3109  _LIBUNWIND_ABORT("unsupported mips_o32 register");3110}3111 3112inline bool Registers_mips_o32::validFloatRegister(int regNum) const {3113#if defined(__mips_hard_float) && __mips_fpr == 643114  if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)3115    return true;3116#else3117  (void)regNum;3118#endif3119  return false;3120}3121 3122inline double Registers_mips_o32::getFloatRegister(int regNum) const {3123#if defined(__mips_hard_float) && __mips_fpr == 643124  assert(validFloatRegister(regNum));3125  return _floats[regNum - UNW_MIPS_F0];3126#else3127  (void)regNum;3128  _LIBUNWIND_ABORT("mips_o32 float support not implemented");3129#endif3130}3131 3132inline void Registers_mips_o32::setFloatRegister(int regNum,3133                                                 double value) {3134#if defined(__mips_hard_float) && __mips_fpr == 643135  assert(validFloatRegister(regNum));3136  _floats[regNum - UNW_MIPS_F0] = value;3137#else3138  (void)regNum;3139  (void)value;3140  _LIBUNWIND_ABORT("mips_o32 float support not implemented");3141#endif3142}3143 3144inline bool Registers_mips_o32::validVectorRegister(int /* regNum */) const {3145  return false;3146}3147 3148inline v128 Registers_mips_o32::getVectorRegister(int /* regNum */) const {3149  _LIBUNWIND_ABORT("mips_o32 vector support not implemented");3150}3151 3152inline void Registers_mips_o32::setVectorRegister(int /* regNum */, v128 /* value */) {3153  _LIBUNWIND_ABORT("mips_o32 vector support not implemented");3154}3155 3156inline const char *Registers_mips_o32::getRegisterName(int regNum) {3157  switch (regNum) {3158  case UNW_MIPS_R0:3159    return "$0";3160  case UNW_MIPS_R1:3161    return "$1";3162  case UNW_MIPS_R2:3163    return "$2";3164  case UNW_MIPS_R3:3165    return "$3";3166  case UNW_MIPS_R4:3167    return "$4";3168  case UNW_MIPS_R5:3169    return "$5";3170  case UNW_MIPS_R6:3171    return "$6";3172  case UNW_MIPS_R7:3173    return "$7";3174  case UNW_MIPS_R8:3175    return "$8";3176  case UNW_MIPS_R9:3177    return "$9";3178  case UNW_MIPS_R10:3179    return "$10";3180  case UNW_MIPS_R11:3181    return "$11";3182  case UNW_MIPS_R12:3183    return "$12";3184  case UNW_MIPS_R13:3185    return "$13";3186  case UNW_MIPS_R14:3187    return "$14";3188  case UNW_MIPS_R15:3189    return "$15";3190  case UNW_MIPS_R16:3191    return "$16";3192  case UNW_MIPS_R17:3193    return "$17";3194  case UNW_MIPS_R18:3195    return "$18";3196  case UNW_MIPS_R19:3197    return "$19";3198  case UNW_MIPS_R20:3199    return "$20";3200  case UNW_MIPS_R21:3201    return "$21";3202  case UNW_MIPS_R22:3203    return "$22";3204  case UNW_MIPS_R23:3205    return "$23";3206  case UNW_MIPS_R24:3207    return "$24";3208  case UNW_MIPS_R25:3209    return "$25";3210  case UNW_MIPS_R26:3211    return "$26";3212  case UNW_MIPS_R27:3213    return "$27";3214  case UNW_MIPS_R28:3215    return "$28";3216  case UNW_MIPS_R29:3217    return "$29";3218  case UNW_MIPS_R30:3219    return "$30";3220  case UNW_MIPS_R31:3221    return "$31";3222  case UNW_MIPS_F0:3223    return "$f0";3224  case UNW_MIPS_F1:3225    return "$f1";3226  case UNW_MIPS_F2:3227    return "$f2";3228  case UNW_MIPS_F3:3229    return "$f3";3230  case UNW_MIPS_F4:3231    return "$f4";3232  case UNW_MIPS_F5:3233    return "$f5";3234  case UNW_MIPS_F6:3235    return "$f6";3236  case UNW_MIPS_F7:3237    return "$f7";3238  case UNW_MIPS_F8:3239    return "$f8";3240  case UNW_MIPS_F9:3241    return "$f9";3242  case UNW_MIPS_F10:3243    return "$f10";3244  case UNW_MIPS_F11:3245    return "$f11";3246  case UNW_MIPS_F12:3247    return "$f12";3248  case UNW_MIPS_F13:3249    return "$f13";3250  case UNW_MIPS_F14:3251    return "$f14";3252  case UNW_MIPS_F15:3253    return "$f15";3254  case UNW_MIPS_F16:3255    return "$f16";3256  case UNW_MIPS_F17:3257    return "$f17";3258  case UNW_MIPS_F18:3259    return "$f18";3260  case UNW_MIPS_F19:3261    return "$f19";3262  case UNW_MIPS_F20:3263    return "$f20";3264  case UNW_MIPS_F21:3265    return "$f21";3266  case UNW_MIPS_F22:3267    return "$f22";3268  case UNW_MIPS_F23:3269    return "$f23";3270  case UNW_MIPS_F24:3271    return "$f24";3272  case UNW_MIPS_F25:3273    return "$f25";3274  case UNW_MIPS_F26:3275    return "$f26";3276  case UNW_MIPS_F27:3277    return "$f27";3278  case UNW_MIPS_F28:3279    return "$f28";3280  case UNW_MIPS_F29:3281    return "$f29";3282  case UNW_MIPS_F30:3283    return "$f30";3284  case UNW_MIPS_F31:3285    return "$f31";3286#if __mips_isa_rev < 63287  case UNW_MIPS_HI:3288    return "$hi";3289  case UNW_MIPS_LO:3290    return "$lo";3291#endif3292  default:3293    return "unknown register";3294  }3295}3296#endif // _LIBUNWIND_TARGET_MIPS_O323297 3298#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI)3299/// Registers_mips_newabi holds the register state of a thread in a3300/// MIPS process using NEWABI (the N32 or N64 ABIs).3301class _LIBUNWIND_HIDDEN Registers_mips_newabi {3302public:3303  Registers_mips_newabi();3304  Registers_mips_newabi(const void *registers);3305 3306  typedef uint64_t reg_t;3307  typedef uint64_t link_reg_t;3308 3309  bool        validRegister(int num) const;3310  uint64_t    getRegister(int num) const;3311  void        setRegister(int num, uint64_t value);3312  bool        validFloatRegister(int num) const;3313  double      getFloatRegister(int num) const;3314  void        setFloatRegister(int num, double value);3315  bool        validVectorRegister(int num) const;3316  v128        getVectorRegister(int num) const;3317  void        setVectorRegister(int num, v128 value);3318  static const char *getRegisterName(int num);3319  void        jumpto();3320  static constexpr int lastDwarfRegNum() {3321    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS;3322  }3323  static int  getArch() { return REGISTERS_MIPS_NEWABI; }3324 3325  uint64_t  getSP() const         { return _registers.__r[29]; }3326  void      setSP(uint64_t value) { _registers.__r[29] = value; }3327  uint64_t  getIP() const         { return _registers.__pc; }3328  void      setIP(uint64_t value) { _registers.__pc = value; }3329 3330private:3331  struct mips_newabi_thread_state_t {3332    uint64_t __r[32];3333    uint64_t __pc;3334    uint64_t __hi;3335    uint64_t __lo;3336  };3337 3338  mips_newabi_thread_state_t _registers;3339#ifdef __mips_hard_float3340  double _floats[32];3341#endif3342};3343 3344inline Registers_mips_newabi::Registers_mips_newabi(const void *registers) {3345  static_assert((check_fit<Registers_mips_newabi, unw_context_t>::does_fit),3346                "mips_newabi registers do not fit into unw_context_t");3347  memcpy(&_registers, static_cast<const uint8_t *>(registers),3348         sizeof(_registers));3349}3350 3351inline Registers_mips_newabi::Registers_mips_newabi() {3352  memset(&_registers, 0, sizeof(_registers));3353}3354 3355inline bool Registers_mips_newabi::validRegister(int regNum) const {3356  if (regNum == UNW_REG_IP)3357    return true;3358  if (regNum == UNW_REG_SP)3359    return true;3360  if (regNum < 0)3361    return false;3362  if (regNum <= UNW_MIPS_R31)3363    return true;3364#if __mips_isa_rev < 63365  if (regNum == UNW_MIPS_HI)3366    return true;3367  if (regNum == UNW_MIPS_LO)3368    return true;3369#endif3370  // FIXME: Hard float, DSP accumulator registers, MSA registers3371  return false;3372}3373 3374inline uint64_t Registers_mips_newabi::getRegister(int regNum) const {3375  if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)3376    return _registers.__r[regNum - UNW_MIPS_R0];3377 3378  switch (regNum) {3379  case UNW_REG_IP:3380    return _registers.__pc;3381  case UNW_REG_SP:3382    return _registers.__r[29];3383#if __mips_isa_rev < 63384  case UNW_MIPS_HI:3385    return _registers.__hi;3386  case UNW_MIPS_LO:3387    return _registers.__lo;3388#endif3389  }3390  _LIBUNWIND_ABORT("unsupported mips_newabi register");3391}3392 3393inline void Registers_mips_newabi::setRegister(int regNum, uint64_t value) {3394  if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {3395    _registers.__r[regNum - UNW_MIPS_R0] = value;3396    return;3397  }3398 3399  switch (regNum) {3400  case UNW_REG_IP:3401    _registers.__pc = value;3402    return;3403  case UNW_REG_SP:3404    _registers.__r[29] = value;3405    return;3406#if __mips_isa_rev < 63407  case UNW_MIPS_HI:3408    _registers.__hi = value;3409    return;3410  case UNW_MIPS_LO:3411    _registers.__lo = value;3412    return;3413#endif3414  }3415  _LIBUNWIND_ABORT("unsupported mips_newabi register");3416}3417 3418inline bool Registers_mips_newabi::validFloatRegister(int regNum) const {3419#ifdef __mips_hard_float3420  if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)3421    return true;3422#else3423  (void)regNum;3424#endif3425  return false;3426}3427 3428inline double Registers_mips_newabi::getFloatRegister(int regNum) const {3429#ifdef __mips_hard_float3430  assert(validFloatRegister(regNum));3431  return _floats[regNum - UNW_MIPS_F0];3432#else3433  (void)regNum;3434  _LIBUNWIND_ABORT("mips_newabi float support not implemented");3435#endif3436}3437 3438inline void Registers_mips_newabi::setFloatRegister(int regNum,3439                                                    double value) {3440#ifdef __mips_hard_float3441  assert(validFloatRegister(regNum));3442  _floats[regNum - UNW_MIPS_F0] = value;3443#else3444  (void)regNum;3445  (void)value;3446  _LIBUNWIND_ABORT("mips_newabi float support not implemented");3447#endif3448}3449 3450inline bool Registers_mips_newabi::validVectorRegister(int /* regNum */) const {3451  return false;3452}3453 3454inline v128 Registers_mips_newabi::getVectorRegister(int /* regNum */) const {3455  _LIBUNWIND_ABORT("mips_newabi vector support not implemented");3456}3457 3458inline void Registers_mips_newabi::setVectorRegister(int /* regNum */, v128 /* value */) {3459  _LIBUNWIND_ABORT("mips_newabi vector support not implemented");3460}3461 3462inline const char *Registers_mips_newabi::getRegisterName(int regNum) {3463  switch (regNum) {3464  case UNW_MIPS_R0:3465    return "$0";3466  case UNW_MIPS_R1:3467    return "$1";3468  case UNW_MIPS_R2:3469    return "$2";3470  case UNW_MIPS_R3:3471    return "$3";3472  case UNW_MIPS_R4:3473    return "$4";3474  case UNW_MIPS_R5:3475    return "$5";3476  case UNW_MIPS_R6:3477    return "$6";3478  case UNW_MIPS_R7:3479    return "$7";3480  case UNW_MIPS_R8:3481    return "$8";3482  case UNW_MIPS_R9:3483    return "$9";3484  case UNW_MIPS_R10:3485    return "$10";3486  case UNW_MIPS_R11:3487    return "$11";3488  case UNW_MIPS_R12:3489    return "$12";3490  case UNW_MIPS_R13:3491    return "$13";3492  case UNW_MIPS_R14:3493    return "$14";3494  case UNW_MIPS_R15:3495    return "$15";3496  case UNW_MIPS_R16:3497    return "$16";3498  case UNW_MIPS_R17:3499    return "$17";3500  case UNW_MIPS_R18:3501    return "$18";3502  case UNW_MIPS_R19:3503    return "$19";3504  case UNW_MIPS_R20:3505    return "$20";3506  case UNW_MIPS_R21:3507    return "$21";3508  case UNW_MIPS_R22:3509    return "$22";3510  case UNW_MIPS_R23:3511    return "$23";3512  case UNW_MIPS_R24:3513    return "$24";3514  case UNW_MIPS_R25:3515    return "$25";3516  case UNW_MIPS_R26:3517    return "$26";3518  case UNW_MIPS_R27:3519    return "$27";3520  case UNW_MIPS_R28:3521    return "$28";3522  case UNW_MIPS_R29:3523    return "$29";3524  case UNW_MIPS_R30:3525    return "$30";3526  case UNW_MIPS_R31:3527    return "$31";3528  case UNW_MIPS_F0:3529    return "$f0";3530  case UNW_MIPS_F1:3531    return "$f1";3532  case UNW_MIPS_F2:3533    return "$f2";3534  case UNW_MIPS_F3:3535    return "$f3";3536  case UNW_MIPS_F4:3537    return "$f4";3538  case UNW_MIPS_F5:3539    return "$f5";3540  case UNW_MIPS_F6:3541    return "$f6";3542  case UNW_MIPS_F7:3543    return "$f7";3544  case UNW_MIPS_F8:3545    return "$f8";3546  case UNW_MIPS_F9:3547    return "$f9";3548  case UNW_MIPS_F10:3549    return "$f10";3550  case UNW_MIPS_F11:3551    return "$f11";3552  case UNW_MIPS_F12:3553    return "$f12";3554  case UNW_MIPS_F13:3555    return "$f13";3556  case UNW_MIPS_F14:3557    return "$f14";3558  case UNW_MIPS_F15:3559    return "$f15";3560  case UNW_MIPS_F16:3561    return "$f16";3562  case UNW_MIPS_F17:3563    return "$f17";3564  case UNW_MIPS_F18:3565    return "$f18";3566  case UNW_MIPS_F19:3567    return "$f19";3568  case UNW_MIPS_F20:3569    return "$f20";3570  case UNW_MIPS_F21:3571    return "$f21";3572  case UNW_MIPS_F22:3573    return "$f22";3574  case UNW_MIPS_F23:3575    return "$f23";3576  case UNW_MIPS_F24:3577    return "$f24";3578  case UNW_MIPS_F25:3579    return "$f25";3580  case UNW_MIPS_F26:3581    return "$f26";3582  case UNW_MIPS_F27:3583    return "$f27";3584  case UNW_MIPS_F28:3585    return "$f28";3586  case UNW_MIPS_F29:3587    return "$f29";3588  case UNW_MIPS_F30:3589    return "$f30";3590  case UNW_MIPS_F31:3591    return "$f31";3592#if __mips_isa_rev < 63593  case UNW_MIPS_HI:3594    return "$hi";3595  case UNW_MIPS_LO:3596    return "$lo";3597#endif3598  default:3599    return "unknown register";3600  }3601}3602#endif // _LIBUNWIND_TARGET_MIPS_NEWABI3603 3604#if defined(_LIBUNWIND_TARGET_SPARC)3605/// Registers_sparc holds the register state of a thread in a 32-bit Sparc3606/// process.3607class _LIBUNWIND_HIDDEN Registers_sparc {3608public:3609  Registers_sparc();3610  Registers_sparc(const void *registers);3611 3612  typedef uint32_t reg_t;3613  typedef uint32_t link_reg_t;3614 3615  bool        validRegister(int num) const;3616  uint32_t    getRegister(int num) const;3617  void        setRegister(int num, uint32_t value);3618  bool        validFloatRegister(int num) const;3619  double      getFloatRegister(int num) const;3620  void        setFloatRegister(int num, double value);3621  bool        validVectorRegister(int num) const;3622  v128        getVectorRegister(int num) const;3623  void        setVectorRegister(int num, v128 value);3624  static const char *getRegisterName(int num);3625  void        jumpto();3626  static constexpr int lastDwarfRegNum() {3627    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC;3628  }3629  static int  getArch() { return REGISTERS_SPARC; }3630 3631  uint64_t  getSP() const         { return _registers.__regs[UNW_SPARC_O6]; }3632  void      setSP(uint32_t value) { _registers.__regs[UNW_SPARC_O6] = value; }3633  uint64_t  getIP() const         { return _registers.__regs[UNW_SPARC_O7]; }3634  void      setIP(uint32_t value) { _registers.__regs[UNW_SPARC_O7] = value; }3635 3636private:3637  struct sparc_thread_state_t {3638    unsigned int __regs[32];3639  };3640 3641  sparc_thread_state_t _registers;3642};3643 3644inline Registers_sparc::Registers_sparc(const void *registers) {3645  static_assert((check_fit<Registers_sparc, unw_context_t>::does_fit),3646                "sparc registers do not fit into unw_context_t");3647  memcpy(&_registers, static_cast<const uint8_t *>(registers),3648         sizeof(_registers));3649}3650 3651inline Registers_sparc::Registers_sparc() {3652  memset(&_registers, 0, sizeof(_registers));3653}3654 3655inline bool Registers_sparc::validRegister(int regNum) const {3656  if (regNum == UNW_REG_IP)3657    return true;3658  if (regNum == UNW_REG_SP)3659    return true;3660  if (regNum < 0)3661    return false;3662  if (regNum <= UNW_SPARC_I7)3663    return true;3664  return false;3665}3666 3667inline uint32_t Registers_sparc::getRegister(int regNum) const {3668  if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) {3669    return _registers.__regs[regNum];3670  }3671 3672  switch (regNum) {3673  case UNW_REG_IP:3674    return _registers.__regs[UNW_SPARC_O7];3675  case UNW_REG_SP:3676    return _registers.__regs[UNW_SPARC_O6];3677  }3678  _LIBUNWIND_ABORT("unsupported sparc register");3679}3680 3681inline void Registers_sparc::setRegister(int regNum, uint32_t value) {3682  if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) {3683    _registers.__regs[regNum] = value;3684    return;3685  }3686 3687  switch (regNum) {3688  case UNW_REG_IP:3689    _registers.__regs[UNW_SPARC_O7] = value;3690    return;3691  case UNW_REG_SP:3692    _registers.__regs[UNW_SPARC_O6] = value;3693    return;3694  }3695  _LIBUNWIND_ABORT("unsupported sparc register");3696}3697 3698inline bool Registers_sparc::validFloatRegister(int) const { return false; }3699 3700inline double Registers_sparc::getFloatRegister(int) const {3701  _LIBUNWIND_ABORT("no Sparc float registers");3702}3703 3704inline void Registers_sparc::setFloatRegister(int, double) {3705  _LIBUNWIND_ABORT("no Sparc float registers");3706}3707 3708inline bool Registers_sparc::validVectorRegister(int) const { return false; }3709 3710inline v128 Registers_sparc::getVectorRegister(int) const {3711  _LIBUNWIND_ABORT("no Sparc vector registers");3712}3713 3714inline void Registers_sparc::setVectorRegister(int, v128) {3715  _LIBUNWIND_ABORT("no Sparc vector registers");3716}3717 3718inline const char *Registers_sparc::getRegisterName(int regNum) {3719  switch (regNum) {3720  case UNW_REG_IP:3721    return "pc";3722  case UNW_SPARC_G0:3723    return "g0";3724  case UNW_SPARC_G1:3725    return "g1";3726  case UNW_SPARC_G2:3727    return "g2";3728  case UNW_SPARC_G3:3729    return "g3";3730  case UNW_SPARC_G4:3731    return "g4";3732  case UNW_SPARC_G5:3733    return "g5";3734  case UNW_SPARC_G6:3735    return "g6";3736  case UNW_SPARC_G7:3737    return "g7";3738  case UNW_SPARC_O0:3739    return "o0";3740  case UNW_SPARC_O1:3741    return "o1";3742  case UNW_SPARC_O2:3743    return "o2";3744  case UNW_SPARC_O3:3745    return "o3";3746  case UNW_SPARC_O4:3747    return "o4";3748  case UNW_SPARC_O5:3749    return "o5";3750  case UNW_REG_SP:3751  case UNW_SPARC_O6:3752    return "sp";3753  case UNW_SPARC_O7:3754    return "o7";3755  case UNW_SPARC_L0:3756    return "l0";3757  case UNW_SPARC_L1:3758    return "l1";3759  case UNW_SPARC_L2:3760    return "l2";3761  case UNW_SPARC_L3:3762    return "l3";3763  case UNW_SPARC_L4:3764    return "l4";3765  case UNW_SPARC_L5:3766    return "l5";3767  case UNW_SPARC_L6:3768    return "l6";3769  case UNW_SPARC_L7:3770    return "l7";3771  case UNW_SPARC_I0:3772    return "i0";3773  case UNW_SPARC_I1:3774    return "i1";3775  case UNW_SPARC_I2:3776    return "i2";3777  case UNW_SPARC_I3:3778    return "i3";3779  case UNW_SPARC_I4:3780    return "i4";3781  case UNW_SPARC_I5:3782    return "i5";3783  case UNW_SPARC_I6:3784    return "fp";3785  case UNW_SPARC_I7:3786    return "i7";3787  default:3788    return "unknown register";3789  }3790}3791#endif // _LIBUNWIND_TARGET_SPARC3792 3793#if defined(_LIBUNWIND_TARGET_SPARC64)3794/// Registers_sparc64 holds the register state of a thread in a 64-bit3795/// sparc process.3796class _LIBUNWIND_HIDDEN Registers_sparc64 {3797public:3798  Registers_sparc64() = default;3799  Registers_sparc64(const void *registers);3800 3801  typedef uint64_t reg_t;3802  typedef uint64_t link_reg_t;3803 3804  bool validRegister(int num) const;3805  uint64_t getRegister(int num) const;3806  void setRegister(int num, uint64_t value);3807  bool validFloatRegister(int num) const;3808  double getFloatRegister(int num) const;3809  void setFloatRegister(int num, double value);3810  bool validVectorRegister(int num) const;3811  v128 getVectorRegister(int num) const;3812  void setVectorRegister(int num, v128 value);3813  const char *getRegisterName(int num);3814  void jumpto();3815  static constexpr int lastDwarfRegNum() {3816    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC64;3817  }3818  static int getArch() { return REGISTERS_SPARC64; }3819 3820  uint64_t getSP() const { return _registers.__regs[UNW_SPARC_O6] + 2047; }3821  void setSP(uint64_t value) { _registers.__regs[UNW_SPARC_O6] = value - 2047; }3822  uint64_t getIP() const { return _registers.__regs[UNW_SPARC_O7]; }3823  void setIP(uint64_t value) { _registers.__regs[UNW_SPARC_O7] = value; }3824  uint64_t getWCookie() const { return _wcookie; }3825 3826private:3827  struct sparc64_thread_state_t {3828    uint64_t __regs[32];3829  };3830 3831  sparc64_thread_state_t _registers{};3832  uint64_t _wcookie = 0;3833};3834 3835inline Registers_sparc64::Registers_sparc64(const void *registers) {3836  static_assert((check_fit<Registers_sparc64, unw_context_t>::does_fit),3837                "sparc64 registers do not fit into unw_context_t");3838  memcpy(&_registers, registers, sizeof(_registers));3839  memcpy(&_wcookie,3840         static_cast<const uint8_t *>(registers) + sizeof(_registers),3841         sizeof(_wcookie));3842}3843 3844inline bool Registers_sparc64::validRegister(int regNum) const {3845  if (regNum == UNW_REG_IP)3846    return true;3847  if (regNum == UNW_REG_SP)3848    return true;3849  if (regNum < 0)3850    return false;3851  if (regNum <= UNW_SPARC_I7)3852    return true;3853  return false;3854}3855 3856inline uint64_t Registers_sparc64::getRegister(int regNum) const {3857  if (regNum >= UNW_SPARC_G0 && regNum <= UNW_SPARC_I7)3858    return _registers.__regs[regNum];3859 3860  switch (regNum) {3861  case UNW_REG_IP:3862    return _registers.__regs[UNW_SPARC_O7];3863  case UNW_REG_SP:3864    return _registers.__regs[UNW_SPARC_O6] + 2047;3865  }3866  _LIBUNWIND_ABORT("unsupported sparc64 register");3867}3868 3869inline void Registers_sparc64::setRegister(int regNum, uint64_t value) {3870  if (regNum >= UNW_SPARC_G0 && regNum <= UNW_SPARC_I7) {3871    _registers.__regs[regNum] = value;3872    return;3873  }3874 3875  switch (regNum) {3876  case UNW_REG_IP:3877    _registers.__regs[UNW_SPARC_O7] = value;3878    return;3879  case UNW_REG_SP:3880    _registers.__regs[UNW_SPARC_O6] = value - 2047;3881    return;3882  }3883  _LIBUNWIND_ABORT("unsupported sparc64 register");3884}3885 3886inline bool Registers_sparc64::validFloatRegister(int) const { return false; }3887 3888inline double Registers_sparc64::getFloatRegister(int) const {3889  _LIBUNWIND_ABORT("no sparc64 float registers");3890}3891 3892inline void Registers_sparc64::setFloatRegister(int, double) {3893  _LIBUNWIND_ABORT("no sparc64 float registers");3894}3895 3896inline bool Registers_sparc64::validVectorRegister(int) const { return false; }3897 3898inline v128 Registers_sparc64::getVectorRegister(int) const {3899  _LIBUNWIND_ABORT("no sparc64 vector registers");3900}3901 3902inline void Registers_sparc64::setVectorRegister(int, v128) {3903  _LIBUNWIND_ABORT("no sparc64 vector registers");3904}3905 3906inline const char *Registers_sparc64::getRegisterName(int regNum) {3907  switch (regNum) {3908  case UNW_REG_IP:3909    return "pc";3910  case UNW_SPARC_G0:3911    return "g0";3912  case UNW_SPARC_G1:3913    return "g1";3914  case UNW_SPARC_G2:3915    return "g2";3916  case UNW_SPARC_G3:3917    return "g3";3918  case UNW_SPARC_G4:3919    return "g4";3920  case UNW_SPARC_G5:3921    return "g5";3922  case UNW_SPARC_G6:3923    return "g6";3924  case UNW_SPARC_G7:3925    return "g7";3926  case UNW_SPARC_O0:3927    return "o0";3928  case UNW_SPARC_O1:3929    return "o1";3930  case UNW_SPARC_O2:3931    return "o2";3932  case UNW_SPARC_O3:3933    return "o3";3934  case UNW_SPARC_O4:3935    return "o4";3936  case UNW_SPARC_O5:3937    return "o5";3938  case UNW_REG_SP:3939  case UNW_SPARC_O6:3940    return "o6";3941  case UNW_SPARC_O7:3942    return "o7";3943  case UNW_SPARC_L0:3944    return "l0";3945  case UNW_SPARC_L1:3946    return "l1";3947  case UNW_SPARC_L2:3948    return "l2";3949  case UNW_SPARC_L3:3950    return "l3";3951  case UNW_SPARC_L4:3952    return "l4";3953  case UNW_SPARC_L5:3954    return "l5";3955  case UNW_SPARC_L6:3956    return "l6";3957  case UNW_SPARC_L7:3958    return "l7";3959  case UNW_SPARC_I0:3960    return "i0";3961  case UNW_SPARC_I1:3962    return "i1";3963  case UNW_SPARC_I2:3964    return "i2";3965  case UNW_SPARC_I3:3966    return "i3";3967  case UNW_SPARC_I4:3968    return "i4";3969  case UNW_SPARC_I5:3970    return "i5";3971  case UNW_SPARC_I6:3972    return "i6";3973  case UNW_SPARC_I7:3974    return "i7";3975  default:3976    return "unknown register";3977  }3978}3979#endif // _LIBUNWIND_TARGET_SPARC643980 3981#if defined(_LIBUNWIND_TARGET_HEXAGON)3982/// Registers_hexagon holds the register state of a thread in a Hexagon QDSP63983/// process.3984class _LIBUNWIND_HIDDEN Registers_hexagon {3985public:3986  Registers_hexagon();3987  Registers_hexagon(const void *registers);3988 3989  typedef uint32_t reg_t;3990  typedef uint32_t link_reg_t;3991 3992  bool        validRegister(int num) const;3993  uint32_t    getRegister(int num) const;3994  void        setRegister(int num, uint32_t value);3995  bool        validFloatRegister(int num) const;3996  double      getFloatRegister(int num) const;3997  void        setFloatRegister(int num, double value);3998  bool        validVectorRegister(int num) const;3999  v128        getVectorRegister(int num) const;4000  void        setVectorRegister(int num, v128 value);4001  const char *getRegisterName(int num);4002  void        jumpto();4003  static constexpr int lastDwarfRegNum() {4004    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON;4005  }4006  static int  getArch() { return REGISTERS_HEXAGON; }4007 4008  uint32_t  getSP() const         { return _registers.__r[UNW_HEXAGON_R29]; }4009  void      setSP(uint32_t value) { _registers.__r[UNW_HEXAGON_R29] = value; }4010  uint32_t  getIP() const         { return _registers.__r[UNW_HEXAGON_PC]; }4011  void      setIP(uint32_t value) { _registers.__r[UNW_HEXAGON_PC] = value; }4012 4013private:4014  struct hexagon_thread_state_t {4015    unsigned int __r[35];4016  };4017 4018  hexagon_thread_state_t _registers;4019};4020 4021inline Registers_hexagon::Registers_hexagon(const void *registers) {4022  static_assert((check_fit<Registers_hexagon, unw_context_t>::does_fit),4023                "hexagon registers do not fit into unw_context_t");4024  memcpy(&_registers, static_cast<const uint8_t *>(registers),4025         sizeof(_registers));4026}4027 4028inline Registers_hexagon::Registers_hexagon() {4029  memset(&_registers, 0, sizeof(_registers));4030}4031 4032inline bool Registers_hexagon::validRegister(int regNum) const {4033  if (regNum <= UNW_HEXAGON_R31)4034    return true;4035  return false;4036}4037 4038inline uint32_t Registers_hexagon::getRegister(int regNum) const {4039  if (regNum >= UNW_HEXAGON_R0 && regNum <= UNW_HEXAGON_R31)4040    return _registers.__r[regNum - UNW_HEXAGON_R0];4041 4042  switch (regNum) {4043  case UNW_REG_IP:4044    return _registers.__r[UNW_HEXAGON_PC];4045  case UNW_REG_SP:4046    return _registers.__r[UNW_HEXAGON_R29];4047  }4048  _LIBUNWIND_ABORT("unsupported hexagon register");4049}4050 4051inline void Registers_hexagon::setRegister(int regNum, uint32_t value) {4052  if (regNum >= UNW_HEXAGON_R0 && regNum <= UNW_HEXAGON_R31) {4053    _registers.__r[regNum - UNW_HEXAGON_R0] = value;4054    return;4055  }4056 4057  switch (regNum) {4058  case UNW_REG_IP:4059    _registers.__r[UNW_HEXAGON_PC] = value;4060    return;4061  case UNW_REG_SP:4062    _registers.__r[UNW_HEXAGON_R29] = value;4063    return;4064  }4065  _LIBUNWIND_ABORT("unsupported hexagon register");4066}4067 4068inline bool Registers_hexagon::validFloatRegister(int /* regNum */) const {4069  return false;4070}4071 4072inline double Registers_hexagon::getFloatRegister(int /* regNum */) const {4073  _LIBUNWIND_ABORT("hexagon float support not implemented");4074}4075 4076inline void Registers_hexagon::setFloatRegister(int /* regNum */,4077                                             double /* value */) {4078  _LIBUNWIND_ABORT("hexagon float support not implemented");4079}4080 4081inline bool Registers_hexagon::validVectorRegister(int /* regNum */) const {4082  return false;4083}4084 4085inline v128 Registers_hexagon::getVectorRegister(int /* regNum */) const {4086  _LIBUNWIND_ABORT("hexagon vector support not implemented");4087}4088 4089inline void Registers_hexagon::setVectorRegister(int /* regNum */, v128 /* value */) {4090  _LIBUNWIND_ABORT("hexagon vector support not implemented");4091}4092 4093inline const char *Registers_hexagon::getRegisterName(int regNum) {4094  switch (regNum) {4095  case UNW_HEXAGON_R0:4096    return "r0";4097  case UNW_HEXAGON_R1:4098    return "r1";4099  case UNW_HEXAGON_R2:4100    return "r2";4101  case UNW_HEXAGON_R3:4102    return "r3";4103  case UNW_HEXAGON_R4:4104    return "r4";4105  case UNW_HEXAGON_R5:4106    return "r5";4107  case UNW_HEXAGON_R6:4108    return "r6";4109  case UNW_HEXAGON_R7:4110    return "r7";4111  case UNW_HEXAGON_R8:4112    return "r8";4113  case UNW_HEXAGON_R9:4114    return "r9";4115  case UNW_HEXAGON_R10:4116    return "r10";4117  case UNW_HEXAGON_R11:4118    return "r11";4119  case UNW_HEXAGON_R12:4120    return "r12";4121  case UNW_HEXAGON_R13:4122    return "r13";4123  case UNW_HEXAGON_R14:4124    return "r14";4125  case UNW_HEXAGON_R15:4126    return "r15";4127  case UNW_HEXAGON_R16:4128    return "r16";4129  case UNW_HEXAGON_R17:4130    return "r17";4131  case UNW_HEXAGON_R18:4132    return "r18";4133  case UNW_HEXAGON_R19:4134    return "r19";4135  case UNW_HEXAGON_R20:4136    return "r20";4137  case UNW_HEXAGON_R21:4138    return "r21";4139  case UNW_HEXAGON_R22:4140    return "r22";4141  case UNW_HEXAGON_R23:4142    return "r23";4143  case UNW_HEXAGON_R24:4144    return "r24";4145  case UNW_HEXAGON_R25:4146    return "r25";4147  case UNW_HEXAGON_R26:4148    return "r26";4149  case UNW_HEXAGON_R27:4150    return "r27";4151  case UNW_HEXAGON_R28:4152    return "r28";4153  case UNW_HEXAGON_R29:4154    return "r29";4155  case UNW_HEXAGON_R30:4156    return "r30";4157  case UNW_HEXAGON_R31:4158    return "r31";4159  default:4160    return "unknown register";4161  }4162 4163}4164#endif // _LIBUNWIND_TARGET_HEXAGON4165 4166 4167#if defined(_LIBUNWIND_TARGET_RISCV)4168/// Registers_riscv holds the register state of a thread in a RISC-V4169/// process.4170 4171// This check makes it safe when LIBUNWIND_ENABLE_CROSS_UNWINDING enabled.4172# ifdef __riscv4173#  if __riscv_xlen == 324174typedef uint32_t reg_t;4175#  elif __riscv_xlen == 644176typedef uint64_t reg_t;4177#  else4178#   error "Unsupported __riscv_xlen"4179#  endif4180 4181#  if defined(__riscv_flen)4182#   if __riscv_flen == 644183typedef double fp_t;4184#   elif __riscv_flen == 324185typedef float fp_t;4186#   else4187#    error "Unsupported __riscv_flen"4188#   endif4189#  else4190// This is just for suppressing undeclared error of fp_t.4191typedef double fp_t;4192#  endif4193# else4194// Use Max possible width when cross unwinding4195typedef uint64_t reg_t;4196typedef double fp_t;4197# define __riscv_xlen 644198# define __riscv_flen 644199#endif4200 4201/// Registers_riscv holds the register state of a thread.4202class _LIBUNWIND_HIDDEN Registers_riscv {4203public:4204  Registers_riscv();4205  Registers_riscv(const void *registers);4206 4207  typedef ::libunwind::reg_t reg_t;4208  typedef ::libunwind::reg_t link_reg_t;4209 4210  bool        validRegister(int num) const;4211  reg_t       getRegister(int num) const;4212  void        setRegister(int num, reg_t value);4213  bool        validFloatRegister(int num) const;4214  fp_t        getFloatRegister(int num) const;4215  void        setFloatRegister(int num, fp_t value);4216  bool        validVectorRegister(int num) const;4217  v128        getVectorRegister(int num) const;4218  void        setVectorRegister(int num, v128 value);4219  static const char *getRegisterName(int num);4220  void        jumpto();4221  static constexpr int lastDwarfRegNum() {4222    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV;4223  }4224  static int  getArch() { return REGISTERS_RISCV; }4225 4226  reg_t       getSP() const { return _registers[2]; }4227  void        setSP(reg_t value) { _registers[2] = value; }4228  reg_t       getIP() const { return _registers[0]; }4229  void        setIP(reg_t value) { _registers[0] = value; }4230 4231private:4232  // _registers[0] holds the pc4233  reg_t _registers[32];4234# if defined(__riscv_flen)4235  fp_t _floats[32];4236# endif4237};4238 4239inline Registers_riscv::Registers_riscv(const void *registers) {4240  static_assert((check_fit<Registers_riscv, unw_context_t>::does_fit),4241                "riscv registers do not fit into unw_context_t");4242  memcpy(&_registers, registers, sizeof(_registers));4243# if __riscv_xlen == 324244  static_assert(sizeof(_registers) == 0x80,4245                "expected float registers to be at offset 128");4246# elif __riscv_xlen == 644247  static_assert(sizeof(_registers) == 0x100,4248                "expected float registers to be at offset 256");4249# else4250# error "Unexpected float registers."4251# endif4252 4253# if defined(__riscv_flen)4254  memcpy(_floats,4255         static_cast<const uint8_t *>(registers) + sizeof(_registers),4256         sizeof(_floats));4257# endif4258}4259 4260inline Registers_riscv::Registers_riscv() {4261  memset(&_registers, 0, sizeof(_registers));4262# if defined(__riscv_flen)4263  memset(&_floats, 0, sizeof(_floats));4264# endif4265}4266 4267inline bool Registers_riscv::validRegister(int regNum) const {4268  if (regNum == UNW_REG_IP)4269    return true;4270  if (regNum == UNW_REG_SP)4271    return true;4272  if (regNum < 0)4273    return false;4274  if (regNum == UNW_RISCV_VLENB)4275    return true;4276  if (regNum > UNW_RISCV_F31)4277    return false;4278  return true;4279}4280 4281inline reg_t Registers_riscv::getRegister(int regNum) const {4282  if (regNum == UNW_REG_IP)4283    return _registers[0];4284  if (regNum == UNW_REG_SP)4285    return _registers[2];4286  if (regNum == UNW_RISCV_X0)4287    return 0;4288  if ((regNum > 0) && (regNum < 32))4289    return _registers[regNum];4290  if (regNum == UNW_RISCV_VLENB) {4291    reg_t vlenb;4292    __asm__ volatile("csrr %0, 0xC22" : "=r"(vlenb));4293    return vlenb;4294  }4295  _LIBUNWIND_ABORT("unsupported riscv register");4296}4297 4298inline void Registers_riscv::setRegister(int regNum, reg_t value) {4299  if (regNum == UNW_REG_IP)4300    _registers[0] = value;4301  else if (regNum == UNW_REG_SP)4302    _registers[2] = value;4303  else if (regNum == UNW_RISCV_X0)4304    /* x0 is hardwired to zero */4305    return;4306  else if ((regNum > 0) && (regNum < 32))4307    _registers[regNum] = value;4308  else4309    _LIBUNWIND_ABORT("unsupported riscv register");4310}4311 4312inline const char *Registers_riscv::getRegisterName(int regNum) {4313  switch (regNum) {4314  case UNW_REG_IP:4315    return "pc";4316  case UNW_REG_SP:4317    return "sp";4318  case UNW_RISCV_X0:4319    return "zero";4320  case UNW_RISCV_X1:4321    return "ra";4322  case UNW_RISCV_X2:4323    return "sp";4324  case UNW_RISCV_X3:4325    return "gp";4326  case UNW_RISCV_X4:4327    return "tp";4328  case UNW_RISCV_X5:4329    return "t0";4330  case UNW_RISCV_X6:4331    return "t1";4332  case UNW_RISCV_X7:4333    return "t2";4334  case UNW_RISCV_X8:4335    return "s0";4336  case UNW_RISCV_X9:4337    return "s1";4338  case UNW_RISCV_X10:4339    return "a0";4340  case UNW_RISCV_X11:4341    return "a1";4342  case UNW_RISCV_X12:4343    return "a2";4344  case UNW_RISCV_X13:4345    return "a3";4346  case UNW_RISCV_X14:4347    return "a4";4348  case UNW_RISCV_X15:4349    return "a5";4350  case UNW_RISCV_X16:4351    return "a6";4352  case UNW_RISCV_X17:4353    return "a7";4354  case UNW_RISCV_X18:4355    return "s2";4356  case UNW_RISCV_X19:4357    return "s3";4358  case UNW_RISCV_X20:4359    return "s4";4360  case UNW_RISCV_X21:4361    return "s5";4362  case UNW_RISCV_X22:4363    return "s6";4364  case UNW_RISCV_X23:4365    return "s7";4366  case UNW_RISCV_X24:4367    return "s8";4368  case UNW_RISCV_X25:4369    return "s9";4370  case UNW_RISCV_X26:4371    return "s10";4372  case UNW_RISCV_X27:4373    return "s11";4374  case UNW_RISCV_X28:4375    return "t3";4376  case UNW_RISCV_X29:4377    return "t4";4378  case UNW_RISCV_X30:4379    return "t5";4380  case UNW_RISCV_X31:4381    return "t6";4382  case UNW_RISCV_F0:4383    return "ft0";4384  case UNW_RISCV_F1:4385    return "ft1";4386  case UNW_RISCV_F2:4387    return "ft2";4388  case UNW_RISCV_F3:4389    return "ft3";4390  case UNW_RISCV_F4:4391    return "ft4";4392  case UNW_RISCV_F5:4393    return "ft5";4394  case UNW_RISCV_F6:4395    return "ft6";4396  case UNW_RISCV_F7:4397    return "ft7";4398  case UNW_RISCV_F8:4399    return "fs0";4400  case UNW_RISCV_F9:4401    return "fs1";4402  case UNW_RISCV_F10:4403    return "fa0";4404  case UNW_RISCV_F11:4405    return "fa1";4406  case UNW_RISCV_F12:4407    return "fa2";4408  case UNW_RISCV_F13:4409    return "fa3";4410  case UNW_RISCV_F14:4411    return "fa4";4412  case UNW_RISCV_F15:4413    return "fa5";4414  case UNW_RISCV_F16:4415    return "fa6";4416  case UNW_RISCV_F17:4417    return "fa7";4418  case UNW_RISCV_F18:4419    return "fs2";4420  case UNW_RISCV_F19:4421    return "fs3";4422  case UNW_RISCV_F20:4423    return "fs4";4424  case UNW_RISCV_F21:4425    return "fs5";4426  case UNW_RISCV_F22:4427    return "fs6";4428  case UNW_RISCV_F23:4429    return "fs7";4430  case UNW_RISCV_F24:4431    return "fs8";4432  case UNW_RISCV_F25:4433    return "fs9";4434  case UNW_RISCV_F26:4435    return "fs10";4436  case UNW_RISCV_F27:4437    return "fs11";4438  case UNW_RISCV_F28:4439    return "ft8";4440  case UNW_RISCV_F29:4441    return "ft9";4442  case UNW_RISCV_F30:4443    return "ft10";4444  case UNW_RISCV_F31:4445    return "ft11";4446  case UNW_RISCV_VLENB:4447    return "vlenb";4448  default:4449    return "unknown register";4450  }4451}4452 4453inline bool Registers_riscv::validFloatRegister(int regNum) const {4454# if defined(__riscv_flen)4455  if (regNum < UNW_RISCV_F0)4456    return false;4457  if (regNum > UNW_RISCV_F31)4458    return false;4459  return true;4460# else4461  (void)regNum;4462  return false;4463# endif4464}4465 4466inline fp_t Registers_riscv::getFloatRegister(int regNum) const {4467# if defined(__riscv_flen)4468  assert(validFloatRegister(regNum));4469  return _floats[regNum - UNW_RISCV_F0];4470# else4471  (void)regNum;4472  _LIBUNWIND_ABORT("libunwind not built with float support");4473# endif4474}4475 4476inline void Registers_riscv::setFloatRegister(int regNum, fp_t value) {4477# if defined(__riscv_flen)4478  assert(validFloatRegister(regNum));4479  _floats[regNum - UNW_RISCV_F0] = value;4480# else4481  (void)regNum;4482  (void)value;4483  _LIBUNWIND_ABORT("libunwind not built with float support");4484# endif4485}4486 4487inline bool Registers_riscv::validVectorRegister(int) const {4488  return false;4489}4490 4491inline v128 Registers_riscv::getVectorRegister(int) const {4492  _LIBUNWIND_ABORT("no riscv vector register support yet");4493}4494 4495inline void Registers_riscv::setVectorRegister(int, v128) {4496  _LIBUNWIND_ABORT("no riscv vector register support yet");4497}4498#endif // _LIBUNWIND_TARGET_RISCV4499 4500#if defined(_LIBUNWIND_TARGET_VE)4501/// Registers_ve holds the register state of a thread in a VE process.4502class _LIBUNWIND_HIDDEN Registers_ve {4503public:4504  Registers_ve();4505  Registers_ve(const void *registers);4506 4507  typedef uint64_t reg_t;4508  typedef uint64_t link_reg_t;4509 4510  bool        validRegister(int num) const;4511  uint64_t    getRegister(int num) const;4512  void        setRegister(int num, uint64_t value);4513  bool        validFloatRegister(int num) const;4514  double      getFloatRegister(int num) const;4515  void        setFloatRegister(int num, double value);4516  bool        validVectorRegister(int num) const;4517  v128        getVectorRegister(int num) const;4518  void        setVectorRegister(int num, v128 value);4519  static const char *getRegisterName(int num);4520  void        jumpto();4521  static constexpr int lastDwarfRegNum() {4522    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE;4523  }4524  static int  getArch() { return REGISTERS_VE; }4525 4526  uint64_t  getSP() const         { return _registers.__s[11]; }4527  void      setSP(uint64_t value) { _registers.__s[11] = value; }4528  uint64_t  getIP() const         { return _registers.__ic; }4529  void      setIP(uint64_t value) { _registers.__ic = value; }4530 4531private:4532  // FIXME: Need to store not only scalar registers but also vector and vector4533  // mask registers.  VEOS uses mcontext_t defined in ucontext.h.  It takes4534  // 524288 bytes (65536*8 bytes), though.  Currently, we use libunwind for4535  // SjLj exception support only, so Registers_ve is not implemented completely.4536  struct ve_thread_state_t {4537    uint64_t __s[64]; // s0-s644538    uint64_t __ic;    // Instruction counter (IC)4539    uint64_t __vixr;  // Vector Index Register4540    uint64_t __vl;    // Vector Length Register4541  };4542 4543  ve_thread_state_t _registers; // total 67 registers4544 4545  // Currently no vector register is preserved.4546};4547 4548inline Registers_ve::Registers_ve(const void *registers) {4549  static_assert((check_fit<Registers_ve, unw_context_t>::does_fit),4550                "ve registers do not fit into unw_context_t");4551  memcpy(&_registers, static_cast<const uint8_t *>(registers),4552         sizeof(_registers));4553  static_assert(sizeof(_registers) == 536,4554                "expected vector register offset to be 536");4555}4556 4557inline Registers_ve::Registers_ve() {4558  memset(&_registers, 0, sizeof(_registers));4559}4560 4561inline bool Registers_ve::validRegister(int regNum) const {4562  if (regNum >= UNW_VE_S0 && regNum <= UNW_VE_S63)4563    return true;4564 4565  switch (regNum) {4566  case UNW_REG_IP:4567  case UNW_REG_SP:4568  case UNW_VE_VIXR:4569  case UNW_VE_VL:4570    return true;4571  default:4572    return false;4573  }4574}4575 4576inline uint64_t Registers_ve::getRegister(int regNum) const {4577  if (regNum >= UNW_VE_S0 && regNum <= UNW_VE_S63)4578    return _registers.__s[regNum - UNW_VE_S0];4579 4580  switch (regNum) {4581  case UNW_REG_IP:4582    return _registers.__ic;4583  case UNW_REG_SP:4584    return _registers.__s[11];4585  case UNW_VE_VIXR:4586    return _registers.__vixr;4587  case UNW_VE_VL:4588    return _registers.__vl;4589  }4590  _LIBUNWIND_ABORT("unsupported ve register");4591}4592 4593inline void Registers_ve::setRegister(int regNum, uint64_t value) {4594  if (regNum >= UNW_VE_S0 && regNum <= UNW_VE_S63) {4595    _registers.__s[regNum - UNW_VE_S0] = value;4596    return;4597  }4598 4599  switch (regNum) {4600  case UNW_REG_IP:4601    _registers.__ic = value;4602    return;4603  case UNW_REG_SP:4604    _registers.__s[11] = value;4605    return;4606  case UNW_VE_VIXR:4607    _registers.__vixr = value;4608    return;4609  case UNW_VE_VL:4610    _registers.__vl = value;4611    return;4612  }4613  _LIBUNWIND_ABORT("unsupported ve register");4614}4615 4616inline bool Registers_ve::validFloatRegister(int /* regNum */) const {4617  return false;4618}4619 4620inline double Registers_ve::getFloatRegister(int /* regNum */) const {4621  _LIBUNWIND_ABORT("VE doesn't have float registers");4622}4623 4624inline void Registers_ve::setFloatRegister(int /* regNum */,4625                                           double /* value */) {4626  _LIBUNWIND_ABORT("VE doesn't have float registers");4627}4628 4629inline bool Registers_ve::validVectorRegister(int /* regNum */) const {4630  return false;4631}4632 4633inline v128 Registers_ve::getVectorRegister(int /* regNum */) const {4634  _LIBUNWIND_ABORT("VE vector support not implemented");4635}4636 4637inline void Registers_ve::setVectorRegister(int /* regNum */,4638                                            v128 /* value */) {4639  _LIBUNWIND_ABORT("VE vector support not implemented");4640}4641 4642inline const char *Registers_ve::getRegisterName(int regNum) {4643  switch (regNum) {4644  case UNW_REG_IP:4645    return "ip";4646  case UNW_REG_SP:4647    return "sp";4648  case UNW_VE_VIXR:4649    return "vixr";4650  case UNW_VE_VL:4651    return "vl";4652  case UNW_VE_S0:4653    return "s0";4654  case UNW_VE_S1:4655    return "s1";4656  case UNW_VE_S2:4657    return "s2";4658  case UNW_VE_S3:4659    return "s3";4660  case UNW_VE_S4:4661    return "s4";4662  case UNW_VE_S5:4663    return "s5";4664  case UNW_VE_S6:4665    return "s6";4666  case UNW_VE_S7:4667    return "s7";4668  case UNW_VE_S8:4669    return "s8";4670  case UNW_VE_S9:4671    return "s9";4672  case UNW_VE_S10:4673    return "s10";4674  case UNW_VE_S11:4675    return "s11";4676  case UNW_VE_S12:4677    return "s12";4678  case UNW_VE_S13:4679    return "s13";4680  case UNW_VE_S14:4681    return "s14";4682  case UNW_VE_S15:4683    return "s15";4684  case UNW_VE_S16:4685    return "s16";4686  case UNW_VE_S17:4687    return "s17";4688  case UNW_VE_S18:4689    return "s18";4690  case UNW_VE_S19:4691    return "s19";4692  case UNW_VE_S20:4693    return "s20";4694  case UNW_VE_S21:4695    return "s21";4696  case UNW_VE_S22:4697    return "s22";4698  case UNW_VE_S23:4699    return "s23";4700  case UNW_VE_S24:4701    return "s24";4702  case UNW_VE_S25:4703    return "s25";4704  case UNW_VE_S26:4705    return "s26";4706  case UNW_VE_S27:4707    return "s27";4708  case UNW_VE_S28:4709    return "s28";4710  case UNW_VE_S29:4711    return "s29";4712  case UNW_VE_S30:4713    return "s30";4714  case UNW_VE_S31:4715    return "s31";4716  case UNW_VE_S32:4717    return "s32";4718  case UNW_VE_S33:4719    return "s33";4720  case UNW_VE_S34:4721    return "s34";4722  case UNW_VE_S35:4723    return "s35";4724  case UNW_VE_S36:4725    return "s36";4726  case UNW_VE_S37:4727    return "s37";4728  case UNW_VE_S38:4729    return "s38";4730  case UNW_VE_S39:4731    return "s39";4732  case UNW_VE_S40:4733    return "s40";4734  case UNW_VE_S41:4735    return "s41";4736  case UNW_VE_S42:4737    return "s42";4738  case UNW_VE_S43:4739    return "s43";4740  case UNW_VE_S44:4741    return "s44";4742  case UNW_VE_S45:4743    return "s45";4744  case UNW_VE_S46:4745    return "s46";4746  case UNW_VE_S47:4747    return "s47";4748  case UNW_VE_S48:4749    return "s48";4750  case UNW_VE_S49:4751    return "s49";4752  case UNW_VE_S50:4753    return "s50";4754  case UNW_VE_S51:4755    return "s51";4756  case UNW_VE_S52:4757    return "s52";4758  case UNW_VE_S53:4759    return "s53";4760  case UNW_VE_S54:4761    return "s54";4762  case UNW_VE_S55:4763    return "s55";4764  case UNW_VE_S56:4765    return "s56";4766  case UNW_VE_S57:4767    return "s57";4768  case UNW_VE_S58:4769    return "s58";4770  case UNW_VE_S59:4771    return "s59";4772  case UNW_VE_S60:4773    return "s60";4774  case UNW_VE_S61:4775    return "s61";4776  case UNW_VE_S62:4777    return "s62";4778  case UNW_VE_S63:4779    return "s63";4780  case UNW_VE_V0:4781    return "v0";4782  case UNW_VE_V1:4783    return "v1";4784  case UNW_VE_V2:4785    return "v2";4786  case UNW_VE_V3:4787    return "v3";4788  case UNW_VE_V4:4789    return "v4";4790  case UNW_VE_V5:4791    return "v5";4792  case UNW_VE_V6:4793    return "v6";4794  case UNW_VE_V7:4795    return "v7";4796  case UNW_VE_V8:4797    return "v8";4798  case UNW_VE_V9:4799    return "v9";4800  case UNW_VE_V10:4801    return "v10";4802  case UNW_VE_V11:4803    return "v11";4804  case UNW_VE_V12:4805    return "v12";4806  case UNW_VE_V13:4807    return "v13";4808  case UNW_VE_V14:4809    return "v14";4810  case UNW_VE_V15:4811    return "v15";4812  case UNW_VE_V16:4813    return "v16";4814  case UNW_VE_V17:4815    return "v17";4816  case UNW_VE_V18:4817    return "v18";4818  case UNW_VE_V19:4819    return "v19";4820  case UNW_VE_V20:4821    return "v20";4822  case UNW_VE_V21:4823    return "v21";4824  case UNW_VE_V22:4825    return "v22";4826  case UNW_VE_V23:4827    return "v23";4828  case UNW_VE_V24:4829    return "v24";4830  case UNW_VE_V25:4831    return "v25";4832  case UNW_VE_V26:4833    return "v26";4834  case UNW_VE_V27:4835    return "v27";4836  case UNW_VE_V28:4837    return "v28";4838  case UNW_VE_V29:4839    return "v29";4840  case UNW_VE_V30:4841    return "v30";4842  case UNW_VE_V31:4843    return "v31";4844  case UNW_VE_V32:4845    return "v32";4846  case UNW_VE_V33:4847    return "v33";4848  case UNW_VE_V34:4849    return "v34";4850  case UNW_VE_V35:4851    return "v35";4852  case UNW_VE_V36:4853    return "v36";4854  case UNW_VE_V37:4855    return "v37";4856  case UNW_VE_V38:4857    return "v38";4858  case UNW_VE_V39:4859    return "v39";4860  case UNW_VE_V40:4861    return "v40";4862  case UNW_VE_V41:4863    return "v41";4864  case UNW_VE_V42:4865    return "v42";4866  case UNW_VE_V43:4867    return "v43";4868  case UNW_VE_V44:4869    return "v44";4870  case UNW_VE_V45:4871    return "v45";4872  case UNW_VE_V46:4873    return "v46";4874  case UNW_VE_V47:4875    return "v47";4876  case UNW_VE_V48:4877    return "v48";4878  case UNW_VE_V49:4879    return "v49";4880  case UNW_VE_V50:4881    return "v50";4882  case UNW_VE_V51:4883    return "v51";4884  case UNW_VE_V52:4885    return "v52";4886  case UNW_VE_V53:4887    return "v53";4888  case UNW_VE_V54:4889    return "v54";4890  case UNW_VE_V55:4891    return "v55";4892  case UNW_VE_V56:4893    return "v56";4894  case UNW_VE_V57:4895    return "v57";4896  case UNW_VE_V58:4897    return "v58";4898  case UNW_VE_V59:4899    return "v59";4900  case UNW_VE_V60:4901    return "v60";4902  case UNW_VE_V61:4903    return "v61";4904  case UNW_VE_V62:4905    return "v62";4906  case UNW_VE_V63:4907    return "v63";4908  case UNW_VE_VM0:4909    return "vm0";4910  case UNW_VE_VM1:4911    return "vm1";4912  case UNW_VE_VM2:4913    return "vm2";4914  case UNW_VE_VM3:4915    return "vm3";4916  case UNW_VE_VM4:4917    return "vm4";4918  case UNW_VE_VM5:4919    return "vm5";4920  case UNW_VE_VM6:4921    return "vm6";4922  case UNW_VE_VM7:4923    return "vm7";4924  case UNW_VE_VM8:4925    return "vm8";4926  case UNW_VE_VM9:4927    return "vm9";4928  case UNW_VE_VM10:4929    return "vm10";4930  case UNW_VE_VM11:4931    return "vm11";4932  case UNW_VE_VM12:4933    return "vm12";4934  case UNW_VE_VM13:4935    return "vm13";4936  case UNW_VE_VM14:4937    return "vm14";4938  case UNW_VE_VM15:4939    return "vm15";4940  }4941  return "unknown register";4942}4943#endif // _LIBUNWIND_TARGET_VE4944 4945#if defined(_LIBUNWIND_TARGET_S390X)4946/// Registers_s390x holds the register state of a thread in a4947/// 64-bit Linux on IBM zSystems process.4948class _LIBUNWIND_HIDDEN Registers_s390x {4949public:4950  Registers_s390x();4951  Registers_s390x(const void *registers);4952 4953  typedef uint64_t reg_t;4954  typedef uint64_t link_reg_t;4955 4956  bool        validRegister(int num) const;4957  uint64_t    getRegister(int num) const;4958  void        setRegister(int num, uint64_t value);4959  bool        validFloatRegister(int num) const;4960  double      getFloatRegister(int num) const;4961  void        setFloatRegister(int num, double value);4962  bool        validVectorRegister(int num) const;4963  v128        getVectorRegister(int num) const;4964  void        setVectorRegister(int num, v128 value);4965  static const char *getRegisterName(int num);4966  void        jumpto();4967  static constexpr int lastDwarfRegNum() {4968    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_S390X;4969  }4970  static int  getArch() { return REGISTERS_S390X; }4971 4972  uint64_t  getSP() const         { return _registers.__gpr[15]; }4973  void      setSP(uint64_t value) { _registers.__gpr[15] = value; }4974  uint64_t  getIP() const         { return _registers.__pswa; }4975  void      setIP(uint64_t value) { _registers.__pswa = value; }4976 4977private:4978  struct s390x_thread_state_t {4979    uint64_t __pswm;    // Problem Status Word: Mask4980    uint64_t __pswa;    // Problem Status Word: Address (PC)4981    uint64_t __gpr[16]; // General Purpose Registers4982    double __fpr[16];   // Floating-Point Registers4983  };4984 4985  s390x_thread_state_t _registers;4986};4987 4988inline Registers_s390x::Registers_s390x(const void *registers) {4989  static_assert((check_fit<Registers_s390x, unw_context_t>::does_fit),4990                "s390x registers do not fit into unw_context_t");4991  memcpy(&_registers, static_cast<const uint8_t *>(registers),4992         sizeof(_registers));4993}4994 4995inline Registers_s390x::Registers_s390x() {4996  memset(&_registers, 0, sizeof(_registers));4997}4998 4999inline bool Registers_s390x::validRegister(int regNum) const {5000  switch (regNum) {5001  case UNW_S390X_PSWM:5002  case UNW_S390X_PSWA:5003  case UNW_REG_IP:5004  case UNW_REG_SP:5005      return true;5006  }5007 5008  if (regNum >= UNW_S390X_R0 && regNum <= UNW_S390X_R15)5009    return true;5010 5011  return false;5012}5013 5014inline uint64_t Registers_s390x::getRegister(int regNum) const {5015  if (regNum >= UNW_S390X_R0 && regNum <= UNW_S390X_R15)5016    return _registers.__gpr[regNum - UNW_S390X_R0];5017 5018  switch (regNum) {5019  case UNW_S390X_PSWM:5020    return _registers.__pswm;5021  case UNW_S390X_PSWA:5022  case UNW_REG_IP:5023    return _registers.__pswa;5024  case UNW_REG_SP:5025    return _registers.__gpr[15];5026  }5027  _LIBUNWIND_ABORT("unsupported s390x register");5028}5029 5030inline void Registers_s390x::setRegister(int regNum, uint64_t value) {5031  if (regNum >= UNW_S390X_R0 && regNum <= UNW_S390X_R15) {5032    _registers.__gpr[regNum - UNW_S390X_R0] = value;5033    return;5034  }5035 5036  switch (regNum) {5037  case UNW_S390X_PSWM:5038    _registers.__pswm = value;5039    return;5040  case UNW_S390X_PSWA:5041  case UNW_REG_IP:5042    _registers.__pswa = value;5043    return;5044  case UNW_REG_SP:5045    _registers.__gpr[15] = value;5046    return;5047  }5048  _LIBUNWIND_ABORT("unsupported s390x register");5049}5050 5051inline bool Registers_s390x::validFloatRegister(int regNum) const {5052  return regNum >= UNW_S390X_F0 && regNum <= UNW_S390X_F15;5053}5054 5055inline double Registers_s390x::getFloatRegister(int regNum) const {5056  // NOTE: FPR DWARF register numbers are not consecutive.5057  switch (regNum) {5058  case UNW_S390X_F0:5059    return _registers.__fpr[0];5060  case UNW_S390X_F1:5061    return _registers.__fpr[1];5062  case UNW_S390X_F2:5063    return _registers.__fpr[2];5064  case UNW_S390X_F3:5065    return _registers.__fpr[3];5066  case UNW_S390X_F4:5067    return _registers.__fpr[4];5068  case UNW_S390X_F5:5069    return _registers.__fpr[5];5070  case UNW_S390X_F6:5071    return _registers.__fpr[6];5072  case UNW_S390X_F7:5073    return _registers.__fpr[7];5074  case UNW_S390X_F8:5075    return _registers.__fpr[8];5076  case UNW_S390X_F9:5077    return _registers.__fpr[9];5078  case UNW_S390X_F10:5079    return _registers.__fpr[10];5080  case UNW_S390X_F11:5081    return _registers.__fpr[11];5082  case UNW_S390X_F12:5083    return _registers.__fpr[12];5084  case UNW_S390X_F13:5085    return _registers.__fpr[13];5086  case UNW_S390X_F14:5087    return _registers.__fpr[14];5088  case UNW_S390X_F15:5089    return _registers.__fpr[15];5090  }5091  _LIBUNWIND_ABORT("unsupported s390x register");5092}5093 5094inline void Registers_s390x::setFloatRegister(int regNum, double value) {5095  // NOTE: FPR DWARF register numbers are not consecutive.5096  switch (regNum) {5097  case UNW_S390X_F0:5098    _registers.__fpr[0] = value;5099    return;5100  case UNW_S390X_F1:5101    _registers.__fpr[1] = value;5102    return;5103  case UNW_S390X_F2:5104    _registers.__fpr[2] = value;5105    return;5106  case UNW_S390X_F3:5107    _registers.__fpr[3] = value;5108    return;5109  case UNW_S390X_F4:5110    _registers.__fpr[4] = value;5111    return;5112  case UNW_S390X_F5:5113    _registers.__fpr[5] = value;5114    return;5115  case UNW_S390X_F6:5116    _registers.__fpr[6] = value;5117    return;5118  case UNW_S390X_F7:5119    _registers.__fpr[7] = value;5120    return;5121  case UNW_S390X_F8:5122    _registers.__fpr[8] = value;5123    return;5124  case UNW_S390X_F9:5125    _registers.__fpr[9] = value;5126    return;5127  case UNW_S390X_F10:5128    _registers.__fpr[10] = value;5129    return;5130  case UNW_S390X_F11:5131    _registers.__fpr[11] = value;5132    return;5133  case UNW_S390X_F12:5134    _registers.__fpr[12] = value;5135    return;5136  case UNW_S390X_F13:5137    _registers.__fpr[13] = value;5138    return;5139  case UNW_S390X_F14:5140    _registers.__fpr[14] = value;5141    return;5142  case UNW_S390X_F15:5143    _registers.__fpr[15] = value;5144    return;5145  }5146  _LIBUNWIND_ABORT("unsupported s390x register");5147}5148 5149inline bool Registers_s390x::validVectorRegister(int /*regNum*/) const {5150  return false;5151}5152 5153inline v128 Registers_s390x::getVectorRegister(int /*regNum*/) const {5154  _LIBUNWIND_ABORT("s390x vector support not implemented");5155}5156 5157inline void Registers_s390x::setVectorRegister(int /*regNum*/, v128 /*value*/) {5158  _LIBUNWIND_ABORT("s390x vector support not implemented");5159}5160 5161inline const char *Registers_s390x::getRegisterName(int regNum) {5162  switch (regNum) {5163  case UNW_REG_IP:5164    return "ip";5165  case UNW_REG_SP:5166    return "sp";5167  case UNW_S390X_R0:5168    return "r0";5169  case UNW_S390X_R1:5170    return "r1";5171  case UNW_S390X_R2:5172    return "r2";5173  case UNW_S390X_R3:5174    return "r3";5175  case UNW_S390X_R4:5176    return "r4";5177  case UNW_S390X_R5:5178    return "r5";5179  case UNW_S390X_R6:5180    return "r6";5181  case UNW_S390X_R7:5182    return "r7";5183  case UNW_S390X_R8:5184    return "r8";5185  case UNW_S390X_R9:5186    return "r9";5187  case UNW_S390X_R10:5188    return "r10";5189  case UNW_S390X_R11:5190    return "r11";5191  case UNW_S390X_R12:5192    return "r12";5193  case UNW_S390X_R13:5194    return "r13";5195  case UNW_S390X_R14:5196    return "r14";5197  case UNW_S390X_R15:5198    return "r15";5199  case UNW_S390X_F0:5200    return "f0";5201  case UNW_S390X_F1:5202    return "f1";5203  case UNW_S390X_F2:5204    return "f2";5205  case UNW_S390X_F3:5206    return "f3";5207  case UNW_S390X_F4:5208    return "f4";5209  case UNW_S390X_F5:5210    return "f5";5211  case UNW_S390X_F6:5212    return "f6";5213  case UNW_S390X_F7:5214    return "f7";5215  case UNW_S390X_F8:5216    return "f8";5217  case UNW_S390X_F9:5218    return "f9";5219  case UNW_S390X_F10:5220    return "f10";5221  case UNW_S390X_F11:5222    return "f11";5223  case UNW_S390X_F12:5224    return "f12";5225  case UNW_S390X_F13:5226    return "f13";5227  case UNW_S390X_F14:5228    return "f14";5229  case UNW_S390X_F15:5230    return "f15";5231  }5232  return "unknown register";5233}5234#endif // _LIBUNWIND_TARGET_S390X5235 5236#if defined(_LIBUNWIND_TARGET_LOONGARCH)5237/// Registers_loongarch holds the register state of a thread in a 64-bit5238/// LoongArch process.5239class _LIBUNWIND_HIDDEN Registers_loongarch {5240public:5241  Registers_loongarch();5242  Registers_loongarch(const void *registers);5243 5244  typedef uint64_t reg_t;5245  typedef uint64_t link_reg_t;5246 5247  bool validRegister(int num) const;5248  uint64_t getRegister(int num) const;5249  void setRegister(int num, uint64_t value);5250  bool validFloatRegister(int num) const;5251  double getFloatRegister(int num) const;5252  void setFloatRegister(int num, double value);5253  bool validVectorRegister(int num) const;5254  v128 getVectorRegister(int num) const;5255  void setVectorRegister(int num, v128 value);5256  static const char *getRegisterName(int num);5257  void jumpto();5258  static constexpr int lastDwarfRegNum() {5259    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_LOONGARCH;5260  }5261  static int getArch() { return REGISTERS_LOONGARCH; }5262 5263  uint64_t getSP() const { return _registers.__r[3]; }5264  void setSP(uint64_t value) { _registers.__r[3] = value; }5265  uint64_t getIP() const { return _registers.__pc; }5266  void setIP(uint64_t value) { _registers.__pc = value; }5267 5268private:5269  struct loongarch_thread_state_t {5270    uint64_t __r[32];5271    uint64_t __pc;5272  };5273 5274  loongarch_thread_state_t _registers;5275#if __loongarch_frlen == 645276  double _floats[32];5277#endif5278};5279 5280inline Registers_loongarch::Registers_loongarch(const void *registers) {5281  static_assert((check_fit<Registers_loongarch, unw_context_t>::does_fit),5282                "loongarch registers do not fit into unw_context_t");5283  memcpy(&_registers, registers, sizeof(_registers));5284  static_assert(sizeof(_registers) == 0x108,5285                "expected float registers to be at offset 264");5286#if __loongarch_frlen == 645287  memcpy(_floats, static_cast<const uint8_t *>(registers) + sizeof(_registers),5288         sizeof(_floats));5289#endif5290}5291 5292inline Registers_loongarch::Registers_loongarch() {5293  memset(&_registers, 0, sizeof(_registers));5294#if __loongarch_frlen == 645295  memset(&_floats, 0, sizeof(_floats));5296#endif5297}5298 5299inline bool Registers_loongarch::validRegister(int regNum) const {5300  if (regNum == UNW_REG_IP || regNum == UNW_REG_SP)5301    return true;5302  if (regNum < 0 || regNum > UNW_LOONGARCH_F31)5303    return false;5304  return true;5305}5306 5307inline uint64_t Registers_loongarch::getRegister(int regNum) const {5308  if (regNum >= UNW_LOONGARCH_R0 && regNum <= UNW_LOONGARCH_R31)5309    return _registers.__r[regNum - UNW_LOONGARCH_R0];5310 5311  if (regNum == UNW_REG_IP)5312    return _registers.__pc;5313  if (regNum == UNW_REG_SP)5314    return _registers.__r[3];5315  _LIBUNWIND_ABORT("unsupported loongarch register");5316}5317 5318inline void Registers_loongarch::setRegister(int regNum, uint64_t value) {5319  if (regNum >= UNW_LOONGARCH_R0 && regNum <= UNW_LOONGARCH_R31)5320    _registers.__r[regNum - UNW_LOONGARCH_R0] = value;5321  else if (regNum == UNW_REG_IP)5322    _registers.__pc = value;5323  else if (regNum == UNW_REG_SP)5324    _registers.__r[3] = value;5325  else5326    _LIBUNWIND_ABORT("unsupported loongarch register");5327}5328 5329inline const char *Registers_loongarch::getRegisterName(int regNum) {5330  switch (regNum) {5331  case UNW_REG_IP:5332    return "$pc";5333  case UNW_REG_SP:5334    return "$sp";5335  case UNW_LOONGARCH_R0:5336    return "$r0";5337  case UNW_LOONGARCH_R1:5338    return "$r1";5339  case UNW_LOONGARCH_R2:5340    return "$r2";5341  case UNW_LOONGARCH_R3:5342    return "$r3";5343  case UNW_LOONGARCH_R4:5344    return "$r4";5345  case UNW_LOONGARCH_R5:5346    return "$r5";5347  case UNW_LOONGARCH_R6:5348    return "$r6";5349  case UNW_LOONGARCH_R7:5350    return "$r7";5351  case UNW_LOONGARCH_R8:5352    return "$r8";5353  case UNW_LOONGARCH_R9:5354    return "$r9";5355  case UNW_LOONGARCH_R10:5356    return "$r10";5357  case UNW_LOONGARCH_R11:5358    return "$r11";5359  case UNW_LOONGARCH_R12:5360    return "$r12";5361  case UNW_LOONGARCH_R13:5362    return "$r13";5363  case UNW_LOONGARCH_R14:5364    return "$r14";5365  case UNW_LOONGARCH_R15:5366    return "$r15";5367  case UNW_LOONGARCH_R16:5368    return "$r16";5369  case UNW_LOONGARCH_R17:5370    return "$r17";5371  case UNW_LOONGARCH_R18:5372    return "$r18";5373  case UNW_LOONGARCH_R19:5374    return "$r19";5375  case UNW_LOONGARCH_R20:5376    return "$r20";5377  case UNW_LOONGARCH_R21:5378    return "$r21";5379  case UNW_LOONGARCH_R22:5380    return "$r22";5381  case UNW_LOONGARCH_R23:5382    return "$r23";5383  case UNW_LOONGARCH_R24:5384    return "$r24";5385  case UNW_LOONGARCH_R25:5386    return "$r25";5387  case UNW_LOONGARCH_R26:5388    return "$r26";5389  case UNW_LOONGARCH_R27:5390    return "$r27";5391  case UNW_LOONGARCH_R28:5392    return "$r28";5393  case UNW_LOONGARCH_R29:5394    return "$r29";5395  case UNW_LOONGARCH_R30:5396    return "$r30";5397  case UNW_LOONGARCH_R31:5398    return "$r31";5399  case UNW_LOONGARCH_F0:5400    return "$f0";5401  case UNW_LOONGARCH_F1:5402    return "$f1";5403  case UNW_LOONGARCH_F2:5404    return "$f2";5405  case UNW_LOONGARCH_F3:5406    return "$f3";5407  case UNW_LOONGARCH_F4:5408    return "$f4";5409  case UNW_LOONGARCH_F5:5410    return "$f5";5411  case UNW_LOONGARCH_F6:5412    return "$f6";5413  case UNW_LOONGARCH_F7:5414    return "$f7";5415  case UNW_LOONGARCH_F8:5416    return "$f8";5417  case UNW_LOONGARCH_F9:5418    return "$f9";5419  case UNW_LOONGARCH_F10:5420    return "$f10";5421  case UNW_LOONGARCH_F11:5422    return "$f11";5423  case UNW_LOONGARCH_F12:5424    return "$f12";5425  case UNW_LOONGARCH_F13:5426    return "$f13";5427  case UNW_LOONGARCH_F14:5428    return "$f14";5429  case UNW_LOONGARCH_F15:5430    return "$f15";5431  case UNW_LOONGARCH_F16:5432    return "$f16";5433  case UNW_LOONGARCH_F17:5434    return "$f17";5435  case UNW_LOONGARCH_F18:5436    return "$f18";5437  case UNW_LOONGARCH_F19:5438    return "$f19";5439  case UNW_LOONGARCH_F20:5440    return "$f20";5441  case UNW_LOONGARCH_F21:5442    return "$f21";5443  case UNW_LOONGARCH_F22:5444    return "$f22";5445  case UNW_LOONGARCH_F23:5446    return "$f23";5447  case UNW_LOONGARCH_F24:5448    return "$f24";5449  case UNW_LOONGARCH_F25:5450    return "$f25";5451  case UNW_LOONGARCH_F26:5452    return "$f26";5453  case UNW_LOONGARCH_F27:5454    return "$f27";5455  case UNW_LOONGARCH_F28:5456    return "$f28";5457  case UNW_LOONGARCH_F29:5458    return "$f29";5459  case UNW_LOONGARCH_F30:5460    return "$f30";5461  case UNW_LOONGARCH_F31:5462    return "$f31";5463  default:5464    return "unknown register";5465  }5466}5467 5468inline bool Registers_loongarch::validFloatRegister(int regNum) const {5469  if (regNum < UNW_LOONGARCH_F0 || regNum > UNW_LOONGARCH_F31)5470    return false;5471  return true;5472}5473 5474inline double Registers_loongarch::getFloatRegister(int regNum) const {5475#if __loongarch_frlen == 645476  assert(validFloatRegister(regNum));5477  return _floats[regNum - UNW_LOONGARCH_F0];5478#else5479  _LIBUNWIND_ABORT("libunwind not built with float support");5480#endif5481}5482 5483inline void Registers_loongarch::setFloatRegister(int regNum, double value) {5484#if __loongarch_frlen == 645485  assert(validFloatRegister(regNum));5486  _floats[regNum - UNW_LOONGARCH_F0] = value;5487#else5488  _LIBUNWIND_ABORT("libunwind not built with float support");5489#endif5490}5491 5492inline bool Registers_loongarch::validVectorRegister(int) const {5493  return false;5494}5495 5496inline v128 Registers_loongarch::getVectorRegister(int) const {5497  _LIBUNWIND_ABORT("loongarch vector support not implemented");5498}5499 5500inline void Registers_loongarch::setVectorRegister(int, v128) {5501  _LIBUNWIND_ABORT("loongarch vector support not implemented");5502}5503#endif //_LIBUNWIND_TARGET_LOONGARCH5504 5505} // namespace libunwind5506 5507#endif // __REGISTERS_HPP__5508