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 memcpy(&_registers, registers, sizeof(_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 memcpy(&_registers, registers, sizeof(_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 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
Registers_ppc()564 inline Registers_ppc::Registers_ppc() {
565 memset(&_registers, 0, sizeof(_registers));
566 memset(&_floatRegisters, 0, sizeof(_floatRegisters));
567 memset(&_vectorRegisters, 0, sizeof(_vectorRegisters));
568 }
569
validRegister(int regNum) const570 inline 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
getRegister(int regNum) const592 inline 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
setRegister(int regNum,uint32_t value)686 inline 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
validFloatRegister(int regNum) const849 inline 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
getFloatRegister(int regNum) const857 inline double Registers_ppc::getFloatRegister(int regNum) const {
858 assert(validFloatRegister(regNum));
859 return _floatRegisters.__fpregs[regNum - UNW_PPC_F0];
860 }
861
setFloatRegister(int regNum,double value)862 inline void Registers_ppc::setFloatRegister(int regNum, double value) {
863 assert(validFloatRegister(regNum));
864 _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value;
865 }
866
validVectorRegister(int regNum) const867 inline 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
getVectorRegister(int regNum) const875 inline v128 Registers_ppc::getVectorRegister(int regNum) const {
876 assert(validVectorRegister(regNum));
877 v128 result = _vectorRegisters[regNum - UNW_PPC_V0];
878 return result;
879 }
880
setVectorRegister(int regNum,v128 value)881 inline void Registers_ppc::setVectorRegister(int regNum, v128 value) {
882 assert(validVectorRegister(regNum));
883 _vectorRegisters[regNum - UNW_PPC_V0] = value;
884 }
885
getRegisterName(int regNum)886 inline 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.
1031 class _LIBUNWIND_HIDDEN Registers_arm64 {
1032 public:
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();
lastDwarfRegNum()1047 static int lastDwarfRegNum() { return 95; }
1048
getSP() const1049 uint64_t getSP() const { return _registers.__sp; }
setSP(uint64_t value)1050 void setSP(uint64_t value) { _registers.__sp = value; }
getIP() const1051 uint64_t getIP() const { return _registers.__pc; }
setIP(uint64_t value)1052 void setIP(uint64_t value) { _registers.__pc = value; }
getFP() const1053 uint64_t getFP() const { return _registers.__fp; }
setFP(uint64_t value)1054 void setFP(uint64_t value) { _registers.__fp = value; }
1055
1056 private:
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
Registers_arm64(const void * registers)1074 inline 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
Registers_arm64()1085 inline Registers_arm64::Registers_arm64() {
1086 memset(&_registers, 0, sizeof(_registers));
1087 memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
1088 }
1089
validRegister(int regNum) const1090 inline 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
getRegister(int regNum) const1104 inline 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
setRegister(int regNum,uint64_t value)1114 inline 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
getRegisterName(int regNum)1125 inline 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
validFloatRegister(int regNum) const1264 inline 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
getFloatRegister(int regNum) const1272 inline double Registers_arm64::getFloatRegister(int regNum) const {
1273 assert(validFloatRegister(regNum));
1274 return _vectorHalfRegisters[regNum - UNW_ARM64_D0];
1275 }
1276
setFloatRegister(int regNum,double value)1277 inline void Registers_arm64::setFloatRegister(int regNum, double value) {
1278 assert(validFloatRegister(regNum));
1279 _vectorHalfRegisters[regNum - UNW_ARM64_D0] = value;
1280 }
1281
validVectorRegister(int) const1282 inline bool Registers_arm64::validVectorRegister(int) const {
1283 return false;
1284 }
1285
getVectorRegister(int) const1286 inline v128 Registers_arm64::getVectorRegister(int) const {
1287 _LIBUNWIND_ABORT("no arm64 vector register support yet");
1288 }
1289
setVectorRegister(int,v128)1290 inline 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.
1299 class _LIBUNWIND_HIDDEN Registers_arm {
1300 public:
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);
jumpto()1314 void jumpto() {
1315 restoreSavedFloatRegisters();
1316 restoreCoreAndJumpTo();
1317 }
1318
getSP() const1319 uint32_t getSP() const { return _registers.__sp; }
setSP(uint32_t value)1320 void setSP(uint32_t value) { _registers.__sp = value; }
getIP() const1321 uint32_t getIP() const { return _registers.__pc; }
setIP(uint32_t value)1322 void setIP(uint32_t value) { _registers.__pc = value; }
1323
saveVFPAsX()1324 void saveVFPAsX() {
1325 assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15);
1326 _use_X_for_vfp_save = true;
1327 }
1328
restoreSavedFloatRegisters()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
1344 private:
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
Registers_arm(const void * registers)1393 inline 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
Registers_arm()1409 inline 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
validRegister(int regNum) const1422 inline 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
getRegister(int regNum)1436 inline 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
setRegister(int regNum,uint32_t value)1455 inline 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
getRegisterName(int regNum)1474 inline 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
validFloatRegister(int regNum) const1643 inline 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
getFloatRegister(int regNum)1650 inline 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
setFloatRegister(int regNum,unw_fpreg_t value)1677 inline 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
validVectorRegister(int) const1704 inline bool Registers_arm::validVectorRegister(int) const {
1705 return false;
1706 }
1707
getVectorRegister(int) const1708 inline v128 Registers_arm::getVectorRegister(int) const {
1709 _LIBUNWIND_ABORT("ARM vector support not implemented");
1710 }
1711
setVectorRegister(int,v128)1712 inline 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