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