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