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