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 23namespace libunwind { 24 25// For emulating 128-bit registers 26struct v128 { uint32_t vec[4]; }; 27 28 29/// Registers_x86 holds the register state of a thread in a 32-bit intel 30/// process. 31class _LIBUNWIND_HIDDEN Registers_x86 { 32public: 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 66private: 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 89inline 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 memcpy(&_registers, registers, sizeof(_registers)); 93} 94 95inline Registers_x86::Registers_x86() { 96 memset(&_registers, 0, sizeof(_registers)); 97} 98 99inline 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 111inline 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 137inline 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 173inline 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 200inline double Registers_x86::getFloatRegister(int) const { 201 _LIBUNWIND_ABORT("no x86 float registers"); 202} 203 204inline void Registers_x86::setFloatRegister(int, double) { 205 _LIBUNWIND_ABORT("no x86 float registers"); 206} 207 208inline v128 Registers_x86::getVectorRegister(int) const { 209 _LIBUNWIND_ABORT("no x86 vector registers"); 210} 211 212inline 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. 219class _LIBUNWIND_HIDDEN Registers_x86_64 { 220public: 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 254private: 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 281inline 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 memcpy(&_registers, registers, sizeof(_registers)); 285} 286 287inline Registers_x86_64::Registers_x86_64() { 288 memset(&_registers, 0, sizeof(_registers)); 289} 290 291inline 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 303inline 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 345inline 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 405inline 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 448inline double Registers_x86_64::getFloatRegister(int) const { 449 _LIBUNWIND_ABORT("no x86_64 float registers"); 450} 451 452inline void Registers_x86_64::setFloatRegister(int, double) { 453 _LIBUNWIND_ABORT("no x86_64 float registers"); 454} 455 456inline v128 Registers_x86_64::getVectorRegister(int) const { 457 _LIBUNWIND_ABORT("no x86_64 vector registers"); 458} 459 460inline 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. 467class _LIBUNWIND_HIDDEN Registers_ppc { 468public: 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 490private: 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 546inline 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 memcpy(&_registers, static_cast<const uint8_t *>(registers), 550 sizeof(_registers)); 551 static_assert(sizeof(ppc_thread_state_t) == 160, 552 "expected float register offset to be 160"); 553 memcpy(&_floatRegisters, 554 static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t), 555 sizeof(_floatRegisters)); 556 static_assert(sizeof(ppc_thread_state_t) + sizeof(ppc_float_state_t) == 424, 557 "expected vector register offset to be 424 bytes"); 558 memcpy(_vectorRegisters, 559 static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t) + 560 sizeof(ppc_float_state_t), 561 sizeof(_vectorRegisters)); 562} 563 564inline Registers_ppc::Registers_ppc() { 565 memset(&_registers, 0, sizeof(_registers)); 566 memset(&_floatRegisters, 0, sizeof(_floatRegisters)); 567 memset(&_vectorRegisters, 0, sizeof(_vectorRegisters)); 568} 569 570inline bool Registers_ppc::validRegister(int regNum) const { 571 if (regNum == UNW_REG_IP) 572 return true; 573 if (regNum == UNW_REG_SP) 574 return true; 575 if (regNum == UNW_PPC_VRSAVE) 576 return true; 577 if (regNum < 0) 578 return false; 579 if (regNum <= UNW_PPC_R31) 580 return true; 581 if (regNum == UNW_PPC_MQ) 582 return true; 583 if (regNum == UNW_PPC_LR) 584 return true; 585 if (regNum == UNW_PPC_CTR) 586 return true; 587 if ((UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7)) 588 return true; 589 return false; 590} 591 592inline uint32_t Registers_ppc::getRegister(int regNum) const { 593 switch (regNum) { 594 case UNW_REG_IP: 595 return _registers.__srr0; 596 case UNW_REG_SP: 597 return _registers.__r1; 598 case UNW_PPC_R0: 599 return _registers.__r0; 600 case UNW_PPC_R1: 601 return _registers.__r1; 602 case UNW_PPC_R2: 603 return _registers.__r2; 604 case UNW_PPC_R3: 605 return _registers.__r3; 606 case UNW_PPC_R4: 607 return _registers.__r4; 608 case UNW_PPC_R5: 609 return _registers.__r5; 610 case UNW_PPC_R6: 611 return _registers.__r6; 612 case UNW_PPC_R7: 613 return _registers.__r7; 614 case UNW_PPC_R8: 615 return _registers.__r8; 616 case UNW_PPC_R9: 617 return _registers.__r9; 618 case UNW_PPC_R10: 619 return _registers.__r10; 620 case UNW_PPC_R11: 621 return _registers.__r11; 622 case UNW_PPC_R12: 623 return _registers.__r12; 624 case UNW_PPC_R13: 625 return _registers.__r13; 626 case UNW_PPC_R14: 627 return _registers.__r14; 628 case UNW_PPC_R15: 629 return _registers.__r15; 630 case UNW_PPC_R16: 631 return _registers.__r16; 632 case UNW_PPC_R17: 633 return _registers.__r17; 634 case UNW_PPC_R18: 635 return _registers.__r18; 636 case UNW_PPC_R19: 637 return _registers.__r19; 638 case UNW_PPC_R20: 639 return _registers.__r20; 640 case UNW_PPC_R21: 641 return _registers.__r21; 642 case UNW_PPC_R22: 643 return _registers.__r22; 644 case UNW_PPC_R23: 645 return _registers.__r23; 646 case UNW_PPC_R24: 647 return _registers.__r24; 648 case UNW_PPC_R25: 649 return _registers.__r25; 650 case UNW_PPC_R26: 651 return _registers.__r26; 652 case UNW_PPC_R27: 653 return _registers.__r27; 654 case UNW_PPC_R28: 655 return _registers.__r28; 656 case UNW_PPC_R29: 657 return _registers.__r29; 658 case UNW_PPC_R30: 659 return _registers.__r30; 660 case UNW_PPC_R31: 661 return _registers.__r31; 662 case UNW_PPC_LR: 663 return _registers.__lr; 664 case UNW_PPC_CR0: 665 return (_registers.__cr & 0xF0000000); 666 case UNW_PPC_CR1: 667 return (_registers.__cr & 0x0F000000); 668 case UNW_PPC_CR2: 669 return (_registers.__cr & 0x00F00000); 670 case UNW_PPC_CR3: 671 return (_registers.__cr & 0x000F0000); 672 case UNW_PPC_CR4: 673 return (_registers.__cr & 0x0000F000); 674 case UNW_PPC_CR5: 675 return (_registers.__cr & 0x00000F00); 676 case UNW_PPC_CR6: 677 return (_registers.__cr & 0x000000F0); 678 case UNW_PPC_CR7: 679 return (_registers.__cr & 0x0000000F); 680 case UNW_PPC_VRSAVE: 681 return _registers.__vrsave; 682 } 683 _LIBUNWIND_ABORT("unsupported ppc register"); 684} 685 686inline void Registers_ppc::setRegister(int regNum, uint32_t value) { 687 //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value); 688 switch (regNum) { 689 case UNW_REG_IP: 690 _registers.__srr0 = value; 691 return; 692 case UNW_REG_SP: 693 _registers.__r1 = value; 694 return; 695 case UNW_PPC_R0: 696 _registers.__r0 = value; 697 return; 698 case UNW_PPC_R1: 699 _registers.__r1 = value; 700 return; 701 case UNW_PPC_R2: 702 _registers.__r2 = value; 703 return; 704 case UNW_PPC_R3: 705 _registers.__r3 = value; 706 return; 707 case UNW_PPC_R4: 708 _registers.__r4 = value; 709 return; 710 case UNW_PPC_R5: 711 _registers.__r5 = value; 712 return; 713 case UNW_PPC_R6: 714 _registers.__r6 = value; 715 return; 716 case UNW_PPC_R7: 717 _registers.__r7 = value; 718 return; 719 case UNW_PPC_R8: 720 _registers.__r8 = value; 721 return; 722 case UNW_PPC_R9: 723 _registers.__r9 = value; 724 return; 725 case UNW_PPC_R10: 726 _registers.__r10 = value; 727 return; 728 case UNW_PPC_R11: 729 _registers.__r11 = value; 730 return; 731 case UNW_PPC_R12: 732 _registers.__r12 = value; 733 return; 734 case UNW_PPC_R13: 735 _registers.__r13 = value; 736 return; 737 case UNW_PPC_R14: 738 _registers.__r14 = value; 739 return; 740 case UNW_PPC_R15: 741 _registers.__r15 = value; 742 return; 743 case UNW_PPC_R16: 744 _registers.__r16 = value; 745 return; 746 case UNW_PPC_R17: 747 _registers.__r17 = value; 748 return; 749 case UNW_PPC_R18: 750 _registers.__r18 = value; 751 return; 752 case UNW_PPC_R19: 753 _registers.__r19 = value; 754 return; 755 case UNW_PPC_R20: 756 _registers.__r20 = value; 757 return; 758 case UNW_PPC_R21: 759 _registers.__r21 = value; 760 return; 761 case UNW_PPC_R22: 762 _registers.__r22 = value; 763 return; 764 case UNW_PPC_R23: 765 _registers.__r23 = value; 766 return; 767 case UNW_PPC_R24: 768 _registers.__r24 = value; 769 return; 770 case UNW_PPC_R25: 771 _registers.__r25 = value; 772 return; 773 case UNW_PPC_R26: 774 _registers.__r26 = value; 775 return; 776 case UNW_PPC_R27: 777 _registers.__r27 = value; 778 return; 779 case UNW_PPC_R28: 780 _registers.__r28 = value; 781 return; 782 case UNW_PPC_R29: 783 _registers.__r29 = value; 784 return; 785 case UNW_PPC_R30: 786 _registers.__r30 = value; 787 return; 788 case UNW_PPC_R31: 789 _registers.__r31 = value; 790 return; 791 case UNW_PPC_MQ: 792 _registers.__mq = value; 793 return; 794 case UNW_PPC_LR: 795 _registers.__lr = value; 796 return; 797 case UNW_PPC_CTR: 798 _registers.__ctr = value; 799 return; 800 case UNW_PPC_CR0: 801 _registers.__cr &= 0x0FFFFFFF; 802 _registers.__cr |= (value & 0xF0000000); 803 return; 804 case UNW_PPC_CR1: 805 _registers.__cr &= 0xF0FFFFFF; 806 _registers.__cr |= (value & 0x0F000000); 807 return; 808 case UNW_PPC_CR2: 809 _registers.__cr &= 0xFF0FFFFF; 810 _registers.__cr |= (value & 0x00F00000); 811 return; 812 case UNW_PPC_CR3: 813 _registers.__cr &= 0xFFF0FFFF; 814 _registers.__cr |= (value & 0x000F0000); 815 return; 816 case UNW_PPC_CR4: 817 _registers.__cr &= 0xFFFF0FFF; 818 _registers.__cr |= (value & 0x0000F000); 819 return; 820 case UNW_PPC_CR5: 821 _registers.__cr &= 0xFFFFF0FF; 822 _registers.__cr |= (value & 0x00000F00); 823 return; 824 case UNW_PPC_CR6: 825 _registers.__cr &= 0xFFFFFF0F; 826 _registers.__cr |= (value & 0x000000F0); 827 return; 828 case UNW_PPC_CR7: 829 _registers.__cr &= 0xFFFFFFF0; 830 _registers.__cr |= (value & 0x0000000F); 831 return; 832 case UNW_PPC_VRSAVE: 833 _registers.__vrsave = value; 834 return; 835 // not saved 836 return; 837 case UNW_PPC_XER: 838 _registers.__xer = value; 839 return; 840 case UNW_PPC_AP: 841 case UNW_PPC_VSCR: 842 case UNW_PPC_SPEFSCR: 843 // not saved 844 return; 845 } 846 _LIBUNWIND_ABORT("unsupported ppc register"); 847} 848 849inline bool Registers_ppc::validFloatRegister(int regNum) const { 850 if (regNum < UNW_PPC_F0) 851 return false; 852 if (regNum > UNW_PPC_F31) 853 return false; 854 return true; 855} 856 857inline double Registers_ppc::getFloatRegister(int regNum) const { 858 assert(validFloatRegister(regNum)); 859 return _floatRegisters.__fpregs[regNum - UNW_PPC_F0]; 860} 861 862inline void Registers_ppc::setFloatRegister(int regNum, double value) { 863 assert(validFloatRegister(regNum)); 864 _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value; 865} 866 867inline bool Registers_ppc::validVectorRegister(int regNum) const { 868 if (regNum < UNW_PPC_V0) 869 return false; 870 if (regNum > UNW_PPC_V31) 871 return false; 872 return true; 873} 874 875inline v128 Registers_ppc::getVectorRegister(int regNum) const { 876 assert(validVectorRegister(regNum)); 877 v128 result = _vectorRegisters[regNum - UNW_PPC_V0]; 878 return result; 879} 880 881inline void Registers_ppc::setVectorRegister(int regNum, v128 value) { 882 assert(validVectorRegister(regNum)); 883 _vectorRegisters[regNum - UNW_PPC_V0] = value; 884} 885 886inline const char *Registers_ppc::getRegisterName(int regNum) { 887 switch (regNum) { 888 case UNW_REG_IP: 889 return "ip"; 890 case UNW_REG_SP: 891 return "sp"; 892 case UNW_PPC_R0: 893 return "r0"; 894 case UNW_PPC_R1: 895 return "r1"; 896 case UNW_PPC_R2: 897 return "r2"; 898 case UNW_PPC_R3: 899 return "r3"; 900 case UNW_PPC_R4: 901 return "r4"; 902 case UNW_PPC_R5: 903 return "r5"; 904 case UNW_PPC_R6: 905 return "r6"; 906 case UNW_PPC_R7: 907 return "r7"; 908 case UNW_PPC_R8: 909 return "r8"; 910 case UNW_PPC_R9: 911 return "r9"; 912 case UNW_PPC_R10: 913 return "r10"; 914 case UNW_PPC_R11: 915 return "r11"; 916 case UNW_PPC_R12: 917 return "r12"; 918 case UNW_PPC_R13: 919 return "r13"; 920 case UNW_PPC_R14: 921 return "r14"; 922 case UNW_PPC_R15: 923 return "r15"; 924 case UNW_PPC_R16: 925 return "r16"; 926 case UNW_PPC_R17: 927 return "r17"; 928 case UNW_PPC_R18: 929 return "r18"; 930 case UNW_PPC_R19: 931 return "r19"; 932 case UNW_PPC_R20: 933 return "r20"; 934 case UNW_PPC_R21: 935 return "r21"; 936 case UNW_PPC_R22: 937 return "r22"; 938 case UNW_PPC_R23: 939 return "r23"; 940 case UNW_PPC_R24: 941 return "r24"; 942 case UNW_PPC_R25: 943 return "r25"; 944 case UNW_PPC_R26: 945 return "r26"; 946 case UNW_PPC_R27: 947 return "r27"; 948 case UNW_PPC_R28: 949 return "r28"; 950 case UNW_PPC_R29: 951 return "r29"; 952 case UNW_PPC_R30: 953 return "r30"; 954 case UNW_PPC_R31: 955 return "r31"; 956 case UNW_PPC_F0: 957 return "fp0"; 958 case UNW_PPC_F1: 959 return "fp1"; 960 case UNW_PPC_F2: 961 return "fp2"; 962 case UNW_PPC_F3: 963 return "fp3"; 964 case UNW_PPC_F4: 965 return "fp4"; 966 case UNW_PPC_F5: 967 return "fp5"; 968 case UNW_PPC_F6: 969 return "fp6"; 970 case UNW_PPC_F7: 971 return "fp7"; 972 case UNW_PPC_F8: 973 return "fp8"; 974 case UNW_PPC_F9: 975 return "fp9"; 976 case UNW_PPC_F10: 977 return "fp10"; 978 case UNW_PPC_F11: 979 return "fp11"; 980 case UNW_PPC_F12: 981 return "fp12"; 982 case UNW_PPC_F13: 983 return "fp13"; 984 case UNW_PPC_F14: 985 return "fp14"; 986 case UNW_PPC_F15: 987 return "fp15"; 988 case UNW_PPC_F16: 989 return "fp16"; 990 case UNW_PPC_F17: 991 return "fp17"; 992 case UNW_PPC_F18: 993 return "fp18"; 994 case UNW_PPC_F19: 995 return "fp19"; 996 case UNW_PPC_F20: 997 return "fp20"; 998 case UNW_PPC_F21: 999 return "fp21"; 1000 case UNW_PPC_F22: 1001 return "fp22"; 1002 case UNW_PPC_F23: 1003 return "fp23"; 1004 case UNW_PPC_F24: 1005 return "fp24"; 1006 case UNW_PPC_F25: 1007 return "fp25"; 1008 case UNW_PPC_F26: 1009 return "fp26"; 1010 case UNW_PPC_F27: 1011 return "fp27"; 1012 case UNW_PPC_F28: 1013 return "fp28"; 1014 case UNW_PPC_F29: 1015 return "fp29"; 1016 case UNW_PPC_F30: 1017 return "fp30"; 1018 case UNW_PPC_F31: 1019 return "fp31"; 1020 case UNW_PPC_LR: 1021 return "lr"; 1022 default: 1023 return "unknown register"; 1024 } 1025 1026} 1027 1028 1029/// Registers_arm64 holds the register state of a thread in a 64-bit arm 1030/// process. 1031class _LIBUNWIND_HIDDEN Registers_arm64 { 1032public: 1033 Registers_arm64(); 1034 Registers_arm64(const void *registers); 1035 1036 bool validRegister(int num) const; 1037 uint64_t getRegister(int num) const; 1038 void setRegister(int num, uint64_t value); 1039 bool validFloatRegister(int num) const; 1040 double getFloatRegister(int num) const; 1041 void setFloatRegister(int num, double value); 1042 bool validVectorRegister(int num) const; 1043 v128 getVectorRegister(int num) const; 1044 void setVectorRegister(int num, v128 value); 1045 const char *getRegisterName(int num); 1046 void jumpto(); 1047 static int lastDwarfRegNum() { return 95; } 1048 1049 uint64_t getSP() const { return _registers.__sp; } 1050 void setSP(uint64_t value) { _registers.__sp = value; } 1051 uint64_t getIP() const { return _registers.__pc; } 1052 void setIP(uint64_t value) { _registers.__pc = value; } 1053 uint64_t getFP() const { return _registers.__fp; } 1054 void setFP(uint64_t value) { _registers.__fp = value; } 1055 1056private: 1057 struct GPRs { 1058 uint64_t __x[29]; // x0-x28 1059 uint64_t __fp; // Frame pointer x29 1060 uint64_t __lr; // Link register x30 1061 uint64_t __sp; // Stack pointer x31 1062 uint64_t __pc; // Program counter 1063 uint64_t padding; // 16-byte align 1064 }; 1065 1066 GPRs _registers; 1067 double _vectorHalfRegisters[32]; 1068 // Currently only the lower double in 128-bit vectore registers 1069 // is perserved during unwinding. We could define new register 1070 // numbers (> 96) which mean whole vector registers, then this 1071 // struct would need to change to contain whole vector registers. 1072}; 1073 1074inline Registers_arm64::Registers_arm64(const void *registers) { 1075 static_assert(sizeof(Registers_arm64) < sizeof(unw_context_t), 1076 "arm64 registers do not fit into unw_context_t"); 1077 memcpy(&_registers, registers, sizeof(_registers)); 1078 static_assert(sizeof(GPRs) == 0x110, 1079 "expected VFP registers to be at offset 272"); 1080 memcpy(_vectorHalfRegisters, 1081 static_cast<const uint8_t *>(registers) + sizeof(GPRs), 1082 sizeof(_vectorHalfRegisters)); 1083} 1084 1085inline Registers_arm64::Registers_arm64() { 1086 memset(&_registers, 0, sizeof(_registers)); 1087 memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters)); 1088} 1089 1090inline bool Registers_arm64::validRegister(int regNum) const { 1091 if (regNum == UNW_REG_IP) 1092 return true; 1093 if (regNum == UNW_REG_SP) 1094 return true; 1095 if (regNum < 0) 1096 return false; 1097 if (regNum > 95) 1098 return false; 1099 if ((regNum > 31) && (regNum < 64)) 1100 return false; 1101 return true; 1102} 1103 1104inline uint64_t Registers_arm64::getRegister(int regNum) const { 1105 if (regNum == UNW_REG_IP) 1106 return _registers.__pc; 1107 if (regNum == UNW_REG_SP) 1108 return _registers.__sp; 1109 if ((regNum >= 0) && (regNum < 32)) 1110 return _registers.__x[regNum]; 1111 _LIBUNWIND_ABORT("unsupported arm64 register"); 1112} 1113 1114inline void Registers_arm64::setRegister(int regNum, uint64_t value) { 1115 if (regNum == UNW_REG_IP) 1116 _registers.__pc = value; 1117 else if (regNum == UNW_REG_SP) 1118 _registers.__sp = value; 1119 else if ((regNum >= 0) && (regNum < 32)) 1120 _registers.__x[regNum] = value; 1121 else 1122 _LIBUNWIND_ABORT("unsupported arm64 register"); 1123} 1124 1125inline const char *Registers_arm64::getRegisterName(int regNum) { 1126 switch (regNum) { 1127 case UNW_REG_IP: 1128 return "pc"; 1129 case UNW_REG_SP: 1130 return "sp"; 1131 case UNW_ARM64_X0: 1132 return "x0"; 1133 case UNW_ARM64_X1: 1134 return "x1"; 1135 case UNW_ARM64_X2: 1136 return "x2"; 1137 case UNW_ARM64_X3: 1138 return "x3"; 1139 case UNW_ARM64_X4: 1140 return "x4"; 1141 case UNW_ARM64_X5: 1142 return "x5"; 1143 case UNW_ARM64_X6: 1144 return "x6"; 1145 case UNW_ARM64_X7: 1146 return "x7"; 1147 case UNW_ARM64_X8: 1148 return "x8"; 1149 case UNW_ARM64_X9: 1150 return "x9"; 1151 case UNW_ARM64_X10: 1152 return "x10"; 1153 case UNW_ARM64_X11: 1154 return "x11"; 1155 case UNW_ARM64_X12: 1156 return "x12"; 1157 case UNW_ARM64_X13: 1158 return "x13"; 1159 case UNW_ARM64_X14: 1160 return "x14"; 1161 case UNW_ARM64_X15: 1162 return "x15"; 1163 case UNW_ARM64_X16: 1164 return "x16"; 1165 case UNW_ARM64_X17: 1166 return "x17"; 1167 case UNW_ARM64_X18: 1168 return "x18"; 1169 case UNW_ARM64_X19: 1170 return "x19"; 1171 case UNW_ARM64_X20: 1172 return "x20"; 1173 case UNW_ARM64_X21: 1174 return "x21"; 1175 case UNW_ARM64_X22: 1176 return "x22"; 1177 case UNW_ARM64_X23: 1178 return "x23"; 1179 case UNW_ARM64_X24: 1180 return "x24"; 1181 case UNW_ARM64_X25: 1182 return "x25"; 1183 case UNW_ARM64_X26: 1184 return "x26"; 1185 case UNW_ARM64_X27: 1186 return "x27"; 1187 case UNW_ARM64_X28: 1188 return "x28"; 1189 case UNW_ARM64_X29: 1190 return "fp"; 1191 case UNW_ARM64_X30: 1192 return "lr"; 1193 case UNW_ARM64_X31: 1194 return "sp"; 1195 case UNW_ARM64_D0: 1196 return "d0"; 1197 case UNW_ARM64_D1: 1198 return "d1"; 1199 case UNW_ARM64_D2: 1200 return "d2"; 1201 case UNW_ARM64_D3: 1202 return "d3"; 1203 case UNW_ARM64_D4: 1204 return "d4"; 1205 case UNW_ARM64_D5: 1206 return "d5"; 1207 case UNW_ARM64_D6: 1208 return "d6"; 1209 case UNW_ARM64_D7: 1210 return "d7"; 1211 case UNW_ARM64_D8: 1212 return "d8"; 1213 case UNW_ARM64_D9: 1214 return "d9"; 1215 case UNW_ARM64_D10: 1216 return "d10"; 1217 case UNW_ARM64_D11: 1218 return "d11"; 1219 case UNW_ARM64_D12: 1220 return "d12"; 1221 case UNW_ARM64_D13: 1222 return "d13"; 1223 case UNW_ARM64_D14: 1224 return "d14"; 1225 case UNW_ARM64_D15: 1226 return "d15"; 1227 case UNW_ARM64_D16: 1228 return "d16"; 1229 case UNW_ARM64_D17: 1230 return "d17"; 1231 case UNW_ARM64_D18: 1232 return "d18"; 1233 case UNW_ARM64_D19: 1234 return "d19"; 1235 case UNW_ARM64_D20: 1236 return "d20"; 1237 case UNW_ARM64_D21: 1238 return "d21"; 1239 case UNW_ARM64_D22: 1240 return "d22"; 1241 case UNW_ARM64_D23: 1242 return "d23"; 1243 case UNW_ARM64_D24: 1244 return "d24"; 1245 case UNW_ARM64_D25: 1246 return "d25"; 1247 case UNW_ARM64_D26: 1248 return "d26"; 1249 case UNW_ARM64_D27: 1250 return "d27"; 1251 case UNW_ARM64_D28: 1252 return "d28"; 1253 case UNW_ARM64_D29: 1254 return "d29"; 1255 case UNW_ARM64_D30: 1256 return "d30"; 1257 case UNW_ARM64_D31: 1258 return "d31"; 1259 default: 1260 return "unknown register"; 1261 } 1262} 1263 1264inline bool Registers_arm64::validFloatRegister(int regNum) const { 1265 if (regNum < UNW_ARM64_D0) 1266 return false; 1267 if (regNum > UNW_ARM64_D31) 1268 return false; 1269 return true; 1270} 1271 1272inline double Registers_arm64::getFloatRegister(int regNum) const { 1273 assert(validFloatRegister(regNum)); 1274 return _vectorHalfRegisters[regNum - UNW_ARM64_D0]; 1275} 1276 1277inline void Registers_arm64::setFloatRegister(int regNum, double value) { 1278 assert(validFloatRegister(regNum)); 1279 _vectorHalfRegisters[regNum - UNW_ARM64_D0] = value; 1280} 1281 1282inline bool Registers_arm64::validVectorRegister(int) const { 1283 return false; 1284} 1285 1286inline v128 Registers_arm64::getVectorRegister(int) const { 1287 _LIBUNWIND_ABORT("no arm64 vector register support yet"); 1288} 1289 1290inline void Registers_arm64::setVectorRegister(int, v128) { 1291 _LIBUNWIND_ABORT("no arm64 vector register support yet"); 1292} 1293 1294/// Registers_arm holds the register state of a thread in a 32-bit arm 1295/// process. 1296/// 1297/// NOTE: Assumes VFPv3. On ARM processors without a floating point unit, 1298/// this uses more memory than required. 1299class _LIBUNWIND_HIDDEN Registers_arm { 1300public: 1301 Registers_arm(); 1302 Registers_arm(const void *registers); 1303 1304 bool validRegister(int num) const; 1305 uint32_t getRegister(int num); 1306 void setRegister(int num, uint32_t value); 1307 bool validFloatRegister(int num) const; 1308 unw_fpreg_t getFloatRegister(int num); 1309 void setFloatRegister(int num, unw_fpreg_t value); 1310 bool validVectorRegister(int num) const; 1311 v128 getVectorRegister(int num) const; 1312 void setVectorRegister(int num, v128 value); 1313 const char *getRegisterName(int num); 1314 void jumpto() { 1315 restoreSavedFloatRegisters(); 1316 restoreCoreAndJumpTo(); 1317 } 1318 1319 uint32_t getSP() const { return _registers.__sp; } 1320 void setSP(uint32_t value) { _registers.__sp = value; } 1321 uint32_t getIP() const { return _registers.__pc; } 1322 void setIP(uint32_t value) { _registers.__pc = value; } 1323 1324 void saveVFPAsX() { 1325 assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15); 1326 _use_X_for_vfp_save = true; 1327 } 1328 1329 void restoreSavedFloatRegisters() { 1330 if (_saved_vfp_d0_d15) { 1331 if (_use_X_for_vfp_save) 1332 restoreVFPWithFLDMX(_vfp_d0_d15_pad); 1333 else 1334 restoreVFPWithFLDMD(_vfp_d0_d15_pad); 1335 } 1336 if (_saved_vfp_d16_d31) 1337 restoreVFPv3(_vfp_d16_d31); 1338 if (_saved_iwmmx) 1339 restoreiWMMX(_iwmmx); 1340 if (_saved_iwmmx_control) 1341 restoreiWMMXControl(_iwmmx_control); 1342 } 1343 1344private: 1345 struct GPRs { 1346 uint32_t __r[13]; // r0-r12 1347 uint32_t __sp; // Stack pointer r13 1348 uint32_t __lr; // Link register r14 1349 uint32_t __pc; // Program counter r15 1350 }; 1351 1352 static void saveVFPWithFSTMD(unw_fpreg_t*); 1353 static void saveVFPWithFSTMX(unw_fpreg_t*); 1354 static void saveVFPv3(unw_fpreg_t*); 1355 static void saveiWMMX(unw_fpreg_t*); 1356 static void saveiWMMXControl(uint32_t*); 1357 static void restoreVFPWithFLDMD(unw_fpreg_t*); 1358 static void restoreVFPWithFLDMX(unw_fpreg_t*); 1359 static void restoreVFPv3(unw_fpreg_t*); 1360 static void restoreiWMMX(unw_fpreg_t*); 1361 static void restoreiWMMXControl(uint32_t*); 1362 void restoreCoreAndJumpTo(); 1363 1364 // ARM registers 1365 GPRs _registers; 1366 1367 // We save floating point registers lazily because we can't know ahead of 1368 // time which ones are used. See EHABI #4.7. 1369 1370 // Whether D0-D15 are saved in the FTSMX instead of FSTMD format. 1371 // 1372 // See EHABI #7.5 that explains how matching instruction sequences for load 1373 // and store need to be used to correctly restore the exact register bits. 1374 bool _use_X_for_vfp_save; 1375 // Whether VFP D0-D15 are saved. 1376 bool _saved_vfp_d0_d15; 1377 // Whether VFPv3 D16-D31 are saved. 1378 bool _saved_vfp_d16_d31; 1379 // Whether iWMMX data registers are saved. 1380 bool _saved_iwmmx; 1381 // Whether iWMMX control registers are saved. 1382 bool _saved_iwmmx_control; 1383 // VFP registers D0-D15, + padding if saved using FSTMX 1384 unw_fpreg_t _vfp_d0_d15_pad[17]; 1385 // VFPv3 registers D16-D31, always saved using FSTMD 1386 unw_fpreg_t _vfp_d16_d31[16]; 1387 // iWMMX registers 1388 unw_fpreg_t _iwmmx[16]; 1389 // iWMMX control registers 1390 uint32_t _iwmmx_control[4]; 1391}; 1392 1393inline Registers_arm::Registers_arm(const void *registers) 1394 : _use_X_for_vfp_save(false), 1395 _saved_vfp_d0_d15(false), 1396 _saved_vfp_d16_d31(false), 1397 _saved_iwmmx(false), 1398 _saved_iwmmx_control(false) { 1399 static_assert(sizeof(Registers_arm) < sizeof(unw_context_t), 1400 "arm registers do not fit into unw_context_t"); 1401 // See unw_getcontext() note about data. 1402 memcpy(&_registers, registers, 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 1409inline Registers_arm::Registers_arm() 1410 : _use_X_for_vfp_save(false), 1411 _saved_vfp_d0_d15(false), 1412 _saved_vfp_d16_d31(false), 1413 _saved_iwmmx(false), 1414 _saved_iwmmx_control(false) { 1415 memset(&_registers, 0, sizeof(_registers)); 1416 memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad)); 1417 memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31)); 1418 memset(&_iwmmx, 0, sizeof(_iwmmx)); 1419 memset(&_iwmmx_control, 0, sizeof(_iwmmx_control)); 1420} 1421 1422inline bool Registers_arm::validRegister(int regNum) const { 1423 // Returns true for all non-VFP registers supported by the EHABI 1424 // virtual register set (VRS). 1425 if (regNum == UNW_REG_IP) 1426 return true; 1427 if (regNum == UNW_REG_SP) 1428 return true; 1429 if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15) 1430 return true; 1431 if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) 1432 return true; 1433 return false; 1434} 1435 1436inline uint32_t Registers_arm::getRegister(int regNum) { 1437 if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) 1438 return _registers.__sp; 1439 if (regNum == UNW_ARM_LR) 1440 return _registers.__lr; 1441 if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) 1442 return _registers.__pc; 1443 if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) 1444 return _registers.__r[regNum]; 1445 if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) { 1446 if (!_saved_iwmmx_control) { 1447 _saved_iwmmx_control = true; 1448 saveiWMMXControl(_iwmmx_control); 1449 } 1450 return _iwmmx_control[regNum - UNW_ARM_WC0]; 1451 } 1452 _LIBUNWIND_ABORT("unsupported arm register"); 1453} 1454 1455inline void Registers_arm::setRegister(int regNum, uint32_t value) { 1456 if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) 1457 _registers.__sp = value; 1458 else if (regNum == UNW_ARM_LR) 1459 _registers.__lr = value; 1460 else if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) 1461 _registers.__pc = value; 1462 else if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) 1463 _registers.__r[regNum] = value; 1464 else if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) { 1465 if (!_saved_iwmmx_control) { 1466 _saved_iwmmx_control = true; 1467 saveiWMMXControl(_iwmmx_control); 1468 } 1469 _iwmmx_control[regNum - UNW_ARM_WC0] = value; 1470 } else 1471 _LIBUNWIND_ABORT("unsupported arm register"); 1472} 1473 1474inline const char *Registers_arm::getRegisterName(int regNum) { 1475 switch (regNum) { 1476 case UNW_REG_IP: 1477 case UNW_ARM_IP: // UNW_ARM_R15 is alias 1478 return "pc"; 1479 case UNW_ARM_LR: // UNW_ARM_R14 is alias 1480 return "lr"; 1481 case UNW_REG_SP: 1482 case UNW_ARM_SP: // UNW_ARM_R13 is alias 1483 return "sp"; 1484 case UNW_ARM_R0: 1485 return "r0"; 1486 case UNW_ARM_R1: 1487 return "r1"; 1488 case UNW_ARM_R2: 1489 return "r2"; 1490 case UNW_ARM_R3: 1491 return "r3"; 1492 case UNW_ARM_R4: 1493 return "r4"; 1494 case UNW_ARM_R5: 1495 return "r5"; 1496 case UNW_ARM_R6: 1497 return "r6"; 1498 case UNW_ARM_R7: 1499 return "r7"; 1500 case UNW_ARM_R8: 1501 return "r8"; 1502 case UNW_ARM_R9: 1503 return "r9"; 1504 case UNW_ARM_R10: 1505 return "r10"; 1506 case UNW_ARM_R11: 1507 return "r11"; 1508 case UNW_ARM_R12: 1509 return "r12"; 1510 case UNW_ARM_S0: 1511 return "s0"; 1512 case UNW_ARM_S1: 1513 return "s1"; 1514 case UNW_ARM_S2: 1515 return "s2"; 1516 case UNW_ARM_S3: 1517 return "s3"; 1518 case UNW_ARM_S4: 1519 return "s4"; 1520 case UNW_ARM_S5: 1521 return "s5"; 1522 case UNW_ARM_S6: 1523 return "s6"; 1524 case UNW_ARM_S7: 1525 return "s7"; 1526 case UNW_ARM_S8: 1527 return "s8"; 1528 case UNW_ARM_S9: 1529 return "s9"; 1530 case UNW_ARM_S10: 1531 return "s10"; 1532 case UNW_ARM_S11: 1533 return "s11"; 1534 case UNW_ARM_S12: 1535 return "s12"; 1536 case UNW_ARM_S13: 1537 return "s13"; 1538 case UNW_ARM_S14: 1539 return "s14"; 1540 case UNW_ARM_S15: 1541 return "s15"; 1542 case UNW_ARM_S16: 1543 return "s16"; 1544 case UNW_ARM_S17: 1545 return "s17"; 1546 case UNW_ARM_S18: 1547 return "s18"; 1548 case UNW_ARM_S19: 1549 return "s19"; 1550 case UNW_ARM_S20: 1551 return "s20"; 1552 case UNW_ARM_S21: 1553 return "s21"; 1554 case UNW_ARM_S22: 1555 return "s22"; 1556 case UNW_ARM_S23: 1557 return "s23"; 1558 case UNW_ARM_S24: 1559 return "s24"; 1560 case UNW_ARM_S25: 1561 return "s25"; 1562 case UNW_ARM_S26: 1563 return "s26"; 1564 case UNW_ARM_S27: 1565 return "s27"; 1566 case UNW_ARM_S28: 1567 return "s28"; 1568 case UNW_ARM_S29: 1569 return "s29"; 1570 case UNW_ARM_S30: 1571 return "s30"; 1572 case UNW_ARM_S31: 1573 return "s31"; 1574 case UNW_ARM_D0: 1575 return "d0"; 1576 case UNW_ARM_D1: 1577 return "d1"; 1578 case UNW_ARM_D2: 1579 return "d2"; 1580 case UNW_ARM_D3: 1581 return "d3"; 1582 case UNW_ARM_D4: 1583 return "d4"; 1584 case UNW_ARM_D5: 1585 return "d5"; 1586 case UNW_ARM_D6: 1587 return "d6"; 1588 case UNW_ARM_D7: 1589 return "d7"; 1590 case UNW_ARM_D8: 1591 return "d8"; 1592 case UNW_ARM_D9: 1593 return "d9"; 1594 case UNW_ARM_D10: 1595 return "d10"; 1596 case UNW_ARM_D11: 1597 return "d11"; 1598 case UNW_ARM_D12: 1599 return "d12"; 1600 case UNW_ARM_D13: 1601 return "d13"; 1602 case UNW_ARM_D14: 1603 return "d14"; 1604 case UNW_ARM_D15: 1605 return "d15"; 1606 case UNW_ARM_D16: 1607 return "d16"; 1608 case UNW_ARM_D17: 1609 return "d17"; 1610 case UNW_ARM_D18: 1611 return "d18"; 1612 case UNW_ARM_D19: 1613 return "d19"; 1614 case UNW_ARM_D20: 1615 return "d20"; 1616 case UNW_ARM_D21: 1617 return "d21"; 1618 case UNW_ARM_D22: 1619 return "d22"; 1620 case UNW_ARM_D23: 1621 return "d23"; 1622 case UNW_ARM_D24: 1623 return "d24"; 1624 case UNW_ARM_D25: 1625 return "d25"; 1626 case UNW_ARM_D26: 1627 return "d26"; 1628 case UNW_ARM_D27: 1629 return "d27"; 1630 case UNW_ARM_D28: 1631 return "d28"; 1632 case UNW_ARM_D29: 1633 return "d29"; 1634 case UNW_ARM_D30: 1635 return "d30"; 1636 case UNW_ARM_D31: 1637 return "d31"; 1638 default: 1639 return "unknown register"; 1640 } 1641} 1642 1643inline bool Registers_arm::validFloatRegister(int regNum) const { 1644 // NOTE: Consider the intel MMX registers floating points so the 1645 // unw_get_fpreg can be used to transmit the 64-bit data back. 1646 return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31)) 1647 || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15)); 1648} 1649 1650inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) { 1651 if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) { 1652 if (!_saved_vfp_d0_d15) { 1653 _saved_vfp_d0_d15 = true; 1654 if (_use_X_for_vfp_save) 1655 saveVFPWithFSTMX(_vfp_d0_d15_pad); 1656 else 1657 saveVFPWithFSTMD(_vfp_d0_d15_pad); 1658 } 1659 return _vfp_d0_d15_pad[regNum - UNW_ARM_D0]; 1660 } else if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) { 1661 if (!_saved_vfp_d16_d31) { 1662 _saved_vfp_d16_d31 = true; 1663 saveVFPv3(_vfp_d16_d31); 1664 } 1665 return _vfp_d16_d31[regNum - UNW_ARM_D16]; 1666 } else if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) { 1667 if (!_saved_iwmmx) { 1668 _saved_iwmmx = true; 1669 saveiWMMX(_iwmmx); 1670 } 1671 return _iwmmx[regNum - UNW_ARM_WR0]; 1672 } else { 1673 _LIBUNWIND_ABORT("Unknown ARM float register"); 1674 } 1675} 1676 1677inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) { 1678 if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) { 1679 if (!_saved_vfp_d0_d15) { 1680 _saved_vfp_d0_d15 = true; 1681 if (_use_X_for_vfp_save) 1682 saveVFPWithFSTMX(_vfp_d0_d15_pad); 1683 else 1684 saveVFPWithFSTMD(_vfp_d0_d15_pad); 1685 } 1686 _vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value; 1687 } else if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) { 1688 if (!_saved_vfp_d16_d31) { 1689 _saved_vfp_d16_d31 = true; 1690 saveVFPv3(_vfp_d16_d31); 1691 } 1692 _vfp_d16_d31[regNum - UNW_ARM_D16] = value; 1693 } else if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) { 1694 if (!_saved_iwmmx) { 1695 _saved_iwmmx = true; 1696 saveiWMMX(_iwmmx); 1697 } 1698 _iwmmx[regNum - UNW_ARM_WR0] = value; 1699 } else { 1700 _LIBUNWIND_ABORT("Unknown ARM float register"); 1701 } 1702} 1703 1704inline bool Registers_arm::validVectorRegister(int) const { 1705 return false; 1706} 1707 1708inline v128 Registers_arm::getVectorRegister(int) const { 1709 _LIBUNWIND_ABORT("ARM vector support not implemented"); 1710} 1711 1712inline void Registers_arm::setVectorRegister(int, v128) { 1713 _LIBUNWIND_ABORT("ARM vector support not implemented"); 1714} 1715 1716} // namespace libunwind 1717 1718#endif // __REGISTERS_HPP__ 1719