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