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