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