1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
3 * Copyright (c) 2007-2011 Apple Inc. All rights reserved.
5 * @APPLE_LICENSE_HEADER_START@
7 * This file contains Original Code and/or Modifications of Original Code
8 * as defined in and that are subject to the Apple Public Source License
9 * Version 2.0 (the 'License'). You may not use this file except in
10 * compliance with the License. Please obtain a copy of the License at
11 * http://www.opensource.apple.com/apsl/ and read it before using this
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19 * Please see the License for the specific language governing rights and
20 * limitations under the License.
22 * @APPLE_LICENSE_HEADER_END@
26 // C++ interface to lower levels of libuwind
29 #ifndef __REGISTERS_HPP__
30 #define __REGISTERS_HPP__
36 #include <mach-o/loader.h>
37 #include <mach-o/getsect.h>
38 #include <mach/i386/thread_status.h>
40 #include "libunwind.h"
41 #include "InternalMacros.h"
47 /// Registers_x86 holds the register state of a thread in a 32-bit intel process.
53 Registers_x86(const void* registers);
55 bool validRegister(int num) const;
56 uint32_t getRegister(int num) const;
57 void setRegister(int num, uint32_t value);
58 bool validFloatRegister(int num) const { return false; }
59 double getFloatRegister(int num) const;
60 void setFloatRegister(int num, double value);
61 bool validVectorRegister(int num) const { return false; }
62 v128 getVectorRegister(int num) const;
63 void setVectorRegister(int num, v128 value);
64 const char* getRegisterName(int num);
67 uint32_t getSP() const { return fRegisters.__esp; }
68 void setSP(uint32_t value) { fRegisters.__esp = value; }
69 uint32_t getIP() const { return fRegisters.__eip; }
70 void setIP(uint32_t value) { fRegisters.__eip = value; }
71 uint32_t getEBP() const { return fRegisters.__ebp; }
72 void setEBP(uint32_t value) { fRegisters.__ebp = value; }
73 uint32_t getEBX() const { return fRegisters.__ebx; }
74 void setEBX(uint32_t value) { fRegisters.__ebx = value; }
75 uint32_t getECX() const { return fRegisters.__ecx; }
76 void setECX(uint32_t value) { fRegisters.__ecx = value; }
77 uint32_t getEDX() const { return fRegisters.__edx; }
78 void setEDX(uint32_t value) { fRegisters.__edx = value; }
79 uint32_t getESI() const { return fRegisters.__esi; }
80 void setESI(uint32_t value) { fRegisters.__esi = value; }
81 uint32_t getEDI() const { return fRegisters.__edi; }
82 void setEDI(uint32_t value) { fRegisters.__edi = value; }
85 i386_thread_state_t fRegisters;
88 inline Registers_x86::Registers_x86(const void* registers)
90 COMPILE_TIME_ASSERT( sizeof(Registers_x86) < sizeof(unw_context_t) );
91 fRegisters = *((i386_thread_state_t*)registers);
94 inline Registers_x86::Registers_x86()
96 bzero(&fRegisters, sizeof(fRegisters));
100 inline bool Registers_x86::validRegister(int regNum) const
102 if ( regNum == UNW_REG_IP )
104 if ( regNum == UNW_REG_SP )
113 inline uint32_t Registers_x86::getRegister(int regNum) const
117 return fRegisters.__eip;
119 return fRegisters.__esp;
121 return fRegisters.__eax;
123 return fRegisters.__ecx;
125 return fRegisters.__edx;
127 return fRegisters.__ebx;
129 return fRegisters.__ebp;
131 return fRegisters.__esp;
133 return fRegisters.__esi;
135 return fRegisters.__edi;
137 ABORT("unsupported x86 register");
140 inline void Registers_x86::setRegister(int regNum, uint32_t value)
144 fRegisters.__eip = value;
147 fRegisters.__esp = value;
150 fRegisters.__eax = value;
153 fRegisters.__ecx = value;
156 fRegisters.__edx = value;
159 fRegisters.__ebx = value;
162 fRegisters.__ebp = value;
165 fRegisters.__esp = value;
168 fRegisters.__esi = value;
171 fRegisters.__edi = value;
174 ABORT("unsupported x86 register");
177 inline const char* Registers_x86::getRegisterName(int regNum)
201 return "unknown register";
205 inline double Registers_x86::getFloatRegister(int num) const
207 ABORT("no x86 float registers");
210 inline void Registers_x86::setFloatRegister(int num, double value)
212 ABORT("no x86 float registers");
215 inline v128 Registers_x86::getVectorRegister(int num) const
217 ABORT("no x86 vector registers");
220 inline void Registers_x86::setVectorRegister(int num, v128 value)
222 ABORT("no x86 vector registers");
229 /// Registers_x86_64 holds the register state of a thread in a 64-bit intel process.
231 class Registers_x86_64
235 Registers_x86_64(const void* registers);
237 bool validRegister(int num) const;
238 uint64_t getRegister(int num) const;
239 void setRegister(int num, uint64_t value);
240 bool validFloatRegister(int num) const{ return false; }
241 double getFloatRegister(int num) const;
242 void setFloatRegister(int num, double value);
243 bool validVectorRegister(int num) const { return false; }
244 v128 getVectorRegister(int num) const;
245 void setVectorRegister(int num, v128 value);
246 const char* getRegisterName(int num);
248 uint64_t getSP() const { return fRegisters.__rsp; }
249 void setSP(uint64_t value) { fRegisters.__rsp = value; }
250 uint64_t getIP() const { return fRegisters.__rip; }
251 void setIP(uint64_t value) { fRegisters.__rip = value; }
252 uint64_t getRBP() const { return fRegisters.__rbp; }
253 void setRBP(uint64_t value) { fRegisters.__rbp = value; }
254 uint64_t getRBX() const { return fRegisters.__rbx; }
255 void setRBX(uint64_t value) { fRegisters.__rbx = value; }
256 uint64_t getR12() const { return fRegisters.__r12; }
257 void setR12(uint64_t value) { fRegisters.__r12 = value; }
258 uint64_t getR13() const { return fRegisters.__r13; }
259 void setR13(uint64_t value) { fRegisters.__r13 = value; }
260 uint64_t getR14() const { return fRegisters.__r14; }
261 void setR14(uint64_t value) { fRegisters.__r14 = value; }
262 uint64_t getR15() const { return fRegisters.__r15; }
263 void setR15(uint64_t value) { fRegisters.__r15 = value; }
265 x86_thread_state64_t fRegisters;
268 inline Registers_x86_64::Registers_x86_64(const void* registers)
270 COMPILE_TIME_ASSERT( sizeof(Registers_x86_64) < sizeof(unw_context_t) );
271 fRegisters = *((x86_thread_state64_t*)registers);
274 inline Registers_x86_64::Registers_x86_64()
276 bzero(&fRegisters, sizeof(fRegisters));
280 inline bool Registers_x86_64::validRegister(int regNum) const
282 if ( regNum == UNW_REG_IP )
284 if ( regNum == UNW_REG_SP )
293 inline uint64_t Registers_x86_64::getRegister(int regNum) const
297 return fRegisters.__rip;
299 return fRegisters.__rsp;
301 return fRegisters.__rax;
303 return fRegisters.__rdx;
305 return fRegisters.__rcx;
307 return fRegisters.__rbx;
309 return fRegisters.__rsi;
311 return fRegisters.__rdi;
313 return fRegisters.__rbp;
315 return fRegisters.__rsp;
317 return fRegisters.__r8;
319 return fRegisters.__r9;
321 return fRegisters.__r10;
323 return fRegisters.__r11;
325 return fRegisters.__r12;
327 return fRegisters.__r13;
329 return fRegisters.__r14;
331 return fRegisters.__r15;
333 ABORT("unsupported x86_64 register");
336 inline void Registers_x86_64::setRegister(int regNum, uint64_t value)
340 fRegisters.__rip = value;
343 fRegisters.__rsp = value;
346 fRegisters.__rax = value;
349 fRegisters.__rdx = value;
352 fRegisters.__rcx = value;
355 fRegisters.__rbx = value;
358 fRegisters.__rsi = value;
361 fRegisters.__rdi = value;
364 fRegisters.__rbp = value;
367 fRegisters.__rsp = value;
370 fRegisters.__r8 = value;
373 fRegisters.__r9 = value;
376 fRegisters.__r10 = value;
379 fRegisters.__r11 = value;
382 fRegisters.__r12 = value;
385 fRegisters.__r13 = value;
388 fRegisters.__r14 = value;
391 fRegisters.__r15 = value;
394 ABORT("unsupported x86_64 register");
397 inline const char* Registers_x86_64::getRegisterName(int regNum)
437 return "unknown register";
441 double Registers_x86_64::getFloatRegister(int num) const
443 ABORT("no x86_64 float registers");
446 void Registers_x86_64::setFloatRegister(int num, double value)
448 ABORT("no x86_64 float registers");
451 inline v128 Registers_x86_64::getVectorRegister(int num) const
453 ABORT("no x86_64 vector registers");
456 inline void Registers_x86_64::setVectorRegister(int num, v128 value)
458 ABORT("no x86_64 vector registers");
463 /// Registers_ppc holds the register state of a thread in a 32-bit PowerPC process.
469 Registers_ppc(const void* registers);
471 bool validRegister(int num) const;
472 uint32_t getRegister(int num) const;
473 void setRegister(int num, uint32_t value);
474 bool validFloatRegister(int num) const;
475 double getFloatRegister(int num) const;
476 void setFloatRegister(int num, double value);
477 bool validVectorRegister(int num) const;
478 v128 getVectorRegister(int num) const;
479 void setVectorRegister(int num, v128 value);
481 const char* getRegisterName(int num);
482 uint64_t getSP() const { return fRegisters.__r1; }
483 void setSP(uint64_t value) { fRegisters.__r1 = value; }
484 uint64_t getIP() const { return fRegisters.__srr0; }
485 void setIP(uint64_t value) { fRegisters.__srr0 = value; }
487 struct ppc_thread_state_t
489 unsigned int __srr0; /* Instruction address register (PC) */
490 unsigned int __srr1; /* Machine state register (supervisor) */
523 unsigned int __cr; /* Condition register */
524 unsigned int __xer; /* User's integer exception register */
525 unsigned int __lr; /* Link register */
526 unsigned int __ctr; /* Count register */
527 unsigned int __mq; /* MQ register (601 only) */
528 unsigned int __vrsave; /* Vector Save Register */
531 struct ppc_float_state_t
535 unsigned int __fpscr_pad; /* fpscr is 64 bits, 32 bits of rubbish */
536 unsigned int __fpscr; /* floating point status register */
539 ppc_thread_state_t fRegisters;
540 ppc_float_state_t fFloatRegisters;
541 v128 fVectorRegisters[32]; // offset 424
546 inline Registers_ppc::Registers_ppc(const void* registers)
548 COMPILE_TIME_ASSERT( sizeof(Registers_ppc) < sizeof(unw_context_t) );
549 fRegisters = *((ppc_thread_state_t*)registers);
550 fFloatRegisters = *((ppc_float_state_t*)((char*)registers+160));
551 memcpy(fVectorRegisters, ((char*)registers+424), sizeof(fVectorRegisters));
554 inline Registers_ppc::Registers_ppc()
556 bzero(&fRegisters, sizeof(fRegisters));
557 bzero(&fFloatRegisters, sizeof(fFloatRegisters));
558 bzero(&fVectorRegisters, sizeof(fVectorRegisters));
562 inline bool Registers_ppc::validRegister(int regNum) const
564 if ( regNum == UNW_REG_IP )
566 if ( regNum == UNW_REG_SP )
568 if ( regNum == UNW_PPC_VRSAVE )
572 if ( regNum <= UNW_PPC_R31 )
574 if ( regNum == UNW_PPC_MQ )
576 if ( regNum == UNW_PPC_LR )
578 if ( regNum == UNW_PPC_CTR )
580 if ( (UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7) )
586 inline uint32_t Registers_ppc::getRegister(int regNum) const
590 return fRegisters.__srr0;
592 return fRegisters.__r1;
594 return fRegisters.__r0;
596 return fRegisters.__r1;
598 return fRegisters.__r2;
600 return fRegisters.__r3;
602 return fRegisters.__r4;
604 return fRegisters.__r5;
606 return fRegisters.__r6;
608 return fRegisters.__r7;
610 return fRegisters.__r8;
612 return fRegisters.__r9;
614 return fRegisters.__r10;
616 return fRegisters.__r11;
618 return fRegisters.__r12;
620 return fRegisters.__r13;
622 return fRegisters.__r14;
624 return fRegisters.__r15;
626 return fRegisters.__r16;
628 return fRegisters.__r17;
630 return fRegisters.__r18;
632 return fRegisters.__r19;
634 return fRegisters.__r20;
636 return fRegisters.__r21;
638 return fRegisters.__r22;
640 return fRegisters.__r23;
642 return fRegisters.__r24;
644 return fRegisters.__r25;
646 return fRegisters.__r26;
648 return fRegisters.__r27;
650 return fRegisters.__r28;
652 return fRegisters.__r29;
654 return fRegisters.__r30;
656 return fRegisters.__r31;
658 return fRegisters.__lr;
660 return (fRegisters.__cr & 0xF0000000);
662 return (fRegisters.__cr & 0x0F000000);
664 return (fRegisters.__cr & 0x00F00000);
666 return (fRegisters.__cr & 0x000F0000);
668 return (fRegisters.__cr & 0x0000F000);
670 return (fRegisters.__cr & 0x00000F00);
672 return (fRegisters.__cr & 0x000000F0);
674 return (fRegisters.__cr & 0x0000000F);
676 return fRegisters.__vrsave;
678 ABORT("unsupported ppc register");
682 inline void Registers_ppc::setRegister(int regNum, uint32_t value)
684 //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value);
687 fRegisters.__srr0 = value;
690 fRegisters.__r1 = value;
693 fRegisters.__r0 = value;
696 fRegisters.__r1 = value;
699 fRegisters.__r2 = value;
702 fRegisters.__r3 = value;
705 fRegisters.__r4 = value;
708 fRegisters.__r5 = value;
711 fRegisters.__r6 = value;
714 fRegisters.__r7 = value;
717 fRegisters.__r8 = value;
720 fRegisters.__r9 = value;
723 fRegisters.__r10 = value;
726 fRegisters.__r11 = value;
729 fRegisters.__r12 = value;
732 fRegisters.__r13 = value;
735 fRegisters.__r14 = value;
738 fRegisters.__r15 = value;
741 fRegisters.__r16 = value;
744 fRegisters.__r17 = value;
747 fRegisters.__r18 = value;
750 fRegisters.__r19 = value;
753 fRegisters.__r20 = value;
756 fRegisters.__r21 = value;
759 fRegisters.__r22 = value;
762 fRegisters.__r23 = value;
765 fRegisters.__r24 = value;
768 fRegisters.__r25 = value;
771 fRegisters.__r26 = value;
774 fRegisters.__r27 = value;
777 fRegisters.__r28 = value;
780 fRegisters.__r29 = value;
783 fRegisters.__r30 = value;
786 fRegisters.__r31 = value;
789 fRegisters.__mq = value;
792 fRegisters.__lr = value;
795 fRegisters.__ctr = value;
798 fRegisters.__cr &= 0x0FFFFFFF;
799 fRegisters.__cr |= (value & 0xF0000000);
802 fRegisters.__cr &= 0xF0FFFFFF;
803 fRegisters.__cr |= (value & 0x0F000000);
806 fRegisters.__cr &= 0xFF0FFFFF;
807 fRegisters.__cr |= (value & 0x00F00000);
810 fRegisters.__cr &= 0xFFF0FFFF;
811 fRegisters.__cr |= (value & 0x000F0000);
814 fRegisters.__cr &= 0xFFFF0FFF;
815 fRegisters.__cr |= (value & 0x0000F000);
818 fRegisters.__cr &= 0xFFFFF0FF;
819 fRegisters.__cr |= (value & 0x00000F00);
822 fRegisters.__cr &= 0xFFFFFF0F;
823 fRegisters.__cr |= (value & 0x000000F0);
826 fRegisters.__cr &= 0xFFFFFFF0;
827 fRegisters.__cr |= (value & 0x0000000F);
830 fRegisters.__vrsave = value;
835 fRegisters.__xer = value;
839 case UNW_PPC_SPEFSCR:
843 ABORT("unsupported ppc register");
846 inline bool Registers_ppc::validFloatRegister(int regNum) const
848 if ( regNum < UNW_PPC_F0 )
850 if ( regNum > UNW_PPC_F31 )
855 inline double Registers_ppc::getFloatRegister(int regNum) const
857 assert(validFloatRegister(regNum));
858 return fFloatRegisters.__fpregs[regNum-UNW_PPC_F0];
861 inline void Registers_ppc::setFloatRegister(int regNum, double value)
863 //fprintf(stderr, "Registers_ppc::setFloatRegister(%d, %g))\n", regNum, value);
864 assert(validFloatRegister(regNum));
865 fFloatRegisters.__fpregs[regNum-UNW_PPC_F0] = value;
869 inline bool Registers_ppc::validVectorRegister(int regNum) const
871 if ( regNum < UNW_PPC_V0 )
873 if ( regNum > UNW_PPC_V31 )
878 v128 Registers_ppc::getVectorRegister(int regNum) const
880 assert(validVectorRegister(regNum));
881 v128 result = fVectorRegisters[regNum-UNW_PPC_V0];
882 //fprintf(stderr, "Registers_ppc::getVectorRegister(this=%p, %d) => <0x%08X, 0x%08X, 0x%08X, 0x%08X> \n",
883 // this, regNum, result.vec[0], result.vec[1], result.vec[2], result.vec[3]);
887 void Registers_ppc::setVectorRegister(int regNum, v128 value)
889 assert(validVectorRegister(regNum));
890 //fprintf(stderr, "Registers_ppc::setVectorRegister(this=%p, %d) <0x%08X, 0x%08X, 0x%08X, 0x%08X> => <0x%08X, 0x%08X, 0x%08X, 0x%08X> \n",
891 // this, regNum, fVectorRegisters[regNum-UNW_PPC_V0].vec[0], fVectorRegisters[regNum-UNW_PPC_V0].vec[1], fVectorRegisters[regNum-UNW_PPC_V0].vec[2],
892 // fVectorRegisters[regNum-UNW_PPC_V0].vec[3], value.vec[0], value.vec[1], value.vec[2], value.vec[3]);
893 fVectorRegisters[regNum-UNW_PPC_V0] = value;
897 inline const char* Registers_ppc::getRegisterName(int regNum)
1035 return "unknown register";
1044 struct arm_thread_state64_t
1046 __uint64_t __x[29]; /* General purpose registers x0-x28 */
1047 __uint64_t __fp; /* Frame pointer x29 */
1048 __uint64_t __lr; /* Link register x30 */
1049 __uint64_t __sp; /* Stack pointer x31 */
1050 __uint64_t __pc; /* Program counter */
1051 __uint32_t __cpsr; /* Current program status register */
1052 __uint32_t padding[3]; /* round up struct size to be 0x110 */
1057 /// Registers_arm64 holds the register state of a thread in a 64-bit intel process.
1059 class Registers_arm64
1063 Registers_arm64(const void* registers);
1065 bool validRegister(int num) const;
1066 uint64_t getRegister(int num) const;
1067 void setRegister(int num, uint64_t value);
1068 bool validFloatRegister(int num) const;
1069 double getFloatRegister(int num) const;
1070 void setFloatRegister(int num, double value);
1071 bool validVectorRegister(int num) const;
1072 v128 getVectorRegister(int num) const;
1073 void setVectorRegister(int num, v128 value);
1074 const char* getRegisterName(int num);
1076 uint64_t getSP() const { return fRegisters.__sp; }
1077 void setSP(uint64_t value) { fRegisters.__sp = value; }
1078 uint64_t getIP() const { return fRegisters.__pc; }
1079 void setIP(uint64_t value) { fRegisters.__pc = value; }
1080 uint64_t getFP() const { return fRegisters.__fp; }
1081 void setFP(uint64_t value) { fRegisters.__fp = value; }
1083 arm_thread_state64_t fRegisters;
1084 double fHalfVectorRegisters[32];
1085 // Currently only the lower double in 128-bit vectore registers
1086 // is perserved during unwinding. We could define new register
1087 // numbers (> 96) which mean whole vector registers, then this
1088 // struct would need to change to contain whole vector registers.
1091 inline Registers_arm64::Registers_arm64(const void* registers)
1093 COMPILE_TIME_ASSERT( sizeof(Registers_arm64) < sizeof(unw_context_t) );
1094 fRegisters = *((arm_thread_state64_t*)registers);
1097 inline Registers_arm64::Registers_arm64()
1099 bzero(&fRegisters, sizeof(fRegisters));
1100 bzero(&fRegisters, sizeof(fHalfVectorRegisters));
1104 inline bool Registers_arm64::validRegister(int regNum) const
1106 if ( regNum == UNW_REG_IP )
1108 if ( regNum == UNW_REG_SP )
1114 if ( (regNum > 31) && (regNum < 64) )
1119 inline uint64_t Registers_arm64::getRegister(int regNum) const
1121 if ( regNum == UNW_REG_IP )
1122 return fRegisters.__pc;
1123 if ( regNum == UNW_REG_SP )
1124 return fRegisters.__sp;
1125 if ( (regNum >= 0) && (regNum < 32) )
1126 return fRegisters.__x[regNum];
1127 ABORT("unsupported arm64 register");
1130 inline void Registers_arm64::setRegister(int regNum, uint64_t value)
1132 if ( regNum == UNW_REG_IP )
1133 fRegisters.__pc = value;
1134 else if ( regNum == UNW_REG_SP )
1135 fRegisters.__sp = value;
1136 else if ( (regNum >= 0) && (regNum < 32) )
1137 fRegisters.__x[regNum] = value;
1139 ABORT("unsupported arm64 register");
1142 inline const char* Registers_arm64::getRegisterName(int regNum)
1278 return "unknown register";
1282 bool Registers_arm64::validFloatRegister(int regNum) const
1284 if ( regNum < UNW_ARM64_D0 )
1286 if ( regNum > UNW_ARM64_D31 )
1292 double Registers_arm64::getFloatRegister(int regNum) const
1294 assert(validFloatRegister(regNum));
1295 return fHalfVectorRegisters[regNum-UNW_ARM64_D0];
1298 void Registers_arm64::setFloatRegister(int regNum, double value)
1300 assert(validFloatRegister(regNum));
1301 fHalfVectorRegisters[regNum-UNW_ARM64_D0] = value;
1304 inline bool Registers_arm64::validVectorRegister(int regNum) const
1309 inline v128 Registers_arm64::getVectorRegister(int regNum) const
1311 ABORT("no arm64 vector register support yet");
1314 inline void Registers_arm64::setVectorRegister(int regNum, v128 value)
1316 ABORT("no arm64 vector register support yet");
1321 /// Registers_arm holds the register state of a thread in a 32-bit arm process.
1323 class Registers_arm {
1327 bool validRegister(int num) const;
1328 uint32_t getRegister(int num) const;
1329 void setRegister(int num, uint32_t value);
1330 bool validFloatRegister(int num) const;
1331 unw_fpreg_t getFloatRegister(int num) const;
1332 void setFloatRegister(int num, unw_fpreg_t value);
1333 bool validVectorRegister(int num) const;
1334 v128 getVectorRegister(int num) const;
1335 void setVectorRegister(int num, v128 value);
1336 const char *getRegisterName(int num);
1339 uint32_t getSP() const { return _registers[13]; }
1340 void setSP(uint32_t value) { _registers[13] = value; }
1341 uint32_t getIP() const { return _registers[15]; }
1342 void setIP(uint32_t value) { _registers[15] = value; }
1345 uint32_t _registers[16];
1348 inline Registers_arm::Registers_arm() {
1349 bzero(&_registers, sizeof(_registers));
1353 } // namespace libunwind
1357 #endif // __REGISTERS_HPP__