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