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