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