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 return false; 521 #endif 522 } 523 524 inline v128 Registers_x86_64::getVectorRegister(int regNum) const { 525 #if defined(_WIN64) 526 assert(validVectorRegister(regNum)); 527 return _xmm[regNum - UNW_X86_64_XMM0]; 528 #else 529 _LIBUNWIND_ABORT("no x86_64 vector registers"); 530 #endif 531 } 532 533 inline void Registers_x86_64::setVectorRegister(int regNum, v128 value) { 534 #if defined(_WIN64) 535 assert(validVectorRegister(regNum)); 536 _xmm[regNum - UNW_X86_64_XMM0] = value; 537 #else 538 _LIBUNWIND_ABORT("no x86_64 vector registers"); 539 #endif 540 } 541 #endif // _LIBUNWIND_TARGET_X86_64 542 543 544 #if defined(_LIBUNWIND_TARGET_PPC) 545 /// Registers_ppc holds the register state of a thread in a 32-bit PowerPC 546 /// process. 547 class _LIBUNWIND_HIDDEN Registers_ppc { 548 public: 549 Registers_ppc(); 550 Registers_ppc(const void *registers); 551 552 bool validRegister(int num) const; 553 uint32_t getRegister(int num) const; 554 void setRegister(int num, uint32_t value); 555 bool validFloatRegister(int num) const; 556 double getFloatRegister(int num) const; 557 void setFloatRegister(int num, double value); 558 bool validVectorRegister(int num) const; 559 v128 getVectorRegister(int num) const; 560 void setVectorRegister(int num, v128 value); 561 const char *getRegisterName(int num); 562 void jumpto(); 563 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC; } 564 565 uint64_t getSP() const { return _registers.__r1; } 566 void setSP(uint32_t value) { _registers.__r1 = value; } 567 uint64_t getIP() const { return _registers.__srr0; } 568 void setIP(uint32_t value) { _registers.__srr0 = value; } 569 570 private: 571 struct ppc_thread_state_t { 572 unsigned int __srr0; /* Instruction address register (PC) */ 573 unsigned int __srr1; /* Machine state register (supervisor) */ 574 unsigned int __r0; 575 unsigned int __r1; 576 unsigned int __r2; 577 unsigned int __r3; 578 unsigned int __r4; 579 unsigned int __r5; 580 unsigned int __r6; 581 unsigned int __r7; 582 unsigned int __r8; 583 unsigned int __r9; 584 unsigned int __r10; 585 unsigned int __r11; 586 unsigned int __r12; 587 unsigned int __r13; 588 unsigned int __r14; 589 unsigned int __r15; 590 unsigned int __r16; 591 unsigned int __r17; 592 unsigned int __r18; 593 unsigned int __r19; 594 unsigned int __r20; 595 unsigned int __r21; 596 unsigned int __r22; 597 unsigned int __r23; 598 unsigned int __r24; 599 unsigned int __r25; 600 unsigned int __r26; 601 unsigned int __r27; 602 unsigned int __r28; 603 unsigned int __r29; 604 unsigned int __r30; 605 unsigned int __r31; 606 unsigned int __cr; /* Condition register */ 607 unsigned int __xer; /* User's integer exception register */ 608 unsigned int __lr; /* Link register */ 609 unsigned int __ctr; /* Count register */ 610 unsigned int __mq; /* MQ register (601 only) */ 611 unsigned int __vrsave; /* Vector Save Register */ 612 }; 613 614 struct ppc_float_state_t { 615 double __fpregs[32]; 616 617 unsigned int __fpscr_pad; /* fpscr is 64 bits, 32 bits of rubbish */ 618 unsigned int __fpscr; /* floating point status register */ 619 }; 620 621 ppc_thread_state_t _registers; 622 ppc_float_state_t _floatRegisters; 623 v128 _vectorRegisters[32]; // offset 424 624 }; 625 626 inline Registers_ppc::Registers_ppc(const void *registers) { 627 static_assert((check_fit<Registers_ppc, unw_context_t>::does_fit), 628 "ppc registers do not fit into unw_context_t"); 629 memcpy(&_registers, static_cast<const uint8_t *>(registers), 630 sizeof(_registers)); 631 static_assert(sizeof(ppc_thread_state_t) == 160, 632 "expected float register offset to be 160"); 633 memcpy(&_floatRegisters, 634 static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t), 635 sizeof(_floatRegisters)); 636 static_assert(sizeof(ppc_thread_state_t) + sizeof(ppc_float_state_t) == 424, 637 "expected vector register offset to be 424 bytes"); 638 memcpy(_vectorRegisters, 639 static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t) + 640 sizeof(ppc_float_state_t), 641 sizeof(_vectorRegisters)); 642 } 643 644 inline Registers_ppc::Registers_ppc() { 645 memset(&_registers, 0, sizeof(_registers)); 646 memset(&_floatRegisters, 0, sizeof(_floatRegisters)); 647 memset(&_vectorRegisters, 0, sizeof(_vectorRegisters)); 648 } 649 650 inline bool Registers_ppc::validRegister(int regNum) const { 651 if (regNum == UNW_REG_IP) 652 return true; 653 if (regNum == UNW_REG_SP) 654 return true; 655 if (regNum == UNW_PPC_VRSAVE) 656 return true; 657 if (regNum < 0) 658 return false; 659 if (regNum <= UNW_PPC_R31) 660 return true; 661 if (regNum == UNW_PPC_MQ) 662 return true; 663 if (regNum == UNW_PPC_LR) 664 return true; 665 if (regNum == UNW_PPC_CTR) 666 return true; 667 if ((UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7)) 668 return true; 669 return false; 670 } 671 672 inline uint32_t Registers_ppc::getRegister(int regNum) const { 673 switch (regNum) { 674 case UNW_REG_IP: 675 return _registers.__srr0; 676 case UNW_REG_SP: 677 return _registers.__r1; 678 case UNW_PPC_R0: 679 return _registers.__r0; 680 case UNW_PPC_R1: 681 return _registers.__r1; 682 case UNW_PPC_R2: 683 return _registers.__r2; 684 case UNW_PPC_R3: 685 return _registers.__r3; 686 case UNW_PPC_R4: 687 return _registers.__r4; 688 case UNW_PPC_R5: 689 return _registers.__r5; 690 case UNW_PPC_R6: 691 return _registers.__r6; 692 case UNW_PPC_R7: 693 return _registers.__r7; 694 case UNW_PPC_R8: 695 return _registers.__r8; 696 case UNW_PPC_R9: 697 return _registers.__r9; 698 case UNW_PPC_R10: 699 return _registers.__r10; 700 case UNW_PPC_R11: 701 return _registers.__r11; 702 case UNW_PPC_R12: 703 return _registers.__r12; 704 case UNW_PPC_R13: 705 return _registers.__r13; 706 case UNW_PPC_R14: 707 return _registers.__r14; 708 case UNW_PPC_R15: 709 return _registers.__r15; 710 case UNW_PPC_R16: 711 return _registers.__r16; 712 case UNW_PPC_R17: 713 return _registers.__r17; 714 case UNW_PPC_R18: 715 return _registers.__r18; 716 case UNW_PPC_R19: 717 return _registers.__r19; 718 case UNW_PPC_R20: 719 return _registers.__r20; 720 case UNW_PPC_R21: 721 return _registers.__r21; 722 case UNW_PPC_R22: 723 return _registers.__r22; 724 case UNW_PPC_R23: 725 return _registers.__r23; 726 case UNW_PPC_R24: 727 return _registers.__r24; 728 case UNW_PPC_R25: 729 return _registers.__r25; 730 case UNW_PPC_R26: 731 return _registers.__r26; 732 case UNW_PPC_R27: 733 return _registers.__r27; 734 case UNW_PPC_R28: 735 return _registers.__r28; 736 case UNW_PPC_R29: 737 return _registers.__r29; 738 case UNW_PPC_R30: 739 return _registers.__r30; 740 case UNW_PPC_R31: 741 return _registers.__r31; 742 case UNW_PPC_LR: 743 return _registers.__lr; 744 case UNW_PPC_CR0: 745 return (_registers.__cr & 0xF0000000); 746 case UNW_PPC_CR1: 747 return (_registers.__cr & 0x0F000000); 748 case UNW_PPC_CR2: 749 return (_registers.__cr & 0x00F00000); 750 case UNW_PPC_CR3: 751 return (_registers.__cr & 0x000F0000); 752 case UNW_PPC_CR4: 753 return (_registers.__cr & 0x0000F000); 754 case UNW_PPC_CR5: 755 return (_registers.__cr & 0x00000F00); 756 case UNW_PPC_CR6: 757 return (_registers.__cr & 0x000000F0); 758 case UNW_PPC_CR7: 759 return (_registers.__cr & 0x0000000F); 760 case UNW_PPC_VRSAVE: 761 return _registers.__vrsave; 762 } 763 _LIBUNWIND_ABORT("unsupported ppc register"); 764 } 765 766 inline void Registers_ppc::setRegister(int regNum, uint32_t value) { 767 //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value); 768 switch (regNum) { 769 case UNW_REG_IP: 770 _registers.__srr0 = value; 771 return; 772 case UNW_REG_SP: 773 _registers.__r1 = value; 774 return; 775 case UNW_PPC_R0: 776 _registers.__r0 = value; 777 return; 778 case UNW_PPC_R1: 779 _registers.__r1 = value; 780 return; 781 case UNW_PPC_R2: 782 _registers.__r2 = value; 783 return; 784 case UNW_PPC_R3: 785 _registers.__r3 = value; 786 return; 787 case UNW_PPC_R4: 788 _registers.__r4 = value; 789 return; 790 case UNW_PPC_R5: 791 _registers.__r5 = value; 792 return; 793 case UNW_PPC_R6: 794 _registers.__r6 = value; 795 return; 796 case UNW_PPC_R7: 797 _registers.__r7 = value; 798 return; 799 case UNW_PPC_R8: 800 _registers.__r8 = value; 801 return; 802 case UNW_PPC_R9: 803 _registers.__r9 = value; 804 return; 805 case UNW_PPC_R10: 806 _registers.__r10 = value; 807 return; 808 case UNW_PPC_R11: 809 _registers.__r11 = value; 810 return; 811 case UNW_PPC_R12: 812 _registers.__r12 = value; 813 return; 814 case UNW_PPC_R13: 815 _registers.__r13 = value; 816 return; 817 case UNW_PPC_R14: 818 _registers.__r14 = value; 819 return; 820 case UNW_PPC_R15: 821 _registers.__r15 = value; 822 return; 823 case UNW_PPC_R16: 824 _registers.__r16 = value; 825 return; 826 case UNW_PPC_R17: 827 _registers.__r17 = value; 828 return; 829 case UNW_PPC_R18: 830 _registers.__r18 = value; 831 return; 832 case UNW_PPC_R19: 833 _registers.__r19 = value; 834 return; 835 case UNW_PPC_R20: 836 _registers.__r20 = value; 837 return; 838 case UNW_PPC_R21: 839 _registers.__r21 = value; 840 return; 841 case UNW_PPC_R22: 842 _registers.__r22 = value; 843 return; 844 case UNW_PPC_R23: 845 _registers.__r23 = value; 846 return; 847 case UNW_PPC_R24: 848 _registers.__r24 = value; 849 return; 850 case UNW_PPC_R25: 851 _registers.__r25 = value; 852 return; 853 case UNW_PPC_R26: 854 _registers.__r26 = value; 855 return; 856 case UNW_PPC_R27: 857 _registers.__r27 = value; 858 return; 859 case UNW_PPC_R28: 860 _registers.__r28 = value; 861 return; 862 case UNW_PPC_R29: 863 _registers.__r29 = value; 864 return; 865 case UNW_PPC_R30: 866 _registers.__r30 = value; 867 return; 868 case UNW_PPC_R31: 869 _registers.__r31 = value; 870 return; 871 case UNW_PPC_MQ: 872 _registers.__mq = value; 873 return; 874 case UNW_PPC_LR: 875 _registers.__lr = value; 876 return; 877 case UNW_PPC_CTR: 878 _registers.__ctr = value; 879 return; 880 case UNW_PPC_CR0: 881 _registers.__cr &= 0x0FFFFFFF; 882 _registers.__cr |= (value & 0xF0000000); 883 return; 884 case UNW_PPC_CR1: 885 _registers.__cr &= 0xF0FFFFFF; 886 _registers.__cr |= (value & 0x0F000000); 887 return; 888 case UNW_PPC_CR2: 889 _registers.__cr &= 0xFF0FFFFF; 890 _registers.__cr |= (value & 0x00F00000); 891 return; 892 case UNW_PPC_CR3: 893 _registers.__cr &= 0xFFF0FFFF; 894 _registers.__cr |= (value & 0x000F0000); 895 return; 896 case UNW_PPC_CR4: 897 _registers.__cr &= 0xFFFF0FFF; 898 _registers.__cr |= (value & 0x0000F000); 899 return; 900 case UNW_PPC_CR5: 901 _registers.__cr &= 0xFFFFF0FF; 902 _registers.__cr |= (value & 0x00000F00); 903 return; 904 case UNW_PPC_CR6: 905 _registers.__cr &= 0xFFFFFF0F; 906 _registers.__cr |= (value & 0x000000F0); 907 return; 908 case UNW_PPC_CR7: 909 _registers.__cr &= 0xFFFFFFF0; 910 _registers.__cr |= (value & 0x0000000F); 911 return; 912 case UNW_PPC_VRSAVE: 913 _registers.__vrsave = value; 914 return; 915 // not saved 916 return; 917 case UNW_PPC_XER: 918 _registers.__xer = value; 919 return; 920 case UNW_PPC_AP: 921 case UNW_PPC_VSCR: 922 case UNW_PPC_SPEFSCR: 923 // not saved 924 return; 925 } 926 _LIBUNWIND_ABORT("unsupported ppc register"); 927 } 928 929 inline bool Registers_ppc::validFloatRegister(int regNum) const { 930 if (regNum < UNW_PPC_F0) 931 return false; 932 if (regNum > UNW_PPC_F31) 933 return false; 934 return true; 935 } 936 937 inline double Registers_ppc::getFloatRegister(int regNum) const { 938 assert(validFloatRegister(regNum)); 939 return _floatRegisters.__fpregs[regNum - UNW_PPC_F0]; 940 } 941 942 inline void Registers_ppc::setFloatRegister(int regNum, double value) { 943 assert(validFloatRegister(regNum)); 944 _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value; 945 } 946 947 inline bool Registers_ppc::validVectorRegister(int regNum) const { 948 if (regNum < UNW_PPC_V0) 949 return false; 950 if (regNum > UNW_PPC_V31) 951 return false; 952 return true; 953 } 954 955 inline v128 Registers_ppc::getVectorRegister(int regNum) const { 956 assert(validVectorRegister(regNum)); 957 v128 result = _vectorRegisters[regNum - UNW_PPC_V0]; 958 return result; 959 } 960 961 inline void Registers_ppc::setVectorRegister(int regNum, v128 value) { 962 assert(validVectorRegister(regNum)); 963 _vectorRegisters[regNum - UNW_PPC_V0] = value; 964 } 965 966 inline const char *Registers_ppc::getRegisterName(int regNum) { 967 switch (regNum) { 968 case UNW_REG_IP: 969 return "ip"; 970 case UNW_REG_SP: 971 return "sp"; 972 case UNW_PPC_R0: 973 return "r0"; 974 case UNW_PPC_R1: 975 return "r1"; 976 case UNW_PPC_R2: 977 return "r2"; 978 case UNW_PPC_R3: 979 return "r3"; 980 case UNW_PPC_R4: 981 return "r4"; 982 case UNW_PPC_R5: 983 return "r5"; 984 case UNW_PPC_R6: 985 return "r6"; 986 case UNW_PPC_R7: 987 return "r7"; 988 case UNW_PPC_R8: 989 return "r8"; 990 case UNW_PPC_R9: 991 return "r9"; 992 case UNW_PPC_R10: 993 return "r10"; 994 case UNW_PPC_R11: 995 return "r11"; 996 case UNW_PPC_R12: 997 return "r12"; 998 case UNW_PPC_R13: 999 return "r13"; 1000 case UNW_PPC_R14: 1001 return "r14"; 1002 case UNW_PPC_R15: 1003 return "r15"; 1004 case UNW_PPC_R16: 1005 return "r16"; 1006 case UNW_PPC_R17: 1007 return "r17"; 1008 case UNW_PPC_R18: 1009 return "r18"; 1010 case UNW_PPC_R19: 1011 return "r19"; 1012 case UNW_PPC_R20: 1013 return "r20"; 1014 case UNW_PPC_R21: 1015 return "r21"; 1016 case UNW_PPC_R22: 1017 return "r22"; 1018 case UNW_PPC_R23: 1019 return "r23"; 1020 case UNW_PPC_R24: 1021 return "r24"; 1022 case UNW_PPC_R25: 1023 return "r25"; 1024 case UNW_PPC_R26: 1025 return "r26"; 1026 case UNW_PPC_R27: 1027 return "r27"; 1028 case UNW_PPC_R28: 1029 return "r28"; 1030 case UNW_PPC_R29: 1031 return "r29"; 1032 case UNW_PPC_R30: 1033 return "r30"; 1034 case UNW_PPC_R31: 1035 return "r31"; 1036 case UNW_PPC_F0: 1037 return "fp0"; 1038 case UNW_PPC_F1: 1039 return "fp1"; 1040 case UNW_PPC_F2: 1041 return "fp2"; 1042 case UNW_PPC_F3: 1043 return "fp3"; 1044 case UNW_PPC_F4: 1045 return "fp4"; 1046 case UNW_PPC_F5: 1047 return "fp5"; 1048 case UNW_PPC_F6: 1049 return "fp6"; 1050 case UNW_PPC_F7: 1051 return "fp7"; 1052 case UNW_PPC_F8: 1053 return "fp8"; 1054 case UNW_PPC_F9: 1055 return "fp9"; 1056 case UNW_PPC_F10: 1057 return "fp10"; 1058 case UNW_PPC_F11: 1059 return "fp11"; 1060 case UNW_PPC_F12: 1061 return "fp12"; 1062 case UNW_PPC_F13: 1063 return "fp13"; 1064 case UNW_PPC_F14: 1065 return "fp14"; 1066 case UNW_PPC_F15: 1067 return "fp15"; 1068 case UNW_PPC_F16: 1069 return "fp16"; 1070 case UNW_PPC_F17: 1071 return "fp17"; 1072 case UNW_PPC_F18: 1073 return "fp18"; 1074 case UNW_PPC_F19: 1075 return "fp19"; 1076 case UNW_PPC_F20: 1077 return "fp20"; 1078 case UNW_PPC_F21: 1079 return "fp21"; 1080 case UNW_PPC_F22: 1081 return "fp22"; 1082 case UNW_PPC_F23: 1083 return "fp23"; 1084 case UNW_PPC_F24: 1085 return "fp24"; 1086 case UNW_PPC_F25: 1087 return "fp25"; 1088 case UNW_PPC_F26: 1089 return "fp26"; 1090 case UNW_PPC_F27: 1091 return "fp27"; 1092 case UNW_PPC_F28: 1093 return "fp28"; 1094 case UNW_PPC_F29: 1095 return "fp29"; 1096 case UNW_PPC_F30: 1097 return "fp30"; 1098 case UNW_PPC_F31: 1099 return "fp31"; 1100 case UNW_PPC_LR: 1101 return "lr"; 1102 default: 1103 return "unknown register"; 1104 } 1105 1106 } 1107 #endif // _LIBUNWIND_TARGET_PPC 1108 1109 1110 #if defined(_LIBUNWIND_TARGET_AARCH64) 1111 /// Registers_arm64 holds the register state of a thread in a 64-bit arm 1112 /// process. 1113 class _LIBUNWIND_HIDDEN Registers_arm64 { 1114 public: 1115 Registers_arm64(); 1116 Registers_arm64(const void *registers); 1117 1118 bool validRegister(int num) const; 1119 uint64_t getRegister(int num) const; 1120 void setRegister(int num, uint64_t value); 1121 bool validFloatRegister(int num) const; 1122 double getFloatRegister(int num) const; 1123 void setFloatRegister(int num, double value); 1124 bool validVectorRegister(int num) const; 1125 v128 getVectorRegister(int num) const; 1126 void setVectorRegister(int num, v128 value); 1127 const char *getRegisterName(int num); 1128 void jumpto(); 1129 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64; } 1130 1131 uint64_t getSP() const { return _registers.__sp; } 1132 void setSP(uint64_t value) { _registers.__sp = value; } 1133 uint64_t getIP() const { return _registers.__pc; } 1134 void setIP(uint64_t value) { _registers.__pc = value; } 1135 uint64_t getFP() const { return _registers.__fp; } 1136 void setFP(uint64_t value) { _registers.__fp = value; } 1137 1138 private: 1139 struct GPRs { 1140 uint64_t __x[29]; // x0-x28 1141 uint64_t __fp; // Frame pointer x29 1142 uint64_t __lr; // Link register x30 1143 uint64_t __sp; // Stack pointer x31 1144 uint64_t __pc; // Program counter 1145 uint64_t padding; // 16-byte align 1146 }; 1147 1148 GPRs _registers; 1149 double _vectorHalfRegisters[32]; 1150 // Currently only the lower double in 128-bit vectore registers 1151 // is perserved during unwinding. We could define new register 1152 // numbers (> 96) which mean whole vector registers, then this 1153 // struct would need to change to contain whole vector registers. 1154 }; 1155 1156 inline Registers_arm64::Registers_arm64(const void *registers) { 1157 static_assert((check_fit<Registers_arm64, unw_context_t>::does_fit), 1158 "arm64 registers do not fit into unw_context_t"); 1159 memcpy(&_registers, registers, sizeof(_registers)); 1160 static_assert(sizeof(GPRs) == 0x110, 1161 "expected VFP registers to be at offset 272"); 1162 memcpy(_vectorHalfRegisters, 1163 static_cast<const uint8_t *>(registers) + sizeof(GPRs), 1164 sizeof(_vectorHalfRegisters)); 1165 } 1166 1167 inline Registers_arm64::Registers_arm64() { 1168 memset(&_registers, 0, sizeof(_registers)); 1169 memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters)); 1170 } 1171 1172 inline bool Registers_arm64::validRegister(int regNum) const { 1173 if (regNum == UNW_REG_IP) 1174 return true; 1175 if (regNum == UNW_REG_SP) 1176 return true; 1177 if (regNum < 0) 1178 return false; 1179 if (regNum > 95) 1180 return false; 1181 if ((regNum > 31) && (regNum < 64)) 1182 return false; 1183 return true; 1184 } 1185 1186 inline uint64_t Registers_arm64::getRegister(int regNum) const { 1187 if (regNum == UNW_REG_IP) 1188 return _registers.__pc; 1189 if (regNum == UNW_REG_SP) 1190 return _registers.__sp; 1191 if ((regNum >= 0) && (regNum < 32)) 1192 return _registers.__x[regNum]; 1193 _LIBUNWIND_ABORT("unsupported arm64 register"); 1194 } 1195 1196 inline void Registers_arm64::setRegister(int regNum, uint64_t value) { 1197 if (regNum == UNW_REG_IP) 1198 _registers.__pc = value; 1199 else if (regNum == UNW_REG_SP) 1200 _registers.__sp = value; 1201 else if ((regNum >= 0) && (regNum < 32)) 1202 _registers.__x[regNum] = value; 1203 else 1204 _LIBUNWIND_ABORT("unsupported arm64 register"); 1205 } 1206 1207 inline const char *Registers_arm64::getRegisterName(int regNum) { 1208 switch (regNum) { 1209 case UNW_REG_IP: 1210 return "pc"; 1211 case UNW_REG_SP: 1212 return "sp"; 1213 case UNW_ARM64_X0: 1214 return "x0"; 1215 case UNW_ARM64_X1: 1216 return "x1"; 1217 case UNW_ARM64_X2: 1218 return "x2"; 1219 case UNW_ARM64_X3: 1220 return "x3"; 1221 case UNW_ARM64_X4: 1222 return "x4"; 1223 case UNW_ARM64_X5: 1224 return "x5"; 1225 case UNW_ARM64_X6: 1226 return "x6"; 1227 case UNW_ARM64_X7: 1228 return "x7"; 1229 case UNW_ARM64_X8: 1230 return "x8"; 1231 case UNW_ARM64_X9: 1232 return "x9"; 1233 case UNW_ARM64_X10: 1234 return "x10"; 1235 case UNW_ARM64_X11: 1236 return "x11"; 1237 case UNW_ARM64_X12: 1238 return "x12"; 1239 case UNW_ARM64_X13: 1240 return "x13"; 1241 case UNW_ARM64_X14: 1242 return "x14"; 1243 case UNW_ARM64_X15: 1244 return "x15"; 1245 case UNW_ARM64_X16: 1246 return "x16"; 1247 case UNW_ARM64_X17: 1248 return "x17"; 1249 case UNW_ARM64_X18: 1250 return "x18"; 1251 case UNW_ARM64_X19: 1252 return "x19"; 1253 case UNW_ARM64_X20: 1254 return "x20"; 1255 case UNW_ARM64_X21: 1256 return "x21"; 1257 case UNW_ARM64_X22: 1258 return "x22"; 1259 case UNW_ARM64_X23: 1260 return "x23"; 1261 case UNW_ARM64_X24: 1262 return "x24"; 1263 case UNW_ARM64_X25: 1264 return "x25"; 1265 case UNW_ARM64_X26: 1266 return "x26"; 1267 case UNW_ARM64_X27: 1268 return "x27"; 1269 case UNW_ARM64_X28: 1270 return "x28"; 1271 case UNW_ARM64_X29: 1272 return "fp"; 1273 case UNW_ARM64_X30: 1274 return "lr"; 1275 case UNW_ARM64_X31: 1276 return "sp"; 1277 case UNW_ARM64_D0: 1278 return "d0"; 1279 case UNW_ARM64_D1: 1280 return "d1"; 1281 case UNW_ARM64_D2: 1282 return "d2"; 1283 case UNW_ARM64_D3: 1284 return "d3"; 1285 case UNW_ARM64_D4: 1286 return "d4"; 1287 case UNW_ARM64_D5: 1288 return "d5"; 1289 case UNW_ARM64_D6: 1290 return "d6"; 1291 case UNW_ARM64_D7: 1292 return "d7"; 1293 case UNW_ARM64_D8: 1294 return "d8"; 1295 case UNW_ARM64_D9: 1296 return "d9"; 1297 case UNW_ARM64_D10: 1298 return "d10"; 1299 case UNW_ARM64_D11: 1300 return "d11"; 1301 case UNW_ARM64_D12: 1302 return "d12"; 1303 case UNW_ARM64_D13: 1304 return "d13"; 1305 case UNW_ARM64_D14: 1306 return "d14"; 1307 case UNW_ARM64_D15: 1308 return "d15"; 1309 case UNW_ARM64_D16: 1310 return "d16"; 1311 case UNW_ARM64_D17: 1312 return "d17"; 1313 case UNW_ARM64_D18: 1314 return "d18"; 1315 case UNW_ARM64_D19: 1316 return "d19"; 1317 case UNW_ARM64_D20: 1318 return "d20"; 1319 case UNW_ARM64_D21: 1320 return "d21"; 1321 case UNW_ARM64_D22: 1322 return "d22"; 1323 case UNW_ARM64_D23: 1324 return "d23"; 1325 case UNW_ARM64_D24: 1326 return "d24"; 1327 case UNW_ARM64_D25: 1328 return "d25"; 1329 case UNW_ARM64_D26: 1330 return "d26"; 1331 case UNW_ARM64_D27: 1332 return "d27"; 1333 case UNW_ARM64_D28: 1334 return "d28"; 1335 case UNW_ARM64_D29: 1336 return "d29"; 1337 case UNW_ARM64_D30: 1338 return "d30"; 1339 case UNW_ARM64_D31: 1340 return "d31"; 1341 default: 1342 return "unknown register"; 1343 } 1344 } 1345 1346 inline bool Registers_arm64::validFloatRegister(int regNum) const { 1347 if (regNum < UNW_ARM64_D0) 1348 return false; 1349 if (regNum > UNW_ARM64_D31) 1350 return false; 1351 return true; 1352 } 1353 1354 inline double Registers_arm64::getFloatRegister(int regNum) const { 1355 assert(validFloatRegister(regNum)); 1356 return _vectorHalfRegisters[regNum - UNW_ARM64_D0]; 1357 } 1358 1359 inline void Registers_arm64::setFloatRegister(int regNum, double value) { 1360 assert(validFloatRegister(regNum)); 1361 _vectorHalfRegisters[regNum - UNW_ARM64_D0] = value; 1362 } 1363 1364 inline bool Registers_arm64::validVectorRegister(int) const { 1365 return false; 1366 } 1367 1368 inline v128 Registers_arm64::getVectorRegister(int) const { 1369 _LIBUNWIND_ABORT("no arm64 vector register support yet"); 1370 } 1371 1372 inline void Registers_arm64::setVectorRegister(int, v128) { 1373 _LIBUNWIND_ABORT("no arm64 vector register support yet"); 1374 } 1375 #endif // _LIBUNWIND_TARGET_AARCH64 1376 1377 #if defined(_LIBUNWIND_TARGET_ARM) 1378 /// Registers_arm holds the register state of a thread in a 32-bit arm 1379 /// process. 1380 /// 1381 /// NOTE: Assumes VFPv3. On ARM processors without a floating point unit, 1382 /// this uses more memory than required. 1383 class _LIBUNWIND_HIDDEN Registers_arm { 1384 public: 1385 Registers_arm(); 1386 Registers_arm(const void *registers); 1387 1388 bool validRegister(int num) const; 1389 uint32_t getRegister(int num) const; 1390 void setRegister(int num, uint32_t value); 1391 bool validFloatRegister(int num) const; 1392 unw_fpreg_t getFloatRegister(int num); 1393 void setFloatRegister(int num, unw_fpreg_t value); 1394 bool validVectorRegister(int num) const; 1395 v128 getVectorRegister(int num) const; 1396 void setVectorRegister(int num, v128 value); 1397 const char *getRegisterName(int num); 1398 void jumpto() { 1399 restoreSavedFloatRegisters(); 1400 restoreCoreAndJumpTo(); 1401 } 1402 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM; } 1403 1404 uint32_t getSP() const { return _registers.__sp; } 1405 void setSP(uint32_t value) { _registers.__sp = value; } 1406 uint32_t getIP() const { return _registers.__pc; } 1407 void setIP(uint32_t value) { _registers.__pc = value; } 1408 1409 void saveVFPAsX() { 1410 assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15); 1411 _use_X_for_vfp_save = true; 1412 } 1413 1414 void restoreSavedFloatRegisters() { 1415 if (_saved_vfp_d0_d15) { 1416 if (_use_X_for_vfp_save) 1417 restoreVFPWithFLDMX(_vfp_d0_d15_pad); 1418 else 1419 restoreVFPWithFLDMD(_vfp_d0_d15_pad); 1420 } 1421 if (_saved_vfp_d16_d31) 1422 restoreVFPv3(_vfp_d16_d31); 1423 #if defined(__ARM_WMMX) 1424 if (_saved_iwmmx) 1425 restoreiWMMX(_iwmmx); 1426 if (_saved_iwmmx_control) 1427 restoreiWMMXControl(_iwmmx_control); 1428 #endif 1429 } 1430 1431 private: 1432 struct GPRs { 1433 uint32_t __r[13]; // r0-r12 1434 uint32_t __sp; // Stack pointer r13 1435 uint32_t __lr; // Link register r14 1436 uint32_t __pc; // Program counter r15 1437 }; 1438 1439 static void saveVFPWithFSTMD(unw_fpreg_t*); 1440 static void saveVFPWithFSTMX(unw_fpreg_t*); 1441 static void saveVFPv3(unw_fpreg_t*); 1442 static void restoreVFPWithFLDMD(unw_fpreg_t*); 1443 static void restoreVFPWithFLDMX(unw_fpreg_t*); 1444 static void restoreVFPv3(unw_fpreg_t*); 1445 #if defined(__ARM_WMMX) 1446 static void saveiWMMX(unw_fpreg_t*); 1447 static void saveiWMMXControl(uint32_t*); 1448 static void restoreiWMMX(unw_fpreg_t*); 1449 static void restoreiWMMXControl(uint32_t*); 1450 #endif 1451 void restoreCoreAndJumpTo(); 1452 1453 // ARM registers 1454 GPRs _registers; 1455 1456 // We save floating point registers lazily because we can't know ahead of 1457 // time which ones are used. See EHABI #4.7. 1458 1459 // Whether D0-D15 are saved in the FTSMX instead of FSTMD format. 1460 // 1461 // See EHABI #7.5 that explains how matching instruction sequences for load 1462 // and store need to be used to correctly restore the exact register bits. 1463 bool _use_X_for_vfp_save; 1464 // Whether VFP D0-D15 are saved. 1465 bool _saved_vfp_d0_d15; 1466 // Whether VFPv3 D16-D31 are saved. 1467 bool _saved_vfp_d16_d31; 1468 // VFP registers D0-D15, + padding if saved using FSTMX 1469 unw_fpreg_t _vfp_d0_d15_pad[17]; 1470 // VFPv3 registers D16-D31, always saved using FSTMD 1471 unw_fpreg_t _vfp_d16_d31[16]; 1472 #if defined(__ARM_WMMX) 1473 // Whether iWMMX data registers are saved. 1474 bool _saved_iwmmx; 1475 // Whether iWMMX control registers are saved. 1476 mutable bool _saved_iwmmx_control; 1477 // iWMMX registers 1478 unw_fpreg_t _iwmmx[16]; 1479 // iWMMX control registers 1480 mutable uint32_t _iwmmx_control[4]; 1481 #endif 1482 }; 1483 1484 inline Registers_arm::Registers_arm(const void *registers) 1485 : _use_X_for_vfp_save(false), 1486 _saved_vfp_d0_d15(false), 1487 _saved_vfp_d16_d31(false) { 1488 static_assert((check_fit<Registers_arm, unw_context_t>::does_fit), 1489 "arm registers do not fit into unw_context_t"); 1490 // See unw_getcontext() note about data. 1491 memcpy(&_registers, registers, sizeof(_registers)); 1492 memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad)); 1493 memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31)); 1494 #if defined(__ARM_WMMX) 1495 _saved_iwmmx = false; 1496 _saved_iwmmx_control = false; 1497 memset(&_iwmmx, 0, sizeof(_iwmmx)); 1498 memset(&_iwmmx_control, 0, sizeof(_iwmmx_control)); 1499 #endif 1500 } 1501 1502 inline Registers_arm::Registers_arm() 1503 : _use_X_for_vfp_save(false), 1504 _saved_vfp_d0_d15(false), 1505 _saved_vfp_d16_d31(false) { 1506 memset(&_registers, 0, sizeof(_registers)); 1507 memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad)); 1508 memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31)); 1509 #if defined(__ARM_WMMX) 1510 _saved_iwmmx = false; 1511 _saved_iwmmx_control = false; 1512 memset(&_iwmmx, 0, sizeof(_iwmmx)); 1513 memset(&_iwmmx_control, 0, sizeof(_iwmmx_control)); 1514 #endif 1515 } 1516 1517 inline bool Registers_arm::validRegister(int regNum) const { 1518 // Returns true for all non-VFP registers supported by the EHABI 1519 // virtual register set (VRS). 1520 if (regNum == UNW_REG_IP) 1521 return true; 1522 1523 if (regNum == UNW_REG_SP) 1524 return true; 1525 1526 if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15) 1527 return true; 1528 1529 #if defined(__ARM_WMMX) 1530 if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) 1531 return true; 1532 #endif 1533 1534 return false; 1535 } 1536 1537 inline uint32_t Registers_arm::getRegister(int regNum) const { 1538 if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) 1539 return _registers.__sp; 1540 1541 if (regNum == UNW_ARM_LR) 1542 return _registers.__lr; 1543 1544 if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) 1545 return _registers.__pc; 1546 1547 if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) 1548 return _registers.__r[regNum]; 1549 1550 #if defined(__ARM_WMMX) 1551 if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) { 1552 if (!_saved_iwmmx_control) { 1553 _saved_iwmmx_control = true; 1554 saveiWMMXControl(_iwmmx_control); 1555 } 1556 return _iwmmx_control[regNum - UNW_ARM_WC0]; 1557 } 1558 #endif 1559 1560 _LIBUNWIND_ABORT("unsupported arm register"); 1561 } 1562 1563 inline void Registers_arm::setRegister(int regNum, uint32_t value) { 1564 if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) { 1565 _registers.__sp = value; 1566 return; 1567 } 1568 1569 if (regNum == UNW_ARM_LR) { 1570 _registers.__lr = value; 1571 return; 1572 } 1573 1574 if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) { 1575 _registers.__pc = value; 1576 return; 1577 } 1578 1579 if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) { 1580 _registers.__r[regNum] = value; 1581 return; 1582 } 1583 1584 #if defined(__ARM_WMMX) 1585 if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) { 1586 if (!_saved_iwmmx_control) { 1587 _saved_iwmmx_control = true; 1588 saveiWMMXControl(_iwmmx_control); 1589 } 1590 _iwmmx_control[regNum - UNW_ARM_WC0] = value; 1591 return; 1592 } 1593 #endif 1594 1595 _LIBUNWIND_ABORT("unsupported arm register"); 1596 } 1597 1598 inline const char *Registers_arm::getRegisterName(int regNum) { 1599 switch (regNum) { 1600 case UNW_REG_IP: 1601 case UNW_ARM_IP: // UNW_ARM_R15 is alias 1602 return "pc"; 1603 case UNW_ARM_LR: // UNW_ARM_R14 is alias 1604 return "lr"; 1605 case UNW_REG_SP: 1606 case UNW_ARM_SP: // UNW_ARM_R13 is alias 1607 return "sp"; 1608 case UNW_ARM_R0: 1609 return "r0"; 1610 case UNW_ARM_R1: 1611 return "r1"; 1612 case UNW_ARM_R2: 1613 return "r2"; 1614 case UNW_ARM_R3: 1615 return "r3"; 1616 case UNW_ARM_R4: 1617 return "r4"; 1618 case UNW_ARM_R5: 1619 return "r5"; 1620 case UNW_ARM_R6: 1621 return "r6"; 1622 case UNW_ARM_R7: 1623 return "r7"; 1624 case UNW_ARM_R8: 1625 return "r8"; 1626 case UNW_ARM_R9: 1627 return "r9"; 1628 case UNW_ARM_R10: 1629 return "r10"; 1630 case UNW_ARM_R11: 1631 return "r11"; 1632 case UNW_ARM_R12: 1633 return "r12"; 1634 case UNW_ARM_S0: 1635 return "s0"; 1636 case UNW_ARM_S1: 1637 return "s1"; 1638 case UNW_ARM_S2: 1639 return "s2"; 1640 case UNW_ARM_S3: 1641 return "s3"; 1642 case UNW_ARM_S4: 1643 return "s4"; 1644 case UNW_ARM_S5: 1645 return "s5"; 1646 case UNW_ARM_S6: 1647 return "s6"; 1648 case UNW_ARM_S7: 1649 return "s7"; 1650 case UNW_ARM_S8: 1651 return "s8"; 1652 case UNW_ARM_S9: 1653 return "s9"; 1654 case UNW_ARM_S10: 1655 return "s10"; 1656 case UNW_ARM_S11: 1657 return "s11"; 1658 case UNW_ARM_S12: 1659 return "s12"; 1660 case UNW_ARM_S13: 1661 return "s13"; 1662 case UNW_ARM_S14: 1663 return "s14"; 1664 case UNW_ARM_S15: 1665 return "s15"; 1666 case UNW_ARM_S16: 1667 return "s16"; 1668 case UNW_ARM_S17: 1669 return "s17"; 1670 case UNW_ARM_S18: 1671 return "s18"; 1672 case UNW_ARM_S19: 1673 return "s19"; 1674 case UNW_ARM_S20: 1675 return "s20"; 1676 case UNW_ARM_S21: 1677 return "s21"; 1678 case UNW_ARM_S22: 1679 return "s22"; 1680 case UNW_ARM_S23: 1681 return "s23"; 1682 case UNW_ARM_S24: 1683 return "s24"; 1684 case UNW_ARM_S25: 1685 return "s25"; 1686 case UNW_ARM_S26: 1687 return "s26"; 1688 case UNW_ARM_S27: 1689 return "s27"; 1690 case UNW_ARM_S28: 1691 return "s28"; 1692 case UNW_ARM_S29: 1693 return "s29"; 1694 case UNW_ARM_S30: 1695 return "s30"; 1696 case UNW_ARM_S31: 1697 return "s31"; 1698 case UNW_ARM_D0: 1699 return "d0"; 1700 case UNW_ARM_D1: 1701 return "d1"; 1702 case UNW_ARM_D2: 1703 return "d2"; 1704 case UNW_ARM_D3: 1705 return "d3"; 1706 case UNW_ARM_D4: 1707 return "d4"; 1708 case UNW_ARM_D5: 1709 return "d5"; 1710 case UNW_ARM_D6: 1711 return "d6"; 1712 case UNW_ARM_D7: 1713 return "d7"; 1714 case UNW_ARM_D8: 1715 return "d8"; 1716 case UNW_ARM_D9: 1717 return "d9"; 1718 case UNW_ARM_D10: 1719 return "d10"; 1720 case UNW_ARM_D11: 1721 return "d11"; 1722 case UNW_ARM_D12: 1723 return "d12"; 1724 case UNW_ARM_D13: 1725 return "d13"; 1726 case UNW_ARM_D14: 1727 return "d14"; 1728 case UNW_ARM_D15: 1729 return "d15"; 1730 case UNW_ARM_D16: 1731 return "d16"; 1732 case UNW_ARM_D17: 1733 return "d17"; 1734 case UNW_ARM_D18: 1735 return "d18"; 1736 case UNW_ARM_D19: 1737 return "d19"; 1738 case UNW_ARM_D20: 1739 return "d20"; 1740 case UNW_ARM_D21: 1741 return "d21"; 1742 case UNW_ARM_D22: 1743 return "d22"; 1744 case UNW_ARM_D23: 1745 return "d23"; 1746 case UNW_ARM_D24: 1747 return "d24"; 1748 case UNW_ARM_D25: 1749 return "d25"; 1750 case UNW_ARM_D26: 1751 return "d26"; 1752 case UNW_ARM_D27: 1753 return "d27"; 1754 case UNW_ARM_D28: 1755 return "d28"; 1756 case UNW_ARM_D29: 1757 return "d29"; 1758 case UNW_ARM_D30: 1759 return "d30"; 1760 case UNW_ARM_D31: 1761 return "d31"; 1762 default: 1763 return "unknown register"; 1764 } 1765 } 1766 1767 inline bool Registers_arm::validFloatRegister(int regNum) const { 1768 // NOTE: Consider the intel MMX registers floating points so the 1769 // unw_get_fpreg can be used to transmit the 64-bit data back. 1770 return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31)) 1771 #if defined(__ARM_WMMX) 1772 || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15)) 1773 #endif 1774 ; 1775 } 1776 1777 inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) { 1778 if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) { 1779 if (!_saved_vfp_d0_d15) { 1780 _saved_vfp_d0_d15 = true; 1781 if (_use_X_for_vfp_save) 1782 saveVFPWithFSTMX(_vfp_d0_d15_pad); 1783 else 1784 saveVFPWithFSTMD(_vfp_d0_d15_pad); 1785 } 1786 return _vfp_d0_d15_pad[regNum - UNW_ARM_D0]; 1787 } 1788 1789 if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) { 1790 if (!_saved_vfp_d16_d31) { 1791 _saved_vfp_d16_d31 = true; 1792 saveVFPv3(_vfp_d16_d31); 1793 } 1794 return _vfp_d16_d31[regNum - UNW_ARM_D16]; 1795 } 1796 1797 #if defined(__ARM_WMMX) 1798 if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) { 1799 if (!_saved_iwmmx) { 1800 _saved_iwmmx = true; 1801 saveiWMMX(_iwmmx); 1802 } 1803 return _iwmmx[regNum - UNW_ARM_WR0]; 1804 } 1805 #endif 1806 1807 _LIBUNWIND_ABORT("Unknown ARM float register"); 1808 } 1809 1810 inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) { 1811 if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) { 1812 if (!_saved_vfp_d0_d15) { 1813 _saved_vfp_d0_d15 = true; 1814 if (_use_X_for_vfp_save) 1815 saveVFPWithFSTMX(_vfp_d0_d15_pad); 1816 else 1817 saveVFPWithFSTMD(_vfp_d0_d15_pad); 1818 } 1819 _vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value; 1820 return; 1821 } 1822 1823 if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) { 1824 if (!_saved_vfp_d16_d31) { 1825 _saved_vfp_d16_d31 = true; 1826 saveVFPv3(_vfp_d16_d31); 1827 } 1828 _vfp_d16_d31[regNum - UNW_ARM_D16] = value; 1829 return; 1830 } 1831 1832 #if defined(__ARM_WMMX) 1833 if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) { 1834 if (!_saved_iwmmx) { 1835 _saved_iwmmx = true; 1836 saveiWMMX(_iwmmx); 1837 } 1838 _iwmmx[regNum - UNW_ARM_WR0] = value; 1839 return; 1840 } 1841 #endif 1842 1843 _LIBUNWIND_ABORT("Unknown ARM float register"); 1844 } 1845 1846 inline bool Registers_arm::validVectorRegister(int) const { 1847 return false; 1848 } 1849 1850 inline v128 Registers_arm::getVectorRegister(int) const { 1851 _LIBUNWIND_ABORT("ARM vector support not implemented"); 1852 } 1853 1854 inline void Registers_arm::setVectorRegister(int, v128) { 1855 _LIBUNWIND_ABORT("ARM vector support not implemented"); 1856 } 1857 #endif // _LIBUNWIND_TARGET_ARM 1858 1859 1860 #if defined(_LIBUNWIND_TARGET_OR1K) 1861 /// Registers_or1k holds the register state of a thread in an OpenRISC1000 1862 /// process. 1863 class _LIBUNWIND_HIDDEN Registers_or1k { 1864 public: 1865 Registers_or1k(); 1866 Registers_or1k(const void *registers); 1867 1868 bool validRegister(int num) const; 1869 uint32_t getRegister(int num) const; 1870 void setRegister(int num, uint32_t value); 1871 bool validFloatRegister(int num) const; 1872 double getFloatRegister(int num) const; 1873 void setFloatRegister(int num, double value); 1874 bool validVectorRegister(int num) const; 1875 v128 getVectorRegister(int num) const; 1876 void setVectorRegister(int num, v128 value); 1877 const char *getRegisterName(int num); 1878 void jumpto(); 1879 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K; } 1880 1881 uint64_t getSP() const { return _registers.__r[1]; } 1882 void setSP(uint32_t value) { _registers.__r[1] = value; } 1883 uint64_t getIP() const { return _registers.__r[9]; } 1884 void setIP(uint32_t value) { _registers.__r[9] = value; } 1885 1886 private: 1887 struct or1k_thread_state_t { 1888 unsigned int __r[32]; 1889 }; 1890 1891 or1k_thread_state_t _registers; 1892 }; 1893 1894 inline Registers_or1k::Registers_or1k(const void *registers) { 1895 static_assert((check_fit<Registers_or1k, unw_context_t>::does_fit), 1896 "or1k registers do not fit into unw_context_t"); 1897 memcpy(&_registers, static_cast<const uint8_t *>(registers), 1898 sizeof(_registers)); 1899 } 1900 1901 inline Registers_or1k::Registers_or1k() { 1902 memset(&_registers, 0, sizeof(_registers)); 1903 } 1904 1905 inline bool Registers_or1k::validRegister(int regNum) const { 1906 if (regNum == UNW_REG_IP) 1907 return true; 1908 if (regNum == UNW_REG_SP) 1909 return true; 1910 if (regNum < 0) 1911 return false; 1912 if (regNum <= UNW_OR1K_R31) 1913 return true; 1914 return false; 1915 } 1916 1917 inline uint32_t Registers_or1k::getRegister(int regNum) const { 1918 if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) 1919 return _registers.__r[regNum - UNW_OR1K_R0]; 1920 1921 switch (regNum) { 1922 case UNW_REG_IP: 1923 return _registers.__r[9]; 1924 case UNW_REG_SP: 1925 return _registers.__r[1]; 1926 } 1927 _LIBUNWIND_ABORT("unsupported or1k register"); 1928 } 1929 1930 inline void Registers_or1k::setRegister(int regNum, uint32_t value) { 1931 if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) { 1932 _registers.__r[regNum - UNW_OR1K_R0] = value; 1933 return; 1934 } 1935 1936 switch (regNum) { 1937 case UNW_REG_IP: 1938 _registers.__r[9] = value; 1939 return; 1940 case UNW_REG_SP: 1941 _registers.__r[1] = value; 1942 return; 1943 } 1944 _LIBUNWIND_ABORT("unsupported or1k register"); 1945 } 1946 1947 inline bool Registers_or1k::validFloatRegister(int /* regNum */) const { 1948 return false; 1949 } 1950 1951 inline double Registers_or1k::getFloatRegister(int /* regNum */) const { 1952 _LIBUNWIND_ABORT("or1k float support not implemented"); 1953 } 1954 1955 inline void Registers_or1k::setFloatRegister(int /* regNum */, 1956 double /* value */) { 1957 _LIBUNWIND_ABORT("or1k float support not implemented"); 1958 } 1959 1960 inline bool Registers_or1k::validVectorRegister(int /* regNum */) const { 1961 return false; 1962 } 1963 1964 inline v128 Registers_or1k::getVectorRegister(int /* regNum */) const { 1965 _LIBUNWIND_ABORT("or1k vector support not implemented"); 1966 } 1967 1968 inline void Registers_or1k::setVectorRegister(int /* regNum */, v128 /* value */) { 1969 _LIBUNWIND_ABORT("or1k vector support not implemented"); 1970 } 1971 1972 inline const char *Registers_or1k::getRegisterName(int regNum) { 1973 switch (regNum) { 1974 case UNW_OR1K_R0: 1975 return "r0"; 1976 case UNW_OR1K_R1: 1977 return "r1"; 1978 case UNW_OR1K_R2: 1979 return "r2"; 1980 case UNW_OR1K_R3: 1981 return "r3"; 1982 case UNW_OR1K_R4: 1983 return "r4"; 1984 case UNW_OR1K_R5: 1985 return "r5"; 1986 case UNW_OR1K_R6: 1987 return "r6"; 1988 case UNW_OR1K_R7: 1989 return "r7"; 1990 case UNW_OR1K_R8: 1991 return "r8"; 1992 case UNW_OR1K_R9: 1993 return "r9"; 1994 case UNW_OR1K_R10: 1995 return "r10"; 1996 case UNW_OR1K_R11: 1997 return "r11"; 1998 case UNW_OR1K_R12: 1999 return "r12"; 2000 case UNW_OR1K_R13: 2001 return "r13"; 2002 case UNW_OR1K_R14: 2003 return "r14"; 2004 case UNW_OR1K_R15: 2005 return "r15"; 2006 case UNW_OR1K_R16: 2007 return "r16"; 2008 case UNW_OR1K_R17: 2009 return "r17"; 2010 case UNW_OR1K_R18: 2011 return "r18"; 2012 case UNW_OR1K_R19: 2013 return "r19"; 2014 case UNW_OR1K_R20: 2015 return "r20"; 2016 case UNW_OR1K_R21: 2017 return "r21"; 2018 case UNW_OR1K_R22: 2019 return "r22"; 2020 case UNW_OR1K_R23: 2021 return "r23"; 2022 case UNW_OR1K_R24: 2023 return "r24"; 2024 case UNW_OR1K_R25: 2025 return "r25"; 2026 case UNW_OR1K_R26: 2027 return "r26"; 2028 case UNW_OR1K_R27: 2029 return "r27"; 2030 case UNW_OR1K_R28: 2031 return "r28"; 2032 case UNW_OR1K_R29: 2033 return "r29"; 2034 case UNW_OR1K_R30: 2035 return "r30"; 2036 case UNW_OR1K_R31: 2037 return "r31"; 2038 default: 2039 return "unknown register"; 2040 } 2041 2042 } 2043 #endif // _LIBUNWIND_TARGET_OR1K 2044 2045 #if defined(_LIBUNWIND_TARGET_MIPS_O32) 2046 /// Registers_mips_o32 holds the register state of a thread in a 32-bit MIPS 2047 /// process. 2048 class _LIBUNWIND_HIDDEN Registers_mips_o32 { 2049 public: 2050 Registers_mips_o32(); 2051 Registers_mips_o32(const void *registers); 2052 2053 bool validRegister(int num) const; 2054 uint32_t getRegister(int num) const; 2055 void setRegister(int num, uint32_t value); 2056 bool validFloatRegister(int num) const; 2057 double getFloatRegister(int num) const; 2058 void setFloatRegister(int num, double value); 2059 bool validVectorRegister(int num) const; 2060 v128 getVectorRegister(int num) const; 2061 void setVectorRegister(int num, v128 value); 2062 const char *getRegisterName(int num); 2063 void jumpto(); 2064 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; } 2065 2066 uint32_t getSP() const { return _registers.__r[29]; } 2067 void setSP(uint32_t value) { _registers.__r[29] = value; } 2068 uint32_t getIP() const { return _registers.__pc; } 2069 void setIP(uint32_t value) { _registers.__pc = value; } 2070 2071 private: 2072 struct mips_o32_thread_state_t { 2073 uint32_t __r[32]; 2074 uint32_t __pc; 2075 uint32_t __hi; 2076 uint32_t __lo; 2077 }; 2078 2079 mips_o32_thread_state_t _registers; 2080 }; 2081 2082 inline Registers_mips_o32::Registers_mips_o32(const void *registers) { 2083 static_assert((check_fit<Registers_mips_o32, unw_context_t>::does_fit), 2084 "mips_o32 registers do not fit into unw_context_t"); 2085 memcpy(&_registers, static_cast<const uint8_t *>(registers), 2086 sizeof(_registers)); 2087 } 2088 2089 inline Registers_mips_o32::Registers_mips_o32() { 2090 memset(&_registers, 0, sizeof(_registers)); 2091 } 2092 2093 inline bool Registers_mips_o32::validRegister(int regNum) const { 2094 if (regNum == UNW_REG_IP) 2095 return true; 2096 if (regNum == UNW_REG_SP) 2097 return true; 2098 if (regNum < 0) 2099 return false; 2100 if (regNum <= UNW_MIPS_R31) 2101 return true; 2102 if (regNum == UNW_MIPS_HI) 2103 return true; 2104 if (regNum == UNW_MIPS_LO) 2105 return true; 2106 // FIXME: Hard float, DSP accumulator registers, MSA registers 2107 return false; 2108 } 2109 2110 inline uint32_t Registers_mips_o32::getRegister(int regNum) const { 2111 if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) 2112 return _registers.__r[regNum - UNW_MIPS_R0]; 2113 2114 switch (regNum) { 2115 case UNW_REG_IP: 2116 return _registers.__pc; 2117 case UNW_REG_SP: 2118 return _registers.__r[29]; 2119 case UNW_MIPS_HI: 2120 return _registers.__hi; 2121 case UNW_MIPS_LO: 2122 return _registers.__lo; 2123 } 2124 _LIBUNWIND_ABORT("unsupported mips_o32 register"); 2125 } 2126 2127 inline void Registers_mips_o32::setRegister(int regNum, uint32_t value) { 2128 if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) { 2129 _registers.__r[regNum - UNW_MIPS_R0] = value; 2130 return; 2131 } 2132 2133 switch (regNum) { 2134 case UNW_REG_IP: 2135 _registers.__pc = value; 2136 return; 2137 case UNW_REG_SP: 2138 _registers.__r[29] = value; 2139 return; 2140 case UNW_MIPS_HI: 2141 _registers.__hi = value; 2142 return; 2143 case UNW_MIPS_LO: 2144 _registers.__lo = value; 2145 return; 2146 } 2147 _LIBUNWIND_ABORT("unsupported mips_o32 register"); 2148 } 2149 2150 inline bool Registers_mips_o32::validFloatRegister(int /* regNum */) const { 2151 return false; 2152 } 2153 2154 inline double Registers_mips_o32::getFloatRegister(int /* regNum */) const { 2155 _LIBUNWIND_ABORT("mips_o32 float support not implemented"); 2156 } 2157 2158 inline void Registers_mips_o32::setFloatRegister(int /* regNum */, 2159 double /* value */) { 2160 _LIBUNWIND_ABORT("mips_o32 float support not implemented"); 2161 } 2162 2163 inline bool Registers_mips_o32::validVectorRegister(int /* regNum */) const { 2164 return false; 2165 } 2166 2167 inline v128 Registers_mips_o32::getVectorRegister(int /* regNum */) const { 2168 _LIBUNWIND_ABORT("mips_o32 vector support not implemented"); 2169 } 2170 2171 inline void Registers_mips_o32::setVectorRegister(int /* regNum */, v128 /* value */) { 2172 _LIBUNWIND_ABORT("mips_o32 vector support not implemented"); 2173 } 2174 2175 inline const char *Registers_mips_o32::getRegisterName(int regNum) { 2176 switch (regNum) { 2177 case UNW_MIPS_R0: 2178 return "$0"; 2179 case UNW_MIPS_R1: 2180 return "$1"; 2181 case UNW_MIPS_R2: 2182 return "$2"; 2183 case UNW_MIPS_R3: 2184 return "$3"; 2185 case UNW_MIPS_R4: 2186 return "$4"; 2187 case UNW_MIPS_R5: 2188 return "$5"; 2189 case UNW_MIPS_R6: 2190 return "$6"; 2191 case UNW_MIPS_R7: 2192 return "$7"; 2193 case UNW_MIPS_R8: 2194 return "$8"; 2195 case UNW_MIPS_R9: 2196 return "$9"; 2197 case UNW_MIPS_R10: 2198 return "$10"; 2199 case UNW_MIPS_R11: 2200 return "$11"; 2201 case UNW_MIPS_R12: 2202 return "$12"; 2203 case UNW_MIPS_R13: 2204 return "$13"; 2205 case UNW_MIPS_R14: 2206 return "$14"; 2207 case UNW_MIPS_R15: 2208 return "$15"; 2209 case UNW_MIPS_R16: 2210 return "$16"; 2211 case UNW_MIPS_R17: 2212 return "$17"; 2213 case UNW_MIPS_R18: 2214 return "$18"; 2215 case UNW_MIPS_R19: 2216 return "$19"; 2217 case UNW_MIPS_R20: 2218 return "$20"; 2219 case UNW_MIPS_R21: 2220 return "$21"; 2221 case UNW_MIPS_R22: 2222 return "$22"; 2223 case UNW_MIPS_R23: 2224 return "$23"; 2225 case UNW_MIPS_R24: 2226 return "$24"; 2227 case UNW_MIPS_R25: 2228 return "$25"; 2229 case UNW_MIPS_R26: 2230 return "$26"; 2231 case UNW_MIPS_R27: 2232 return "$27"; 2233 case UNW_MIPS_R28: 2234 return "$28"; 2235 case UNW_MIPS_R29: 2236 return "$29"; 2237 case UNW_MIPS_R30: 2238 return "$30"; 2239 case UNW_MIPS_R31: 2240 return "$31"; 2241 case UNW_MIPS_HI: 2242 return "$hi"; 2243 case UNW_MIPS_LO: 2244 return "$lo"; 2245 default: 2246 return "unknown register"; 2247 } 2248 } 2249 #endif // _LIBUNWIND_TARGET_MIPS_O32 2250 2251 #if defined(_LIBUNWIND_TARGET_MIPS_N64) 2252 /// Registers_mips_n64 holds the register state of a thread in a 64-bit MIPS 2253 /// process. 2254 class _LIBUNWIND_HIDDEN Registers_mips_n64 { 2255 public: 2256 Registers_mips_n64(); 2257 Registers_mips_n64(const void *registers); 2258 2259 bool validRegister(int num) const; 2260 uint64_t getRegister(int num) const; 2261 void setRegister(int num, uint64_t value); 2262 bool validFloatRegister(int num) const; 2263 double getFloatRegister(int num) const; 2264 void setFloatRegister(int num, double value); 2265 bool validVectorRegister(int num) const; 2266 v128 getVectorRegister(int num) const; 2267 void setVectorRegister(int num, v128 value); 2268 const char *getRegisterName(int num); 2269 void jumpto(); 2270 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; } 2271 2272 uint64_t getSP() const { return _registers.__r[29]; } 2273 void setSP(uint64_t value) { _registers.__r[29] = value; } 2274 uint64_t getIP() const { return _registers.__pc; } 2275 void setIP(uint64_t value) { _registers.__pc = value; } 2276 2277 private: 2278 struct mips_n64_thread_state_t { 2279 uint64_t __r[32]; 2280 uint64_t __pc; 2281 uint64_t __hi; 2282 uint64_t __lo; 2283 }; 2284 2285 mips_n64_thread_state_t _registers; 2286 }; 2287 2288 inline Registers_mips_n64::Registers_mips_n64(const void *registers) { 2289 static_assert((check_fit<Registers_mips_n64, unw_context_t>::does_fit), 2290 "mips_n64 registers do not fit into unw_context_t"); 2291 memcpy(&_registers, static_cast<const uint8_t *>(registers), 2292 sizeof(_registers)); 2293 } 2294 2295 inline Registers_mips_n64::Registers_mips_n64() { 2296 memset(&_registers, 0, sizeof(_registers)); 2297 } 2298 2299 inline bool Registers_mips_n64::validRegister(int regNum) const { 2300 if (regNum == UNW_REG_IP) 2301 return true; 2302 if (regNum == UNW_REG_SP) 2303 return true; 2304 if (regNum < 0) 2305 return false; 2306 if (regNum <= UNW_MIPS_R31) 2307 return true; 2308 if (regNum == UNW_MIPS_HI) 2309 return true; 2310 if (regNum == UNW_MIPS_LO) 2311 return true; 2312 // FIXME: Hard float, DSP accumulator registers, MSA registers 2313 return false; 2314 } 2315 2316 inline uint64_t Registers_mips_n64::getRegister(int regNum) const { 2317 if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) 2318 return _registers.__r[regNum - UNW_MIPS_R0]; 2319 2320 switch (regNum) { 2321 case UNW_REG_IP: 2322 return _registers.__pc; 2323 case UNW_REG_SP: 2324 return _registers.__r[29]; 2325 case UNW_MIPS_HI: 2326 return _registers.__hi; 2327 case UNW_MIPS_LO: 2328 return _registers.__lo; 2329 } 2330 _LIBUNWIND_ABORT("unsupported mips_n64 register"); 2331 } 2332 2333 inline void Registers_mips_n64::setRegister(int regNum, uint64_t value) { 2334 if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) { 2335 _registers.__r[regNum - UNW_MIPS_R0] = value; 2336 return; 2337 } 2338 2339 switch (regNum) { 2340 case UNW_REG_IP: 2341 _registers.__pc = value; 2342 return; 2343 case UNW_REG_SP: 2344 _registers.__r[29] = value; 2345 return; 2346 case UNW_MIPS_HI: 2347 _registers.__hi = value; 2348 return; 2349 case UNW_MIPS_LO: 2350 _registers.__lo = value; 2351 return; 2352 } 2353 _LIBUNWIND_ABORT("unsupported mips_n64 register"); 2354 } 2355 2356 inline bool Registers_mips_n64::validFloatRegister(int /* regNum */) const { 2357 return false; 2358 } 2359 2360 inline double Registers_mips_n64::getFloatRegister(int /* regNum */) const { 2361 _LIBUNWIND_ABORT("mips_n64 float support not implemented"); 2362 } 2363 2364 inline void Registers_mips_n64::setFloatRegister(int /* regNum */, 2365 double /* value */) { 2366 _LIBUNWIND_ABORT("mips_n64 float support not implemented"); 2367 } 2368 2369 inline bool Registers_mips_n64::validVectorRegister(int /* regNum */) const { 2370 return false; 2371 } 2372 2373 inline v128 Registers_mips_n64::getVectorRegister(int /* regNum */) const { 2374 _LIBUNWIND_ABORT("mips_n64 vector support not implemented"); 2375 } 2376 2377 inline void Registers_mips_n64::setVectorRegister(int /* regNum */, v128 /* value */) { 2378 _LIBUNWIND_ABORT("mips_n64 vector support not implemented"); 2379 } 2380 2381 inline const char *Registers_mips_n64::getRegisterName(int regNum) { 2382 switch (regNum) { 2383 case UNW_MIPS_R0: 2384 return "$0"; 2385 case UNW_MIPS_R1: 2386 return "$1"; 2387 case UNW_MIPS_R2: 2388 return "$2"; 2389 case UNW_MIPS_R3: 2390 return "$3"; 2391 case UNW_MIPS_R4: 2392 return "$4"; 2393 case UNW_MIPS_R5: 2394 return "$5"; 2395 case UNW_MIPS_R6: 2396 return "$6"; 2397 case UNW_MIPS_R7: 2398 return "$7"; 2399 case UNW_MIPS_R8: 2400 return "$8"; 2401 case UNW_MIPS_R9: 2402 return "$9"; 2403 case UNW_MIPS_R10: 2404 return "$10"; 2405 case UNW_MIPS_R11: 2406 return "$11"; 2407 case UNW_MIPS_R12: 2408 return "$12"; 2409 case UNW_MIPS_R13: 2410 return "$13"; 2411 case UNW_MIPS_R14: 2412 return "$14"; 2413 case UNW_MIPS_R15: 2414 return "$15"; 2415 case UNW_MIPS_R16: 2416 return "$16"; 2417 case UNW_MIPS_R17: 2418 return "$17"; 2419 case UNW_MIPS_R18: 2420 return "$18"; 2421 case UNW_MIPS_R19: 2422 return "$19"; 2423 case UNW_MIPS_R20: 2424 return "$20"; 2425 case UNW_MIPS_R21: 2426 return "$21"; 2427 case UNW_MIPS_R22: 2428 return "$22"; 2429 case UNW_MIPS_R23: 2430 return "$23"; 2431 case UNW_MIPS_R24: 2432 return "$24"; 2433 case UNW_MIPS_R25: 2434 return "$25"; 2435 case UNW_MIPS_R26: 2436 return "$26"; 2437 case UNW_MIPS_R27: 2438 return "$27"; 2439 case UNW_MIPS_R28: 2440 return "$28"; 2441 case UNW_MIPS_R29: 2442 return "$29"; 2443 case UNW_MIPS_R30: 2444 return "$30"; 2445 case UNW_MIPS_R31: 2446 return "$31"; 2447 case UNW_MIPS_HI: 2448 return "$hi"; 2449 case UNW_MIPS_LO: 2450 return "$lo"; 2451 default: 2452 return "unknown register"; 2453 } 2454 } 2455 #endif // _LIBUNWIND_TARGET_MIPS_N64 2456 } // namespace libunwind 2457 2458 #endif // __REGISTERS_HPP__ 2459