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