1 //===----------------------------- Registers.hpp --------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 // 9 // Models register sets for supported processors. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef __REGISTERS_HPP__ 14 #define __REGISTERS_HPP__ 15 16 #include <stdint.h> 17 #include <string.h> 18 19 #include "libunwind.h" 20 #include "config.h" 21 22 namespace libunwind { 23 24 // For emulating 128-bit registers 25 struct v128 { uint32_t vec[4]; }; 26 27 28 #if defined(_LIBUNWIND_TARGET_I386) 29 /// Registers_x86 holds the register state of a thread in a 32-bit intel 30 /// process. 31 class _LIBUNWIND_HIDDEN Registers_x86 { 32 public: 33 Registers_x86(); 34 Registers_x86(const void *registers); 35 36 bool validRegister(int num) const; 37 uint32_t getRegister(int num) const; 38 void setRegister(int num, uint32_t value); 39 bool validFloatRegister(int) const { return false; } 40 double getFloatRegister(int num) const; 41 void setFloatRegister(int num, double value); 42 bool validVectorRegister(int) const { return false; } 43 v128 getVectorRegister(int num) const; 44 void setVectorRegister(int num, v128 value); 45 const char *getRegisterName(int num); 46 void jumpto(); 47 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86; } 48 49 uint32_t getSP() const { return _registers.__esp; } 50 void setSP(uint32_t value) { _registers.__esp = value; } 51 uint32_t getIP() const { return _registers.__eip; } 52 void setIP(uint32_t value) { _registers.__eip = value; } 53 uint32_t getEBP() const { return _registers.__ebp; } 54 void setEBP(uint32_t value) { _registers.__ebp = value; } 55 uint32_t getEBX() const { return _registers.__ebx; } 56 void setEBX(uint32_t value) { _registers.__ebx = value; } 57 uint32_t getECX() const { return _registers.__ecx; } 58 void setECX(uint32_t value) { _registers.__ecx = value; } 59 uint32_t getEDX() const { return _registers.__edx; } 60 void setEDX(uint32_t value) { _registers.__edx = value; } 61 uint32_t getESI() const { return _registers.__esi; } 62 void setESI(uint32_t value) { _registers.__esi = value; } 63 uint32_t getEDI() const { return _registers.__edi; } 64 void setEDI(uint32_t value) { _registers.__edi = value; } 65 66 private: 67 struct GPRs { 68 unsigned int __eax; 69 unsigned int __ebx; 70 unsigned int __ecx; 71 unsigned int __edx; 72 unsigned int __edi; 73 unsigned int __esi; 74 unsigned int __ebp; 75 unsigned int __esp; 76 unsigned int __ss; 77 unsigned int __eflags; 78 unsigned int __eip; 79 unsigned int __cs; 80 unsigned int __ds; 81 unsigned int __es; 82 unsigned int __fs; 83 unsigned int __gs; 84 }; 85 86 GPRs _registers; 87 }; 88 89 inline Registers_x86::Registers_x86(const void *registers) { 90 static_assert((check_fit<Registers_x86, unw_context_t>::does_fit), 91 "x86 registers do not fit into unw_context_t"); 92 memcpy(&_registers, registers, sizeof(_registers)); 93 } 94 95 inline Registers_x86::Registers_x86() { 96 memset(&_registers, 0, sizeof(_registers)); 97 } 98 99 inline bool Registers_x86::validRegister(int regNum) const { 100 if (regNum == UNW_REG_IP) 101 return true; 102 if (regNum == UNW_REG_SP) 103 return true; 104 if (regNum < 0) 105 return false; 106 if (regNum > 7) 107 return false; 108 return true; 109 } 110 111 inline uint32_t Registers_x86::getRegister(int regNum) const { 112 switch (regNum) { 113 case UNW_REG_IP: 114 return _registers.__eip; 115 case UNW_REG_SP: 116 return _registers.__esp; 117 case UNW_X86_EAX: 118 return _registers.__eax; 119 case UNW_X86_ECX: 120 return _registers.__ecx; 121 case UNW_X86_EDX: 122 return _registers.__edx; 123 case UNW_X86_EBX: 124 return _registers.__ebx; 125 #if !defined(__APPLE__) 126 case UNW_X86_ESP: 127 #else 128 case UNW_X86_EBP: 129 #endif 130 return _registers.__ebp; 131 #if !defined(__APPLE__) 132 case UNW_X86_EBP: 133 #else 134 case UNW_X86_ESP: 135 #endif 136 return _registers.__esp; 137 case UNW_X86_ESI: 138 return _registers.__esi; 139 case UNW_X86_EDI: 140 return _registers.__edi; 141 } 142 _LIBUNWIND_ABORT("unsupported x86 register"); 143 } 144 145 inline void Registers_x86::setRegister(int regNum, uint32_t value) { 146 switch (regNum) { 147 case UNW_REG_IP: 148 _registers.__eip = value; 149 return; 150 case UNW_REG_SP: 151 _registers.__esp = value; 152 return; 153 case UNW_X86_EAX: 154 _registers.__eax = value; 155 return; 156 case UNW_X86_ECX: 157 _registers.__ecx = value; 158 return; 159 case UNW_X86_EDX: 160 _registers.__edx = value; 161 return; 162 case UNW_X86_EBX: 163 _registers.__ebx = value; 164 return; 165 #if !defined(__APPLE__) 166 case UNW_X86_ESP: 167 #else 168 case UNW_X86_EBP: 169 #endif 170 _registers.__ebp = value; 171 return; 172 #if !defined(__APPLE__) 173 case UNW_X86_EBP: 174 #else 175 case UNW_X86_ESP: 176 #endif 177 _registers.__esp = value; 178 return; 179 case UNW_X86_ESI: 180 _registers.__esi = value; 181 return; 182 case UNW_X86_EDI: 183 _registers.__edi = value; 184 return; 185 } 186 _LIBUNWIND_ABORT("unsupported x86 register"); 187 } 188 189 inline const char *Registers_x86::getRegisterName(int regNum) { 190 switch (regNum) { 191 case UNW_REG_IP: 192 return "ip"; 193 case UNW_REG_SP: 194 return "esp"; 195 case UNW_X86_EAX: 196 return "eax"; 197 case UNW_X86_ECX: 198 return "ecx"; 199 case UNW_X86_EDX: 200 return "edx"; 201 case UNW_X86_EBX: 202 return "ebx"; 203 case UNW_X86_EBP: 204 return "ebp"; 205 case UNW_X86_ESP: 206 return "esp"; 207 case UNW_X86_ESI: 208 return "esi"; 209 case UNW_X86_EDI: 210 return "edi"; 211 default: 212 return "unknown register"; 213 } 214 } 215 216 inline double Registers_x86::getFloatRegister(int) const { 217 _LIBUNWIND_ABORT("no x86 float registers"); 218 } 219 220 inline void Registers_x86::setFloatRegister(int, double) { 221 _LIBUNWIND_ABORT("no x86 float registers"); 222 } 223 224 inline v128 Registers_x86::getVectorRegister(int) const { 225 _LIBUNWIND_ABORT("no x86 vector registers"); 226 } 227 228 inline void Registers_x86::setVectorRegister(int, v128) { 229 _LIBUNWIND_ABORT("no x86 vector registers"); 230 } 231 #endif // _LIBUNWIND_TARGET_I386 232 233 234 #if defined(_LIBUNWIND_TARGET_X86_64) 235 /// Registers_x86_64 holds the register state of a thread in a 64-bit intel 236 /// process. 237 class _LIBUNWIND_HIDDEN Registers_x86_64 { 238 public: 239 Registers_x86_64(); 240 Registers_x86_64(const void *registers); 241 242 bool validRegister(int num) const; 243 uint64_t getRegister(int num) const; 244 void setRegister(int num, uint64_t value); 245 bool validFloatRegister(int) const { return false; } 246 double getFloatRegister(int num) const; 247 void setFloatRegister(int num, double value); 248 bool validVectorRegister(int) const; 249 v128 getVectorRegister(int num) const; 250 void setVectorRegister(int num, v128 value); 251 const char *getRegisterName(int num); 252 void jumpto(); 253 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64; } 254 255 uint64_t getSP() const { return _registers.__rsp; } 256 void setSP(uint64_t value) { _registers.__rsp = value; } 257 uint64_t getIP() const { return _registers.__rip; } 258 void setIP(uint64_t value) { _registers.__rip = value; } 259 uint64_t getRBP() const { return _registers.__rbp; } 260 void setRBP(uint64_t value) { _registers.__rbp = value; } 261 uint64_t getRBX() const { return _registers.__rbx; } 262 void setRBX(uint64_t value) { _registers.__rbx = value; } 263 uint64_t getR12() const { return _registers.__r12; } 264 void setR12(uint64_t value) { _registers.__r12 = value; } 265 uint64_t getR13() const { return _registers.__r13; } 266 void setR13(uint64_t value) { _registers.__r13 = value; } 267 uint64_t getR14() const { return _registers.__r14; } 268 void setR14(uint64_t value) { _registers.__r14 = value; } 269 uint64_t getR15() const { return _registers.__r15; } 270 void setR15(uint64_t value) { _registers.__r15 = value; } 271 272 private: 273 struct GPRs { 274 uint64_t __rax; 275 uint64_t __rbx; 276 uint64_t __rcx; 277 uint64_t __rdx; 278 uint64_t __rdi; 279 uint64_t __rsi; 280 uint64_t __rbp; 281 uint64_t __rsp; 282 uint64_t __r8; 283 uint64_t __r9; 284 uint64_t __r10; 285 uint64_t __r11; 286 uint64_t __r12; 287 uint64_t __r13; 288 uint64_t __r14; 289 uint64_t __r15; 290 uint64_t __rip; 291 uint64_t __rflags; 292 uint64_t __cs; 293 uint64_t __fs; 294 uint64_t __gs; 295 #if defined(_WIN64) 296 uint64_t __padding; // 16-byte align 297 #endif 298 }; 299 GPRs _registers; 300 #if defined(_WIN64) 301 v128 _xmm[16]; 302 #endif 303 }; 304 305 inline Registers_x86_64::Registers_x86_64(const void *registers) { 306 static_assert((check_fit<Registers_x86_64, unw_context_t>::does_fit), 307 "x86_64 registers do not fit into unw_context_t"); 308 memcpy(&_registers, registers, sizeof(_registers)); 309 } 310 311 inline Registers_x86_64::Registers_x86_64() { 312 memset(&_registers, 0, sizeof(_registers)); 313 } 314 315 inline bool Registers_x86_64::validRegister(int regNum) const { 316 if (regNum == UNW_REG_IP) 317 return true; 318 if (regNum == UNW_REG_SP) 319 return true; 320 if (regNum < 0) 321 return false; 322 if (regNum > 15) 323 return false; 324 return true; 325 } 326 327 inline uint64_t Registers_x86_64::getRegister(int regNum) const { 328 switch (regNum) { 329 case UNW_REG_IP: 330 return _registers.__rip; 331 case UNW_REG_SP: 332 return _registers.__rsp; 333 case UNW_X86_64_RAX: 334 return _registers.__rax; 335 case UNW_X86_64_RDX: 336 return _registers.__rdx; 337 case UNW_X86_64_RCX: 338 return _registers.__rcx; 339 case UNW_X86_64_RBX: 340 return _registers.__rbx; 341 case UNW_X86_64_RSI: 342 return _registers.__rsi; 343 case UNW_X86_64_RDI: 344 return _registers.__rdi; 345 case UNW_X86_64_RBP: 346 return _registers.__rbp; 347 case UNW_X86_64_RSP: 348 return _registers.__rsp; 349 case UNW_X86_64_R8: 350 return _registers.__r8; 351 case UNW_X86_64_R9: 352 return _registers.__r9; 353 case UNW_X86_64_R10: 354 return _registers.__r10; 355 case UNW_X86_64_R11: 356 return _registers.__r11; 357 case UNW_X86_64_R12: 358 return _registers.__r12; 359 case UNW_X86_64_R13: 360 return _registers.__r13; 361 case UNW_X86_64_R14: 362 return _registers.__r14; 363 case UNW_X86_64_R15: 364 return _registers.__r15; 365 } 366 _LIBUNWIND_ABORT("unsupported x86_64 register"); 367 } 368 369 inline void Registers_x86_64::setRegister(int regNum, uint64_t value) { 370 switch (regNum) { 371 case UNW_REG_IP: 372 _registers.__rip = value; 373 return; 374 case UNW_REG_SP: 375 _registers.__rsp = value; 376 return; 377 case UNW_X86_64_RAX: 378 _registers.__rax = value; 379 return; 380 case UNW_X86_64_RDX: 381 _registers.__rdx = value; 382 return; 383 case UNW_X86_64_RCX: 384 _registers.__rcx = value; 385 return; 386 case UNW_X86_64_RBX: 387 _registers.__rbx = value; 388 return; 389 case UNW_X86_64_RSI: 390 _registers.__rsi = value; 391 return; 392 case UNW_X86_64_RDI: 393 _registers.__rdi = value; 394 return; 395 case UNW_X86_64_RBP: 396 _registers.__rbp = value; 397 return; 398 case UNW_X86_64_RSP: 399 _registers.__rsp = value; 400 return; 401 case UNW_X86_64_R8: 402 _registers.__r8 = value; 403 return; 404 case UNW_X86_64_R9: 405 _registers.__r9 = value; 406 return; 407 case UNW_X86_64_R10: 408 _registers.__r10 = value; 409 return; 410 case UNW_X86_64_R11: 411 _registers.__r11 = value; 412 return; 413 case UNW_X86_64_R12: 414 _registers.__r12 = value; 415 return; 416 case UNW_X86_64_R13: 417 _registers.__r13 = value; 418 return; 419 case UNW_X86_64_R14: 420 _registers.__r14 = value; 421 return; 422 case UNW_X86_64_R15: 423 _registers.__r15 = value; 424 return; 425 } 426 _LIBUNWIND_ABORT("unsupported x86_64 register"); 427 } 428 429 inline const char *Registers_x86_64::getRegisterName(int regNum) { 430 switch (regNum) { 431 case UNW_REG_IP: 432 return "rip"; 433 case UNW_REG_SP: 434 return "rsp"; 435 case UNW_X86_64_RAX: 436 return "rax"; 437 case UNW_X86_64_RDX: 438 return "rdx"; 439 case UNW_X86_64_RCX: 440 return "rcx"; 441 case UNW_X86_64_RBX: 442 return "rbx"; 443 case UNW_X86_64_RSI: 444 return "rsi"; 445 case UNW_X86_64_RDI: 446 return "rdi"; 447 case UNW_X86_64_RBP: 448 return "rbp"; 449 case UNW_X86_64_RSP: 450 return "rsp"; 451 case UNW_X86_64_R8: 452 return "r8"; 453 case UNW_X86_64_R9: 454 return "r9"; 455 case UNW_X86_64_R10: 456 return "r10"; 457 case UNW_X86_64_R11: 458 return "r11"; 459 case UNW_X86_64_R12: 460 return "r12"; 461 case UNW_X86_64_R13: 462 return "r13"; 463 case UNW_X86_64_R14: 464 return "r14"; 465 case UNW_X86_64_R15: 466 return "r15"; 467 case UNW_X86_64_XMM0: 468 return "xmm0"; 469 case UNW_X86_64_XMM1: 470 return "xmm1"; 471 case UNW_X86_64_XMM2: 472 return "xmm2"; 473 case UNW_X86_64_XMM3: 474 return "xmm3"; 475 case UNW_X86_64_XMM4: 476 return "xmm4"; 477 case UNW_X86_64_XMM5: 478 return "xmm5"; 479 case UNW_X86_64_XMM6: 480 return "xmm6"; 481 case UNW_X86_64_XMM7: 482 return "xmm7"; 483 case UNW_X86_64_XMM8: 484 return "xmm8"; 485 case UNW_X86_64_XMM9: 486 return "xmm9"; 487 case UNW_X86_64_XMM10: 488 return "xmm10"; 489 case UNW_X86_64_XMM11: 490 return "xmm11"; 491 case UNW_X86_64_XMM12: 492 return "xmm12"; 493 case UNW_X86_64_XMM13: 494 return "xmm13"; 495 case UNW_X86_64_XMM14: 496 return "xmm14"; 497 case UNW_X86_64_XMM15: 498 return "xmm15"; 499 default: 500 return "unknown register"; 501 } 502 } 503 504 inline double Registers_x86_64::getFloatRegister(int) const { 505 _LIBUNWIND_ABORT("no x86_64 float registers"); 506 } 507 508 inline void Registers_x86_64::setFloatRegister(int, double) { 509 _LIBUNWIND_ABORT("no x86_64 float registers"); 510 } 511 512 inline bool Registers_x86_64::validVectorRegister(int regNum) const { 513 #if defined(_WIN64) 514 if (regNum < UNW_X86_64_XMM0) 515 return false; 516 if (regNum > UNW_X86_64_XMM15) 517 return false; 518 return true; 519 #else 520 (void)regNum; // suppress unused parameter warning 521 return false; 522 #endif 523 } 524 525 inline v128 Registers_x86_64::getVectorRegister(int regNum) const { 526 #if defined(_WIN64) 527 assert(validVectorRegister(regNum)); 528 return _xmm[regNum - UNW_X86_64_XMM0]; 529 #else 530 (void)regNum; // suppress unused parameter warning 531 _LIBUNWIND_ABORT("no x86_64 vector registers"); 532 #endif 533 } 534 535 inline void Registers_x86_64::setVectorRegister(int regNum, v128 value) { 536 #if defined(_WIN64) 537 assert(validVectorRegister(regNum)); 538 _xmm[regNum - UNW_X86_64_XMM0] = value; 539 #else 540 (void)regNum; (void)value; // suppress unused parameter warnings 541 _LIBUNWIND_ABORT("no x86_64 vector registers"); 542 #endif 543 } 544 #endif // _LIBUNWIND_TARGET_X86_64 545 546 547 #if defined(_LIBUNWIND_TARGET_PPC) 548 /// Registers_ppc holds the register state of a thread in a 32-bit PowerPC 549 /// process. 550 class _LIBUNWIND_HIDDEN Registers_ppc { 551 public: 552 Registers_ppc(); 553 Registers_ppc(const void *registers); 554 555 bool validRegister(int num) const; 556 uint32_t getRegister(int num) const; 557 void setRegister(int num, uint32_t value); 558 bool validFloatRegister(int num) const; 559 double getFloatRegister(int num) const; 560 void setFloatRegister(int num, double value); 561 bool validVectorRegister(int num) const; 562 v128 getVectorRegister(int num) const; 563 void setVectorRegister(int num, v128 value); 564 const char *getRegisterName(int num); 565 void jumpto(); 566 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC; } 567 568 uint64_t getSP() const { return _registers.__r1; } 569 void setSP(uint32_t value) { _registers.__r1 = value; } 570 uint64_t getIP() const { return _registers.__srr0; } 571 void setIP(uint32_t value) { _registers.__srr0 = value; } 572 573 private: 574 struct ppc_thread_state_t { 575 unsigned int __srr0; /* Instruction address register (PC) */ 576 unsigned int __srr1; /* Machine state register (supervisor) */ 577 unsigned int __r0; 578 unsigned int __r1; 579 unsigned int __r2; 580 unsigned int __r3; 581 unsigned int __r4; 582 unsigned int __r5; 583 unsigned int __r6; 584 unsigned int __r7; 585 unsigned int __r8; 586 unsigned int __r9; 587 unsigned int __r10; 588 unsigned int __r11; 589 unsigned int __r12; 590 unsigned int __r13; 591 unsigned int __r14; 592 unsigned int __r15; 593 unsigned int __r16; 594 unsigned int __r17; 595 unsigned int __r18; 596 unsigned int __r19; 597 unsigned int __r20; 598 unsigned int __r21; 599 unsigned int __r22; 600 unsigned int __r23; 601 unsigned int __r24; 602 unsigned int __r25; 603 unsigned int __r26; 604 unsigned int __r27; 605 unsigned int __r28; 606 unsigned int __r29; 607 unsigned int __r30; 608 unsigned int __r31; 609 unsigned int __cr; /* Condition register */ 610 unsigned int __xer; /* User's integer exception register */ 611 unsigned int __lr; /* Link register */ 612 unsigned int __ctr; /* Count register */ 613 unsigned int __mq; /* MQ register (601 only) */ 614 unsigned int __vrsave; /* Vector Save Register */ 615 }; 616 617 struct ppc_float_state_t { 618 double __fpregs[32]; 619 620 unsigned int __fpscr_pad; /* fpscr is 64 bits, 32 bits of rubbish */ 621 unsigned int __fpscr; /* floating point status register */ 622 }; 623 624 ppc_thread_state_t _registers; 625 ppc_float_state_t _floatRegisters; 626 v128 _vectorRegisters[32]; // offset 424 627 }; 628 629 inline Registers_ppc::Registers_ppc(const void *registers) { 630 static_assert((check_fit<Registers_ppc, unw_context_t>::does_fit), 631 "ppc registers do not fit into unw_context_t"); 632 memcpy(&_registers, static_cast<const uint8_t *>(registers), 633 sizeof(_registers)); 634 static_assert(sizeof(ppc_thread_state_t) == 160, 635 "expected float register offset to be 160"); 636 memcpy(&_floatRegisters, 637 static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t), 638 sizeof(_floatRegisters)); 639 static_assert(sizeof(ppc_thread_state_t) + sizeof(ppc_float_state_t) == 424, 640 "expected vector register offset to be 424 bytes"); 641 memcpy(_vectorRegisters, 642 static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t) + 643 sizeof(ppc_float_state_t), 644 sizeof(_vectorRegisters)); 645 } 646 647 inline Registers_ppc::Registers_ppc() { 648 memset(&_registers, 0, sizeof(_registers)); 649 memset(&_floatRegisters, 0, sizeof(_floatRegisters)); 650 memset(&_vectorRegisters, 0, sizeof(_vectorRegisters)); 651 } 652 653 inline bool Registers_ppc::validRegister(int regNum) const { 654 if (regNum == UNW_REG_IP) 655 return true; 656 if (regNum == UNW_REG_SP) 657 return true; 658 if (regNum == UNW_PPC_VRSAVE) 659 return true; 660 if (regNum < 0) 661 return false; 662 if (regNum <= UNW_PPC_R31) 663 return true; 664 if (regNum == UNW_PPC_MQ) 665 return true; 666 if (regNum == UNW_PPC_LR) 667 return true; 668 if (regNum == UNW_PPC_CTR) 669 return true; 670 if ((UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7)) 671 return true; 672 return false; 673 } 674 675 inline uint32_t Registers_ppc::getRegister(int regNum) const { 676 switch (regNum) { 677 case UNW_REG_IP: 678 return _registers.__srr0; 679 case UNW_REG_SP: 680 return _registers.__r1; 681 case UNW_PPC_R0: 682 return _registers.__r0; 683 case UNW_PPC_R1: 684 return _registers.__r1; 685 case UNW_PPC_R2: 686 return _registers.__r2; 687 case UNW_PPC_R3: 688 return _registers.__r3; 689 case UNW_PPC_R4: 690 return _registers.__r4; 691 case UNW_PPC_R5: 692 return _registers.__r5; 693 case UNW_PPC_R6: 694 return _registers.__r6; 695 case UNW_PPC_R7: 696 return _registers.__r7; 697 case UNW_PPC_R8: 698 return _registers.__r8; 699 case UNW_PPC_R9: 700 return _registers.__r9; 701 case UNW_PPC_R10: 702 return _registers.__r10; 703 case UNW_PPC_R11: 704 return _registers.__r11; 705 case UNW_PPC_R12: 706 return _registers.__r12; 707 case UNW_PPC_R13: 708 return _registers.__r13; 709 case UNW_PPC_R14: 710 return _registers.__r14; 711 case UNW_PPC_R15: 712 return _registers.__r15; 713 case UNW_PPC_R16: 714 return _registers.__r16; 715 case UNW_PPC_R17: 716 return _registers.__r17; 717 case UNW_PPC_R18: 718 return _registers.__r18; 719 case UNW_PPC_R19: 720 return _registers.__r19; 721 case UNW_PPC_R20: 722 return _registers.__r20; 723 case UNW_PPC_R21: 724 return _registers.__r21; 725 case UNW_PPC_R22: 726 return _registers.__r22; 727 case UNW_PPC_R23: 728 return _registers.__r23; 729 case UNW_PPC_R24: 730 return _registers.__r24; 731 case UNW_PPC_R25: 732 return _registers.__r25; 733 case UNW_PPC_R26: 734 return _registers.__r26; 735 case UNW_PPC_R27: 736 return _registers.__r27; 737 case UNW_PPC_R28: 738 return _registers.__r28; 739 case UNW_PPC_R29: 740 return _registers.__r29; 741 case UNW_PPC_R30: 742 return _registers.__r30; 743 case UNW_PPC_R31: 744 return _registers.__r31; 745 case UNW_PPC_LR: 746 return _registers.__lr; 747 case UNW_PPC_CR0: 748 return (_registers.__cr & 0xF0000000); 749 case UNW_PPC_CR1: 750 return (_registers.__cr & 0x0F000000); 751 case UNW_PPC_CR2: 752 return (_registers.__cr & 0x00F00000); 753 case UNW_PPC_CR3: 754 return (_registers.__cr & 0x000F0000); 755 case UNW_PPC_CR4: 756 return (_registers.__cr & 0x0000F000); 757 case UNW_PPC_CR5: 758 return (_registers.__cr & 0x00000F00); 759 case UNW_PPC_CR6: 760 return (_registers.__cr & 0x000000F0); 761 case UNW_PPC_CR7: 762 return (_registers.__cr & 0x0000000F); 763 case UNW_PPC_VRSAVE: 764 return _registers.__vrsave; 765 } 766 _LIBUNWIND_ABORT("unsupported ppc register"); 767 } 768 769 inline void Registers_ppc::setRegister(int regNum, uint32_t value) { 770 //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value); 771 switch (regNum) { 772 case UNW_REG_IP: 773 _registers.__srr0 = value; 774 return; 775 case UNW_REG_SP: 776 _registers.__r1 = value; 777 return; 778 case UNW_PPC_R0: 779 _registers.__r0 = value; 780 return; 781 case UNW_PPC_R1: 782 _registers.__r1 = value; 783 return; 784 case UNW_PPC_R2: 785 _registers.__r2 = value; 786 return; 787 case UNW_PPC_R3: 788 _registers.__r3 = value; 789 return; 790 case UNW_PPC_R4: 791 _registers.__r4 = value; 792 return; 793 case UNW_PPC_R5: 794 _registers.__r5 = value; 795 return; 796 case UNW_PPC_R6: 797 _registers.__r6 = value; 798 return; 799 case UNW_PPC_R7: 800 _registers.__r7 = value; 801 return; 802 case UNW_PPC_R8: 803 _registers.__r8 = value; 804 return; 805 case UNW_PPC_R9: 806 _registers.__r9 = value; 807 return; 808 case UNW_PPC_R10: 809 _registers.__r10 = value; 810 return; 811 case UNW_PPC_R11: 812 _registers.__r11 = value; 813 return; 814 case UNW_PPC_R12: 815 _registers.__r12 = value; 816 return; 817 case UNW_PPC_R13: 818 _registers.__r13 = value; 819 return; 820 case UNW_PPC_R14: 821 _registers.__r14 = value; 822 return; 823 case UNW_PPC_R15: 824 _registers.__r15 = value; 825 return; 826 case UNW_PPC_R16: 827 _registers.__r16 = value; 828 return; 829 case UNW_PPC_R17: 830 _registers.__r17 = value; 831 return; 832 case UNW_PPC_R18: 833 _registers.__r18 = value; 834 return; 835 case UNW_PPC_R19: 836 _registers.__r19 = value; 837 return; 838 case UNW_PPC_R20: 839 _registers.__r20 = value; 840 return; 841 case UNW_PPC_R21: 842 _registers.__r21 = value; 843 return; 844 case UNW_PPC_R22: 845 _registers.__r22 = value; 846 return; 847 case UNW_PPC_R23: 848 _registers.__r23 = value; 849 return; 850 case UNW_PPC_R24: 851 _registers.__r24 = value; 852 return; 853 case UNW_PPC_R25: 854 _registers.__r25 = value; 855 return; 856 case UNW_PPC_R26: 857 _registers.__r26 = value; 858 return; 859 case UNW_PPC_R27: 860 _registers.__r27 = value; 861 return; 862 case UNW_PPC_R28: 863 _registers.__r28 = value; 864 return; 865 case UNW_PPC_R29: 866 _registers.__r29 = value; 867 return; 868 case UNW_PPC_R30: 869 _registers.__r30 = value; 870 return; 871 case UNW_PPC_R31: 872 _registers.__r31 = value; 873 return; 874 case UNW_PPC_MQ: 875 _registers.__mq = value; 876 return; 877 case UNW_PPC_LR: 878 _registers.__lr = value; 879 return; 880 case UNW_PPC_CTR: 881 _registers.__ctr = value; 882 return; 883 case UNW_PPC_CR0: 884 _registers.__cr &= 0x0FFFFFFF; 885 _registers.__cr |= (value & 0xF0000000); 886 return; 887 case UNW_PPC_CR1: 888 _registers.__cr &= 0xF0FFFFFF; 889 _registers.__cr |= (value & 0x0F000000); 890 return; 891 case UNW_PPC_CR2: 892 _registers.__cr &= 0xFF0FFFFF; 893 _registers.__cr |= (value & 0x00F00000); 894 return; 895 case UNW_PPC_CR3: 896 _registers.__cr &= 0xFFF0FFFF; 897 _registers.__cr |= (value & 0x000F0000); 898 return; 899 case UNW_PPC_CR4: 900 _registers.__cr &= 0xFFFF0FFF; 901 _registers.__cr |= (value & 0x0000F000); 902 return; 903 case UNW_PPC_CR5: 904 _registers.__cr &= 0xFFFFF0FF; 905 _registers.__cr |= (value & 0x00000F00); 906 return; 907 case UNW_PPC_CR6: 908 _registers.__cr &= 0xFFFFFF0F; 909 _registers.__cr |= (value & 0x000000F0); 910 return; 911 case UNW_PPC_CR7: 912 _registers.__cr &= 0xFFFFFFF0; 913 _registers.__cr |= (value & 0x0000000F); 914 return; 915 case UNW_PPC_VRSAVE: 916 _registers.__vrsave = value; 917 return; 918 // not saved 919 return; 920 case UNW_PPC_XER: 921 _registers.__xer = value; 922 return; 923 case UNW_PPC_AP: 924 case UNW_PPC_VSCR: 925 case UNW_PPC_SPEFSCR: 926 // not saved 927 return; 928 } 929 _LIBUNWIND_ABORT("unsupported ppc register"); 930 } 931 932 inline bool Registers_ppc::validFloatRegister(int regNum) const { 933 if (regNum < UNW_PPC_F0) 934 return false; 935 if (regNum > UNW_PPC_F31) 936 return false; 937 return true; 938 } 939 940 inline double Registers_ppc::getFloatRegister(int regNum) const { 941 assert(validFloatRegister(regNum)); 942 return _floatRegisters.__fpregs[regNum - UNW_PPC_F0]; 943 } 944 945 inline void Registers_ppc::setFloatRegister(int regNum, double value) { 946 assert(validFloatRegister(regNum)); 947 _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value; 948 } 949 950 inline bool Registers_ppc::validVectorRegister(int regNum) const { 951 if (regNum < UNW_PPC_V0) 952 return false; 953 if (regNum > UNW_PPC_V31) 954 return false; 955 return true; 956 } 957 958 inline v128 Registers_ppc::getVectorRegister(int regNum) const { 959 assert(validVectorRegister(regNum)); 960 v128 result = _vectorRegisters[regNum - UNW_PPC_V0]; 961 return result; 962 } 963 964 inline void Registers_ppc::setVectorRegister(int regNum, v128 value) { 965 assert(validVectorRegister(regNum)); 966 _vectorRegisters[regNum - UNW_PPC_V0] = value; 967 } 968 969 inline const char *Registers_ppc::getRegisterName(int regNum) { 970 switch (regNum) { 971 case UNW_REG_IP: 972 return "ip"; 973 case UNW_REG_SP: 974 return "sp"; 975 case UNW_PPC_R0: 976 return "r0"; 977 case UNW_PPC_R1: 978 return "r1"; 979 case UNW_PPC_R2: 980 return "r2"; 981 case UNW_PPC_R3: 982 return "r3"; 983 case UNW_PPC_R4: 984 return "r4"; 985 case UNW_PPC_R5: 986 return "r5"; 987 case UNW_PPC_R6: 988 return "r6"; 989 case UNW_PPC_R7: 990 return "r7"; 991 case UNW_PPC_R8: 992 return "r8"; 993 case UNW_PPC_R9: 994 return "r9"; 995 case UNW_PPC_R10: 996 return "r10"; 997 case UNW_PPC_R11: 998 return "r11"; 999 case UNW_PPC_R12: 1000 return "r12"; 1001 case UNW_PPC_R13: 1002 return "r13"; 1003 case UNW_PPC_R14: 1004 return "r14"; 1005 case UNW_PPC_R15: 1006 return "r15"; 1007 case UNW_PPC_R16: 1008 return "r16"; 1009 case UNW_PPC_R17: 1010 return "r17"; 1011 case UNW_PPC_R18: 1012 return "r18"; 1013 case UNW_PPC_R19: 1014 return "r19"; 1015 case UNW_PPC_R20: 1016 return "r20"; 1017 case UNW_PPC_R21: 1018 return "r21"; 1019 case UNW_PPC_R22: 1020 return "r22"; 1021 case UNW_PPC_R23: 1022 return "r23"; 1023 case UNW_PPC_R24: 1024 return "r24"; 1025 case UNW_PPC_R25: 1026 return "r25"; 1027 case UNW_PPC_R26: 1028 return "r26"; 1029 case UNW_PPC_R27: 1030 return "r27"; 1031 case UNW_PPC_R28: 1032 return "r28"; 1033 case UNW_PPC_R29: 1034 return "r29"; 1035 case UNW_PPC_R30: 1036 return "r30"; 1037 case UNW_PPC_R31: 1038 return "r31"; 1039 case UNW_PPC_F0: 1040 return "fp0"; 1041 case UNW_PPC_F1: 1042 return "fp1"; 1043 case UNW_PPC_F2: 1044 return "fp2"; 1045 case UNW_PPC_F3: 1046 return "fp3"; 1047 case UNW_PPC_F4: 1048 return "fp4"; 1049 case UNW_PPC_F5: 1050 return "fp5"; 1051 case UNW_PPC_F6: 1052 return "fp6"; 1053 case UNW_PPC_F7: 1054 return "fp7"; 1055 case UNW_PPC_F8: 1056 return "fp8"; 1057 case UNW_PPC_F9: 1058 return "fp9"; 1059 case UNW_PPC_F10: 1060 return "fp10"; 1061 case UNW_PPC_F11: 1062 return "fp11"; 1063 case UNW_PPC_F12: 1064 return "fp12"; 1065 case UNW_PPC_F13: 1066 return "fp13"; 1067 case UNW_PPC_F14: 1068 return "fp14"; 1069 case UNW_PPC_F15: 1070 return "fp15"; 1071 case UNW_PPC_F16: 1072 return "fp16"; 1073 case UNW_PPC_F17: 1074 return "fp17"; 1075 case UNW_PPC_F18: 1076 return "fp18"; 1077 case UNW_PPC_F19: 1078 return "fp19"; 1079 case UNW_PPC_F20: 1080 return "fp20"; 1081 case UNW_PPC_F21: 1082 return "fp21"; 1083 case UNW_PPC_F22: 1084 return "fp22"; 1085 case UNW_PPC_F23: 1086 return "fp23"; 1087 case UNW_PPC_F24: 1088 return "fp24"; 1089 case UNW_PPC_F25: 1090 return "fp25"; 1091 case UNW_PPC_F26: 1092 return "fp26"; 1093 case UNW_PPC_F27: 1094 return "fp27"; 1095 case UNW_PPC_F28: 1096 return "fp28"; 1097 case UNW_PPC_F29: 1098 return "fp29"; 1099 case UNW_PPC_F30: 1100 return "fp30"; 1101 case UNW_PPC_F31: 1102 return "fp31"; 1103 case UNW_PPC_LR: 1104 return "lr"; 1105 default: 1106 return "unknown register"; 1107 } 1108 1109 } 1110 #endif // _LIBUNWIND_TARGET_PPC 1111 1112 #if defined(_LIBUNWIND_TARGET_PPC64) 1113 /// Registers_ppc64 holds the register state of a thread in a 64-bit PowerPC 1114 /// process. 1115 class _LIBUNWIND_HIDDEN Registers_ppc64 { 1116 public: 1117 Registers_ppc64(); 1118 Registers_ppc64(const void *registers); 1119 1120 bool validRegister(int num) const; 1121 uint64_t getRegister(int num) const; 1122 void setRegister(int num, uint64_t value); 1123 bool validFloatRegister(int num) const; 1124 double getFloatRegister(int num) const; 1125 void setFloatRegister(int num, double value); 1126 bool validVectorRegister(int num) const; 1127 v128 getVectorRegister(int num) const; 1128 void setVectorRegister(int num, v128 value); 1129 const char *getRegisterName(int num); 1130 void jumpto(); 1131 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64; } 1132 1133 uint64_t getSP() const { return _registers.__r1; } 1134 void setSP(uint64_t value) { _registers.__r1 = value; } 1135 uint64_t getIP() const { return _registers.__srr0; } 1136 void setIP(uint64_t value) { _registers.__srr0 = value; } 1137 1138 private: 1139 struct ppc64_thread_state_t { 1140 uint64_t __srr0; // Instruction address register (PC) 1141 uint64_t __srr1; // Machine state register (supervisor) 1142 uint64_t __r0; 1143 uint64_t __r1; 1144 uint64_t __r2; 1145 uint64_t __r3; 1146 uint64_t __r4; 1147 uint64_t __r5; 1148 uint64_t __r6; 1149 uint64_t __r7; 1150 uint64_t __r8; 1151 uint64_t __r9; 1152 uint64_t __r10; 1153 uint64_t __r11; 1154 uint64_t __r12; 1155 uint64_t __r13; 1156 uint64_t __r14; 1157 uint64_t __r15; 1158 uint64_t __r16; 1159 uint64_t __r17; 1160 uint64_t __r18; 1161 uint64_t __r19; 1162 uint64_t __r20; 1163 uint64_t __r21; 1164 uint64_t __r22; 1165 uint64_t __r23; 1166 uint64_t __r24; 1167 uint64_t __r25; 1168 uint64_t __r26; 1169 uint64_t __r27; 1170 uint64_t __r28; 1171 uint64_t __r29; 1172 uint64_t __r30; 1173 uint64_t __r31; 1174 uint64_t __cr; // Condition register 1175 uint64_t __xer; // User's integer exception register 1176 uint64_t __lr; // Link register 1177 uint64_t __ctr; // Count register 1178 uint64_t __vrsave; // Vector Save Register 1179 }; 1180 1181 union ppc64_vsr_t { 1182 struct asfloat_s { 1183 double f; 1184 uint64_t v2; 1185 } asfloat; 1186 v128 v; 1187 }; 1188 1189 ppc64_thread_state_t _registers; 1190 ppc64_vsr_t _vectorScalarRegisters[64]; 1191 1192 static int getVectorRegNum(int num); 1193 }; 1194 1195 inline Registers_ppc64::Registers_ppc64(const void *registers) { 1196 static_assert((check_fit<Registers_ppc64, unw_context_t>::does_fit), 1197 "ppc64 registers do not fit into unw_context_t"); 1198 memcpy(&_registers, static_cast<const uint8_t *>(registers), 1199 sizeof(_registers)); 1200 static_assert(sizeof(_registers) == 312, 1201 "expected vector scalar register offset to be 312"); 1202 memcpy(&_vectorScalarRegisters, 1203 static_cast<const uint8_t *>(registers) + sizeof(_registers), 1204 sizeof(_vectorScalarRegisters)); 1205 static_assert(sizeof(_registers) + 1206 sizeof(_vectorScalarRegisters) == 1336, 1207 "expected vector register offset to be 1336 bytes"); 1208 } 1209 1210 inline Registers_ppc64::Registers_ppc64() { 1211 memset(&_registers, 0, sizeof(_registers)); 1212 memset(&_vectorScalarRegisters, 0, sizeof(_vectorScalarRegisters)); 1213 } 1214 1215 inline bool Registers_ppc64::validRegister(int regNum) const { 1216 switch (regNum) { 1217 case UNW_REG_IP: 1218 case UNW_REG_SP: 1219 case UNW_PPC64_XER: 1220 case UNW_PPC64_LR: 1221 case UNW_PPC64_CTR: 1222 case UNW_PPC64_VRSAVE: 1223 return true; 1224 } 1225 1226 if (regNum >= UNW_PPC64_R0 && regNum <= UNW_PPC64_R31) 1227 return true; 1228 if (regNum >= UNW_PPC64_CR0 && regNum <= UNW_PPC64_CR7) 1229 return true; 1230 1231 return false; 1232 } 1233 1234 inline uint64_t Registers_ppc64::getRegister(int regNum) const { 1235 switch (regNum) { 1236 case UNW_REG_IP: 1237 return _registers.__srr0; 1238 case UNW_PPC64_R0: 1239 return _registers.__r0; 1240 case UNW_PPC64_R1: 1241 case UNW_REG_SP: 1242 return _registers.__r1; 1243 case UNW_PPC64_R2: 1244 return _registers.__r2; 1245 case UNW_PPC64_R3: 1246 return _registers.__r3; 1247 case UNW_PPC64_R4: 1248 return _registers.__r4; 1249 case UNW_PPC64_R5: 1250 return _registers.__r5; 1251 case UNW_PPC64_R6: 1252 return _registers.__r6; 1253 case UNW_PPC64_R7: 1254 return _registers.__r7; 1255 case UNW_PPC64_R8: 1256 return _registers.__r8; 1257 case UNW_PPC64_R9: 1258 return _registers.__r9; 1259 case UNW_PPC64_R10: 1260 return _registers.__r10; 1261 case UNW_PPC64_R11: 1262 return _registers.__r11; 1263 case UNW_PPC64_R12: 1264 return _registers.__r12; 1265 case UNW_PPC64_R13: 1266 return _registers.__r13; 1267 case UNW_PPC64_R14: 1268 return _registers.__r14; 1269 case UNW_PPC64_R15: 1270 return _registers.__r15; 1271 case UNW_PPC64_R16: 1272 return _registers.__r16; 1273 case UNW_PPC64_R17: 1274 return _registers.__r17; 1275 case UNW_PPC64_R18: 1276 return _registers.__r18; 1277 case UNW_PPC64_R19: 1278 return _registers.__r19; 1279 case UNW_PPC64_R20: 1280 return _registers.__r20; 1281 case UNW_PPC64_R21: 1282 return _registers.__r21; 1283 case UNW_PPC64_R22: 1284 return _registers.__r22; 1285 case UNW_PPC64_R23: 1286 return _registers.__r23; 1287 case UNW_PPC64_R24: 1288 return _registers.__r24; 1289 case UNW_PPC64_R25: 1290 return _registers.__r25; 1291 case UNW_PPC64_R26: 1292 return _registers.__r26; 1293 case UNW_PPC64_R27: 1294 return _registers.__r27; 1295 case UNW_PPC64_R28: 1296 return _registers.__r28; 1297 case UNW_PPC64_R29: 1298 return _registers.__r29; 1299 case UNW_PPC64_R30: 1300 return _registers.__r30; 1301 case UNW_PPC64_R31: 1302 return _registers.__r31; 1303 case UNW_PPC64_CR0: 1304 return (_registers.__cr & 0xF0000000); 1305 case UNW_PPC64_CR1: 1306 return (_registers.__cr & 0x0F000000); 1307 case UNW_PPC64_CR2: 1308 return (_registers.__cr & 0x00F00000); 1309 case UNW_PPC64_CR3: 1310 return (_registers.__cr & 0x000F0000); 1311 case UNW_PPC64_CR4: 1312 return (_registers.__cr & 0x0000F000); 1313 case UNW_PPC64_CR5: 1314 return (_registers.__cr & 0x00000F00); 1315 case UNW_PPC64_CR6: 1316 return (_registers.__cr & 0x000000F0); 1317 case UNW_PPC64_CR7: 1318 return (_registers.__cr & 0x0000000F); 1319 case UNW_PPC64_XER: 1320 return _registers.__xer; 1321 case UNW_PPC64_LR: 1322 return _registers.__lr; 1323 case UNW_PPC64_CTR: 1324 return _registers.__ctr; 1325 case UNW_PPC64_VRSAVE: 1326 return _registers.__vrsave; 1327 } 1328 _LIBUNWIND_ABORT("unsupported ppc64 register"); 1329 } 1330 1331 inline void Registers_ppc64::setRegister(int regNum, uint64_t value) { 1332 switch (regNum) { 1333 case UNW_REG_IP: 1334 _registers.__srr0 = value; 1335 return; 1336 case UNW_PPC64_R0: 1337 _registers.__r0 = value; 1338 return; 1339 case UNW_PPC64_R1: 1340 case UNW_REG_SP: 1341 _registers.__r1 = value; 1342 return; 1343 case UNW_PPC64_R2: 1344 _registers.__r2 = value; 1345 return; 1346 case UNW_PPC64_R3: 1347 _registers.__r3 = value; 1348 return; 1349 case UNW_PPC64_R4: 1350 _registers.__r4 = value; 1351 return; 1352 case UNW_PPC64_R5: 1353 _registers.__r5 = value; 1354 return; 1355 case UNW_PPC64_R6: 1356 _registers.__r6 = value; 1357 return; 1358 case UNW_PPC64_R7: 1359 _registers.__r7 = value; 1360 return; 1361 case UNW_PPC64_R8: 1362 _registers.__r8 = value; 1363 return; 1364 case UNW_PPC64_R9: 1365 _registers.__r9 = value; 1366 return; 1367 case UNW_PPC64_R10: 1368 _registers.__r10 = value; 1369 return; 1370 case UNW_PPC64_R11: 1371 _registers.__r11 = value; 1372 return; 1373 case UNW_PPC64_R12: 1374 _registers.__r12 = value; 1375 return; 1376 case UNW_PPC64_R13: 1377 _registers.__r13 = value; 1378 return; 1379 case UNW_PPC64_R14: 1380 _registers.__r14 = value; 1381 return; 1382 case UNW_PPC64_R15: 1383 _registers.__r15 = value; 1384 return; 1385 case UNW_PPC64_R16: 1386 _registers.__r16 = value; 1387 return; 1388 case UNW_PPC64_R17: 1389 _registers.__r17 = value; 1390 return; 1391 case UNW_PPC64_R18: 1392 _registers.__r18 = value; 1393 return; 1394 case UNW_PPC64_R19: 1395 _registers.__r19 = value; 1396 return; 1397 case UNW_PPC64_R20: 1398 _registers.__r20 = value; 1399 return; 1400 case UNW_PPC64_R21: 1401 _registers.__r21 = value; 1402 return; 1403 case UNW_PPC64_R22: 1404 _registers.__r22 = value; 1405 return; 1406 case UNW_PPC64_R23: 1407 _registers.__r23 = value; 1408 return; 1409 case UNW_PPC64_R24: 1410 _registers.__r24 = value; 1411 return; 1412 case UNW_PPC64_R25: 1413 _registers.__r25 = value; 1414 return; 1415 case UNW_PPC64_R26: 1416 _registers.__r26 = value; 1417 return; 1418 case UNW_PPC64_R27: 1419 _registers.__r27 = value; 1420 return; 1421 case UNW_PPC64_R28: 1422 _registers.__r28 = value; 1423 return; 1424 case UNW_PPC64_R29: 1425 _registers.__r29 = value; 1426 return; 1427 case UNW_PPC64_R30: 1428 _registers.__r30 = value; 1429 return; 1430 case UNW_PPC64_R31: 1431 _registers.__r31 = value; 1432 return; 1433 case UNW_PPC64_CR0: 1434 _registers.__cr &= 0x0FFFFFFF; 1435 _registers.__cr |= (value & 0xF0000000); 1436 return; 1437 case UNW_PPC64_CR1: 1438 _registers.__cr &= 0xF0FFFFFF; 1439 _registers.__cr |= (value & 0x0F000000); 1440 return; 1441 case UNW_PPC64_CR2: 1442 _registers.__cr &= 0xFF0FFFFF; 1443 _registers.__cr |= (value & 0x00F00000); 1444 return; 1445 case UNW_PPC64_CR3: 1446 _registers.__cr &= 0xFFF0FFFF; 1447 _registers.__cr |= (value & 0x000F0000); 1448 return; 1449 case UNW_PPC64_CR4: 1450 _registers.__cr &= 0xFFFF0FFF; 1451 _registers.__cr |= (value & 0x0000F000); 1452 return; 1453 case UNW_PPC64_CR5: 1454 _registers.__cr &= 0xFFFFF0FF; 1455 _registers.__cr |= (value & 0x00000F00); 1456 return; 1457 case UNW_PPC64_CR6: 1458 _registers.__cr &= 0xFFFFFF0F; 1459 _registers.__cr |= (value & 0x000000F0); 1460 return; 1461 case UNW_PPC64_CR7: 1462 _registers.__cr &= 0xFFFFFFF0; 1463 _registers.__cr |= (value & 0x0000000F); 1464 return; 1465 case UNW_PPC64_XER: 1466 _registers.__xer = value; 1467 return; 1468 case UNW_PPC64_LR: 1469 _registers.__lr = value; 1470 return; 1471 case UNW_PPC64_CTR: 1472 _registers.__ctr = value; 1473 return; 1474 case UNW_PPC64_VRSAVE: 1475 _registers.__vrsave = value; 1476 return; 1477 } 1478 _LIBUNWIND_ABORT("unsupported ppc64 register"); 1479 } 1480 1481 inline bool Registers_ppc64::validFloatRegister(int regNum) const { 1482 return regNum >= UNW_PPC64_F0 && regNum <= UNW_PPC64_F31; 1483 } 1484 1485 inline double Registers_ppc64::getFloatRegister(int regNum) const { 1486 assert(validFloatRegister(regNum)); 1487 return _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f; 1488 } 1489 1490 inline void Registers_ppc64::setFloatRegister(int regNum, double value) { 1491 assert(validFloatRegister(regNum)); 1492 _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f = value; 1493 } 1494 1495 inline bool Registers_ppc64::validVectorRegister(int regNum) const { 1496 #ifdef PPC64_HAS_VMX 1497 if (regNum >= UNW_PPC64_VS0 && regNum <= UNW_PPC64_VS31) 1498 return true; 1499 if (regNum >= UNW_PPC64_VS32 && regNum <= UNW_PPC64_VS63) 1500 return true; 1501 #else 1502 if (regNum >= UNW_PPC64_V0 && regNum <= UNW_PPC64_V31) 1503 return true; 1504 #endif 1505 return false; 1506 } 1507 1508 inline int Registers_ppc64::getVectorRegNum(int num) 1509 { 1510 if (num >= UNW_PPC64_VS0 && num <= UNW_PPC64_VS31) 1511 return num - UNW_PPC64_VS0; 1512 else 1513 return num - UNW_PPC64_VS32 + 32; 1514 } 1515 1516 inline v128 Registers_ppc64::getVectorRegister(int regNum) const { 1517 assert(validVectorRegister(regNum)); 1518 return _vectorScalarRegisters[getVectorRegNum(regNum)].v; 1519 } 1520 1521 inline void Registers_ppc64::setVectorRegister(int regNum, v128 value) { 1522 assert(validVectorRegister(regNum)); 1523 _vectorScalarRegisters[getVectorRegNum(regNum)].v = value; 1524 } 1525 1526 inline const char *Registers_ppc64::getRegisterName(int regNum) { 1527 switch (regNum) { 1528 case UNW_REG_IP: 1529 return "ip"; 1530 case UNW_REG_SP: 1531 return "sp"; 1532 case UNW_PPC64_R0: 1533 return "r0"; 1534 case UNW_PPC64_R1: 1535 return "r1"; 1536 case UNW_PPC64_R2: 1537 return "r2"; 1538 case UNW_PPC64_R3: 1539 return "r3"; 1540 case UNW_PPC64_R4: 1541 return "r4"; 1542 case UNW_PPC64_R5: 1543 return "r5"; 1544 case UNW_PPC64_R6: 1545 return "r6"; 1546 case UNW_PPC64_R7: 1547 return "r7"; 1548 case UNW_PPC64_R8: 1549 return "r8"; 1550 case UNW_PPC64_R9: 1551 return "r9"; 1552 case UNW_PPC64_R10: 1553 return "r10"; 1554 case UNW_PPC64_R11: 1555 return "r11"; 1556 case UNW_PPC64_R12: 1557 return "r12"; 1558 case UNW_PPC64_R13: 1559 return "r13"; 1560 case UNW_PPC64_R14: 1561 return "r14"; 1562 case UNW_PPC64_R15: 1563 return "r15"; 1564 case UNW_PPC64_R16: 1565 return "r16"; 1566 case UNW_PPC64_R17: 1567 return "r17"; 1568 case UNW_PPC64_R18: 1569 return "r18"; 1570 case UNW_PPC64_R19: 1571 return "r19"; 1572 case UNW_PPC64_R20: 1573 return "r20"; 1574 case UNW_PPC64_R21: 1575 return "r21"; 1576 case UNW_PPC64_R22: 1577 return "r22"; 1578 case UNW_PPC64_R23: 1579 return "r23"; 1580 case UNW_PPC64_R24: 1581 return "r24"; 1582 case UNW_PPC64_R25: 1583 return "r25"; 1584 case UNW_PPC64_R26: 1585 return "r26"; 1586 case UNW_PPC64_R27: 1587 return "r27"; 1588 case UNW_PPC64_R28: 1589 return "r28"; 1590 case UNW_PPC64_R29: 1591 return "r29"; 1592 case UNW_PPC64_R30: 1593 return "r30"; 1594 case UNW_PPC64_R31: 1595 return "r31"; 1596 case UNW_PPC64_CR0: 1597 return "cr0"; 1598 case UNW_PPC64_CR1: 1599 return "cr1"; 1600 case UNW_PPC64_CR2: 1601 return "cr2"; 1602 case UNW_PPC64_CR3: 1603 return "cr3"; 1604 case UNW_PPC64_CR4: 1605 return "cr4"; 1606 case UNW_PPC64_CR5: 1607 return "cr5"; 1608 case UNW_PPC64_CR6: 1609 return "cr6"; 1610 case UNW_PPC64_CR7: 1611 return "cr7"; 1612 case UNW_PPC64_XER: 1613 return "xer"; 1614 case UNW_PPC64_LR: 1615 return "lr"; 1616 case UNW_PPC64_CTR: 1617 return "ctr"; 1618 case UNW_PPC64_VRSAVE: 1619 return "vrsave"; 1620 case UNW_PPC64_F0: 1621 return "fp0"; 1622 case UNW_PPC64_F1: 1623 return "fp1"; 1624 case UNW_PPC64_F2: 1625 return "fp2"; 1626 case UNW_PPC64_F3: 1627 return "fp3"; 1628 case UNW_PPC64_F4: 1629 return "fp4"; 1630 case UNW_PPC64_F5: 1631 return "fp5"; 1632 case UNW_PPC64_F6: 1633 return "fp6"; 1634 case UNW_PPC64_F7: 1635 return "fp7"; 1636 case UNW_PPC64_F8: 1637 return "fp8"; 1638 case UNW_PPC64_F9: 1639 return "fp9"; 1640 case UNW_PPC64_F10: 1641 return "fp10"; 1642 case UNW_PPC64_F11: 1643 return "fp11"; 1644 case UNW_PPC64_F12: 1645 return "fp12"; 1646 case UNW_PPC64_F13: 1647 return "fp13"; 1648 case UNW_PPC64_F14: 1649 return "fp14"; 1650 case UNW_PPC64_F15: 1651 return "fp15"; 1652 case UNW_PPC64_F16: 1653 return "fp16"; 1654 case UNW_PPC64_F17: 1655 return "fp17"; 1656 case UNW_PPC64_F18: 1657 return "fp18"; 1658 case UNW_PPC64_F19: 1659 return "fp19"; 1660 case UNW_PPC64_F20: 1661 return "fp20"; 1662 case UNW_PPC64_F21: 1663 return "fp21"; 1664 case UNW_PPC64_F22: 1665 return "fp22"; 1666 case UNW_PPC64_F23: 1667 return "fp23"; 1668 case UNW_PPC64_F24: 1669 return "fp24"; 1670 case UNW_PPC64_F25: 1671 return "fp25"; 1672 case UNW_PPC64_F26: 1673 return "fp26"; 1674 case UNW_PPC64_F27: 1675 return "fp27"; 1676 case UNW_PPC64_F28: 1677 return "fp28"; 1678 case UNW_PPC64_F29: 1679 return "fp29"; 1680 case UNW_PPC64_F30: 1681 return "fp30"; 1682 case UNW_PPC64_F31: 1683 return "fp31"; 1684 case UNW_PPC64_V0: 1685 return "v0"; 1686 case UNW_PPC64_V1: 1687 return "v1"; 1688 case UNW_PPC64_V2: 1689 return "v2"; 1690 case UNW_PPC64_V3: 1691 return "v3"; 1692 case UNW_PPC64_V4: 1693 return "v4"; 1694 case UNW_PPC64_V5: 1695 return "v5"; 1696 case UNW_PPC64_V6: 1697 return "v6"; 1698 case UNW_PPC64_V7: 1699 return "v7"; 1700 case UNW_PPC64_V8: 1701 return "v8"; 1702 case UNW_PPC64_V9: 1703 return "v9"; 1704 case UNW_PPC64_V10: 1705 return "v10"; 1706 case UNW_PPC64_V11: 1707 return "v11"; 1708 case UNW_PPC64_V12: 1709 return "v12"; 1710 case UNW_PPC64_V13: 1711 return "v13"; 1712 case UNW_PPC64_V14: 1713 return "v14"; 1714 case UNW_PPC64_V15: 1715 return "v15"; 1716 case UNW_PPC64_V16: 1717 return "v16"; 1718 case UNW_PPC64_V17: 1719 return "v17"; 1720 case UNW_PPC64_V18: 1721 return "v18"; 1722 case UNW_PPC64_V19: 1723 return "v19"; 1724 case UNW_PPC64_V20: 1725 return "v20"; 1726 case UNW_PPC64_V21: 1727 return "v21"; 1728 case UNW_PPC64_V22: 1729 return "v22"; 1730 case UNW_PPC64_V23: 1731 return "v23"; 1732 case UNW_PPC64_V24: 1733 return "v24"; 1734 case UNW_PPC64_V25: 1735 return "v25"; 1736 case UNW_PPC64_V26: 1737 return "v26"; 1738 case UNW_PPC64_V27: 1739 return "v27"; 1740 case UNW_PPC64_V28: 1741 return "v28"; 1742 case UNW_PPC64_V29: 1743 return "v29"; 1744 case UNW_PPC64_V30: 1745 return "v30"; 1746 case UNW_PPC64_V31: 1747 return "v31"; 1748 } 1749 return "unknown register"; 1750 } 1751 #endif // _LIBUNWIND_TARGET_PPC64 1752 1753 1754 #if defined(_LIBUNWIND_TARGET_AARCH64) 1755 /// Registers_arm64 holds the register state of a thread in a 64-bit arm 1756 /// process. 1757 class _LIBUNWIND_HIDDEN Registers_arm64 { 1758 public: 1759 Registers_arm64(); 1760 Registers_arm64(const void *registers); 1761 1762 bool validRegister(int num) const; 1763 uint64_t getRegister(int num) const; 1764 void setRegister(int num, uint64_t value); 1765 bool validFloatRegister(int num) const; 1766 double getFloatRegister(int num) const; 1767 void setFloatRegister(int num, double value); 1768 bool validVectorRegister(int num) const; 1769 v128 getVectorRegister(int num) const; 1770 void setVectorRegister(int num, v128 value); 1771 const char *getRegisterName(int num); 1772 void jumpto(); 1773 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64; } 1774 1775 uint64_t getSP() const { return _registers.__sp; } 1776 void setSP(uint64_t value) { _registers.__sp = value; } 1777 uint64_t getIP() const { return _registers.__pc; } 1778 void setIP(uint64_t value) { _registers.__pc = value; } 1779 uint64_t getFP() const { return _registers.__fp; } 1780 void setFP(uint64_t value) { _registers.__fp = value; } 1781 1782 private: 1783 struct GPRs { 1784 uint64_t __x[29]; // x0-x28 1785 uint64_t __fp; // Frame pointer x29 1786 uint64_t __lr; // Link register x30 1787 uint64_t __sp; // Stack pointer x31 1788 uint64_t __pc; // Program counter 1789 uint64_t padding; // 16-byte align 1790 }; 1791 1792 GPRs _registers; 1793 double _vectorHalfRegisters[32]; 1794 // Currently only the lower double in 128-bit vectore registers 1795 // is perserved during unwinding. We could define new register 1796 // numbers (> 96) which mean whole vector registers, then this 1797 // struct would need to change to contain whole vector registers. 1798 }; 1799 1800 inline Registers_arm64::Registers_arm64(const void *registers) { 1801 static_assert((check_fit<Registers_arm64, unw_context_t>::does_fit), 1802 "arm64 registers do not fit into unw_context_t"); 1803 memcpy(&_registers, registers, sizeof(_registers)); 1804 static_assert(sizeof(GPRs) == 0x110, 1805 "expected VFP registers to be at offset 272"); 1806 memcpy(_vectorHalfRegisters, 1807 static_cast<const uint8_t *>(registers) + sizeof(GPRs), 1808 sizeof(_vectorHalfRegisters)); 1809 } 1810 1811 inline Registers_arm64::Registers_arm64() { 1812 memset(&_registers, 0, sizeof(_registers)); 1813 memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters)); 1814 } 1815 1816 inline bool Registers_arm64::validRegister(int regNum) const { 1817 if (regNum == UNW_REG_IP) 1818 return true; 1819 if (regNum == UNW_REG_SP) 1820 return true; 1821 if (regNum < 0) 1822 return false; 1823 if (regNum > 95) 1824 return false; 1825 if ((regNum > 31) && (regNum < 64)) 1826 return false; 1827 return true; 1828 } 1829 1830 inline uint64_t Registers_arm64::getRegister(int regNum) const { 1831 if (regNum == UNW_REG_IP) 1832 return _registers.__pc; 1833 if (regNum == UNW_REG_SP) 1834 return _registers.__sp; 1835 if ((regNum >= 0) && (regNum < 32)) 1836 return _registers.__x[regNum]; 1837 _LIBUNWIND_ABORT("unsupported arm64 register"); 1838 } 1839 1840 inline void Registers_arm64::setRegister(int regNum, uint64_t value) { 1841 if (regNum == UNW_REG_IP) 1842 _registers.__pc = value; 1843 else if (regNum == UNW_REG_SP) 1844 _registers.__sp = value; 1845 else if ((regNum >= 0) && (regNum < 32)) 1846 _registers.__x[regNum] = value; 1847 else 1848 _LIBUNWIND_ABORT("unsupported arm64 register"); 1849 } 1850 1851 inline const char *Registers_arm64::getRegisterName(int regNum) { 1852 switch (regNum) { 1853 case UNW_REG_IP: 1854 return "pc"; 1855 case UNW_REG_SP: 1856 return "sp"; 1857 case UNW_ARM64_X0: 1858 return "x0"; 1859 case UNW_ARM64_X1: 1860 return "x1"; 1861 case UNW_ARM64_X2: 1862 return "x2"; 1863 case UNW_ARM64_X3: 1864 return "x3"; 1865 case UNW_ARM64_X4: 1866 return "x4"; 1867 case UNW_ARM64_X5: 1868 return "x5"; 1869 case UNW_ARM64_X6: 1870 return "x6"; 1871 case UNW_ARM64_X7: 1872 return "x7"; 1873 case UNW_ARM64_X8: 1874 return "x8"; 1875 case UNW_ARM64_X9: 1876 return "x9"; 1877 case UNW_ARM64_X10: 1878 return "x10"; 1879 case UNW_ARM64_X11: 1880 return "x11"; 1881 case UNW_ARM64_X12: 1882 return "x12"; 1883 case UNW_ARM64_X13: 1884 return "x13"; 1885 case UNW_ARM64_X14: 1886 return "x14"; 1887 case UNW_ARM64_X15: 1888 return "x15"; 1889 case UNW_ARM64_X16: 1890 return "x16"; 1891 case UNW_ARM64_X17: 1892 return "x17"; 1893 case UNW_ARM64_X18: 1894 return "x18"; 1895 case UNW_ARM64_X19: 1896 return "x19"; 1897 case UNW_ARM64_X20: 1898 return "x20"; 1899 case UNW_ARM64_X21: 1900 return "x21"; 1901 case UNW_ARM64_X22: 1902 return "x22"; 1903 case UNW_ARM64_X23: 1904 return "x23"; 1905 case UNW_ARM64_X24: 1906 return "x24"; 1907 case UNW_ARM64_X25: 1908 return "x25"; 1909 case UNW_ARM64_X26: 1910 return "x26"; 1911 case UNW_ARM64_X27: 1912 return "x27"; 1913 case UNW_ARM64_X28: 1914 return "x28"; 1915 case UNW_ARM64_X29: 1916 return "fp"; 1917 case UNW_ARM64_X30: 1918 return "lr"; 1919 case UNW_ARM64_X31: 1920 return "sp"; 1921 case UNW_ARM64_D0: 1922 return "d0"; 1923 case UNW_ARM64_D1: 1924 return "d1"; 1925 case UNW_ARM64_D2: 1926 return "d2"; 1927 case UNW_ARM64_D3: 1928 return "d3"; 1929 case UNW_ARM64_D4: 1930 return "d4"; 1931 case UNW_ARM64_D5: 1932 return "d5"; 1933 case UNW_ARM64_D6: 1934 return "d6"; 1935 case UNW_ARM64_D7: 1936 return "d7"; 1937 case UNW_ARM64_D8: 1938 return "d8"; 1939 case UNW_ARM64_D9: 1940 return "d9"; 1941 case UNW_ARM64_D10: 1942 return "d10"; 1943 case UNW_ARM64_D11: 1944 return "d11"; 1945 case UNW_ARM64_D12: 1946 return "d12"; 1947 case UNW_ARM64_D13: 1948 return "d13"; 1949 case UNW_ARM64_D14: 1950 return "d14"; 1951 case UNW_ARM64_D15: 1952 return "d15"; 1953 case UNW_ARM64_D16: 1954 return "d16"; 1955 case UNW_ARM64_D17: 1956 return "d17"; 1957 case UNW_ARM64_D18: 1958 return "d18"; 1959 case UNW_ARM64_D19: 1960 return "d19"; 1961 case UNW_ARM64_D20: 1962 return "d20"; 1963 case UNW_ARM64_D21: 1964 return "d21"; 1965 case UNW_ARM64_D22: 1966 return "d22"; 1967 case UNW_ARM64_D23: 1968 return "d23"; 1969 case UNW_ARM64_D24: 1970 return "d24"; 1971 case UNW_ARM64_D25: 1972 return "d25"; 1973 case UNW_ARM64_D26: 1974 return "d26"; 1975 case UNW_ARM64_D27: 1976 return "d27"; 1977 case UNW_ARM64_D28: 1978 return "d28"; 1979 case UNW_ARM64_D29: 1980 return "d29"; 1981 case UNW_ARM64_D30: 1982 return "d30"; 1983 case UNW_ARM64_D31: 1984 return "d31"; 1985 default: 1986 return "unknown register"; 1987 } 1988 } 1989 1990 inline bool Registers_arm64::validFloatRegister(int regNum) const { 1991 if (regNum < UNW_ARM64_D0) 1992 return false; 1993 if (regNum > UNW_ARM64_D31) 1994 return false; 1995 return true; 1996 } 1997 1998 inline double Registers_arm64::getFloatRegister(int regNum) const { 1999 assert(validFloatRegister(regNum)); 2000 return _vectorHalfRegisters[regNum - UNW_ARM64_D0]; 2001 } 2002 2003 inline void Registers_arm64::setFloatRegister(int regNum, double value) { 2004 assert(validFloatRegister(regNum)); 2005 _vectorHalfRegisters[regNum - UNW_ARM64_D0] = value; 2006 } 2007 2008 inline bool Registers_arm64::validVectorRegister(int) const { 2009 return false; 2010 } 2011 2012 inline v128 Registers_arm64::getVectorRegister(int) const { 2013 _LIBUNWIND_ABORT("no arm64 vector register support yet"); 2014 } 2015 2016 inline void Registers_arm64::setVectorRegister(int, v128) { 2017 _LIBUNWIND_ABORT("no arm64 vector register support yet"); 2018 } 2019 #endif // _LIBUNWIND_TARGET_AARCH64 2020 2021 #if defined(_LIBUNWIND_TARGET_ARM) 2022 /// Registers_arm holds the register state of a thread in a 32-bit arm 2023 /// process. 2024 /// 2025 /// NOTE: Assumes VFPv3. On ARM processors without a floating point unit, 2026 /// this uses more memory than required. 2027 class _LIBUNWIND_HIDDEN Registers_arm { 2028 public: 2029 Registers_arm(); 2030 Registers_arm(const void *registers); 2031 2032 bool validRegister(int num) const; 2033 uint32_t getRegister(int num) const; 2034 void setRegister(int num, uint32_t value); 2035 bool validFloatRegister(int num) const; 2036 unw_fpreg_t getFloatRegister(int num); 2037 void setFloatRegister(int num, unw_fpreg_t value); 2038 bool validVectorRegister(int num) const; 2039 v128 getVectorRegister(int num) const; 2040 void setVectorRegister(int num, v128 value); 2041 const char *getRegisterName(int num); 2042 void jumpto() { 2043 restoreSavedFloatRegisters(); 2044 restoreCoreAndJumpTo(); 2045 } 2046 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM; } 2047 2048 uint32_t getSP() const { return _registers.__sp; } 2049 void setSP(uint32_t value) { _registers.__sp = value; } 2050 uint32_t getIP() const { return _registers.__pc; } 2051 void setIP(uint32_t value) { _registers.__pc = value; } 2052 2053 void saveVFPAsX() { 2054 assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15); 2055 _use_X_for_vfp_save = true; 2056 } 2057 2058 void restoreSavedFloatRegisters() { 2059 if (_saved_vfp_d0_d15) { 2060 if (_use_X_for_vfp_save) 2061 restoreVFPWithFLDMX(_vfp_d0_d15_pad); 2062 else 2063 restoreVFPWithFLDMD(_vfp_d0_d15_pad); 2064 } 2065 if (_saved_vfp_d16_d31) 2066 restoreVFPv3(_vfp_d16_d31); 2067 #if defined(__ARM_WMMX) 2068 if (_saved_iwmmx) 2069 restoreiWMMX(_iwmmx); 2070 if (_saved_iwmmx_control) 2071 restoreiWMMXControl(_iwmmx_control); 2072 #endif 2073 } 2074 2075 private: 2076 struct GPRs { 2077 uint32_t __r[13]; // r0-r12 2078 uint32_t __sp; // Stack pointer r13 2079 uint32_t __lr; // Link register r14 2080 uint32_t __pc; // Program counter r15 2081 }; 2082 2083 static void saveVFPWithFSTMD(unw_fpreg_t*); 2084 static void saveVFPWithFSTMX(unw_fpreg_t*); 2085 static void saveVFPv3(unw_fpreg_t*); 2086 static void restoreVFPWithFLDMD(unw_fpreg_t*); 2087 static void restoreVFPWithFLDMX(unw_fpreg_t*); 2088 static void restoreVFPv3(unw_fpreg_t*); 2089 #if defined(__ARM_WMMX) 2090 static void saveiWMMX(unw_fpreg_t*); 2091 static void saveiWMMXControl(uint32_t*); 2092 static void restoreiWMMX(unw_fpreg_t*); 2093 static void restoreiWMMXControl(uint32_t*); 2094 #endif 2095 void restoreCoreAndJumpTo(); 2096 2097 // ARM registers 2098 GPRs _registers; 2099 2100 // We save floating point registers lazily because we can't know ahead of 2101 // time which ones are used. See EHABI #4.7. 2102 2103 // Whether D0-D15 are saved in the FTSMX instead of FSTMD format. 2104 // 2105 // See EHABI #7.5 that explains how matching instruction sequences for load 2106 // and store need to be used to correctly restore the exact register bits. 2107 bool _use_X_for_vfp_save; 2108 // Whether VFP D0-D15 are saved. 2109 bool _saved_vfp_d0_d15; 2110 // Whether VFPv3 D16-D31 are saved. 2111 bool _saved_vfp_d16_d31; 2112 // VFP registers D0-D15, + padding if saved using FSTMX 2113 unw_fpreg_t _vfp_d0_d15_pad[17]; 2114 // VFPv3 registers D16-D31, always saved using FSTMD 2115 unw_fpreg_t _vfp_d16_d31[16]; 2116 #if defined(__ARM_WMMX) 2117 // Whether iWMMX data registers are saved. 2118 bool _saved_iwmmx; 2119 // Whether iWMMX control registers are saved. 2120 mutable bool _saved_iwmmx_control; 2121 // iWMMX registers 2122 unw_fpreg_t _iwmmx[16]; 2123 // iWMMX control registers 2124 mutable uint32_t _iwmmx_control[4]; 2125 #endif 2126 }; 2127 2128 inline Registers_arm::Registers_arm(const void *registers) 2129 : _use_X_for_vfp_save(false), 2130 _saved_vfp_d0_d15(false), 2131 _saved_vfp_d16_d31(false) { 2132 static_assert((check_fit<Registers_arm, unw_context_t>::does_fit), 2133 "arm registers do not fit into unw_context_t"); 2134 // See unw_getcontext() note about data. 2135 memcpy(&_registers, registers, sizeof(_registers)); 2136 memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad)); 2137 memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31)); 2138 #if defined(__ARM_WMMX) 2139 _saved_iwmmx = false; 2140 _saved_iwmmx_control = false; 2141 memset(&_iwmmx, 0, sizeof(_iwmmx)); 2142 memset(&_iwmmx_control, 0, sizeof(_iwmmx_control)); 2143 #endif 2144 } 2145 2146 inline Registers_arm::Registers_arm() 2147 : _use_X_for_vfp_save(false), 2148 _saved_vfp_d0_d15(false), 2149 _saved_vfp_d16_d31(false) { 2150 memset(&_registers, 0, sizeof(_registers)); 2151 memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad)); 2152 memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31)); 2153 #if defined(__ARM_WMMX) 2154 _saved_iwmmx = false; 2155 _saved_iwmmx_control = false; 2156 memset(&_iwmmx, 0, sizeof(_iwmmx)); 2157 memset(&_iwmmx_control, 0, sizeof(_iwmmx_control)); 2158 #endif 2159 } 2160 2161 inline bool Registers_arm::validRegister(int regNum) const { 2162 // Returns true for all non-VFP registers supported by the EHABI 2163 // virtual register set (VRS). 2164 if (regNum == UNW_REG_IP) 2165 return true; 2166 2167 if (regNum == UNW_REG_SP) 2168 return true; 2169 2170 if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15) 2171 return true; 2172 2173 #if defined(__ARM_WMMX) 2174 if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) 2175 return true; 2176 #endif 2177 2178 return false; 2179 } 2180 2181 inline uint32_t Registers_arm::getRegister(int regNum) const { 2182 if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) 2183 return _registers.__sp; 2184 2185 if (regNum == UNW_ARM_LR) 2186 return _registers.__lr; 2187 2188 if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) 2189 return _registers.__pc; 2190 2191 if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) 2192 return _registers.__r[regNum]; 2193 2194 #if defined(__ARM_WMMX) 2195 if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) { 2196 if (!_saved_iwmmx_control) { 2197 _saved_iwmmx_control = true; 2198 saveiWMMXControl(_iwmmx_control); 2199 } 2200 return _iwmmx_control[regNum - UNW_ARM_WC0]; 2201 } 2202 #endif 2203 2204 _LIBUNWIND_ABORT("unsupported arm register"); 2205 } 2206 2207 inline void Registers_arm::setRegister(int regNum, uint32_t value) { 2208 if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) { 2209 _registers.__sp = value; 2210 return; 2211 } 2212 2213 if (regNum == UNW_ARM_LR) { 2214 _registers.__lr = value; 2215 return; 2216 } 2217 2218 if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) { 2219 _registers.__pc = value; 2220 return; 2221 } 2222 2223 if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) { 2224 _registers.__r[regNum] = value; 2225 return; 2226 } 2227 2228 #if defined(__ARM_WMMX) 2229 if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) { 2230 if (!_saved_iwmmx_control) { 2231 _saved_iwmmx_control = true; 2232 saveiWMMXControl(_iwmmx_control); 2233 } 2234 _iwmmx_control[regNum - UNW_ARM_WC0] = value; 2235 return; 2236 } 2237 #endif 2238 2239 _LIBUNWIND_ABORT("unsupported arm register"); 2240 } 2241 2242 inline const char *Registers_arm::getRegisterName(int regNum) { 2243 switch (regNum) { 2244 case UNW_REG_IP: 2245 case UNW_ARM_IP: // UNW_ARM_R15 is alias 2246 return "pc"; 2247 case UNW_ARM_LR: // UNW_ARM_R14 is alias 2248 return "lr"; 2249 case UNW_REG_SP: 2250 case UNW_ARM_SP: // UNW_ARM_R13 is alias 2251 return "sp"; 2252 case UNW_ARM_R0: 2253 return "r0"; 2254 case UNW_ARM_R1: 2255 return "r1"; 2256 case UNW_ARM_R2: 2257 return "r2"; 2258 case UNW_ARM_R3: 2259 return "r3"; 2260 case UNW_ARM_R4: 2261 return "r4"; 2262 case UNW_ARM_R5: 2263 return "r5"; 2264 case UNW_ARM_R6: 2265 return "r6"; 2266 case UNW_ARM_R7: 2267 return "r7"; 2268 case UNW_ARM_R8: 2269 return "r8"; 2270 case UNW_ARM_R9: 2271 return "r9"; 2272 case UNW_ARM_R10: 2273 return "r10"; 2274 case UNW_ARM_R11: 2275 return "r11"; 2276 case UNW_ARM_R12: 2277 return "r12"; 2278 case UNW_ARM_S0: 2279 return "s0"; 2280 case UNW_ARM_S1: 2281 return "s1"; 2282 case UNW_ARM_S2: 2283 return "s2"; 2284 case UNW_ARM_S3: 2285 return "s3"; 2286 case UNW_ARM_S4: 2287 return "s4"; 2288 case UNW_ARM_S5: 2289 return "s5"; 2290 case UNW_ARM_S6: 2291 return "s6"; 2292 case UNW_ARM_S7: 2293 return "s7"; 2294 case UNW_ARM_S8: 2295 return "s8"; 2296 case UNW_ARM_S9: 2297 return "s9"; 2298 case UNW_ARM_S10: 2299 return "s10"; 2300 case UNW_ARM_S11: 2301 return "s11"; 2302 case UNW_ARM_S12: 2303 return "s12"; 2304 case UNW_ARM_S13: 2305 return "s13"; 2306 case UNW_ARM_S14: 2307 return "s14"; 2308 case UNW_ARM_S15: 2309 return "s15"; 2310 case UNW_ARM_S16: 2311 return "s16"; 2312 case UNW_ARM_S17: 2313 return "s17"; 2314 case UNW_ARM_S18: 2315 return "s18"; 2316 case UNW_ARM_S19: 2317 return "s19"; 2318 case UNW_ARM_S20: 2319 return "s20"; 2320 case UNW_ARM_S21: 2321 return "s21"; 2322 case UNW_ARM_S22: 2323 return "s22"; 2324 case UNW_ARM_S23: 2325 return "s23"; 2326 case UNW_ARM_S24: 2327 return "s24"; 2328 case UNW_ARM_S25: 2329 return "s25"; 2330 case UNW_ARM_S26: 2331 return "s26"; 2332 case UNW_ARM_S27: 2333 return "s27"; 2334 case UNW_ARM_S28: 2335 return "s28"; 2336 case UNW_ARM_S29: 2337 return "s29"; 2338 case UNW_ARM_S30: 2339 return "s30"; 2340 case UNW_ARM_S31: 2341 return "s31"; 2342 case UNW_ARM_D0: 2343 return "d0"; 2344 case UNW_ARM_D1: 2345 return "d1"; 2346 case UNW_ARM_D2: 2347 return "d2"; 2348 case UNW_ARM_D3: 2349 return "d3"; 2350 case UNW_ARM_D4: 2351 return "d4"; 2352 case UNW_ARM_D5: 2353 return "d5"; 2354 case UNW_ARM_D6: 2355 return "d6"; 2356 case UNW_ARM_D7: 2357 return "d7"; 2358 case UNW_ARM_D8: 2359 return "d8"; 2360 case UNW_ARM_D9: 2361 return "d9"; 2362 case UNW_ARM_D10: 2363 return "d10"; 2364 case UNW_ARM_D11: 2365 return "d11"; 2366 case UNW_ARM_D12: 2367 return "d12"; 2368 case UNW_ARM_D13: 2369 return "d13"; 2370 case UNW_ARM_D14: 2371 return "d14"; 2372 case UNW_ARM_D15: 2373 return "d15"; 2374 case UNW_ARM_D16: 2375 return "d16"; 2376 case UNW_ARM_D17: 2377 return "d17"; 2378 case UNW_ARM_D18: 2379 return "d18"; 2380 case UNW_ARM_D19: 2381 return "d19"; 2382 case UNW_ARM_D20: 2383 return "d20"; 2384 case UNW_ARM_D21: 2385 return "d21"; 2386 case UNW_ARM_D22: 2387 return "d22"; 2388 case UNW_ARM_D23: 2389 return "d23"; 2390 case UNW_ARM_D24: 2391 return "d24"; 2392 case UNW_ARM_D25: 2393 return "d25"; 2394 case UNW_ARM_D26: 2395 return "d26"; 2396 case UNW_ARM_D27: 2397 return "d27"; 2398 case UNW_ARM_D28: 2399 return "d28"; 2400 case UNW_ARM_D29: 2401 return "d29"; 2402 case UNW_ARM_D30: 2403 return "d30"; 2404 case UNW_ARM_D31: 2405 return "d31"; 2406 default: 2407 return "unknown register"; 2408 } 2409 } 2410 2411 inline bool Registers_arm::validFloatRegister(int regNum) const { 2412 // NOTE: Consider the intel MMX registers floating points so the 2413 // unw_get_fpreg can be used to transmit the 64-bit data back. 2414 return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31)) 2415 #if defined(__ARM_WMMX) 2416 || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15)) 2417 #endif 2418 ; 2419 } 2420 2421 inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) { 2422 if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) { 2423 if (!_saved_vfp_d0_d15) { 2424 _saved_vfp_d0_d15 = true; 2425 if (_use_X_for_vfp_save) 2426 saveVFPWithFSTMX(_vfp_d0_d15_pad); 2427 else 2428 saveVFPWithFSTMD(_vfp_d0_d15_pad); 2429 } 2430 return _vfp_d0_d15_pad[regNum - UNW_ARM_D0]; 2431 } 2432 2433 if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) { 2434 if (!_saved_vfp_d16_d31) { 2435 _saved_vfp_d16_d31 = true; 2436 saveVFPv3(_vfp_d16_d31); 2437 } 2438 return _vfp_d16_d31[regNum - UNW_ARM_D16]; 2439 } 2440 2441 #if defined(__ARM_WMMX) 2442 if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) { 2443 if (!_saved_iwmmx) { 2444 _saved_iwmmx = true; 2445 saveiWMMX(_iwmmx); 2446 } 2447 return _iwmmx[regNum - UNW_ARM_WR0]; 2448 } 2449 #endif 2450 2451 _LIBUNWIND_ABORT("Unknown ARM float register"); 2452 } 2453 2454 inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) { 2455 if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) { 2456 if (!_saved_vfp_d0_d15) { 2457 _saved_vfp_d0_d15 = true; 2458 if (_use_X_for_vfp_save) 2459 saveVFPWithFSTMX(_vfp_d0_d15_pad); 2460 else 2461 saveVFPWithFSTMD(_vfp_d0_d15_pad); 2462 } 2463 _vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value; 2464 return; 2465 } 2466 2467 if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) { 2468 if (!_saved_vfp_d16_d31) { 2469 _saved_vfp_d16_d31 = true; 2470 saveVFPv3(_vfp_d16_d31); 2471 } 2472 _vfp_d16_d31[regNum - UNW_ARM_D16] = value; 2473 return; 2474 } 2475 2476 #if defined(__ARM_WMMX) 2477 if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) { 2478 if (!_saved_iwmmx) { 2479 _saved_iwmmx = true; 2480 saveiWMMX(_iwmmx); 2481 } 2482 _iwmmx[regNum - UNW_ARM_WR0] = value; 2483 return; 2484 } 2485 #endif 2486 2487 _LIBUNWIND_ABORT("Unknown ARM float register"); 2488 } 2489 2490 inline bool Registers_arm::validVectorRegister(int) const { 2491 return false; 2492 } 2493 2494 inline v128 Registers_arm::getVectorRegister(int) const { 2495 _LIBUNWIND_ABORT("ARM vector support not implemented"); 2496 } 2497 2498 inline void Registers_arm::setVectorRegister(int, v128) { 2499 _LIBUNWIND_ABORT("ARM vector support not implemented"); 2500 } 2501 #endif // _LIBUNWIND_TARGET_ARM 2502 2503 2504 #if defined(_LIBUNWIND_TARGET_OR1K) 2505 /// Registers_or1k holds the register state of a thread in an OpenRISC1000 2506 /// process. 2507 class _LIBUNWIND_HIDDEN Registers_or1k { 2508 public: 2509 Registers_or1k(); 2510 Registers_or1k(const void *registers); 2511 2512 bool validRegister(int num) const; 2513 uint32_t getRegister(int num) const; 2514 void setRegister(int num, uint32_t value); 2515 bool validFloatRegister(int num) const; 2516 double getFloatRegister(int num) const; 2517 void setFloatRegister(int num, double value); 2518 bool validVectorRegister(int num) const; 2519 v128 getVectorRegister(int num) const; 2520 void setVectorRegister(int num, v128 value); 2521 const char *getRegisterName(int num); 2522 void jumpto(); 2523 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K; } 2524 2525 uint64_t getSP() const { return _registers.__r[1]; } 2526 void setSP(uint32_t value) { _registers.__r[1] = value; } 2527 uint64_t getIP() const { return _registers.__pc; } 2528 void setIP(uint32_t value) { _registers.__pc = value; } 2529 2530 private: 2531 struct or1k_thread_state_t { 2532 unsigned int __r[32]; // r0-r31 2533 unsigned int __pc; // Program counter 2534 unsigned int __epcr; // Program counter at exception 2535 }; 2536 2537 or1k_thread_state_t _registers; 2538 }; 2539 2540 inline Registers_or1k::Registers_or1k(const void *registers) { 2541 static_assert((check_fit<Registers_or1k, unw_context_t>::does_fit), 2542 "or1k registers do not fit into unw_context_t"); 2543 memcpy(&_registers, static_cast<const uint8_t *>(registers), 2544 sizeof(_registers)); 2545 } 2546 2547 inline Registers_or1k::Registers_or1k() { 2548 memset(&_registers, 0, sizeof(_registers)); 2549 } 2550 2551 inline bool Registers_or1k::validRegister(int regNum) const { 2552 if (regNum == UNW_REG_IP) 2553 return true; 2554 if (regNum == UNW_REG_SP) 2555 return true; 2556 if (regNum < 0) 2557 return false; 2558 if (regNum <= UNW_OR1K_R31) 2559 return true; 2560 if (regNum == UNW_OR1K_EPCR) 2561 return true; 2562 return false; 2563 } 2564 2565 inline uint32_t Registers_or1k::getRegister(int regNum) const { 2566 if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) 2567 return _registers.__r[regNum - UNW_OR1K_R0]; 2568 2569 switch (regNum) { 2570 case UNW_REG_IP: 2571 return _registers.__pc; 2572 case UNW_REG_SP: 2573 return _registers.__r[1]; 2574 case UNW_OR1K_EPCR: 2575 return _registers.__epcr; 2576 } 2577 _LIBUNWIND_ABORT("unsupported or1k register"); 2578 } 2579 2580 inline void Registers_or1k::setRegister(int regNum, uint32_t value) { 2581 if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) { 2582 _registers.__r[regNum - UNW_OR1K_R0] = value; 2583 return; 2584 } 2585 2586 switch (regNum) { 2587 case UNW_REG_IP: 2588 _registers.__pc = value; 2589 return; 2590 case UNW_REG_SP: 2591 _registers.__r[1] = value; 2592 return; 2593 case UNW_OR1K_EPCR: 2594 _registers.__epcr = value; 2595 return; 2596 } 2597 _LIBUNWIND_ABORT("unsupported or1k register"); 2598 } 2599 2600 inline bool Registers_or1k::validFloatRegister(int /* regNum */) const { 2601 return false; 2602 } 2603 2604 inline double Registers_or1k::getFloatRegister(int /* regNum */) const { 2605 _LIBUNWIND_ABORT("or1k float support not implemented"); 2606 } 2607 2608 inline void Registers_or1k::setFloatRegister(int /* regNum */, 2609 double /* value */) { 2610 _LIBUNWIND_ABORT("or1k float support not implemented"); 2611 } 2612 2613 inline bool Registers_or1k::validVectorRegister(int /* regNum */) const { 2614 return false; 2615 } 2616 2617 inline v128 Registers_or1k::getVectorRegister(int /* regNum */) const { 2618 _LIBUNWIND_ABORT("or1k vector support not implemented"); 2619 } 2620 2621 inline void Registers_or1k::setVectorRegister(int /* regNum */, v128 /* value */) { 2622 _LIBUNWIND_ABORT("or1k vector support not implemented"); 2623 } 2624 2625 inline const char *Registers_or1k::getRegisterName(int regNum) { 2626 switch (regNum) { 2627 case UNW_OR1K_R0: 2628 return "r0"; 2629 case UNW_OR1K_R1: 2630 return "r1"; 2631 case UNW_OR1K_R2: 2632 return "r2"; 2633 case UNW_OR1K_R3: 2634 return "r3"; 2635 case UNW_OR1K_R4: 2636 return "r4"; 2637 case UNW_OR1K_R5: 2638 return "r5"; 2639 case UNW_OR1K_R6: 2640 return "r6"; 2641 case UNW_OR1K_R7: 2642 return "r7"; 2643 case UNW_OR1K_R8: 2644 return "r8"; 2645 case UNW_OR1K_R9: 2646 return "r9"; 2647 case UNW_OR1K_R10: 2648 return "r10"; 2649 case UNW_OR1K_R11: 2650 return "r11"; 2651 case UNW_OR1K_R12: 2652 return "r12"; 2653 case UNW_OR1K_R13: 2654 return "r13"; 2655 case UNW_OR1K_R14: 2656 return "r14"; 2657 case UNW_OR1K_R15: 2658 return "r15"; 2659 case UNW_OR1K_R16: 2660 return "r16"; 2661 case UNW_OR1K_R17: 2662 return "r17"; 2663 case UNW_OR1K_R18: 2664 return "r18"; 2665 case UNW_OR1K_R19: 2666 return "r19"; 2667 case UNW_OR1K_R20: 2668 return "r20"; 2669 case UNW_OR1K_R21: 2670 return "r21"; 2671 case UNW_OR1K_R22: 2672 return "r22"; 2673 case UNW_OR1K_R23: 2674 return "r23"; 2675 case UNW_OR1K_R24: 2676 return "r24"; 2677 case UNW_OR1K_R25: 2678 return "r25"; 2679 case UNW_OR1K_R26: 2680 return "r26"; 2681 case UNW_OR1K_R27: 2682 return "r27"; 2683 case UNW_OR1K_R28: 2684 return "r28"; 2685 case UNW_OR1K_R29: 2686 return "r29"; 2687 case UNW_OR1K_R30: 2688 return "r30"; 2689 case UNW_OR1K_R31: 2690 return "r31"; 2691 case UNW_OR1K_EPCR: 2692 return "EPCR"; 2693 default: 2694 return "unknown register"; 2695 } 2696 2697 } 2698 #endif // _LIBUNWIND_TARGET_OR1K 2699 2700 #if defined(_LIBUNWIND_TARGET_MIPS_O32) 2701 /// Registers_mips_o32 holds the register state of a thread in a 32-bit MIPS 2702 /// process. 2703 class _LIBUNWIND_HIDDEN Registers_mips_o32 { 2704 public: 2705 Registers_mips_o32(); 2706 Registers_mips_o32(const void *registers); 2707 2708 bool validRegister(int num) const; 2709 uint32_t getRegister(int num) const; 2710 void setRegister(int num, uint32_t value); 2711 bool validFloatRegister(int num) const; 2712 double getFloatRegister(int num) const; 2713 void setFloatRegister(int num, double value); 2714 bool validVectorRegister(int num) const; 2715 v128 getVectorRegister(int num) const; 2716 void setVectorRegister(int num, v128 value); 2717 const char *getRegisterName(int num); 2718 void jumpto(); 2719 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; } 2720 2721 uint32_t getSP() const { return _registers.__r[29]; } 2722 void setSP(uint32_t value) { _registers.__r[29] = value; } 2723 uint32_t getIP() const { return _registers.__pc; } 2724 void setIP(uint32_t value) { _registers.__pc = value; } 2725 2726 private: 2727 struct mips_o32_thread_state_t { 2728 uint32_t __r[32]; 2729 uint32_t __pc; 2730 uint32_t __hi; 2731 uint32_t __lo; 2732 }; 2733 2734 mips_o32_thread_state_t _registers; 2735 #ifdef __mips_hard_float 2736 /// O32 with 32-bit floating point registers only uses half of this 2737 /// space. However, using the same layout for 32-bit vs 64-bit 2738 /// floating point registers results in a single context size for 2739 /// O32 with hard float. 2740 uint32_t _padding; 2741 double _floats[32]; 2742 #endif 2743 }; 2744 2745 inline Registers_mips_o32::Registers_mips_o32(const void *registers) { 2746 static_assert((check_fit<Registers_mips_o32, unw_context_t>::does_fit), 2747 "mips_o32 registers do not fit into unw_context_t"); 2748 memcpy(&_registers, static_cast<const uint8_t *>(registers), 2749 sizeof(_registers)); 2750 } 2751 2752 inline Registers_mips_o32::Registers_mips_o32() { 2753 memset(&_registers, 0, sizeof(_registers)); 2754 } 2755 2756 inline bool Registers_mips_o32::validRegister(int regNum) const { 2757 if (regNum == UNW_REG_IP) 2758 return true; 2759 if (regNum == UNW_REG_SP) 2760 return true; 2761 if (regNum < 0) 2762 return false; 2763 if (regNum <= UNW_MIPS_R31) 2764 return true; 2765 #if __mips_isa_rev != 6 2766 if (regNum == UNW_MIPS_HI) 2767 return true; 2768 if (regNum == UNW_MIPS_LO) 2769 return true; 2770 #endif 2771 #if defined(__mips_hard_float) && __mips_fpr == 32 2772 if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) 2773 return true; 2774 #endif 2775 // FIXME: DSP accumulator registers, MSA registers 2776 return false; 2777 } 2778 2779 inline uint32_t Registers_mips_o32::getRegister(int regNum) const { 2780 if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) 2781 return _registers.__r[regNum - UNW_MIPS_R0]; 2782 #if defined(__mips_hard_float) && __mips_fpr == 32 2783 if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) { 2784 uint32_t *p; 2785 2786 if (regNum % 2 == 0) 2787 p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0]; 2788 else 2789 p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1; 2790 return *p; 2791 } 2792 #endif 2793 2794 switch (regNum) { 2795 case UNW_REG_IP: 2796 return _registers.__pc; 2797 case UNW_REG_SP: 2798 return _registers.__r[29]; 2799 case UNW_MIPS_HI: 2800 return _registers.__hi; 2801 case UNW_MIPS_LO: 2802 return _registers.__lo; 2803 } 2804 _LIBUNWIND_ABORT("unsupported mips_o32 register"); 2805 } 2806 2807 inline void Registers_mips_o32::setRegister(int regNum, uint32_t value) { 2808 if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) { 2809 _registers.__r[regNum - UNW_MIPS_R0] = value; 2810 return; 2811 } 2812 #if defined(__mips_hard_float) && __mips_fpr == 32 2813 if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) { 2814 uint32_t *p; 2815 2816 if (regNum % 2 == 0) 2817 p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0]; 2818 else 2819 p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1; 2820 *p = value; 2821 return; 2822 } 2823 #endif 2824 2825 switch (regNum) { 2826 case UNW_REG_IP: 2827 _registers.__pc = value; 2828 return; 2829 case UNW_REG_SP: 2830 _registers.__r[29] = value; 2831 return; 2832 case UNW_MIPS_HI: 2833 _registers.__hi = value; 2834 return; 2835 case UNW_MIPS_LO: 2836 _registers.__lo = value; 2837 return; 2838 } 2839 _LIBUNWIND_ABORT("unsupported mips_o32 register"); 2840 } 2841 2842 inline bool Registers_mips_o32::validFloatRegister(int regNum) const { 2843 #if defined(__mips_hard_float) && __mips_fpr == 64 2844 if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) 2845 return true; 2846 #endif 2847 return false; 2848 } 2849 2850 inline double Registers_mips_o32::getFloatRegister(int regNum) const { 2851 #if defined(__mips_hard_float) && __mips_fpr == 64 2852 assert(validFloatRegister(regNum)); 2853 return _floats[regNum - UNW_MIPS_F0]; 2854 #else 2855 _LIBUNWIND_ABORT("mips_o32 float support not implemented"); 2856 #endif 2857 } 2858 2859 inline void Registers_mips_o32::setFloatRegister(int regNum, 2860 double value) { 2861 #if defined(__mips_hard_float) && __mips_fpr == 64 2862 assert(validFloatRegister(regNum)); 2863 _floats[regNum - UNW_MIPS_F0] = value; 2864 #else 2865 _LIBUNWIND_ABORT("mips_o32 float support not implemented"); 2866 #endif 2867 } 2868 2869 inline bool Registers_mips_o32::validVectorRegister(int /* regNum */) const { 2870 return false; 2871 } 2872 2873 inline v128 Registers_mips_o32::getVectorRegister(int /* regNum */) const { 2874 _LIBUNWIND_ABORT("mips_o32 vector support not implemented"); 2875 } 2876 2877 inline void Registers_mips_o32::setVectorRegister(int /* regNum */, v128 /* value */) { 2878 _LIBUNWIND_ABORT("mips_o32 vector support not implemented"); 2879 } 2880 2881 inline const char *Registers_mips_o32::getRegisterName(int regNum) { 2882 switch (regNum) { 2883 case UNW_MIPS_R0: 2884 return "$0"; 2885 case UNW_MIPS_R1: 2886 return "$1"; 2887 case UNW_MIPS_R2: 2888 return "$2"; 2889 case UNW_MIPS_R3: 2890 return "$3"; 2891 case UNW_MIPS_R4: 2892 return "$4"; 2893 case UNW_MIPS_R5: 2894 return "$5"; 2895 case UNW_MIPS_R6: 2896 return "$6"; 2897 case UNW_MIPS_R7: 2898 return "$7"; 2899 case UNW_MIPS_R8: 2900 return "$8"; 2901 case UNW_MIPS_R9: 2902 return "$9"; 2903 case UNW_MIPS_R10: 2904 return "$10"; 2905 case UNW_MIPS_R11: 2906 return "$11"; 2907 case UNW_MIPS_R12: 2908 return "$12"; 2909 case UNW_MIPS_R13: 2910 return "$13"; 2911 case UNW_MIPS_R14: 2912 return "$14"; 2913 case UNW_MIPS_R15: 2914 return "$15"; 2915 case UNW_MIPS_R16: 2916 return "$16"; 2917 case UNW_MIPS_R17: 2918 return "$17"; 2919 case UNW_MIPS_R18: 2920 return "$18"; 2921 case UNW_MIPS_R19: 2922 return "$19"; 2923 case UNW_MIPS_R20: 2924 return "$20"; 2925 case UNW_MIPS_R21: 2926 return "$21"; 2927 case UNW_MIPS_R22: 2928 return "$22"; 2929 case UNW_MIPS_R23: 2930 return "$23"; 2931 case UNW_MIPS_R24: 2932 return "$24"; 2933 case UNW_MIPS_R25: 2934 return "$25"; 2935 case UNW_MIPS_R26: 2936 return "$26"; 2937 case UNW_MIPS_R27: 2938 return "$27"; 2939 case UNW_MIPS_R28: 2940 return "$28"; 2941 case UNW_MIPS_R29: 2942 return "$29"; 2943 case UNW_MIPS_R30: 2944 return "$30"; 2945 case UNW_MIPS_R31: 2946 return "$31"; 2947 case UNW_MIPS_F0: 2948 return "$f0"; 2949 case UNW_MIPS_F1: 2950 return "$f1"; 2951 case UNW_MIPS_F2: 2952 return "$f2"; 2953 case UNW_MIPS_F3: 2954 return "$f3"; 2955 case UNW_MIPS_F4: 2956 return "$f4"; 2957 case UNW_MIPS_F5: 2958 return "$f5"; 2959 case UNW_MIPS_F6: 2960 return "$f6"; 2961 case UNW_MIPS_F7: 2962 return "$f7"; 2963 case UNW_MIPS_F8: 2964 return "$f8"; 2965 case UNW_MIPS_F9: 2966 return "$f9"; 2967 case UNW_MIPS_F10: 2968 return "$f10"; 2969 case UNW_MIPS_F11: 2970 return "$f11"; 2971 case UNW_MIPS_F12: 2972 return "$f12"; 2973 case UNW_MIPS_F13: 2974 return "$f13"; 2975 case UNW_MIPS_F14: 2976 return "$f14"; 2977 case UNW_MIPS_F15: 2978 return "$f15"; 2979 case UNW_MIPS_F16: 2980 return "$f16"; 2981 case UNW_MIPS_F17: 2982 return "$f17"; 2983 case UNW_MIPS_F18: 2984 return "$f18"; 2985 case UNW_MIPS_F19: 2986 return "$f19"; 2987 case UNW_MIPS_F20: 2988 return "$f20"; 2989 case UNW_MIPS_F21: 2990 return "$f21"; 2991 case UNW_MIPS_F22: 2992 return "$f22"; 2993 case UNW_MIPS_F23: 2994 return "$f23"; 2995 case UNW_MIPS_F24: 2996 return "$f24"; 2997 case UNW_MIPS_F25: 2998 return "$f25"; 2999 case UNW_MIPS_F26: 3000 return "$f26"; 3001 case UNW_MIPS_F27: 3002 return "$f27"; 3003 case UNW_MIPS_F28: 3004 return "$f28"; 3005 case UNW_MIPS_F29: 3006 return "$f29"; 3007 case UNW_MIPS_F30: 3008 return "$f30"; 3009 case UNW_MIPS_F31: 3010 return "$f31"; 3011 case UNW_MIPS_HI: 3012 return "$hi"; 3013 case UNW_MIPS_LO: 3014 return "$lo"; 3015 default: 3016 return "unknown register"; 3017 } 3018 } 3019 #endif // _LIBUNWIND_TARGET_MIPS_O32 3020 3021 #if defined(_LIBUNWIND_TARGET_MIPS_NEWABI) 3022 /// Registers_mips_newabi holds the register state of a thread in a 3023 /// MIPS process using NEWABI (the N32 or N64 ABIs). 3024 class _LIBUNWIND_HIDDEN Registers_mips_newabi { 3025 public: 3026 Registers_mips_newabi(); 3027 Registers_mips_newabi(const void *registers); 3028 3029 bool validRegister(int num) const; 3030 uint64_t getRegister(int num) const; 3031 void setRegister(int num, uint64_t value); 3032 bool validFloatRegister(int num) const; 3033 double getFloatRegister(int num) const; 3034 void setFloatRegister(int num, double value); 3035 bool validVectorRegister(int num) const; 3036 v128 getVectorRegister(int num) const; 3037 void setVectorRegister(int num, v128 value); 3038 const char *getRegisterName(int num); 3039 void jumpto(); 3040 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; } 3041 3042 uint64_t getSP() const { return _registers.__r[29]; } 3043 void setSP(uint64_t value) { _registers.__r[29] = value; } 3044 uint64_t getIP() const { return _registers.__pc; } 3045 void setIP(uint64_t value) { _registers.__pc = value; } 3046 3047 private: 3048 struct mips_newabi_thread_state_t { 3049 uint64_t __r[32]; 3050 uint64_t __pc; 3051 uint64_t __hi; 3052 uint64_t __lo; 3053 }; 3054 3055 mips_newabi_thread_state_t _registers; 3056 #ifdef __mips_hard_float 3057 double _floats[32]; 3058 #endif 3059 }; 3060 3061 inline Registers_mips_newabi::Registers_mips_newabi(const void *registers) { 3062 static_assert((check_fit<Registers_mips_newabi, unw_context_t>::does_fit), 3063 "mips_newabi registers do not fit into unw_context_t"); 3064 memcpy(&_registers, static_cast<const uint8_t *>(registers), 3065 sizeof(_registers)); 3066 } 3067 3068 inline Registers_mips_newabi::Registers_mips_newabi() { 3069 memset(&_registers, 0, sizeof(_registers)); 3070 } 3071 3072 inline bool Registers_mips_newabi::validRegister(int regNum) const { 3073 if (regNum == UNW_REG_IP) 3074 return true; 3075 if (regNum == UNW_REG_SP) 3076 return true; 3077 if (regNum < 0) 3078 return false; 3079 if (regNum <= UNW_MIPS_R31) 3080 return true; 3081 #if __mips_isa_rev != 6 3082 if (regNum == UNW_MIPS_HI) 3083 return true; 3084 if (regNum == UNW_MIPS_LO) 3085 return true; 3086 #endif 3087 // FIXME: Hard float, DSP accumulator registers, MSA registers 3088 return false; 3089 } 3090 3091 inline uint64_t Registers_mips_newabi::getRegister(int regNum) const { 3092 if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) 3093 return _registers.__r[regNum - UNW_MIPS_R0]; 3094 3095 switch (regNum) { 3096 case UNW_REG_IP: 3097 return _registers.__pc; 3098 case UNW_REG_SP: 3099 return _registers.__r[29]; 3100 case UNW_MIPS_HI: 3101 return _registers.__hi; 3102 case UNW_MIPS_LO: 3103 return _registers.__lo; 3104 } 3105 _LIBUNWIND_ABORT("unsupported mips_newabi register"); 3106 } 3107 3108 inline void Registers_mips_newabi::setRegister(int regNum, uint64_t value) { 3109 if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) { 3110 _registers.__r[regNum - UNW_MIPS_R0] = value; 3111 return; 3112 } 3113 3114 switch (regNum) { 3115 case UNW_REG_IP: 3116 _registers.__pc = value; 3117 return; 3118 case UNW_REG_SP: 3119 _registers.__r[29] = value; 3120 return; 3121 case UNW_MIPS_HI: 3122 _registers.__hi = value; 3123 return; 3124 case UNW_MIPS_LO: 3125 _registers.__lo = value; 3126 return; 3127 } 3128 _LIBUNWIND_ABORT("unsupported mips_newabi register"); 3129 } 3130 3131 inline bool Registers_mips_newabi::validFloatRegister(int regNum) const { 3132 #ifdef __mips_hard_float 3133 if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) 3134 return true; 3135 #endif 3136 return false; 3137 } 3138 3139 inline double Registers_mips_newabi::getFloatRegister(int regNum) const { 3140 #ifdef __mips_hard_float 3141 assert(validFloatRegister(regNum)); 3142 return _floats[regNum - UNW_MIPS_F0]; 3143 #else 3144 _LIBUNWIND_ABORT("mips_newabi float support not implemented"); 3145 #endif 3146 } 3147 3148 inline void Registers_mips_newabi::setFloatRegister(int regNum, 3149 double value) { 3150 #ifdef __mips_hard_float 3151 assert(validFloatRegister(regNum)); 3152 _floats[regNum - UNW_MIPS_F0] = value; 3153 #else 3154 _LIBUNWIND_ABORT("mips_newabi float support not implemented"); 3155 #endif 3156 } 3157 3158 inline bool Registers_mips_newabi::validVectorRegister(int /* regNum */) const { 3159 return false; 3160 } 3161 3162 inline v128 Registers_mips_newabi::getVectorRegister(int /* regNum */) const { 3163 _LIBUNWIND_ABORT("mips_newabi vector support not implemented"); 3164 } 3165 3166 inline void Registers_mips_newabi::setVectorRegister(int /* regNum */, v128 /* value */) { 3167 _LIBUNWIND_ABORT("mips_newabi vector support not implemented"); 3168 } 3169 3170 inline const char *Registers_mips_newabi::getRegisterName(int regNum) { 3171 switch (regNum) { 3172 case UNW_MIPS_R0: 3173 return "$0"; 3174 case UNW_MIPS_R1: 3175 return "$1"; 3176 case UNW_MIPS_R2: 3177 return "$2"; 3178 case UNW_MIPS_R3: 3179 return "$3"; 3180 case UNW_MIPS_R4: 3181 return "$4"; 3182 case UNW_MIPS_R5: 3183 return "$5"; 3184 case UNW_MIPS_R6: 3185 return "$6"; 3186 case UNW_MIPS_R7: 3187 return "$7"; 3188 case UNW_MIPS_R8: 3189 return "$8"; 3190 case UNW_MIPS_R9: 3191 return "$9"; 3192 case UNW_MIPS_R10: 3193 return "$10"; 3194 case UNW_MIPS_R11: 3195 return "$11"; 3196 case UNW_MIPS_R12: 3197 return "$12"; 3198 case UNW_MIPS_R13: 3199 return "$13"; 3200 case UNW_MIPS_R14: 3201 return "$14"; 3202 case UNW_MIPS_R15: 3203 return "$15"; 3204 case UNW_MIPS_R16: 3205 return "$16"; 3206 case UNW_MIPS_R17: 3207 return "$17"; 3208 case UNW_MIPS_R18: 3209 return "$18"; 3210 case UNW_MIPS_R19: 3211 return "$19"; 3212 case UNW_MIPS_R20: 3213 return "$20"; 3214 case UNW_MIPS_R21: 3215 return "$21"; 3216 case UNW_MIPS_R22: 3217 return "$22"; 3218 case UNW_MIPS_R23: 3219 return "$23"; 3220 case UNW_MIPS_R24: 3221 return "$24"; 3222 case UNW_MIPS_R25: 3223 return "$25"; 3224 case UNW_MIPS_R26: 3225 return "$26"; 3226 case UNW_MIPS_R27: 3227 return "$27"; 3228 case UNW_MIPS_R28: 3229 return "$28"; 3230 case UNW_MIPS_R29: 3231 return "$29"; 3232 case UNW_MIPS_R30: 3233 return "$30"; 3234 case UNW_MIPS_R31: 3235 return "$31"; 3236 case UNW_MIPS_F0: 3237 return "$f0"; 3238 case UNW_MIPS_F1: 3239 return "$f1"; 3240 case UNW_MIPS_F2: 3241 return "$f2"; 3242 case UNW_MIPS_F3: 3243 return "$f3"; 3244 case UNW_MIPS_F4: 3245 return "$f4"; 3246 case UNW_MIPS_F5: 3247 return "$f5"; 3248 case UNW_MIPS_F6: 3249 return "$f6"; 3250 case UNW_MIPS_F7: 3251 return "$f7"; 3252 case UNW_MIPS_F8: 3253 return "$f8"; 3254 case UNW_MIPS_F9: 3255 return "$f9"; 3256 case UNW_MIPS_F10: 3257 return "$f10"; 3258 case UNW_MIPS_F11: 3259 return "$f11"; 3260 case UNW_MIPS_F12: 3261 return "$f12"; 3262 case UNW_MIPS_F13: 3263 return "$f13"; 3264 case UNW_MIPS_F14: 3265 return "$f14"; 3266 case UNW_MIPS_F15: 3267 return "$f15"; 3268 case UNW_MIPS_F16: 3269 return "$f16"; 3270 case UNW_MIPS_F17: 3271 return "$f17"; 3272 case UNW_MIPS_F18: 3273 return "$f18"; 3274 case UNW_MIPS_F19: 3275 return "$f19"; 3276 case UNW_MIPS_F20: 3277 return "$f20"; 3278 case UNW_MIPS_F21: 3279 return "$f21"; 3280 case UNW_MIPS_F22: 3281 return "$f22"; 3282 case UNW_MIPS_F23: 3283 return "$f23"; 3284 case UNW_MIPS_F24: 3285 return "$f24"; 3286 case UNW_MIPS_F25: 3287 return "$f25"; 3288 case UNW_MIPS_F26: 3289 return "$f26"; 3290 case UNW_MIPS_F27: 3291 return "$f27"; 3292 case UNW_MIPS_F28: 3293 return "$f28"; 3294 case UNW_MIPS_F29: 3295 return "$f29"; 3296 case UNW_MIPS_F30: 3297 return "$f30"; 3298 case UNW_MIPS_F31: 3299 return "$f31"; 3300 case UNW_MIPS_HI: 3301 return "$hi"; 3302 case UNW_MIPS_LO: 3303 return "$lo"; 3304 default: 3305 return "unknown register"; 3306 } 3307 } 3308 #endif // _LIBUNWIND_TARGET_MIPS_NEWABI 3309 } // namespace libunwind 3310 3311 #endif // __REGISTERS_HPP__ 3312