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