1 //===----------------------------- Registers.hpp --------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 // 9 // Models register sets for supported processors. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef __REGISTERS_HPP__ 14 #define __REGISTERS_HPP__ 15 16 #include <stdint.h> 17 #include <strings.h> 18 #include <string.h> 19 20 #include "libunwind.h" 21 #include "config.h" 22 23 namespace libunwind { 24 25 // For emulating 128-bit registers 26 struct v128 { uint32_t vec[4]; }; 27 28 29 /// Registers_x86 holds the register state of a thread in a 32-bit intel 30 /// process. 31 class _LIBUNWIND_HIDDEN Registers_x86 { 32 public: 33 Registers_x86(); 34 Registers_x86(const void *registers); 35 36 bool validRegister(int num) const; 37 uint32_t getRegister(int num) const; 38 void setRegister(int num, uint32_t value); 39 bool validFloatRegister(int) const { return false; } 40 double getFloatRegister(int num) const; 41 void setFloatRegister(int num, double value); 42 bool validVectorRegister(int) const { return false; } 43 v128 getVectorRegister(int num) const; 44 void setVectorRegister(int num, v128 value); 45 const char *getRegisterName(int num); 46 void jumpto(); 47 static int lastDwarfRegNum() { return 8; } 48 49 uint32_t getSP() const { return _registers.__esp; } 50 void setSP(uint32_t value) { _registers.__esp = value; } 51 uint32_t getIP() const { return _registers.__eip; } 52 void setIP(uint32_t value) { _registers.__eip = value; } 53 uint32_t getEBP() const { return _registers.__ebp; } 54 void setEBP(uint32_t value) { _registers.__ebp = value; } 55 uint32_t getEBX() const { return _registers.__ebx; } 56 void setEBX(uint32_t value) { _registers.__ebx = value; } 57 uint32_t getECX() const { return _registers.__ecx; } 58 void setECX(uint32_t value) { _registers.__ecx = value; } 59 uint32_t getEDX() const { return _registers.__edx; } 60 void setEDX(uint32_t value) { _registers.__edx = value; } 61 uint32_t getESI() const { return _registers.__esi; } 62 void setESI(uint32_t value) { _registers.__esi = value; } 63 uint32_t getEDI() const { return _registers.__edi; } 64 void setEDI(uint32_t value) { _registers.__edi = value; } 65 66 private: 67 struct GPRs { 68 unsigned int __eax; 69 unsigned int __ebx; 70 unsigned int __ecx; 71 unsigned int __edx; 72 unsigned int __edi; 73 unsigned int __esi; 74 unsigned int __ebp; 75 unsigned int __esp; 76 unsigned int __ss; 77 unsigned int __eflags; 78 unsigned int __eip; 79 unsigned int __cs; 80 unsigned int __ds; 81 unsigned int __es; 82 unsigned int __fs; 83 unsigned int __gs; 84 }; 85 86 GPRs _registers; 87 }; 88 89 inline Registers_x86::Registers_x86(const void *registers) { 90 static_assert(sizeof(Registers_x86) < sizeof(unw_context_t), 91 "x86 registers do not fit into unw_context_t"); 92 _registers = *((GPRs *)registers); 93 } 94 95 inline Registers_x86::Registers_x86() { 96 memset(&_registers, 0, sizeof(_registers)); 97 } 98 99 inline bool Registers_x86::validRegister(int regNum) const { 100 if (regNum == UNW_REG_IP) 101 return true; 102 if (regNum == UNW_REG_SP) 103 return true; 104 if (regNum < 0) 105 return false; 106 if (regNum > 7) 107 return false; 108 return true; 109 } 110 111 inline uint32_t Registers_x86::getRegister(int regNum) const { 112 switch (regNum) { 113 case UNW_REG_IP: 114 return _registers.__eip; 115 case UNW_REG_SP: 116 return _registers.__esp; 117 case UNW_X86_EAX: 118 return _registers.__eax; 119 case UNW_X86_ECX: 120 return _registers.__ecx; 121 case UNW_X86_EDX: 122 return _registers.__edx; 123 case UNW_X86_EBX: 124 return _registers.__ebx; 125 case UNW_X86_EBP: 126 return _registers.__ebp; 127 case UNW_X86_ESP: 128 return _registers.__esp; 129 case UNW_X86_ESI: 130 return _registers.__esi; 131 case UNW_X86_EDI: 132 return _registers.__edi; 133 } 134 _LIBUNWIND_ABORT("unsupported x86 register"); 135 } 136 137 inline void Registers_x86::setRegister(int regNum, uint32_t value) { 138 switch (regNum) { 139 case UNW_REG_IP: 140 _registers.__eip = value; 141 return; 142 case UNW_REG_SP: 143 _registers.__esp = value; 144 return; 145 case UNW_X86_EAX: 146 _registers.__eax = value; 147 return; 148 case UNW_X86_ECX: 149 _registers.__ecx = value; 150 return; 151 case UNW_X86_EDX: 152 _registers.__edx = value; 153 return; 154 case UNW_X86_EBX: 155 _registers.__ebx = value; 156 return; 157 case UNW_X86_EBP: 158 _registers.__ebp = value; 159 return; 160 case UNW_X86_ESP: 161 _registers.__esp = value; 162 return; 163 case UNW_X86_ESI: 164 _registers.__esi = value; 165 return; 166 case UNW_X86_EDI: 167 _registers.__edi = value; 168 return; 169 } 170 _LIBUNWIND_ABORT("unsupported x86 register"); 171 } 172 173 inline const char *Registers_x86::getRegisterName(int regNum) { 174 switch (regNum) { 175 case UNW_REG_IP: 176 return "ip"; 177 case UNW_REG_SP: 178 return "esp"; 179 case UNW_X86_EAX: 180 return "eax"; 181 case UNW_X86_ECX: 182 return "ecx"; 183 case UNW_X86_EDX: 184 return "edx"; 185 case UNW_X86_EBX: 186 return "ebx"; 187 case UNW_X86_EBP: 188 return "ebp"; 189 case UNW_X86_ESP: 190 return "esp"; 191 case UNW_X86_ESI: 192 return "esi"; 193 case UNW_X86_EDI: 194 return "edi"; 195 default: 196 return "unknown register"; 197 } 198 } 199 200 inline double Registers_x86::getFloatRegister(int) const { 201 _LIBUNWIND_ABORT("no x86 float registers"); 202 } 203 204 inline void Registers_x86::setFloatRegister(int, double) { 205 _LIBUNWIND_ABORT("no x86 float registers"); 206 } 207 208 inline v128 Registers_x86::getVectorRegister(int) const { 209 _LIBUNWIND_ABORT("no x86 vector registers"); 210 } 211 212 inline void Registers_x86::setVectorRegister(int, v128) { 213 _LIBUNWIND_ABORT("no x86 vector registers"); 214 } 215 216 217 /// Registers_x86_64 holds the register state of a thread in a 64-bit intel 218 /// process. 219 class _LIBUNWIND_HIDDEN Registers_x86_64 { 220 public: 221 Registers_x86_64(); 222 Registers_x86_64(const void *registers); 223 224 bool validRegister(int num) const; 225 uint64_t getRegister(int num) const; 226 void setRegister(int num, uint64_t value); 227 bool validFloatRegister(int) const { return false; } 228 double getFloatRegister(int num) const; 229 void setFloatRegister(int num, double value); 230 bool validVectorRegister(int) const { return false; } 231 v128 getVectorRegister(int num) const; 232 void setVectorRegister(int num, v128 value); 233 const char *getRegisterName(int num); 234 void jumpto(); 235 static int lastDwarfRegNum() { return 16; } 236 237 uint64_t getSP() const { return _registers.__rsp; } 238 void setSP(uint64_t value) { _registers.__rsp = value; } 239 uint64_t getIP() const { return _registers.__rip; } 240 void setIP(uint64_t value) { _registers.__rip = value; } 241 uint64_t getRBP() const { return _registers.__rbp; } 242 void setRBP(uint64_t value) { _registers.__rbp = value; } 243 uint64_t getRBX() const { return _registers.__rbx; } 244 void setRBX(uint64_t value) { _registers.__rbx = value; } 245 uint64_t getR12() const { return _registers.__r12; } 246 void setR12(uint64_t value) { _registers.__r12 = value; } 247 uint64_t getR13() const { return _registers.__r13; } 248 void setR13(uint64_t value) { _registers.__r13 = value; } 249 uint64_t getR14() const { return _registers.__r14; } 250 void setR14(uint64_t value) { _registers.__r14 = value; } 251 uint64_t getR15() const { return _registers.__r15; } 252 void setR15(uint64_t value) { _registers.__r15 = value; } 253 254 private: 255 struct GPRs { 256 uint64_t __rax; 257 uint64_t __rbx; 258 uint64_t __rcx; 259 uint64_t __rdx; 260 uint64_t __rdi; 261 uint64_t __rsi; 262 uint64_t __rbp; 263 uint64_t __rsp; 264 uint64_t __r8; 265 uint64_t __r9; 266 uint64_t __r10; 267 uint64_t __r11; 268 uint64_t __r12; 269 uint64_t __r13; 270 uint64_t __r14; 271 uint64_t __r15; 272 uint64_t __rip; 273 uint64_t __rflags; 274 uint64_t __cs; 275 uint64_t __fs; 276 uint64_t __gs; 277 }; 278 GPRs _registers; 279 }; 280 281 inline Registers_x86_64::Registers_x86_64(const void *registers) { 282 static_assert(sizeof(Registers_x86_64) < sizeof(unw_context_t), 283 "x86_64 registers do not fit into unw_context_t"); 284 _registers = *((GPRs *)registers); 285 } 286 287 inline Registers_x86_64::Registers_x86_64() { 288 memset(&_registers, 0, sizeof(_registers)); 289 } 290 291 inline bool Registers_x86_64::validRegister(int regNum) const { 292 if (regNum == UNW_REG_IP) 293 return true; 294 if (regNum == UNW_REG_SP) 295 return true; 296 if (regNum < 0) 297 return false; 298 if (regNum > 15) 299 return false; 300 return true; 301 } 302 303 inline uint64_t Registers_x86_64::getRegister(int regNum) const { 304 switch (regNum) { 305 case UNW_REG_IP: 306 return _registers.__rip; 307 case UNW_REG_SP: 308 return _registers.__rsp; 309 case UNW_X86_64_RAX: 310 return _registers.__rax; 311 case UNW_X86_64_RDX: 312 return _registers.__rdx; 313 case UNW_X86_64_RCX: 314 return _registers.__rcx; 315 case UNW_X86_64_RBX: 316 return _registers.__rbx; 317 case UNW_X86_64_RSI: 318 return _registers.__rsi; 319 case UNW_X86_64_RDI: 320 return _registers.__rdi; 321 case UNW_X86_64_RBP: 322 return _registers.__rbp; 323 case UNW_X86_64_RSP: 324 return _registers.__rsp; 325 case UNW_X86_64_R8: 326 return _registers.__r8; 327 case UNW_X86_64_R9: 328 return _registers.__r9; 329 case UNW_X86_64_R10: 330 return _registers.__r10; 331 case UNW_X86_64_R11: 332 return _registers.__r11; 333 case UNW_X86_64_R12: 334 return _registers.__r12; 335 case UNW_X86_64_R13: 336 return _registers.__r13; 337 case UNW_X86_64_R14: 338 return _registers.__r14; 339 case UNW_X86_64_R15: 340 return _registers.__r15; 341 } 342 _LIBUNWIND_ABORT("unsupported x86_64 register"); 343 } 344 345 inline void Registers_x86_64::setRegister(int regNum, uint64_t value) { 346 switch (regNum) { 347 case UNW_REG_IP: 348 _registers.__rip = value; 349 return; 350 case UNW_REG_SP: 351 _registers.__rsp = value; 352 return; 353 case UNW_X86_64_RAX: 354 _registers.__rax = value; 355 return; 356 case UNW_X86_64_RDX: 357 _registers.__rdx = value; 358 return; 359 case UNW_X86_64_RCX: 360 _registers.__rcx = value; 361 return; 362 case UNW_X86_64_RBX: 363 _registers.__rbx = value; 364 return; 365 case UNW_X86_64_RSI: 366 _registers.__rsi = value; 367 return; 368 case UNW_X86_64_RDI: 369 _registers.__rdi = value; 370 return; 371 case UNW_X86_64_RBP: 372 _registers.__rbp = value; 373 return; 374 case UNW_X86_64_RSP: 375 _registers.__rsp = value; 376 return; 377 case UNW_X86_64_R8: 378 _registers.__r8 = value; 379 return; 380 case UNW_X86_64_R9: 381 _registers.__r9 = value; 382 return; 383 case UNW_X86_64_R10: 384 _registers.__r10 = value; 385 return; 386 case UNW_X86_64_R11: 387 _registers.__r11 = value; 388 return; 389 case UNW_X86_64_R12: 390 _registers.__r12 = value; 391 return; 392 case UNW_X86_64_R13: 393 _registers.__r13 = value; 394 return; 395 case UNW_X86_64_R14: 396 _registers.__r14 = value; 397 return; 398 case UNW_X86_64_R15: 399 _registers.__r15 = value; 400 return; 401 } 402 _LIBUNWIND_ABORT("unsupported x86_64 register"); 403 } 404 405 inline const char *Registers_x86_64::getRegisterName(int regNum) { 406 switch (regNum) { 407 case UNW_REG_IP: 408 return "rip"; 409 case UNW_REG_SP: 410 return "rsp"; 411 case UNW_X86_64_RAX: 412 return "rax"; 413 case UNW_X86_64_RDX: 414 return "rdx"; 415 case UNW_X86_64_RCX: 416 return "rcx"; 417 case UNW_X86_64_RBX: 418 return "rbx"; 419 case UNW_X86_64_RSI: 420 return "rsi"; 421 case UNW_X86_64_RDI: 422 return "rdi"; 423 case UNW_X86_64_RBP: 424 return "rbp"; 425 case UNW_X86_64_RSP: 426 return "rsp"; 427 case UNW_X86_64_R8: 428 return "r8"; 429 case UNW_X86_64_R9: 430 return "r9"; 431 case UNW_X86_64_R10: 432 return "r10"; 433 case UNW_X86_64_R11: 434 return "r11"; 435 case UNW_X86_64_R12: 436 return "r12"; 437 case UNW_X86_64_R13: 438 return "r13"; 439 case UNW_X86_64_R14: 440 return "r14"; 441 case UNW_X86_64_R15: 442 return "r15"; 443 default: 444 return "unknown register"; 445 } 446 } 447 448 inline double Registers_x86_64::getFloatRegister(int) const { 449 _LIBUNWIND_ABORT("no x86_64 float registers"); 450 } 451 452 inline void Registers_x86_64::setFloatRegister(int, double) { 453 _LIBUNWIND_ABORT("no x86_64 float registers"); 454 } 455 456 inline v128 Registers_x86_64::getVectorRegister(int) const { 457 _LIBUNWIND_ABORT("no x86_64 vector registers"); 458 } 459 460 inline void Registers_x86_64::setVectorRegister(int, v128) { 461 _LIBUNWIND_ABORT("no x86_64 vector registers"); 462 } 463 464 465 /// Registers_ppc holds the register state of a thread in a 32-bit PowerPC 466 /// process. 467 class _LIBUNWIND_HIDDEN Registers_ppc { 468 public: 469 Registers_ppc(); 470 Registers_ppc(const void *registers); 471 472 bool validRegister(int num) const; 473 uint32_t getRegister(int num) const; 474 void setRegister(int num, uint32_t value); 475 bool validFloatRegister(int num) const; 476 double getFloatRegister(int num) const; 477 void setFloatRegister(int num, double value); 478 bool validVectorRegister(int num) const; 479 v128 getVectorRegister(int num) const; 480 void setVectorRegister(int num, v128 value); 481 const char *getRegisterName(int num); 482 void jumpto(); 483 static int lastDwarfRegNum() { return 112; } 484 485 uint64_t getSP() const { return _registers.__r1; } 486 void setSP(uint32_t value) { _registers.__r1 = value; } 487 uint64_t getIP() const { return _registers.__srr0; } 488 void setIP(uint32_t value) { _registers.__srr0 = value; } 489 490 private: 491 struct ppc_thread_state_t { 492 unsigned int __srr0; /* Instruction address register (PC) */ 493 unsigned int __srr1; /* Machine state register (supervisor) */ 494 unsigned int __r0; 495 unsigned int __r1; 496 unsigned int __r2; 497 unsigned int __r3; 498 unsigned int __r4; 499 unsigned int __r5; 500 unsigned int __r6; 501 unsigned int __r7; 502 unsigned int __r8; 503 unsigned int __r9; 504 unsigned int __r10; 505 unsigned int __r11; 506 unsigned int __r12; 507 unsigned int __r13; 508 unsigned int __r14; 509 unsigned int __r15; 510 unsigned int __r16; 511 unsigned int __r17; 512 unsigned int __r18; 513 unsigned int __r19; 514 unsigned int __r20; 515 unsigned int __r21; 516 unsigned int __r22; 517 unsigned int __r23; 518 unsigned int __r24; 519 unsigned int __r25; 520 unsigned int __r26; 521 unsigned int __r27; 522 unsigned int __r28; 523 unsigned int __r29; 524 unsigned int __r30; 525 unsigned int __r31; 526 unsigned int __cr; /* Condition register */ 527 unsigned int __xer; /* User's integer exception register */ 528 unsigned int __lr; /* Link register */ 529 unsigned int __ctr; /* Count register */ 530 unsigned int __mq; /* MQ register (601 only) */ 531 unsigned int __vrsave; /* Vector Save Register */ 532 }; 533 534 struct ppc_float_state_t { 535 double __fpregs[32]; 536 537 unsigned int __fpscr_pad; /* fpscr is 64 bits, 32 bits of rubbish */ 538 unsigned int __fpscr; /* floating point status register */ 539 }; 540 541 ppc_thread_state_t _registers; 542 ppc_float_state_t _floatRegisters; 543 v128 _vectorRegisters[32]; // offset 424 544 }; 545 546 inline Registers_ppc::Registers_ppc(const void *registers) { 547 static_assert(sizeof(Registers_ppc) < sizeof(unw_context_t), 548 "ppc registers do not fit into unw_context_t"); 549 _registers = *((ppc_thread_state_t *)registers); 550 _floatRegisters = *((ppc_float_state_t *)((char *)registers + 160)); 551 memcpy(_vectorRegisters, ((char *)registers + 424), sizeof(_vectorRegisters)); 552 } 553 554 inline Registers_ppc::Registers_ppc() { 555 memset(&_registers, 0, sizeof(_registers)); 556 memset(&_floatRegisters, 0, sizeof(_floatRegisters)); 557 memset(&_vectorRegisters, 0, sizeof(_vectorRegisters)); 558 } 559 560 inline bool Registers_ppc::validRegister(int regNum) const { 561 if (regNum == UNW_REG_IP) 562 return true; 563 if (regNum == UNW_REG_SP) 564 return true; 565 if (regNum == UNW_PPC_VRSAVE) 566 return true; 567 if (regNum < 0) 568 return false; 569 if (regNum <= UNW_PPC_R31) 570 return true; 571 if (regNum == UNW_PPC_MQ) 572 return true; 573 if (regNum == UNW_PPC_LR) 574 return true; 575 if (regNum == UNW_PPC_CTR) 576 return true; 577 if ((UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7)) 578 return true; 579 return false; 580 } 581 582 inline uint32_t Registers_ppc::getRegister(int regNum) const { 583 switch (regNum) { 584 case UNW_REG_IP: 585 return _registers.__srr0; 586 case UNW_REG_SP: 587 return _registers.__r1; 588 case UNW_PPC_R0: 589 return _registers.__r0; 590 case UNW_PPC_R1: 591 return _registers.__r1; 592 case UNW_PPC_R2: 593 return _registers.__r2; 594 case UNW_PPC_R3: 595 return _registers.__r3; 596 case UNW_PPC_R4: 597 return _registers.__r4; 598 case UNW_PPC_R5: 599 return _registers.__r5; 600 case UNW_PPC_R6: 601 return _registers.__r6; 602 case UNW_PPC_R7: 603 return _registers.__r7; 604 case UNW_PPC_R8: 605 return _registers.__r8; 606 case UNW_PPC_R9: 607 return _registers.__r9; 608 case UNW_PPC_R10: 609 return _registers.__r10; 610 case UNW_PPC_R11: 611 return _registers.__r11; 612 case UNW_PPC_R12: 613 return _registers.__r12; 614 case UNW_PPC_R13: 615 return _registers.__r13; 616 case UNW_PPC_R14: 617 return _registers.__r14; 618 case UNW_PPC_R15: 619 return _registers.__r15; 620 case UNW_PPC_R16: 621 return _registers.__r16; 622 case UNW_PPC_R17: 623 return _registers.__r17; 624 case UNW_PPC_R18: 625 return _registers.__r18; 626 case UNW_PPC_R19: 627 return _registers.__r19; 628 case UNW_PPC_R20: 629 return _registers.__r20; 630 case UNW_PPC_R21: 631 return _registers.__r21; 632 case UNW_PPC_R22: 633 return _registers.__r22; 634 case UNW_PPC_R23: 635 return _registers.__r23; 636 case UNW_PPC_R24: 637 return _registers.__r24; 638 case UNW_PPC_R25: 639 return _registers.__r25; 640 case UNW_PPC_R26: 641 return _registers.__r26; 642 case UNW_PPC_R27: 643 return _registers.__r27; 644 case UNW_PPC_R28: 645 return _registers.__r28; 646 case UNW_PPC_R29: 647 return _registers.__r29; 648 case UNW_PPC_R30: 649 return _registers.__r30; 650 case UNW_PPC_R31: 651 return _registers.__r31; 652 case UNW_PPC_LR: 653 return _registers.__lr; 654 case UNW_PPC_CR0: 655 return (_registers.__cr & 0xF0000000); 656 case UNW_PPC_CR1: 657 return (_registers.__cr & 0x0F000000); 658 case UNW_PPC_CR2: 659 return (_registers.__cr & 0x00F00000); 660 case UNW_PPC_CR3: 661 return (_registers.__cr & 0x000F0000); 662 case UNW_PPC_CR4: 663 return (_registers.__cr & 0x0000F000); 664 case UNW_PPC_CR5: 665 return (_registers.__cr & 0x00000F00); 666 case UNW_PPC_CR6: 667 return (_registers.__cr & 0x000000F0); 668 case UNW_PPC_CR7: 669 return (_registers.__cr & 0x0000000F); 670 case UNW_PPC_VRSAVE: 671 return _registers.__vrsave; 672 } 673 _LIBUNWIND_ABORT("unsupported ppc register"); 674 } 675 676 inline void Registers_ppc::setRegister(int regNum, uint32_t value) { 677 //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value); 678 switch (regNum) { 679 case UNW_REG_IP: 680 _registers.__srr0 = value; 681 return; 682 case UNW_REG_SP: 683 _registers.__r1 = value; 684 return; 685 case UNW_PPC_R0: 686 _registers.__r0 = value; 687 return; 688 case UNW_PPC_R1: 689 _registers.__r1 = value; 690 return; 691 case UNW_PPC_R2: 692 _registers.__r2 = value; 693 return; 694 case UNW_PPC_R3: 695 _registers.__r3 = value; 696 return; 697 case UNW_PPC_R4: 698 _registers.__r4 = value; 699 return; 700 case UNW_PPC_R5: 701 _registers.__r5 = value; 702 return; 703 case UNW_PPC_R6: 704 _registers.__r6 = value; 705 return; 706 case UNW_PPC_R7: 707 _registers.__r7 = value; 708 return; 709 case UNW_PPC_R8: 710 _registers.__r8 = value; 711 return; 712 case UNW_PPC_R9: 713 _registers.__r9 = value; 714 return; 715 case UNW_PPC_R10: 716 _registers.__r10 = value; 717 return; 718 case UNW_PPC_R11: 719 _registers.__r11 = value; 720 return; 721 case UNW_PPC_R12: 722 _registers.__r12 = value; 723 return; 724 case UNW_PPC_R13: 725 _registers.__r13 = value; 726 return; 727 case UNW_PPC_R14: 728 _registers.__r14 = value; 729 return; 730 case UNW_PPC_R15: 731 _registers.__r15 = value; 732 return; 733 case UNW_PPC_R16: 734 _registers.__r16 = value; 735 return; 736 case UNW_PPC_R17: 737 _registers.__r17 = value; 738 return; 739 case UNW_PPC_R18: 740 _registers.__r18 = value; 741 return; 742 case UNW_PPC_R19: 743 _registers.__r19 = value; 744 return; 745 case UNW_PPC_R20: 746 _registers.__r20 = value; 747 return; 748 case UNW_PPC_R21: 749 _registers.__r21 = value; 750 return; 751 case UNW_PPC_R22: 752 _registers.__r22 = value; 753 return; 754 case UNW_PPC_R23: 755 _registers.__r23 = value; 756 return; 757 case UNW_PPC_R24: 758 _registers.__r24 = value; 759 return; 760 case UNW_PPC_R25: 761 _registers.__r25 = value; 762 return; 763 case UNW_PPC_R26: 764 _registers.__r26 = value; 765 return; 766 case UNW_PPC_R27: 767 _registers.__r27 = value; 768 return; 769 case UNW_PPC_R28: 770 _registers.__r28 = value; 771 return; 772 case UNW_PPC_R29: 773 _registers.__r29 = value; 774 return; 775 case UNW_PPC_R30: 776 _registers.__r30 = value; 777 return; 778 case UNW_PPC_R31: 779 _registers.__r31 = value; 780 return; 781 case UNW_PPC_MQ: 782 _registers.__mq = value; 783 return; 784 case UNW_PPC_LR: 785 _registers.__lr = value; 786 return; 787 case UNW_PPC_CTR: 788 _registers.__ctr = value; 789 return; 790 case UNW_PPC_CR0: 791 _registers.__cr &= 0x0FFFFFFF; 792 _registers.__cr |= (value & 0xF0000000); 793 return; 794 case UNW_PPC_CR1: 795 _registers.__cr &= 0xF0FFFFFF; 796 _registers.__cr |= (value & 0x0F000000); 797 return; 798 case UNW_PPC_CR2: 799 _registers.__cr &= 0xFF0FFFFF; 800 _registers.__cr |= (value & 0x00F00000); 801 return; 802 case UNW_PPC_CR3: 803 _registers.__cr &= 0xFFF0FFFF; 804 _registers.__cr |= (value & 0x000F0000); 805 return; 806 case UNW_PPC_CR4: 807 _registers.__cr &= 0xFFFF0FFF; 808 _registers.__cr |= (value & 0x0000F000); 809 return; 810 case UNW_PPC_CR5: 811 _registers.__cr &= 0xFFFFF0FF; 812 _registers.__cr |= (value & 0x00000F00); 813 return; 814 case UNW_PPC_CR6: 815 _registers.__cr &= 0xFFFFFF0F; 816 _registers.__cr |= (value & 0x000000F0); 817 return; 818 case UNW_PPC_CR7: 819 _registers.__cr &= 0xFFFFFFF0; 820 _registers.__cr |= (value & 0x0000000F); 821 return; 822 case UNW_PPC_VRSAVE: 823 _registers.__vrsave = value; 824 return; 825 // not saved 826 return; 827 case UNW_PPC_XER: 828 _registers.__xer = value; 829 return; 830 case UNW_PPC_AP: 831 case UNW_PPC_VSCR: 832 case UNW_PPC_SPEFSCR: 833 // not saved 834 return; 835 } 836 _LIBUNWIND_ABORT("unsupported ppc register"); 837 } 838 839 inline bool Registers_ppc::validFloatRegister(int regNum) const { 840 if (regNum < UNW_PPC_F0) 841 return false; 842 if (regNum > UNW_PPC_F31) 843 return false; 844 return true; 845 } 846 847 inline double Registers_ppc::getFloatRegister(int regNum) const { 848 assert(validFloatRegister(regNum)); 849 return _floatRegisters.__fpregs[regNum - UNW_PPC_F0]; 850 } 851 852 inline void Registers_ppc::setFloatRegister(int regNum, double value) { 853 assert(validFloatRegister(regNum)); 854 _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value; 855 } 856 857 inline bool Registers_ppc::validVectorRegister(int regNum) const { 858 if (regNum < UNW_PPC_V0) 859 return false; 860 if (regNum > UNW_PPC_V31) 861 return false; 862 return true; 863 } 864 865 inline v128 Registers_ppc::getVectorRegister(int regNum) const { 866 assert(validVectorRegister(regNum)); 867 v128 result = _vectorRegisters[regNum - UNW_PPC_V0]; 868 return result; 869 } 870 871 inline void Registers_ppc::setVectorRegister(int regNum, v128 value) { 872 assert(validVectorRegister(regNum)); 873 _vectorRegisters[regNum - UNW_PPC_V0] = value; 874 } 875 876 inline const char *Registers_ppc::getRegisterName(int regNum) { 877 switch (regNum) { 878 case UNW_REG_IP: 879 return "ip"; 880 case UNW_REG_SP: 881 return "sp"; 882 case UNW_PPC_R0: 883 return "r0"; 884 case UNW_PPC_R1: 885 return "r1"; 886 case UNW_PPC_R2: 887 return "r2"; 888 case UNW_PPC_R3: 889 return "r3"; 890 case UNW_PPC_R4: 891 return "r4"; 892 case UNW_PPC_R5: 893 return "r5"; 894 case UNW_PPC_R6: 895 return "r6"; 896 case UNW_PPC_R7: 897 return "r7"; 898 case UNW_PPC_R8: 899 return "r8"; 900 case UNW_PPC_R9: 901 return "r9"; 902 case UNW_PPC_R10: 903 return "r10"; 904 case UNW_PPC_R11: 905 return "r11"; 906 case UNW_PPC_R12: 907 return "r12"; 908 case UNW_PPC_R13: 909 return "r13"; 910 case UNW_PPC_R14: 911 return "r14"; 912 case UNW_PPC_R15: 913 return "r15"; 914 case UNW_PPC_R16: 915 return "r16"; 916 case UNW_PPC_R17: 917 return "r17"; 918 case UNW_PPC_R18: 919 return "r18"; 920 case UNW_PPC_R19: 921 return "r19"; 922 case UNW_PPC_R20: 923 return "r20"; 924 case UNW_PPC_R21: 925 return "r21"; 926 case UNW_PPC_R22: 927 return "r22"; 928 case UNW_PPC_R23: 929 return "r23"; 930 case UNW_PPC_R24: 931 return "r24"; 932 case UNW_PPC_R25: 933 return "r25"; 934 case UNW_PPC_R26: 935 return "r26"; 936 case UNW_PPC_R27: 937 return "r27"; 938 case UNW_PPC_R28: 939 return "r28"; 940 case UNW_PPC_R29: 941 return "r29"; 942 case UNW_PPC_R30: 943 return "r30"; 944 case UNW_PPC_R31: 945 return "r31"; 946 case UNW_PPC_F0: 947 return "fp0"; 948 case UNW_PPC_F1: 949 return "fp1"; 950 case UNW_PPC_F2: 951 return "fp2"; 952 case UNW_PPC_F3: 953 return "fp3"; 954 case UNW_PPC_F4: 955 return "fp4"; 956 case UNW_PPC_F5: 957 return "fp5"; 958 case UNW_PPC_F6: 959 return "fp6"; 960 case UNW_PPC_F7: 961 return "fp7"; 962 case UNW_PPC_F8: 963 return "fp8"; 964 case UNW_PPC_F9: 965 return "fp9"; 966 case UNW_PPC_F10: 967 return "fp10"; 968 case UNW_PPC_F11: 969 return "fp11"; 970 case UNW_PPC_F12: 971 return "fp12"; 972 case UNW_PPC_F13: 973 return "fp13"; 974 case UNW_PPC_F14: 975 return "fp14"; 976 case UNW_PPC_F15: 977 return "fp15"; 978 case UNW_PPC_F16: 979 return "fp16"; 980 case UNW_PPC_F17: 981 return "fp17"; 982 case UNW_PPC_F18: 983 return "fp18"; 984 case UNW_PPC_F19: 985 return "fp19"; 986 case UNW_PPC_F20: 987 return "fp20"; 988 case UNW_PPC_F21: 989 return "fp21"; 990 case UNW_PPC_F22: 991 return "fp22"; 992 case UNW_PPC_F23: 993 return "fp23"; 994 case UNW_PPC_F24: 995 return "fp24"; 996 case UNW_PPC_F25: 997 return "fp25"; 998 case UNW_PPC_F26: 999 return "fp26"; 1000 case UNW_PPC_F27: 1001 return "fp27"; 1002 case UNW_PPC_F28: 1003 return "fp28"; 1004 case UNW_PPC_F29: 1005 return "fp29"; 1006 case UNW_PPC_F30: 1007 return "fp30"; 1008 case UNW_PPC_F31: 1009 return "fp31"; 1010 case UNW_PPC_LR: 1011 return "lr"; 1012 default: 1013 return "unknown register"; 1014 } 1015 1016 } 1017 1018 1019 /// Registers_arm64 holds the register state of a thread in a 64-bit arm 1020 /// process. 1021 class _LIBUNWIND_HIDDEN Registers_arm64 { 1022 public: 1023 Registers_arm64(); 1024 Registers_arm64(const void *registers); 1025 1026 bool validRegister(int num) const; 1027 uint64_t getRegister(int num) const; 1028 void setRegister(int num, uint64_t value); 1029 bool validFloatRegister(int num) const; 1030 double getFloatRegister(int num) const; 1031 void setFloatRegister(int num, double value); 1032 bool validVectorRegister(int num) const; 1033 v128 getVectorRegister(int num) const; 1034 void setVectorRegister(int num, v128 value); 1035 const char *getRegisterName(int num); 1036 void jumpto(); 1037 static int lastDwarfRegNum() { return 95; } 1038 1039 uint64_t getSP() const { return _registers.__sp; } 1040 void setSP(uint64_t value) { _registers.__sp = value; } 1041 uint64_t getIP() const { return _registers.__pc; } 1042 void setIP(uint64_t value) { _registers.__pc = value; } 1043 uint64_t getFP() const { return _registers.__fp; } 1044 void setFP(uint64_t value) { _registers.__fp = value; } 1045 1046 private: 1047 struct GPRs { 1048 uint64_t __x[29]; // x0-x28 1049 uint64_t __fp; // Frame pointer x29 1050 uint64_t __lr; // Link register x30 1051 uint64_t __sp; // Stack pointer x31 1052 uint64_t __pc; // Program counter 1053 uint64_t padding; // 16-byte align 1054 }; 1055 1056 GPRs _registers; 1057 double _vectorHalfRegisters[32]; 1058 // Currently only the lower double in 128-bit vectore registers 1059 // is perserved during unwinding. We could define new register 1060 // numbers (> 96) which mean whole vector registers, then this 1061 // struct would need to change to contain whole vector registers. 1062 }; 1063 1064 inline Registers_arm64::Registers_arm64(const void *registers) { 1065 static_assert(sizeof(Registers_arm64) < sizeof(unw_context_t), 1066 "arm64 registers do not fit into unw_context_t"); 1067 memcpy(&_registers, registers, sizeof(_registers)); 1068 memcpy(_vectorHalfRegisters, (((char *)registers) + 0x110), 1069 sizeof(_vectorHalfRegisters)); 1070 } 1071 1072 inline Registers_arm64::Registers_arm64() { 1073 memset(&_registers, 0, sizeof(_registers)); 1074 memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters)); 1075 } 1076 1077 inline bool Registers_arm64::validRegister(int regNum) const { 1078 if (regNum == UNW_REG_IP) 1079 return true; 1080 if (regNum == UNW_REG_SP) 1081 return true; 1082 if (regNum < 0) 1083 return false; 1084 if (regNum > 95) 1085 return false; 1086 if ((regNum > 31) && (regNum < 64)) 1087 return false; 1088 return true; 1089 } 1090 1091 inline uint64_t Registers_arm64::getRegister(int regNum) const { 1092 if (regNum == UNW_REG_IP) 1093 return _registers.__pc; 1094 if (regNum == UNW_REG_SP) 1095 return _registers.__sp; 1096 if ((regNum >= 0) && (regNum < 32)) 1097 return _registers.__x[regNum]; 1098 _LIBUNWIND_ABORT("unsupported arm64 register"); 1099 } 1100 1101 inline void Registers_arm64::setRegister(int regNum, uint64_t value) { 1102 if (regNum == UNW_REG_IP) 1103 _registers.__pc = value; 1104 else if (regNum == UNW_REG_SP) 1105 _registers.__sp = value; 1106 else if ((regNum >= 0) && (regNum < 32)) 1107 _registers.__x[regNum] = value; 1108 else 1109 _LIBUNWIND_ABORT("unsupported arm64 register"); 1110 } 1111 1112 inline const char *Registers_arm64::getRegisterName(int regNum) { 1113 switch (regNum) { 1114 case UNW_REG_IP: 1115 return "pc"; 1116 case UNW_REG_SP: 1117 return "sp"; 1118 case UNW_ARM64_X0: 1119 return "x0"; 1120 case UNW_ARM64_X1: 1121 return "x1"; 1122 case UNW_ARM64_X2: 1123 return "x2"; 1124 case UNW_ARM64_X3: 1125 return "x3"; 1126 case UNW_ARM64_X4: 1127 return "x4"; 1128 case UNW_ARM64_X5: 1129 return "x5"; 1130 case UNW_ARM64_X6: 1131 return "x6"; 1132 case UNW_ARM64_X7: 1133 return "x7"; 1134 case UNW_ARM64_X8: 1135 return "x8"; 1136 case UNW_ARM64_X9: 1137 return "x9"; 1138 case UNW_ARM64_X10: 1139 return "x10"; 1140 case UNW_ARM64_X11: 1141 return "x11"; 1142 case UNW_ARM64_X12: 1143 return "x12"; 1144 case UNW_ARM64_X13: 1145 return "x13"; 1146 case UNW_ARM64_X14: 1147 return "x14"; 1148 case UNW_ARM64_X15: 1149 return "x15"; 1150 case UNW_ARM64_X16: 1151 return "x16"; 1152 case UNW_ARM64_X17: 1153 return "x17"; 1154 case UNW_ARM64_X18: 1155 return "x18"; 1156 case UNW_ARM64_X19: 1157 return "x19"; 1158 case UNW_ARM64_X20: 1159 return "x20"; 1160 case UNW_ARM64_X21: 1161 return "x21"; 1162 case UNW_ARM64_X22: 1163 return "x22"; 1164 case UNW_ARM64_X23: 1165 return "x23"; 1166 case UNW_ARM64_X24: 1167 return "x24"; 1168 case UNW_ARM64_X25: 1169 return "x25"; 1170 case UNW_ARM64_X26: 1171 return "x26"; 1172 case UNW_ARM64_X27: 1173 return "x27"; 1174 case UNW_ARM64_X28: 1175 return "x28"; 1176 case UNW_ARM64_X29: 1177 return "fp"; 1178 case UNW_ARM64_X30: 1179 return "lr"; 1180 case UNW_ARM64_X31: 1181 return "sp"; 1182 case UNW_ARM64_D0: 1183 return "d0"; 1184 case UNW_ARM64_D1: 1185 return "d1"; 1186 case UNW_ARM64_D2: 1187 return "d2"; 1188 case UNW_ARM64_D3: 1189 return "d3"; 1190 case UNW_ARM64_D4: 1191 return "d4"; 1192 case UNW_ARM64_D5: 1193 return "d5"; 1194 case UNW_ARM64_D6: 1195 return "d6"; 1196 case UNW_ARM64_D7: 1197 return "d7"; 1198 case UNW_ARM64_D8: 1199 return "d8"; 1200 case UNW_ARM64_D9: 1201 return "d9"; 1202 case UNW_ARM64_D10: 1203 return "d10"; 1204 case UNW_ARM64_D11: 1205 return "d11"; 1206 case UNW_ARM64_D12: 1207 return "d12"; 1208 case UNW_ARM64_D13: 1209 return "d13"; 1210 case UNW_ARM64_D14: 1211 return "d14"; 1212 case UNW_ARM64_D15: 1213 return "d15"; 1214 case UNW_ARM64_D16: 1215 return "d16"; 1216 case UNW_ARM64_D17: 1217 return "d17"; 1218 case UNW_ARM64_D18: 1219 return "d18"; 1220 case UNW_ARM64_D19: 1221 return "d19"; 1222 case UNW_ARM64_D20: 1223 return "d20"; 1224 case UNW_ARM64_D21: 1225 return "d21"; 1226 case UNW_ARM64_D22: 1227 return "d22"; 1228 case UNW_ARM64_D23: 1229 return "d23"; 1230 case UNW_ARM64_D24: 1231 return "d24"; 1232 case UNW_ARM64_D25: 1233 return "d25"; 1234 case UNW_ARM64_D26: 1235 return "d26"; 1236 case UNW_ARM64_D27: 1237 return "d27"; 1238 case UNW_ARM64_D28: 1239 return "d28"; 1240 case UNW_ARM64_D29: 1241 return "d29"; 1242 case UNW_ARM64_D30: 1243 return "d30"; 1244 case UNW_ARM64_D31: 1245 return "d31"; 1246 default: 1247 return "unknown register"; 1248 } 1249 } 1250 1251 inline bool Registers_arm64::validFloatRegister(int regNum) const { 1252 if (regNum < UNW_ARM64_D0) 1253 return false; 1254 if (regNum > UNW_ARM64_D31) 1255 return false; 1256 return true; 1257 } 1258 1259 inline double Registers_arm64::getFloatRegister(int regNum) const { 1260 assert(validFloatRegister(regNum)); 1261 return _vectorHalfRegisters[regNum - UNW_ARM64_D0]; 1262 } 1263 1264 inline void Registers_arm64::setFloatRegister(int regNum, double value) { 1265 assert(validFloatRegister(regNum)); 1266 _vectorHalfRegisters[regNum - UNW_ARM64_D0] = value; 1267 } 1268 1269 inline bool Registers_arm64::validVectorRegister(int) const { 1270 return false; 1271 } 1272 1273 inline v128 Registers_arm64::getVectorRegister(int) const { 1274 _LIBUNWIND_ABORT("no arm64 vector register support yet"); 1275 } 1276 1277 inline void Registers_arm64::setVectorRegister(int, v128) { 1278 _LIBUNWIND_ABORT("no arm64 vector register support yet"); 1279 } 1280 1281 /// Registers_arm holds the register state of a thread in a 32-bit arm 1282 /// process. 1283 /// 1284 /// NOTE: Assumes VFPv3. On ARM processors without a floating point unit, 1285 /// this uses more memory than required. 1286 class _LIBUNWIND_HIDDEN Registers_arm { 1287 public: 1288 Registers_arm(); 1289 Registers_arm(const void *registers); 1290 1291 bool validRegister(int num) const; 1292 uint32_t getRegister(int num); 1293 void setRegister(int num, uint32_t value); 1294 bool validFloatRegister(int num) const; 1295 unw_fpreg_t getFloatRegister(int num); 1296 void setFloatRegister(int num, unw_fpreg_t value); 1297 bool validVectorRegister(int num) const; 1298 v128 getVectorRegister(int num) const; 1299 void setVectorRegister(int num, v128 value); 1300 const char *getRegisterName(int num); 1301 void jumpto() { 1302 restoreSavedFloatRegisters(); 1303 restoreCoreAndJumpTo(); 1304 } 1305 1306 uint32_t getSP() const { return _registers.__sp; } 1307 void setSP(uint32_t value) { _registers.__sp = value; } 1308 uint32_t getIP() const { return _registers.__pc; } 1309 void setIP(uint32_t value) { _registers.__pc = value; } 1310 1311 void saveVFPAsX() { 1312 assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15); 1313 _use_X_for_vfp_save = true; 1314 } 1315 1316 void restoreSavedFloatRegisters() { 1317 if (_saved_vfp_d0_d15) { 1318 if (_use_X_for_vfp_save) 1319 restoreVFPWithFLDMX(_vfp_d0_d15_pad); 1320 else 1321 restoreVFPWithFLDMD(_vfp_d0_d15_pad); 1322 } 1323 if (_saved_vfp_d16_d31) 1324 restoreVFPv3(_vfp_d16_d31); 1325 if (_saved_iwmmx) 1326 restoreiWMMX(_iwmmx); 1327 if (_saved_iwmmx_control) 1328 restoreiWMMXControl(_iwmmx_control); 1329 } 1330 1331 private: 1332 struct GPRs { 1333 uint32_t __r[13]; // r0-r12 1334 uint32_t __sp; // Stack pointer r13 1335 uint32_t __lr; // Link register r14 1336 uint32_t __pc; // Program counter r15 1337 }; 1338 1339 static void saveVFPWithFSTMD(unw_fpreg_t*); 1340 static void saveVFPWithFSTMX(unw_fpreg_t*); 1341 static void saveVFPv3(unw_fpreg_t*); 1342 static void saveiWMMX(unw_fpreg_t*); 1343 static void saveiWMMXControl(uint32_t*); 1344 static void restoreVFPWithFLDMD(unw_fpreg_t*); 1345 static void restoreVFPWithFLDMX(unw_fpreg_t*); 1346 static void restoreVFPv3(unw_fpreg_t*); 1347 static void restoreiWMMX(unw_fpreg_t*); 1348 static void restoreiWMMXControl(uint32_t*); 1349 void restoreCoreAndJumpTo(); 1350 1351 // ARM registers 1352 GPRs _registers; 1353 1354 // We save floating point registers lazily because we can't know ahead of 1355 // time which ones are used. See EHABI #4.7. 1356 1357 // Whether D0-D15 are saved in the FTSMX instead of FSTMD format. 1358 // 1359 // See EHABI #7.5 that explains how matching instruction sequences for load 1360 // and store need to be used to correctly restore the exact register bits. 1361 bool _use_X_for_vfp_save; 1362 // Whether VFP D0-D15 are saved. 1363 bool _saved_vfp_d0_d15; 1364 // Whether VFPv3 D16-D31 are saved. 1365 bool _saved_vfp_d16_d31; 1366 // Whether iWMMX data registers are saved. 1367 bool _saved_iwmmx; 1368 // Whether iWMMX control registers are saved. 1369 bool _saved_iwmmx_control; 1370 // VFP registers D0-D15, + padding if saved using FSTMX 1371 unw_fpreg_t _vfp_d0_d15_pad[17]; 1372 // VFPv3 registers D16-D31, always saved using FSTMD 1373 unw_fpreg_t _vfp_d16_d31[16]; 1374 // iWMMX registers 1375 unw_fpreg_t _iwmmx[16]; 1376 // iWMMX control registers 1377 uint32_t _iwmmx_control[4]; 1378 }; 1379 1380 inline Registers_arm::Registers_arm(const void *registers) 1381 : _use_X_for_vfp_save(false), 1382 _saved_vfp_d0_d15(false), 1383 _saved_vfp_d16_d31(false), 1384 _saved_iwmmx(false), 1385 _saved_iwmmx_control(false) { 1386 static_assert(sizeof(Registers_arm) < sizeof(unw_context_t), 1387 "arm registers do not fit into unw_context_t"); 1388 // See unw_getcontext() note about data. 1389 memcpy(&_registers, registers, sizeof(_registers)); 1390 memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad)); 1391 memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31)); 1392 memset(&_iwmmx, 0, sizeof(_iwmmx)); 1393 memset(&_iwmmx_control, 0, sizeof(_iwmmx_control)); 1394 } 1395 1396 inline Registers_arm::Registers_arm() 1397 : _use_X_for_vfp_save(false), 1398 _saved_vfp_d0_d15(false), 1399 _saved_vfp_d16_d31(false), 1400 _saved_iwmmx(false), 1401 _saved_iwmmx_control(false) { 1402 memset(&_registers, 0, sizeof(_registers)); 1403 memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad)); 1404 memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31)); 1405 memset(&_iwmmx, 0, sizeof(_iwmmx)); 1406 memset(&_iwmmx_control, 0, sizeof(_iwmmx_control)); 1407 } 1408 1409 inline bool Registers_arm::validRegister(int regNum) const { 1410 // Returns true for all non-VFP registers supported by the EHABI 1411 // virtual register set (VRS). 1412 if (regNum == UNW_REG_IP) 1413 return true; 1414 if (regNum == UNW_REG_SP) 1415 return true; 1416 if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15) 1417 return true; 1418 if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) 1419 return true; 1420 return false; 1421 } 1422 1423 inline uint32_t Registers_arm::getRegister(int regNum) { 1424 if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) 1425 return _registers.__sp; 1426 if (regNum == UNW_ARM_LR) 1427 return _registers.__lr; 1428 if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) 1429 return _registers.__pc; 1430 if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) 1431 return _registers.__r[regNum]; 1432 if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) { 1433 if (!_saved_iwmmx_control) { 1434 _saved_iwmmx_control = true; 1435 saveiWMMXControl(_iwmmx_control); 1436 } 1437 return _iwmmx_control[regNum - UNW_ARM_WC0]; 1438 } 1439 _LIBUNWIND_ABORT("unsupported arm register"); 1440 } 1441 1442 inline void Registers_arm::setRegister(int regNum, uint32_t value) { 1443 if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) 1444 _registers.__sp = value; 1445 else if (regNum == UNW_ARM_LR) 1446 _registers.__lr = value; 1447 else if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) 1448 _registers.__pc = value; 1449 else if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) 1450 _registers.__r[regNum] = value; 1451 else if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) { 1452 if (!_saved_iwmmx_control) { 1453 _saved_iwmmx_control = true; 1454 saveiWMMXControl(_iwmmx_control); 1455 } 1456 _iwmmx_control[regNum - UNW_ARM_WC0] = value; 1457 } else 1458 _LIBUNWIND_ABORT("unsupported arm register"); 1459 } 1460 1461 inline const char *Registers_arm::getRegisterName(int regNum) { 1462 switch (regNum) { 1463 case UNW_REG_IP: 1464 case UNW_ARM_IP: // UNW_ARM_R15 is alias 1465 return "pc"; 1466 case UNW_ARM_LR: // UNW_ARM_R14 is alias 1467 return "lr"; 1468 case UNW_REG_SP: 1469 case UNW_ARM_SP: // UNW_ARM_R13 is alias 1470 return "sp"; 1471 case UNW_ARM_R0: 1472 return "r0"; 1473 case UNW_ARM_R1: 1474 return "r1"; 1475 case UNW_ARM_R2: 1476 return "r2"; 1477 case UNW_ARM_R3: 1478 return "r3"; 1479 case UNW_ARM_R4: 1480 return "r4"; 1481 case UNW_ARM_R5: 1482 return "r5"; 1483 case UNW_ARM_R6: 1484 return "r6"; 1485 case UNW_ARM_R7: 1486 return "r7"; 1487 case UNW_ARM_R8: 1488 return "r8"; 1489 case UNW_ARM_R9: 1490 return "r9"; 1491 case UNW_ARM_R10: 1492 return "r10"; 1493 case UNW_ARM_R11: 1494 return "r11"; 1495 case UNW_ARM_R12: 1496 return "r12"; 1497 case UNW_ARM_S0: 1498 return "s0"; 1499 case UNW_ARM_S1: 1500 return "s1"; 1501 case UNW_ARM_S2: 1502 return "s2"; 1503 case UNW_ARM_S3: 1504 return "s3"; 1505 case UNW_ARM_S4: 1506 return "s4"; 1507 case UNW_ARM_S5: 1508 return "s5"; 1509 case UNW_ARM_S6: 1510 return "s6"; 1511 case UNW_ARM_S7: 1512 return "s7"; 1513 case UNW_ARM_S8: 1514 return "s8"; 1515 case UNW_ARM_S9: 1516 return "s9"; 1517 case UNW_ARM_S10: 1518 return "s10"; 1519 case UNW_ARM_S11: 1520 return "s11"; 1521 case UNW_ARM_S12: 1522 return "s12"; 1523 case UNW_ARM_S13: 1524 return "s13"; 1525 case UNW_ARM_S14: 1526 return "s14"; 1527 case UNW_ARM_S15: 1528 return "s15"; 1529 case UNW_ARM_S16: 1530 return "s16"; 1531 case UNW_ARM_S17: 1532 return "s17"; 1533 case UNW_ARM_S18: 1534 return "s18"; 1535 case UNW_ARM_S19: 1536 return "s19"; 1537 case UNW_ARM_S20: 1538 return "s20"; 1539 case UNW_ARM_S21: 1540 return "s21"; 1541 case UNW_ARM_S22: 1542 return "s22"; 1543 case UNW_ARM_S23: 1544 return "s23"; 1545 case UNW_ARM_S24: 1546 return "s24"; 1547 case UNW_ARM_S25: 1548 return "s25"; 1549 case UNW_ARM_S26: 1550 return "s26"; 1551 case UNW_ARM_S27: 1552 return "s27"; 1553 case UNW_ARM_S28: 1554 return "s28"; 1555 case UNW_ARM_S29: 1556 return "s29"; 1557 case UNW_ARM_S30: 1558 return "s30"; 1559 case UNW_ARM_S31: 1560 return "s31"; 1561 case UNW_ARM_D0: 1562 return "d0"; 1563 case UNW_ARM_D1: 1564 return "d1"; 1565 case UNW_ARM_D2: 1566 return "d2"; 1567 case UNW_ARM_D3: 1568 return "d3"; 1569 case UNW_ARM_D4: 1570 return "d4"; 1571 case UNW_ARM_D5: 1572 return "d5"; 1573 case UNW_ARM_D6: 1574 return "d6"; 1575 case UNW_ARM_D7: 1576 return "d7"; 1577 case UNW_ARM_D8: 1578 return "d8"; 1579 case UNW_ARM_D9: 1580 return "d9"; 1581 case UNW_ARM_D10: 1582 return "d10"; 1583 case UNW_ARM_D11: 1584 return "d11"; 1585 case UNW_ARM_D12: 1586 return "d12"; 1587 case UNW_ARM_D13: 1588 return "d13"; 1589 case UNW_ARM_D14: 1590 return "d14"; 1591 case UNW_ARM_D15: 1592 return "d15"; 1593 case UNW_ARM_D16: 1594 return "d16"; 1595 case UNW_ARM_D17: 1596 return "d17"; 1597 case UNW_ARM_D18: 1598 return "d18"; 1599 case UNW_ARM_D19: 1600 return "d19"; 1601 case UNW_ARM_D20: 1602 return "d20"; 1603 case UNW_ARM_D21: 1604 return "d21"; 1605 case UNW_ARM_D22: 1606 return "d22"; 1607 case UNW_ARM_D23: 1608 return "d23"; 1609 case UNW_ARM_D24: 1610 return "d24"; 1611 case UNW_ARM_D25: 1612 return "d25"; 1613 case UNW_ARM_D26: 1614 return "d26"; 1615 case UNW_ARM_D27: 1616 return "d27"; 1617 case UNW_ARM_D28: 1618 return "d28"; 1619 case UNW_ARM_D29: 1620 return "d29"; 1621 case UNW_ARM_D30: 1622 return "d30"; 1623 case UNW_ARM_D31: 1624 return "d31"; 1625 default: 1626 return "unknown register"; 1627 } 1628 } 1629 1630 inline bool Registers_arm::validFloatRegister(int regNum) const { 1631 // NOTE: Consider the intel MMX registers floating points so the 1632 // unw_get_fpreg can be used to transmit the 64-bit data back. 1633 return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31)) 1634 || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15)); 1635 } 1636 1637 inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) { 1638 if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) { 1639 if (!_saved_vfp_d0_d15) { 1640 _saved_vfp_d0_d15 = true; 1641 if (_use_X_for_vfp_save) 1642 saveVFPWithFSTMX(_vfp_d0_d15_pad); 1643 else 1644 saveVFPWithFSTMD(_vfp_d0_d15_pad); 1645 } 1646 return _vfp_d0_d15_pad[regNum - UNW_ARM_D0]; 1647 } else if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) { 1648 if (!_saved_vfp_d16_d31) { 1649 _saved_vfp_d16_d31 = true; 1650 saveVFPv3(_vfp_d16_d31); 1651 } 1652 return _vfp_d16_d31[regNum - UNW_ARM_D16]; 1653 } else if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) { 1654 if (!_saved_iwmmx) { 1655 _saved_iwmmx = true; 1656 saveiWMMX(_iwmmx); 1657 } 1658 return _iwmmx[regNum - UNW_ARM_WR0]; 1659 } else { 1660 _LIBUNWIND_ABORT("Unknown ARM float register"); 1661 } 1662 } 1663 1664 inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) { 1665 if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) { 1666 if (!_saved_vfp_d0_d15) { 1667 _saved_vfp_d0_d15 = true; 1668 if (_use_X_for_vfp_save) 1669 saveVFPWithFSTMX(_vfp_d0_d15_pad); 1670 else 1671 saveVFPWithFSTMD(_vfp_d0_d15_pad); 1672 } 1673 _vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value; 1674 } else if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) { 1675 if (!_saved_vfp_d16_d31) { 1676 _saved_vfp_d16_d31 = true; 1677 saveVFPv3(_vfp_d16_d31); 1678 } 1679 _vfp_d16_d31[regNum - UNW_ARM_D0] = value; 1680 } else if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) { 1681 if (!_saved_iwmmx) { 1682 _saved_iwmmx = true; 1683 saveiWMMX(_iwmmx); 1684 } 1685 _iwmmx[regNum - UNW_ARM_WR0] = value; 1686 } else { 1687 _LIBUNWIND_ABORT("Unknown ARM float register"); 1688 } 1689 } 1690 1691 inline bool Registers_arm::validVectorRegister(int) const { 1692 return false; 1693 } 1694 1695 inline v128 Registers_arm::getVectorRegister(int) const { 1696 _LIBUNWIND_ABORT("ARM vector support not implemented"); 1697 } 1698 1699 inline void Registers_arm::setVectorRegister(int, v128) { 1700 _LIBUNWIND_ABORT("ARM vector support not implemented"); 1701 } 1702 1703 } // namespace libunwind 1704 1705 #endif // __REGISTERS_HPP__ 1706