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