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);
validFloatRegister(int) const39 bool validFloatRegister(int) const { return false; }
40 double getFloatRegister(int num) const;
41 void setFloatRegister(int num, double value);
validVectorRegister(int) const42 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();
lastDwarfRegNum()47 static int lastDwarfRegNum() { return 8; }
48
getSP() const49 uint32_t getSP() const { return _registers.__esp; }
setSP(uint32_t value)50 void setSP(uint32_t value) { _registers.__esp = value; }
getIP() const51 uint32_t getIP() const { return _registers.__eip; }
setIP(uint32_t value)52 void setIP(uint32_t value) { _registers.__eip = value; }
getEBP() const53 uint32_t getEBP() const { return _registers.__ebp; }
setEBP(uint32_t value)54 void setEBP(uint32_t value) { _registers.__ebp = value; }
getEBX() const55 uint32_t getEBX() const { return _registers.__ebx; }
setEBX(uint32_t value)56 void setEBX(uint32_t value) { _registers.__ebx = value; }
getECX() const57 uint32_t getECX() const { return _registers.__ecx; }
setECX(uint32_t value)58 void setECX(uint32_t value) { _registers.__ecx = value; }
getEDX() const59 uint32_t getEDX() const { return _registers.__edx; }
setEDX(uint32_t value)60 void setEDX(uint32_t value) { _registers.__edx = value; }
getESI() const61 uint32_t getESI() const { return _registers.__esi; }
setESI(uint32_t value)62 void setESI(uint32_t value) { _registers.__esi = value; }
getEDI() const63 uint32_t getEDI() const { return _registers.__edi; }
setEDI(uint32_t value)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
Registers_x86(const void * registers)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
Registers_x86()95 inline Registers_x86::Registers_x86() {
96 memset(&_registers, 0, sizeof(_registers));
97 }
98
validRegister(int regNum) const99 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
getRegister(int regNum) const111 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
setRegister(int regNum,uint32_t value)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
getRegisterName(int regNum)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
getFloatRegister(int) const200 inline double Registers_x86::getFloatRegister(int) const {
201 _LIBUNWIND_ABORT("no x86 float registers");
202 }
203
setFloatRegister(int,double)204 inline void Registers_x86::setFloatRegister(int, double) {
205 _LIBUNWIND_ABORT("no x86 float registers");
206 }
207
getVectorRegister(int) const208 inline v128 Registers_x86::getVectorRegister(int) const {
209 _LIBUNWIND_ABORT("no x86 vector registers");
210 }
211
setVectorRegister(int,v128)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);
validFloatRegister(int) const227 bool validFloatRegister(int) const { return false; }
228 double getFloatRegister(int num) const;
229 void setFloatRegister(int num, double value);
validVectorRegister(int) const230 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();
lastDwarfRegNum()235 static int lastDwarfRegNum() { return 16; }
236
getSP() const237 uint64_t getSP() const { return _registers.__rsp; }
setSP(uint64_t value)238 void setSP(uint64_t value) { _registers.__rsp = value; }
getIP() const239 uint64_t getIP() const { return _registers.__rip; }
setIP(uint64_t value)240 void setIP(uint64_t value) { _registers.__rip = value; }
getRBP() const241 uint64_t getRBP() const { return _registers.__rbp; }
setRBP(uint64_t value)242 void setRBP(uint64_t value) { _registers.__rbp = value; }
getRBX() const243 uint64_t getRBX() const { return _registers.__rbx; }
setRBX(uint64_t value)244 void setRBX(uint64_t value) { _registers.__rbx = value; }
getR12() const245 uint64_t getR12() const { return _registers.__r12; }
setR12(uint64_t value)246 void setR12(uint64_t value) { _registers.__r12 = value; }
getR13() const247 uint64_t getR13() const { return _registers.__r13; }
setR13(uint64_t value)248 void setR13(uint64_t value) { _registers.__r13 = value; }
getR14() const249 uint64_t getR14() const { return _registers.__r14; }
setR14(uint64_t value)250 void setR14(uint64_t value) { _registers.__r14 = value; }
getR15() const251 uint64_t getR15() const { return _registers.__r15; }
setR15(uint64_t value)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
Registers_x86_64(const void * registers)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
Registers_x86_64()287 inline Registers_x86_64::Registers_x86_64() {
288 memset(&_registers, 0, sizeof(_registers));
289 }
290
validRegister(int regNum) const291 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
getRegister(int regNum) const303 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
setRegister(int regNum,uint64_t value)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
getRegisterName(int regNum)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
getFloatRegister(int) const448 inline double Registers_x86_64::getFloatRegister(int) const {
449 _LIBUNWIND_ABORT("no x86_64 float registers");
450 }
451
setFloatRegister(int,double)452 inline void Registers_x86_64::setFloatRegister(int, double) {
453 _LIBUNWIND_ABORT("no x86_64 float registers");
454 }
455
getVectorRegister(int) const456 inline v128 Registers_x86_64::getVectorRegister(int) const {
457 _LIBUNWIND_ABORT("no x86_64 vector registers");
458 }
459
setVectorRegister(int,v128)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();
lastDwarfRegNum()483 static int lastDwarfRegNum() { return 112; }
484
getSP() const485 uint64_t getSP() const { return _registers.__r1; }
setSP(uint32_t value)486 void setSP(uint32_t value) { _registers.__r1 = value; }
getIP() const487 uint64_t getIP() const { return _registers.__srr0; }
setIP(uint32_t value)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
Registers_ppc(const void * registers)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
Registers_ppc()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
validRegister(int regNum) const560 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
getRegister(int regNum) const582 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
setRegister(int regNum,uint32_t value)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
validFloatRegister(int regNum) const839 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
getFloatRegister(int regNum) const847 inline double Registers_ppc::getFloatRegister(int regNum) const {
848 assert(validFloatRegister(regNum));
849 return _floatRegisters.__fpregs[regNum - UNW_PPC_F0];
850 }
851
setFloatRegister(int regNum,double value)852 inline void Registers_ppc::setFloatRegister(int regNum, double value) {
853 assert(validFloatRegister(regNum));
854 _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value;
855 }
856
validVectorRegister(int regNum) const857 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
getVectorRegister(int regNum) const865 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
setVectorRegister(int regNum,v128 value)871 inline void Registers_ppc::setVectorRegister(int regNum, v128 value) {
872 assert(validVectorRegister(regNum));
873 _vectorRegisters[regNum - UNW_PPC_V0] = value;
874 }
875
getRegisterName(int regNum)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();
lastDwarfRegNum()1037 static int lastDwarfRegNum() { return 95; }
1038
getSP() const1039 uint64_t getSP() const { return _registers.__sp; }
setSP(uint64_t value)1040 void setSP(uint64_t value) { _registers.__sp = value; }
getIP() const1041 uint64_t getIP() const { return _registers.__pc; }
setIP(uint64_t value)1042 void setIP(uint64_t value) { _registers.__pc = value; }
getFP() const1043 uint64_t getFP() const { return _registers.__fp; }
setFP(uint64_t value)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
Registers_arm64(const void * registers)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
Registers_arm64()1072 inline Registers_arm64::Registers_arm64() {
1073 memset(&_registers, 0, sizeof(_registers));
1074 memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
1075 }
1076
validRegister(int regNum) const1077 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
getRegister(int regNum) const1091 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
setRegister(int regNum,uint64_t value)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
getRegisterName(int regNum)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
validFloatRegister(int regNum) const1251 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
getFloatRegister(int regNum) const1259 inline double Registers_arm64::getFloatRegister(int regNum) const {
1260 assert(validFloatRegister(regNum));
1261 return _vectorHalfRegisters[regNum - UNW_ARM64_D0];
1262 }
1263
setFloatRegister(int regNum,double value)1264 inline void Registers_arm64::setFloatRegister(int regNum, double value) {
1265 assert(validFloatRegister(regNum));
1266 _vectorHalfRegisters[regNum - UNW_ARM64_D0] = value;
1267 }
1268
validVectorRegister(int) const1269 inline bool Registers_arm64::validVectorRegister(int) const {
1270 return false;
1271 }
1272
getVectorRegister(int) const1273 inline v128 Registers_arm64::getVectorRegister(int) const {
1274 _LIBUNWIND_ABORT("no arm64 vector register support yet");
1275 }
1276
setVectorRegister(int,v128)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);
jumpto()1301 void jumpto() {
1302 restoreSavedFloatRegisters();
1303 restoreCoreAndJumpTo();
1304 }
1305
getSP() const1306 uint32_t getSP() const { return _registers.__sp; }
setSP(uint32_t value)1307 void setSP(uint32_t value) { _registers.__sp = value; }
getIP() const1308 uint32_t getIP() const { return _registers.__pc; }
setIP(uint32_t value)1309 void setIP(uint32_t value) { _registers.__pc = value; }
1310
saveVFPAsX()1311 void saveVFPAsX() {
1312 assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15);
1313 _use_X_for_vfp_save = true;
1314 }
1315
restoreSavedFloatRegisters()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
Registers_arm(const void * registers)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
Registers_arm()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
validRegister(int regNum) const1409 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
getRegister(int regNum)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
setRegister(int regNum,uint32_t value)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
getRegisterName(int regNum)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
validFloatRegister(int regNum) const1630 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
getFloatRegister(int regNum)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
setFloatRegister(int regNum,unw_fpreg_t value)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
validVectorRegister(int) const1691 inline bool Registers_arm::validVectorRegister(int) const {
1692 return false;
1693 }
1694
getVectorRegister(int) const1695 inline v128 Registers_arm::getVectorRegister(int) const {
1696 _LIBUNWIND_ABORT("ARM vector support not implemented");
1697 }
1698
setVectorRegister(int,v128)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