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 <string.h>
18
19 #include "libunwind.h"
20 #include "config.h"
21
22 namespace libunwind {
23
24 // For emulating 128-bit registers
25 struct v128 { uint32_t vec[4]; };
26
27 enum {
28 REGISTERS_X86,
29 REGISTERS_X86_64,
30 REGISTERS_PPC,
31 REGISTERS_PPC64,
32 REGISTERS_ARM64,
33 REGISTERS_ARM,
34 REGISTERS_OR1K,
35 REGISTERS_RISCV,
36 REGISTERS_MIPS_O32,
37 REGISTERS_MIPS_NEWABI,
38 REGISTERS_SPARC,
39 };
40
41 #if defined(_LIBUNWIND_TARGET_I386)
42 /// Registers_x86 holds the register state of a thread in a 32-bit intel
43 /// process.
44 class _LIBUNWIND_HIDDEN Registers_x86 {
45 public:
46 Registers_x86();
47 Registers_x86(const void *registers);
48
49 bool validRegister(int num) const;
50 uint32_t getRegister(int num) const;
51 void setRegister(int num, uint32_t value);
validFloatRegister(int) const52 bool validFloatRegister(int) const { return false; }
53 double getFloatRegister(int num) const;
54 void setFloatRegister(int num, double value);
validVectorRegister(int) const55 bool validVectorRegister(int) const { return false; }
56 v128 getVectorRegister(int num) const;
57 void setVectorRegister(int num, v128 value);
58 static const char *getRegisterName(int num);
59 void jumpto();
lastDwarfRegNum()60 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86; }
getArch()61 static int getArch() { return REGISTERS_X86; }
62
getSP() const63 uint32_t getSP() const { return _registers.__esp; }
setSP(uint32_t value)64 void setSP(uint32_t value) { _registers.__esp = value; }
getIP() const65 uint32_t getIP() const { return _registers.__eip; }
setIP(uint32_t value)66 void setIP(uint32_t value) { _registers.__eip = value; }
getEBP() const67 uint32_t getEBP() const { return _registers.__ebp; }
setEBP(uint32_t value)68 void setEBP(uint32_t value) { _registers.__ebp = value; }
getEBX() const69 uint32_t getEBX() const { return _registers.__ebx; }
setEBX(uint32_t value)70 void setEBX(uint32_t value) { _registers.__ebx = value; }
getECX() const71 uint32_t getECX() const { return _registers.__ecx; }
setECX(uint32_t value)72 void setECX(uint32_t value) { _registers.__ecx = value; }
getEDX() const73 uint32_t getEDX() const { return _registers.__edx; }
setEDX(uint32_t value)74 void setEDX(uint32_t value) { _registers.__edx = value; }
getESI() const75 uint32_t getESI() const { return _registers.__esi; }
setESI(uint32_t value)76 void setESI(uint32_t value) { _registers.__esi = value; }
getEDI() const77 uint32_t getEDI() const { return _registers.__edi; }
setEDI(uint32_t value)78 void setEDI(uint32_t value) { _registers.__edi = value; }
79
80 private:
81 struct GPRs {
82 unsigned int __eax;
83 unsigned int __ebx;
84 unsigned int __ecx;
85 unsigned int __edx;
86 unsigned int __edi;
87 unsigned int __esi;
88 unsigned int __ebp;
89 unsigned int __esp;
90 unsigned int __ss;
91 unsigned int __eflags;
92 unsigned int __eip;
93 unsigned int __cs;
94 unsigned int __ds;
95 unsigned int __es;
96 unsigned int __fs;
97 unsigned int __gs;
98 };
99
100 GPRs _registers;
101 };
102
Registers_x86(const void * registers)103 inline Registers_x86::Registers_x86(const void *registers) {
104 static_assert((check_fit<Registers_x86, unw_context_t>::does_fit),
105 "x86 registers do not fit into unw_context_t");
106 memcpy(&_registers, registers, sizeof(_registers));
107 }
108
Registers_x86()109 inline Registers_x86::Registers_x86() {
110 memset(&_registers, 0, sizeof(_registers));
111 }
112
validRegister(int regNum) const113 inline bool Registers_x86::validRegister(int regNum) const {
114 if (regNum == UNW_REG_IP)
115 return true;
116 if (regNum == UNW_REG_SP)
117 return true;
118 if (regNum < 0)
119 return false;
120 if (regNum > 7)
121 return false;
122 return true;
123 }
124
getRegister(int regNum) const125 inline uint32_t Registers_x86::getRegister(int regNum) const {
126 switch (regNum) {
127 case UNW_REG_IP:
128 return _registers.__eip;
129 case UNW_REG_SP:
130 return _registers.__esp;
131 case UNW_X86_EAX:
132 return _registers.__eax;
133 case UNW_X86_ECX:
134 return _registers.__ecx;
135 case UNW_X86_EDX:
136 return _registers.__edx;
137 case UNW_X86_EBX:
138 return _registers.__ebx;
139 #if !defined(__APPLE__)
140 case UNW_X86_ESP:
141 #else
142 case UNW_X86_EBP:
143 #endif
144 return _registers.__ebp;
145 #if !defined(__APPLE__)
146 case UNW_X86_EBP:
147 #else
148 case UNW_X86_ESP:
149 #endif
150 return _registers.__esp;
151 case UNW_X86_ESI:
152 return _registers.__esi;
153 case UNW_X86_EDI:
154 return _registers.__edi;
155 }
156 _LIBUNWIND_ABORT("unsupported x86 register");
157 }
158
setRegister(int regNum,uint32_t value)159 inline void Registers_x86::setRegister(int regNum, uint32_t value) {
160 switch (regNum) {
161 case UNW_REG_IP:
162 _registers.__eip = value;
163 return;
164 case UNW_REG_SP:
165 _registers.__esp = value;
166 return;
167 case UNW_X86_EAX:
168 _registers.__eax = value;
169 return;
170 case UNW_X86_ECX:
171 _registers.__ecx = value;
172 return;
173 case UNW_X86_EDX:
174 _registers.__edx = value;
175 return;
176 case UNW_X86_EBX:
177 _registers.__ebx = value;
178 return;
179 #if !defined(__APPLE__)
180 case UNW_X86_ESP:
181 #else
182 case UNW_X86_EBP:
183 #endif
184 _registers.__ebp = value;
185 return;
186 #if !defined(__APPLE__)
187 case UNW_X86_EBP:
188 #else
189 case UNW_X86_ESP:
190 #endif
191 _registers.__esp = value;
192 return;
193 case UNW_X86_ESI:
194 _registers.__esi = value;
195 return;
196 case UNW_X86_EDI:
197 _registers.__edi = value;
198 return;
199 }
200 _LIBUNWIND_ABORT("unsupported x86 register");
201 }
202
getRegisterName(int regNum)203 inline const char *Registers_x86::getRegisterName(int regNum) {
204 switch (regNum) {
205 case UNW_REG_IP:
206 return "ip";
207 case UNW_REG_SP:
208 return "esp";
209 case UNW_X86_EAX:
210 return "eax";
211 case UNW_X86_ECX:
212 return "ecx";
213 case UNW_X86_EDX:
214 return "edx";
215 case UNW_X86_EBX:
216 return "ebx";
217 case UNW_X86_EBP:
218 return "ebp";
219 case UNW_X86_ESP:
220 return "esp";
221 case UNW_X86_ESI:
222 return "esi";
223 case UNW_X86_EDI:
224 return "edi";
225 default:
226 return "unknown register";
227 }
228 }
229
getFloatRegister(int) const230 inline double Registers_x86::getFloatRegister(int) const {
231 _LIBUNWIND_ABORT("no x86 float registers");
232 }
233
setFloatRegister(int,double)234 inline void Registers_x86::setFloatRegister(int, double) {
235 _LIBUNWIND_ABORT("no x86 float registers");
236 }
237
getVectorRegister(int) const238 inline v128 Registers_x86::getVectorRegister(int) const {
239 _LIBUNWIND_ABORT("no x86 vector registers");
240 }
241
setVectorRegister(int,v128)242 inline void Registers_x86::setVectorRegister(int, v128) {
243 _LIBUNWIND_ABORT("no x86 vector registers");
244 }
245 #endif // _LIBUNWIND_TARGET_I386
246
247
248 #if defined(_LIBUNWIND_TARGET_X86_64)
249 /// Registers_x86_64 holds the register state of a thread in a 64-bit intel
250 /// process.
251 class _LIBUNWIND_HIDDEN Registers_x86_64 {
252 public:
253 Registers_x86_64();
254 Registers_x86_64(const void *registers);
255
256 bool validRegister(int num) const;
257 uint64_t getRegister(int num) const;
258 void setRegister(int num, uint64_t value);
validFloatRegister(int) const259 bool validFloatRegister(int) const { return false; }
260 double getFloatRegister(int num) const;
261 void setFloatRegister(int num, double value);
262 bool validVectorRegister(int) const;
263 v128 getVectorRegister(int num) const;
264 void setVectorRegister(int num, v128 value);
265 static const char *getRegisterName(int num);
266 void jumpto();
lastDwarfRegNum()267 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64; }
getArch()268 static int getArch() { return REGISTERS_X86_64; }
269
getSP() const270 uint64_t getSP() const { return _registers.__rsp; }
setSP(uint64_t value)271 void setSP(uint64_t value) { _registers.__rsp = value; }
getIP() const272 uint64_t getIP() const { return _registers.__rip; }
setIP(uint64_t value)273 void setIP(uint64_t value) { _registers.__rip = value; }
getRBP() const274 uint64_t getRBP() const { return _registers.__rbp; }
setRBP(uint64_t value)275 void setRBP(uint64_t value) { _registers.__rbp = value; }
getRBX() const276 uint64_t getRBX() const { return _registers.__rbx; }
setRBX(uint64_t value)277 void setRBX(uint64_t value) { _registers.__rbx = value; }
getR12() const278 uint64_t getR12() const { return _registers.__r12; }
setR12(uint64_t value)279 void setR12(uint64_t value) { _registers.__r12 = value; }
getR13() const280 uint64_t getR13() const { return _registers.__r13; }
setR13(uint64_t value)281 void setR13(uint64_t value) { _registers.__r13 = value; }
getR14() const282 uint64_t getR14() const { return _registers.__r14; }
setR14(uint64_t value)283 void setR14(uint64_t value) { _registers.__r14 = value; }
getR15() const284 uint64_t getR15() const { return _registers.__r15; }
setR15(uint64_t value)285 void setR15(uint64_t value) { _registers.__r15 = value; }
286
287 private:
288 struct GPRs {
289 uint64_t __rax;
290 uint64_t __rbx;
291 uint64_t __rcx;
292 uint64_t __rdx;
293 uint64_t __rdi;
294 uint64_t __rsi;
295 uint64_t __rbp;
296 uint64_t __rsp;
297 uint64_t __r8;
298 uint64_t __r9;
299 uint64_t __r10;
300 uint64_t __r11;
301 uint64_t __r12;
302 uint64_t __r13;
303 uint64_t __r14;
304 uint64_t __r15;
305 uint64_t __rip;
306 uint64_t __rflags;
307 uint64_t __cs;
308 uint64_t __fs;
309 uint64_t __gs;
310 #if defined(_WIN64)
311 uint64_t __padding; // 16-byte align
312 #endif
313 };
314 GPRs _registers;
315 #if defined(_WIN64)
316 v128 _xmm[16];
317 #endif
318 };
319
Registers_x86_64(const void * registers)320 inline Registers_x86_64::Registers_x86_64(const void *registers) {
321 static_assert((check_fit<Registers_x86_64, unw_context_t>::does_fit),
322 "x86_64 registers do not fit into unw_context_t");
323 memcpy(&_registers, registers, sizeof(_registers));
324 }
325
Registers_x86_64()326 inline Registers_x86_64::Registers_x86_64() {
327 memset(&_registers, 0, sizeof(_registers));
328 }
329
validRegister(int regNum) const330 inline bool Registers_x86_64::validRegister(int regNum) const {
331 if (regNum == UNW_REG_IP)
332 return true;
333 if (regNum == UNW_REG_SP)
334 return true;
335 if (regNum < 0)
336 return false;
337 if (regNum > 15)
338 return false;
339 return true;
340 }
341
getRegister(int regNum) const342 inline uint64_t Registers_x86_64::getRegister(int regNum) const {
343 switch (regNum) {
344 case UNW_REG_IP:
345 return _registers.__rip;
346 case UNW_REG_SP:
347 return _registers.__rsp;
348 case UNW_X86_64_RAX:
349 return _registers.__rax;
350 case UNW_X86_64_RDX:
351 return _registers.__rdx;
352 case UNW_X86_64_RCX:
353 return _registers.__rcx;
354 case UNW_X86_64_RBX:
355 return _registers.__rbx;
356 case UNW_X86_64_RSI:
357 return _registers.__rsi;
358 case UNW_X86_64_RDI:
359 return _registers.__rdi;
360 case UNW_X86_64_RBP:
361 return _registers.__rbp;
362 case UNW_X86_64_RSP:
363 return _registers.__rsp;
364 case UNW_X86_64_R8:
365 return _registers.__r8;
366 case UNW_X86_64_R9:
367 return _registers.__r9;
368 case UNW_X86_64_R10:
369 return _registers.__r10;
370 case UNW_X86_64_R11:
371 return _registers.__r11;
372 case UNW_X86_64_R12:
373 return _registers.__r12;
374 case UNW_X86_64_R13:
375 return _registers.__r13;
376 case UNW_X86_64_R14:
377 return _registers.__r14;
378 case UNW_X86_64_R15:
379 return _registers.__r15;
380 }
381 _LIBUNWIND_ABORT("unsupported x86_64 register");
382 }
383
setRegister(int regNum,uint64_t value)384 inline void Registers_x86_64::setRegister(int regNum, uint64_t value) {
385 switch (regNum) {
386 case UNW_REG_IP:
387 _registers.__rip = value;
388 return;
389 case UNW_REG_SP:
390 _registers.__rsp = value;
391 return;
392 case UNW_X86_64_RAX:
393 _registers.__rax = value;
394 return;
395 case UNW_X86_64_RDX:
396 _registers.__rdx = value;
397 return;
398 case UNW_X86_64_RCX:
399 _registers.__rcx = value;
400 return;
401 case UNW_X86_64_RBX:
402 _registers.__rbx = value;
403 return;
404 case UNW_X86_64_RSI:
405 _registers.__rsi = value;
406 return;
407 case UNW_X86_64_RDI:
408 _registers.__rdi = value;
409 return;
410 case UNW_X86_64_RBP:
411 _registers.__rbp = value;
412 return;
413 case UNW_X86_64_RSP:
414 _registers.__rsp = value;
415 return;
416 case UNW_X86_64_R8:
417 _registers.__r8 = value;
418 return;
419 case UNW_X86_64_R9:
420 _registers.__r9 = value;
421 return;
422 case UNW_X86_64_R10:
423 _registers.__r10 = value;
424 return;
425 case UNW_X86_64_R11:
426 _registers.__r11 = value;
427 return;
428 case UNW_X86_64_R12:
429 _registers.__r12 = value;
430 return;
431 case UNW_X86_64_R13:
432 _registers.__r13 = value;
433 return;
434 case UNW_X86_64_R14:
435 _registers.__r14 = value;
436 return;
437 case UNW_X86_64_R15:
438 _registers.__r15 = value;
439 return;
440 }
441 _LIBUNWIND_ABORT("unsupported x86_64 register");
442 }
443
getRegisterName(int regNum)444 inline const char *Registers_x86_64::getRegisterName(int regNum) {
445 switch (regNum) {
446 case UNW_REG_IP:
447 return "rip";
448 case UNW_REG_SP:
449 return "rsp";
450 case UNW_X86_64_RAX:
451 return "rax";
452 case UNW_X86_64_RDX:
453 return "rdx";
454 case UNW_X86_64_RCX:
455 return "rcx";
456 case UNW_X86_64_RBX:
457 return "rbx";
458 case UNW_X86_64_RSI:
459 return "rsi";
460 case UNW_X86_64_RDI:
461 return "rdi";
462 case UNW_X86_64_RBP:
463 return "rbp";
464 case UNW_X86_64_RSP:
465 return "rsp";
466 case UNW_X86_64_R8:
467 return "r8";
468 case UNW_X86_64_R9:
469 return "r9";
470 case UNW_X86_64_R10:
471 return "r10";
472 case UNW_X86_64_R11:
473 return "r11";
474 case UNW_X86_64_R12:
475 return "r12";
476 case UNW_X86_64_R13:
477 return "r13";
478 case UNW_X86_64_R14:
479 return "r14";
480 case UNW_X86_64_R15:
481 return "r15";
482 case UNW_X86_64_XMM0:
483 return "xmm0";
484 case UNW_X86_64_XMM1:
485 return "xmm1";
486 case UNW_X86_64_XMM2:
487 return "xmm2";
488 case UNW_X86_64_XMM3:
489 return "xmm3";
490 case UNW_X86_64_XMM4:
491 return "xmm4";
492 case UNW_X86_64_XMM5:
493 return "xmm5";
494 case UNW_X86_64_XMM6:
495 return "xmm6";
496 case UNW_X86_64_XMM7:
497 return "xmm7";
498 case UNW_X86_64_XMM8:
499 return "xmm8";
500 case UNW_X86_64_XMM9:
501 return "xmm9";
502 case UNW_X86_64_XMM10:
503 return "xmm10";
504 case UNW_X86_64_XMM11:
505 return "xmm11";
506 case UNW_X86_64_XMM12:
507 return "xmm12";
508 case UNW_X86_64_XMM13:
509 return "xmm13";
510 case UNW_X86_64_XMM14:
511 return "xmm14";
512 case UNW_X86_64_XMM15:
513 return "xmm15";
514 default:
515 return "unknown register";
516 }
517 }
518
getFloatRegister(int) const519 inline double Registers_x86_64::getFloatRegister(int) const {
520 _LIBUNWIND_ABORT("no x86_64 float registers");
521 }
522
setFloatRegister(int,double)523 inline void Registers_x86_64::setFloatRegister(int, double) {
524 _LIBUNWIND_ABORT("no x86_64 float registers");
525 }
526
validVectorRegister(int regNum) const527 inline bool Registers_x86_64::validVectorRegister(int regNum) const {
528 #if defined(_WIN64)
529 if (regNum < UNW_X86_64_XMM0)
530 return false;
531 if (regNum > UNW_X86_64_XMM15)
532 return false;
533 return true;
534 #else
535 (void)regNum; // suppress unused parameter warning
536 return false;
537 #endif
538 }
539
getVectorRegister(int regNum) const540 inline v128 Registers_x86_64::getVectorRegister(int regNum) const {
541 #if defined(_WIN64)
542 assert(validVectorRegister(regNum));
543 return _xmm[regNum - UNW_X86_64_XMM0];
544 #else
545 (void)regNum; // suppress unused parameter warning
546 _LIBUNWIND_ABORT("no x86_64 vector registers");
547 #endif
548 }
549
setVectorRegister(int regNum,v128 value)550 inline void Registers_x86_64::setVectorRegister(int regNum, v128 value) {
551 #if defined(_WIN64)
552 assert(validVectorRegister(regNum));
553 _xmm[regNum - UNW_X86_64_XMM0] = value;
554 #else
555 (void)regNum; (void)value; // suppress unused parameter warnings
556 _LIBUNWIND_ABORT("no x86_64 vector registers");
557 #endif
558 }
559 #endif // _LIBUNWIND_TARGET_X86_64
560
561
562 #if defined(_LIBUNWIND_TARGET_PPC)
563 /// Registers_ppc holds the register state of a thread in a 32-bit PowerPC
564 /// process.
565 class _LIBUNWIND_HIDDEN Registers_ppc {
566 public:
567 Registers_ppc();
568 Registers_ppc(const void *registers);
569
570 bool validRegister(int num) const;
571 uint32_t getRegister(int num) const;
572 void setRegister(int num, uint32_t value);
573 bool validFloatRegister(int num) const;
574 double getFloatRegister(int num) const;
575 void setFloatRegister(int num, double value);
576 bool validVectorRegister(int num) const;
577 v128 getVectorRegister(int num) const;
578 void setVectorRegister(int num, v128 value);
579 static const char *getRegisterName(int num);
580 void jumpto();
lastDwarfRegNum()581 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC; }
getArch()582 static int getArch() { return REGISTERS_PPC; }
583
getSP() const584 uint64_t getSP() const { return _registers.__r1; }
setSP(uint32_t value)585 void setSP(uint32_t value) { _registers.__r1 = value; }
getIP() const586 uint64_t getIP() const { return _registers.__srr0; }
setIP(uint32_t value)587 void setIP(uint32_t value) { _registers.__srr0 = value; }
588
589 private:
590 struct ppc_thread_state_t {
591 unsigned int __srr0; /* Instruction address register (PC) */
592 unsigned int __srr1; /* Machine state register (supervisor) */
593 unsigned int __r0;
594 unsigned int __r1;
595 unsigned int __r2;
596 unsigned int __r3;
597 unsigned int __r4;
598 unsigned int __r5;
599 unsigned int __r6;
600 unsigned int __r7;
601 unsigned int __r8;
602 unsigned int __r9;
603 unsigned int __r10;
604 unsigned int __r11;
605 unsigned int __r12;
606 unsigned int __r13;
607 unsigned int __r14;
608 unsigned int __r15;
609 unsigned int __r16;
610 unsigned int __r17;
611 unsigned int __r18;
612 unsigned int __r19;
613 unsigned int __r20;
614 unsigned int __r21;
615 unsigned int __r22;
616 unsigned int __r23;
617 unsigned int __r24;
618 unsigned int __r25;
619 unsigned int __r26;
620 unsigned int __r27;
621 unsigned int __r28;
622 unsigned int __r29;
623 unsigned int __r30;
624 unsigned int __r31;
625 unsigned int __cr; /* Condition register */
626 unsigned int __xer; /* User's integer exception register */
627 unsigned int __lr; /* Link register */
628 unsigned int __ctr; /* Count register */
629 unsigned int __mq; /* MQ register (601 only) */
630 unsigned int __vrsave; /* Vector Save Register */
631 };
632
633 struct ppc_float_state_t {
634 double __fpregs[32];
635
636 unsigned int __fpscr_pad; /* fpscr is 64 bits, 32 bits of rubbish */
637 unsigned int __fpscr; /* floating point status register */
638 };
639
640 ppc_thread_state_t _registers;
641 ppc_float_state_t _floatRegisters;
642 v128 _vectorRegisters[32]; // offset 424
643 };
644
Registers_ppc(const void * registers)645 inline Registers_ppc::Registers_ppc(const void *registers) {
646 static_assert((check_fit<Registers_ppc, unw_context_t>::does_fit),
647 "ppc registers do not fit into unw_context_t");
648 memcpy(&_registers, static_cast<const uint8_t *>(registers),
649 sizeof(_registers));
650 static_assert(sizeof(ppc_thread_state_t) == 160,
651 "expected float register offset to be 160");
652 memcpy(&_floatRegisters,
653 static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t),
654 sizeof(_floatRegisters));
655 static_assert(sizeof(ppc_thread_state_t) + sizeof(ppc_float_state_t) == 424,
656 "expected vector register offset to be 424 bytes");
657 memcpy(_vectorRegisters,
658 static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t) +
659 sizeof(ppc_float_state_t),
660 sizeof(_vectorRegisters));
661 }
662
Registers_ppc()663 inline Registers_ppc::Registers_ppc() {
664 memset(&_registers, 0, sizeof(_registers));
665 memset(&_floatRegisters, 0, sizeof(_floatRegisters));
666 memset(&_vectorRegisters, 0, sizeof(_vectorRegisters));
667 }
668
validRegister(int regNum) const669 inline bool Registers_ppc::validRegister(int regNum) const {
670 if (regNum == UNW_REG_IP)
671 return true;
672 if (regNum == UNW_REG_SP)
673 return true;
674 if (regNum == UNW_PPC_VRSAVE)
675 return true;
676 if (regNum < 0)
677 return false;
678 if (regNum <= UNW_PPC_R31)
679 return true;
680 if (regNum == UNW_PPC_MQ)
681 return true;
682 if (regNum == UNW_PPC_LR)
683 return true;
684 if (regNum == UNW_PPC_CTR)
685 return true;
686 if ((UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7))
687 return true;
688 return false;
689 }
690
getRegister(int regNum) const691 inline uint32_t Registers_ppc::getRegister(int regNum) const {
692 switch (regNum) {
693 case UNW_REG_IP:
694 return _registers.__srr0;
695 case UNW_REG_SP:
696 return _registers.__r1;
697 case UNW_PPC_R0:
698 return _registers.__r0;
699 case UNW_PPC_R1:
700 return _registers.__r1;
701 case UNW_PPC_R2:
702 return _registers.__r2;
703 case UNW_PPC_R3:
704 return _registers.__r3;
705 case UNW_PPC_R4:
706 return _registers.__r4;
707 case UNW_PPC_R5:
708 return _registers.__r5;
709 case UNW_PPC_R6:
710 return _registers.__r6;
711 case UNW_PPC_R7:
712 return _registers.__r7;
713 case UNW_PPC_R8:
714 return _registers.__r8;
715 case UNW_PPC_R9:
716 return _registers.__r9;
717 case UNW_PPC_R10:
718 return _registers.__r10;
719 case UNW_PPC_R11:
720 return _registers.__r11;
721 case UNW_PPC_R12:
722 return _registers.__r12;
723 case UNW_PPC_R13:
724 return _registers.__r13;
725 case UNW_PPC_R14:
726 return _registers.__r14;
727 case UNW_PPC_R15:
728 return _registers.__r15;
729 case UNW_PPC_R16:
730 return _registers.__r16;
731 case UNW_PPC_R17:
732 return _registers.__r17;
733 case UNW_PPC_R18:
734 return _registers.__r18;
735 case UNW_PPC_R19:
736 return _registers.__r19;
737 case UNW_PPC_R20:
738 return _registers.__r20;
739 case UNW_PPC_R21:
740 return _registers.__r21;
741 case UNW_PPC_R22:
742 return _registers.__r22;
743 case UNW_PPC_R23:
744 return _registers.__r23;
745 case UNW_PPC_R24:
746 return _registers.__r24;
747 case UNW_PPC_R25:
748 return _registers.__r25;
749 case UNW_PPC_R26:
750 return _registers.__r26;
751 case UNW_PPC_R27:
752 return _registers.__r27;
753 case UNW_PPC_R28:
754 return _registers.__r28;
755 case UNW_PPC_R29:
756 return _registers.__r29;
757 case UNW_PPC_R30:
758 return _registers.__r30;
759 case UNW_PPC_R31:
760 return _registers.__r31;
761 case UNW_PPC_LR:
762 return _registers.__lr;
763 case UNW_PPC_CR0:
764 return (_registers.__cr & 0xF0000000);
765 case UNW_PPC_CR1:
766 return (_registers.__cr & 0x0F000000);
767 case UNW_PPC_CR2:
768 return (_registers.__cr & 0x00F00000);
769 case UNW_PPC_CR3:
770 return (_registers.__cr & 0x000F0000);
771 case UNW_PPC_CR4:
772 return (_registers.__cr & 0x0000F000);
773 case UNW_PPC_CR5:
774 return (_registers.__cr & 0x00000F00);
775 case UNW_PPC_CR6:
776 return (_registers.__cr & 0x000000F0);
777 case UNW_PPC_CR7:
778 return (_registers.__cr & 0x0000000F);
779 case UNW_PPC_VRSAVE:
780 return _registers.__vrsave;
781 }
782 _LIBUNWIND_ABORT("unsupported ppc register");
783 }
784
setRegister(int regNum,uint32_t value)785 inline void Registers_ppc::setRegister(int regNum, uint32_t value) {
786 //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value);
787 switch (regNum) {
788 case UNW_REG_IP:
789 _registers.__srr0 = value;
790 return;
791 case UNW_REG_SP:
792 _registers.__r1 = value;
793 return;
794 case UNW_PPC_R0:
795 _registers.__r0 = value;
796 return;
797 case UNW_PPC_R1:
798 _registers.__r1 = value;
799 return;
800 case UNW_PPC_R2:
801 _registers.__r2 = value;
802 return;
803 case UNW_PPC_R3:
804 _registers.__r3 = value;
805 return;
806 case UNW_PPC_R4:
807 _registers.__r4 = value;
808 return;
809 case UNW_PPC_R5:
810 _registers.__r5 = value;
811 return;
812 case UNW_PPC_R6:
813 _registers.__r6 = value;
814 return;
815 case UNW_PPC_R7:
816 _registers.__r7 = value;
817 return;
818 case UNW_PPC_R8:
819 _registers.__r8 = value;
820 return;
821 case UNW_PPC_R9:
822 _registers.__r9 = value;
823 return;
824 case UNW_PPC_R10:
825 _registers.__r10 = value;
826 return;
827 case UNW_PPC_R11:
828 _registers.__r11 = value;
829 return;
830 case UNW_PPC_R12:
831 _registers.__r12 = value;
832 return;
833 case UNW_PPC_R13:
834 _registers.__r13 = value;
835 return;
836 case UNW_PPC_R14:
837 _registers.__r14 = value;
838 return;
839 case UNW_PPC_R15:
840 _registers.__r15 = value;
841 return;
842 case UNW_PPC_R16:
843 _registers.__r16 = value;
844 return;
845 case UNW_PPC_R17:
846 _registers.__r17 = value;
847 return;
848 case UNW_PPC_R18:
849 _registers.__r18 = value;
850 return;
851 case UNW_PPC_R19:
852 _registers.__r19 = value;
853 return;
854 case UNW_PPC_R20:
855 _registers.__r20 = value;
856 return;
857 case UNW_PPC_R21:
858 _registers.__r21 = value;
859 return;
860 case UNW_PPC_R22:
861 _registers.__r22 = value;
862 return;
863 case UNW_PPC_R23:
864 _registers.__r23 = value;
865 return;
866 case UNW_PPC_R24:
867 _registers.__r24 = value;
868 return;
869 case UNW_PPC_R25:
870 _registers.__r25 = value;
871 return;
872 case UNW_PPC_R26:
873 _registers.__r26 = value;
874 return;
875 case UNW_PPC_R27:
876 _registers.__r27 = value;
877 return;
878 case UNW_PPC_R28:
879 _registers.__r28 = value;
880 return;
881 case UNW_PPC_R29:
882 _registers.__r29 = value;
883 return;
884 case UNW_PPC_R30:
885 _registers.__r30 = value;
886 return;
887 case UNW_PPC_R31:
888 _registers.__r31 = value;
889 return;
890 case UNW_PPC_MQ:
891 _registers.__mq = value;
892 return;
893 case UNW_PPC_LR:
894 _registers.__lr = value;
895 return;
896 case UNW_PPC_CTR:
897 _registers.__ctr = value;
898 return;
899 case UNW_PPC_CR0:
900 _registers.__cr &= 0x0FFFFFFF;
901 _registers.__cr |= (value & 0xF0000000);
902 return;
903 case UNW_PPC_CR1:
904 _registers.__cr &= 0xF0FFFFFF;
905 _registers.__cr |= (value & 0x0F000000);
906 return;
907 case UNW_PPC_CR2:
908 _registers.__cr &= 0xFF0FFFFF;
909 _registers.__cr |= (value & 0x00F00000);
910 return;
911 case UNW_PPC_CR3:
912 _registers.__cr &= 0xFFF0FFFF;
913 _registers.__cr |= (value & 0x000F0000);
914 return;
915 case UNW_PPC_CR4:
916 _registers.__cr &= 0xFFFF0FFF;
917 _registers.__cr |= (value & 0x0000F000);
918 return;
919 case UNW_PPC_CR5:
920 _registers.__cr &= 0xFFFFF0FF;
921 _registers.__cr |= (value & 0x00000F00);
922 return;
923 case UNW_PPC_CR6:
924 _registers.__cr &= 0xFFFFFF0F;
925 _registers.__cr |= (value & 0x000000F0);
926 return;
927 case UNW_PPC_CR7:
928 _registers.__cr &= 0xFFFFFFF0;
929 _registers.__cr |= (value & 0x0000000F);
930 return;
931 case UNW_PPC_VRSAVE:
932 _registers.__vrsave = value;
933 return;
934 // not saved
935 return;
936 case UNW_PPC_XER:
937 _registers.__xer = value;
938 return;
939 case UNW_PPC_AP:
940 case UNW_PPC_VSCR:
941 case UNW_PPC_SPEFSCR:
942 // not saved
943 return;
944 }
945 _LIBUNWIND_ABORT("unsupported ppc register");
946 }
947
validFloatRegister(int regNum) const948 inline bool Registers_ppc::validFloatRegister(int regNum) const {
949 if (regNum < UNW_PPC_F0)
950 return false;
951 if (regNum > UNW_PPC_F31)
952 return false;
953 return true;
954 }
955
getFloatRegister(int regNum) const956 inline double Registers_ppc::getFloatRegister(int regNum) const {
957 assert(validFloatRegister(regNum));
958 return _floatRegisters.__fpregs[regNum - UNW_PPC_F0];
959 }
960
setFloatRegister(int regNum,double value)961 inline void Registers_ppc::setFloatRegister(int regNum, double value) {
962 assert(validFloatRegister(regNum));
963 _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value;
964 }
965
validVectorRegister(int regNum) const966 inline bool Registers_ppc::validVectorRegister(int regNum) const {
967 if (regNum < UNW_PPC_V0)
968 return false;
969 if (regNum > UNW_PPC_V31)
970 return false;
971 return true;
972 }
973
getVectorRegister(int regNum) const974 inline v128 Registers_ppc::getVectorRegister(int regNum) const {
975 assert(validVectorRegister(regNum));
976 v128 result = _vectorRegisters[regNum - UNW_PPC_V0];
977 return result;
978 }
979
setVectorRegister(int regNum,v128 value)980 inline void Registers_ppc::setVectorRegister(int regNum, v128 value) {
981 assert(validVectorRegister(regNum));
982 _vectorRegisters[regNum - UNW_PPC_V0] = value;
983 }
984
getRegisterName(int regNum)985 inline const char *Registers_ppc::getRegisterName(int regNum) {
986 switch (regNum) {
987 case UNW_REG_IP:
988 return "ip";
989 case UNW_REG_SP:
990 return "sp";
991 case UNW_PPC_R0:
992 return "r0";
993 case UNW_PPC_R1:
994 return "r1";
995 case UNW_PPC_R2:
996 return "r2";
997 case UNW_PPC_R3:
998 return "r3";
999 case UNW_PPC_R4:
1000 return "r4";
1001 case UNW_PPC_R5:
1002 return "r5";
1003 case UNW_PPC_R6:
1004 return "r6";
1005 case UNW_PPC_R7:
1006 return "r7";
1007 case UNW_PPC_R8:
1008 return "r8";
1009 case UNW_PPC_R9:
1010 return "r9";
1011 case UNW_PPC_R10:
1012 return "r10";
1013 case UNW_PPC_R11:
1014 return "r11";
1015 case UNW_PPC_R12:
1016 return "r12";
1017 case UNW_PPC_R13:
1018 return "r13";
1019 case UNW_PPC_R14:
1020 return "r14";
1021 case UNW_PPC_R15:
1022 return "r15";
1023 case UNW_PPC_R16:
1024 return "r16";
1025 case UNW_PPC_R17:
1026 return "r17";
1027 case UNW_PPC_R18:
1028 return "r18";
1029 case UNW_PPC_R19:
1030 return "r19";
1031 case UNW_PPC_R20:
1032 return "r20";
1033 case UNW_PPC_R21:
1034 return "r21";
1035 case UNW_PPC_R22:
1036 return "r22";
1037 case UNW_PPC_R23:
1038 return "r23";
1039 case UNW_PPC_R24:
1040 return "r24";
1041 case UNW_PPC_R25:
1042 return "r25";
1043 case UNW_PPC_R26:
1044 return "r26";
1045 case UNW_PPC_R27:
1046 return "r27";
1047 case UNW_PPC_R28:
1048 return "r28";
1049 case UNW_PPC_R29:
1050 return "r29";
1051 case UNW_PPC_R30:
1052 return "r30";
1053 case UNW_PPC_R31:
1054 return "r31";
1055 case UNW_PPC_F0:
1056 return "fp0";
1057 case UNW_PPC_F1:
1058 return "fp1";
1059 case UNW_PPC_F2:
1060 return "fp2";
1061 case UNW_PPC_F3:
1062 return "fp3";
1063 case UNW_PPC_F4:
1064 return "fp4";
1065 case UNW_PPC_F5:
1066 return "fp5";
1067 case UNW_PPC_F6:
1068 return "fp6";
1069 case UNW_PPC_F7:
1070 return "fp7";
1071 case UNW_PPC_F8:
1072 return "fp8";
1073 case UNW_PPC_F9:
1074 return "fp9";
1075 case UNW_PPC_F10:
1076 return "fp10";
1077 case UNW_PPC_F11:
1078 return "fp11";
1079 case UNW_PPC_F12:
1080 return "fp12";
1081 case UNW_PPC_F13:
1082 return "fp13";
1083 case UNW_PPC_F14:
1084 return "fp14";
1085 case UNW_PPC_F15:
1086 return "fp15";
1087 case UNW_PPC_F16:
1088 return "fp16";
1089 case UNW_PPC_F17:
1090 return "fp17";
1091 case UNW_PPC_F18:
1092 return "fp18";
1093 case UNW_PPC_F19:
1094 return "fp19";
1095 case UNW_PPC_F20:
1096 return "fp20";
1097 case UNW_PPC_F21:
1098 return "fp21";
1099 case UNW_PPC_F22:
1100 return "fp22";
1101 case UNW_PPC_F23:
1102 return "fp23";
1103 case UNW_PPC_F24:
1104 return "fp24";
1105 case UNW_PPC_F25:
1106 return "fp25";
1107 case UNW_PPC_F26:
1108 return "fp26";
1109 case UNW_PPC_F27:
1110 return "fp27";
1111 case UNW_PPC_F28:
1112 return "fp28";
1113 case UNW_PPC_F29:
1114 return "fp29";
1115 case UNW_PPC_F30:
1116 return "fp30";
1117 case UNW_PPC_F31:
1118 return "fp31";
1119 case UNW_PPC_LR:
1120 return "lr";
1121 default:
1122 return "unknown register";
1123 }
1124
1125 }
1126 #endif // _LIBUNWIND_TARGET_PPC
1127
1128 #if defined(_LIBUNWIND_TARGET_PPC64)
1129 /// Registers_ppc64 holds the register state of a thread in a 64-bit PowerPC
1130 /// process.
1131 class _LIBUNWIND_HIDDEN Registers_ppc64 {
1132 public:
1133 Registers_ppc64();
1134 Registers_ppc64(const void *registers);
1135
1136 bool validRegister(int num) const;
1137 uint64_t getRegister(int num) const;
1138 void setRegister(int num, uint64_t value);
1139 bool validFloatRegister(int num) const;
1140 double getFloatRegister(int num) const;
1141 void setFloatRegister(int num, double value);
1142 bool validVectorRegister(int num) const;
1143 v128 getVectorRegister(int num) const;
1144 void setVectorRegister(int num, v128 value);
1145 static const char *getRegisterName(int num);
1146 void jumpto();
lastDwarfRegNum()1147 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64; }
getArch()1148 static int getArch() { return REGISTERS_PPC64; }
1149
getSP() const1150 uint64_t getSP() const { return _registers.__r1; }
setSP(uint64_t value)1151 void setSP(uint64_t value) { _registers.__r1 = value; }
getIP() const1152 uint64_t getIP() const { return _registers.__srr0; }
setIP(uint64_t value)1153 void setIP(uint64_t value) { _registers.__srr0 = value; }
1154
1155 private:
1156 struct ppc64_thread_state_t {
1157 uint64_t __srr0; // Instruction address register (PC)
1158 uint64_t __srr1; // Machine state register (supervisor)
1159 uint64_t __r0;
1160 uint64_t __r1;
1161 uint64_t __r2;
1162 uint64_t __r3;
1163 uint64_t __r4;
1164 uint64_t __r5;
1165 uint64_t __r6;
1166 uint64_t __r7;
1167 uint64_t __r8;
1168 uint64_t __r9;
1169 uint64_t __r10;
1170 uint64_t __r11;
1171 uint64_t __r12;
1172 uint64_t __r13;
1173 uint64_t __r14;
1174 uint64_t __r15;
1175 uint64_t __r16;
1176 uint64_t __r17;
1177 uint64_t __r18;
1178 uint64_t __r19;
1179 uint64_t __r20;
1180 uint64_t __r21;
1181 uint64_t __r22;
1182 uint64_t __r23;
1183 uint64_t __r24;
1184 uint64_t __r25;
1185 uint64_t __r26;
1186 uint64_t __r27;
1187 uint64_t __r28;
1188 uint64_t __r29;
1189 uint64_t __r30;
1190 uint64_t __r31;
1191 uint64_t __cr; // Condition register
1192 uint64_t __xer; // User's integer exception register
1193 uint64_t __lr; // Link register
1194 uint64_t __ctr; // Count register
1195 uint64_t __vrsave; // Vector Save Register
1196 };
1197
1198 union ppc64_vsr_t {
1199 struct asfloat_s {
1200 double f;
1201 uint64_t v2;
1202 } asfloat;
1203 v128 v;
1204 };
1205
1206 ppc64_thread_state_t _registers;
1207 ppc64_vsr_t _vectorScalarRegisters[64];
1208
1209 static int getVectorRegNum(int num);
1210 };
1211
Registers_ppc64(const void * registers)1212 inline Registers_ppc64::Registers_ppc64(const void *registers) {
1213 static_assert((check_fit<Registers_ppc64, unw_context_t>::does_fit),
1214 "ppc64 registers do not fit into unw_context_t");
1215 memcpy(&_registers, static_cast<const uint8_t *>(registers),
1216 sizeof(_registers));
1217 static_assert(sizeof(_registers) == 312,
1218 "expected vector scalar register offset to be 312");
1219 memcpy(&_vectorScalarRegisters,
1220 static_cast<const uint8_t *>(registers) + sizeof(_registers),
1221 sizeof(_vectorScalarRegisters));
1222 static_assert(sizeof(_registers) +
1223 sizeof(_vectorScalarRegisters) == 1336,
1224 "expected vector register offset to be 1336 bytes");
1225 }
1226
Registers_ppc64()1227 inline Registers_ppc64::Registers_ppc64() {
1228 memset(&_registers, 0, sizeof(_registers));
1229 memset(&_vectorScalarRegisters, 0, sizeof(_vectorScalarRegisters));
1230 }
1231
validRegister(int regNum) const1232 inline bool Registers_ppc64::validRegister(int regNum) const {
1233 switch (regNum) {
1234 case UNW_REG_IP:
1235 case UNW_REG_SP:
1236 case UNW_PPC64_XER:
1237 case UNW_PPC64_LR:
1238 case UNW_PPC64_CTR:
1239 case UNW_PPC64_VRSAVE:
1240 return true;
1241 }
1242
1243 if (regNum >= UNW_PPC64_R0 && regNum <= UNW_PPC64_R31)
1244 return true;
1245 if (regNum >= UNW_PPC64_CR0 && regNum <= UNW_PPC64_CR7)
1246 return true;
1247
1248 return false;
1249 }
1250
getRegister(int regNum) const1251 inline uint64_t Registers_ppc64::getRegister(int regNum) const {
1252 switch (regNum) {
1253 case UNW_REG_IP:
1254 return _registers.__srr0;
1255 case UNW_PPC64_R0:
1256 return _registers.__r0;
1257 case UNW_PPC64_R1:
1258 case UNW_REG_SP:
1259 return _registers.__r1;
1260 case UNW_PPC64_R2:
1261 return _registers.__r2;
1262 case UNW_PPC64_R3:
1263 return _registers.__r3;
1264 case UNW_PPC64_R4:
1265 return _registers.__r4;
1266 case UNW_PPC64_R5:
1267 return _registers.__r5;
1268 case UNW_PPC64_R6:
1269 return _registers.__r6;
1270 case UNW_PPC64_R7:
1271 return _registers.__r7;
1272 case UNW_PPC64_R8:
1273 return _registers.__r8;
1274 case UNW_PPC64_R9:
1275 return _registers.__r9;
1276 case UNW_PPC64_R10:
1277 return _registers.__r10;
1278 case UNW_PPC64_R11:
1279 return _registers.__r11;
1280 case UNW_PPC64_R12:
1281 return _registers.__r12;
1282 case UNW_PPC64_R13:
1283 return _registers.__r13;
1284 case UNW_PPC64_R14:
1285 return _registers.__r14;
1286 case UNW_PPC64_R15:
1287 return _registers.__r15;
1288 case UNW_PPC64_R16:
1289 return _registers.__r16;
1290 case UNW_PPC64_R17:
1291 return _registers.__r17;
1292 case UNW_PPC64_R18:
1293 return _registers.__r18;
1294 case UNW_PPC64_R19:
1295 return _registers.__r19;
1296 case UNW_PPC64_R20:
1297 return _registers.__r20;
1298 case UNW_PPC64_R21:
1299 return _registers.__r21;
1300 case UNW_PPC64_R22:
1301 return _registers.__r22;
1302 case UNW_PPC64_R23:
1303 return _registers.__r23;
1304 case UNW_PPC64_R24:
1305 return _registers.__r24;
1306 case UNW_PPC64_R25:
1307 return _registers.__r25;
1308 case UNW_PPC64_R26:
1309 return _registers.__r26;
1310 case UNW_PPC64_R27:
1311 return _registers.__r27;
1312 case UNW_PPC64_R28:
1313 return _registers.__r28;
1314 case UNW_PPC64_R29:
1315 return _registers.__r29;
1316 case UNW_PPC64_R30:
1317 return _registers.__r30;
1318 case UNW_PPC64_R31:
1319 return _registers.__r31;
1320 case UNW_PPC64_CR0:
1321 return (_registers.__cr & 0xF0000000);
1322 case UNW_PPC64_CR1:
1323 return (_registers.__cr & 0x0F000000);
1324 case UNW_PPC64_CR2:
1325 return (_registers.__cr & 0x00F00000);
1326 case UNW_PPC64_CR3:
1327 return (_registers.__cr & 0x000F0000);
1328 case UNW_PPC64_CR4:
1329 return (_registers.__cr & 0x0000F000);
1330 case UNW_PPC64_CR5:
1331 return (_registers.__cr & 0x00000F00);
1332 case UNW_PPC64_CR6:
1333 return (_registers.__cr & 0x000000F0);
1334 case UNW_PPC64_CR7:
1335 return (_registers.__cr & 0x0000000F);
1336 case UNW_PPC64_XER:
1337 return _registers.__xer;
1338 case UNW_PPC64_LR:
1339 return _registers.__lr;
1340 case UNW_PPC64_CTR:
1341 return _registers.__ctr;
1342 case UNW_PPC64_VRSAVE:
1343 return _registers.__vrsave;
1344 }
1345 _LIBUNWIND_ABORT("unsupported ppc64 register");
1346 }
1347
setRegister(int regNum,uint64_t value)1348 inline void Registers_ppc64::setRegister(int regNum, uint64_t value) {
1349 switch (regNum) {
1350 case UNW_REG_IP:
1351 _registers.__srr0 = value;
1352 return;
1353 case UNW_PPC64_R0:
1354 _registers.__r0 = value;
1355 return;
1356 case UNW_PPC64_R1:
1357 case UNW_REG_SP:
1358 _registers.__r1 = value;
1359 return;
1360 case UNW_PPC64_R2:
1361 _registers.__r2 = value;
1362 return;
1363 case UNW_PPC64_R3:
1364 _registers.__r3 = value;
1365 return;
1366 case UNW_PPC64_R4:
1367 _registers.__r4 = value;
1368 return;
1369 case UNW_PPC64_R5:
1370 _registers.__r5 = value;
1371 return;
1372 case UNW_PPC64_R6:
1373 _registers.__r6 = value;
1374 return;
1375 case UNW_PPC64_R7:
1376 _registers.__r7 = value;
1377 return;
1378 case UNW_PPC64_R8:
1379 _registers.__r8 = value;
1380 return;
1381 case UNW_PPC64_R9:
1382 _registers.__r9 = value;
1383 return;
1384 case UNW_PPC64_R10:
1385 _registers.__r10 = value;
1386 return;
1387 case UNW_PPC64_R11:
1388 _registers.__r11 = value;
1389 return;
1390 case UNW_PPC64_R12:
1391 _registers.__r12 = value;
1392 return;
1393 case UNW_PPC64_R13:
1394 _registers.__r13 = value;
1395 return;
1396 case UNW_PPC64_R14:
1397 _registers.__r14 = value;
1398 return;
1399 case UNW_PPC64_R15:
1400 _registers.__r15 = value;
1401 return;
1402 case UNW_PPC64_R16:
1403 _registers.__r16 = value;
1404 return;
1405 case UNW_PPC64_R17:
1406 _registers.__r17 = value;
1407 return;
1408 case UNW_PPC64_R18:
1409 _registers.__r18 = value;
1410 return;
1411 case UNW_PPC64_R19:
1412 _registers.__r19 = value;
1413 return;
1414 case UNW_PPC64_R20:
1415 _registers.__r20 = value;
1416 return;
1417 case UNW_PPC64_R21:
1418 _registers.__r21 = value;
1419 return;
1420 case UNW_PPC64_R22:
1421 _registers.__r22 = value;
1422 return;
1423 case UNW_PPC64_R23:
1424 _registers.__r23 = value;
1425 return;
1426 case UNW_PPC64_R24:
1427 _registers.__r24 = value;
1428 return;
1429 case UNW_PPC64_R25:
1430 _registers.__r25 = value;
1431 return;
1432 case UNW_PPC64_R26:
1433 _registers.__r26 = value;
1434 return;
1435 case UNW_PPC64_R27:
1436 _registers.__r27 = value;
1437 return;
1438 case UNW_PPC64_R28:
1439 _registers.__r28 = value;
1440 return;
1441 case UNW_PPC64_R29:
1442 _registers.__r29 = value;
1443 return;
1444 case UNW_PPC64_R30:
1445 _registers.__r30 = value;
1446 return;
1447 case UNW_PPC64_R31:
1448 _registers.__r31 = value;
1449 return;
1450 case UNW_PPC64_CR0:
1451 _registers.__cr &= 0x0FFFFFFF;
1452 _registers.__cr |= (value & 0xF0000000);
1453 return;
1454 case UNW_PPC64_CR1:
1455 _registers.__cr &= 0xF0FFFFFF;
1456 _registers.__cr |= (value & 0x0F000000);
1457 return;
1458 case UNW_PPC64_CR2:
1459 _registers.__cr &= 0xFF0FFFFF;
1460 _registers.__cr |= (value & 0x00F00000);
1461 return;
1462 case UNW_PPC64_CR3:
1463 _registers.__cr &= 0xFFF0FFFF;
1464 _registers.__cr |= (value & 0x000F0000);
1465 return;
1466 case UNW_PPC64_CR4:
1467 _registers.__cr &= 0xFFFF0FFF;
1468 _registers.__cr |= (value & 0x0000F000);
1469 return;
1470 case UNW_PPC64_CR5:
1471 _registers.__cr &= 0xFFFFF0FF;
1472 _registers.__cr |= (value & 0x00000F00);
1473 return;
1474 case UNW_PPC64_CR6:
1475 _registers.__cr &= 0xFFFFFF0F;
1476 _registers.__cr |= (value & 0x000000F0);
1477 return;
1478 case UNW_PPC64_CR7:
1479 _registers.__cr &= 0xFFFFFFF0;
1480 _registers.__cr |= (value & 0x0000000F);
1481 return;
1482 case UNW_PPC64_XER:
1483 _registers.__xer = value;
1484 return;
1485 case UNW_PPC64_LR:
1486 _registers.__lr = value;
1487 return;
1488 case UNW_PPC64_CTR:
1489 _registers.__ctr = value;
1490 return;
1491 case UNW_PPC64_VRSAVE:
1492 _registers.__vrsave = value;
1493 return;
1494 }
1495 _LIBUNWIND_ABORT("unsupported ppc64 register");
1496 }
1497
validFloatRegister(int regNum) const1498 inline bool Registers_ppc64::validFloatRegister(int regNum) const {
1499 return regNum >= UNW_PPC64_F0 && regNum <= UNW_PPC64_F31;
1500 }
1501
getFloatRegister(int regNum) const1502 inline double Registers_ppc64::getFloatRegister(int regNum) const {
1503 assert(validFloatRegister(regNum));
1504 return _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f;
1505 }
1506
setFloatRegister(int regNum,double value)1507 inline void Registers_ppc64::setFloatRegister(int regNum, double value) {
1508 assert(validFloatRegister(regNum));
1509 _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f = value;
1510 }
1511
validVectorRegister(int regNum) const1512 inline bool Registers_ppc64::validVectorRegister(int regNum) const {
1513 #ifdef PPC64_HAS_VMX
1514 if (regNum >= UNW_PPC64_VS0 && regNum <= UNW_PPC64_VS31)
1515 return true;
1516 if (regNum >= UNW_PPC64_VS32 && regNum <= UNW_PPC64_VS63)
1517 return true;
1518 #else
1519 if (regNum >= UNW_PPC64_V0 && regNum <= UNW_PPC64_V31)
1520 return true;
1521 #endif
1522 return false;
1523 }
1524
getVectorRegNum(int num)1525 inline int Registers_ppc64::getVectorRegNum(int num)
1526 {
1527 if (num >= UNW_PPC64_VS0 && num <= UNW_PPC64_VS31)
1528 return num - UNW_PPC64_VS0;
1529 else
1530 return num - UNW_PPC64_VS32 + 32;
1531 }
1532
getVectorRegister(int regNum) const1533 inline v128 Registers_ppc64::getVectorRegister(int regNum) const {
1534 assert(validVectorRegister(regNum));
1535 return _vectorScalarRegisters[getVectorRegNum(regNum)].v;
1536 }
1537
setVectorRegister(int regNum,v128 value)1538 inline void Registers_ppc64::setVectorRegister(int regNum, v128 value) {
1539 assert(validVectorRegister(regNum));
1540 _vectorScalarRegisters[getVectorRegNum(regNum)].v = value;
1541 }
1542
getRegisterName(int regNum)1543 inline const char *Registers_ppc64::getRegisterName(int regNum) {
1544 switch (regNum) {
1545 case UNW_REG_IP:
1546 return "ip";
1547 case UNW_REG_SP:
1548 return "sp";
1549 case UNW_PPC64_R0:
1550 return "r0";
1551 case UNW_PPC64_R1:
1552 return "r1";
1553 case UNW_PPC64_R2:
1554 return "r2";
1555 case UNW_PPC64_R3:
1556 return "r3";
1557 case UNW_PPC64_R4:
1558 return "r4";
1559 case UNW_PPC64_R5:
1560 return "r5";
1561 case UNW_PPC64_R6:
1562 return "r6";
1563 case UNW_PPC64_R7:
1564 return "r7";
1565 case UNW_PPC64_R8:
1566 return "r8";
1567 case UNW_PPC64_R9:
1568 return "r9";
1569 case UNW_PPC64_R10:
1570 return "r10";
1571 case UNW_PPC64_R11:
1572 return "r11";
1573 case UNW_PPC64_R12:
1574 return "r12";
1575 case UNW_PPC64_R13:
1576 return "r13";
1577 case UNW_PPC64_R14:
1578 return "r14";
1579 case UNW_PPC64_R15:
1580 return "r15";
1581 case UNW_PPC64_R16:
1582 return "r16";
1583 case UNW_PPC64_R17:
1584 return "r17";
1585 case UNW_PPC64_R18:
1586 return "r18";
1587 case UNW_PPC64_R19:
1588 return "r19";
1589 case UNW_PPC64_R20:
1590 return "r20";
1591 case UNW_PPC64_R21:
1592 return "r21";
1593 case UNW_PPC64_R22:
1594 return "r22";
1595 case UNW_PPC64_R23:
1596 return "r23";
1597 case UNW_PPC64_R24:
1598 return "r24";
1599 case UNW_PPC64_R25:
1600 return "r25";
1601 case UNW_PPC64_R26:
1602 return "r26";
1603 case UNW_PPC64_R27:
1604 return "r27";
1605 case UNW_PPC64_R28:
1606 return "r28";
1607 case UNW_PPC64_R29:
1608 return "r29";
1609 case UNW_PPC64_R30:
1610 return "r30";
1611 case UNW_PPC64_R31:
1612 return "r31";
1613 case UNW_PPC64_CR0:
1614 return "cr0";
1615 case UNW_PPC64_CR1:
1616 return "cr1";
1617 case UNW_PPC64_CR2:
1618 return "cr2";
1619 case UNW_PPC64_CR3:
1620 return "cr3";
1621 case UNW_PPC64_CR4:
1622 return "cr4";
1623 case UNW_PPC64_CR5:
1624 return "cr5";
1625 case UNW_PPC64_CR6:
1626 return "cr6";
1627 case UNW_PPC64_CR7:
1628 return "cr7";
1629 case UNW_PPC64_XER:
1630 return "xer";
1631 case UNW_PPC64_LR:
1632 return "lr";
1633 case UNW_PPC64_CTR:
1634 return "ctr";
1635 case UNW_PPC64_VRSAVE:
1636 return "vrsave";
1637 case UNW_PPC64_F0:
1638 return "fp0";
1639 case UNW_PPC64_F1:
1640 return "fp1";
1641 case UNW_PPC64_F2:
1642 return "fp2";
1643 case UNW_PPC64_F3:
1644 return "fp3";
1645 case UNW_PPC64_F4:
1646 return "fp4";
1647 case UNW_PPC64_F5:
1648 return "fp5";
1649 case UNW_PPC64_F6:
1650 return "fp6";
1651 case UNW_PPC64_F7:
1652 return "fp7";
1653 case UNW_PPC64_F8:
1654 return "fp8";
1655 case UNW_PPC64_F9:
1656 return "fp9";
1657 case UNW_PPC64_F10:
1658 return "fp10";
1659 case UNW_PPC64_F11:
1660 return "fp11";
1661 case UNW_PPC64_F12:
1662 return "fp12";
1663 case UNW_PPC64_F13:
1664 return "fp13";
1665 case UNW_PPC64_F14:
1666 return "fp14";
1667 case UNW_PPC64_F15:
1668 return "fp15";
1669 case UNW_PPC64_F16:
1670 return "fp16";
1671 case UNW_PPC64_F17:
1672 return "fp17";
1673 case UNW_PPC64_F18:
1674 return "fp18";
1675 case UNW_PPC64_F19:
1676 return "fp19";
1677 case UNW_PPC64_F20:
1678 return "fp20";
1679 case UNW_PPC64_F21:
1680 return "fp21";
1681 case UNW_PPC64_F22:
1682 return "fp22";
1683 case UNW_PPC64_F23:
1684 return "fp23";
1685 case UNW_PPC64_F24:
1686 return "fp24";
1687 case UNW_PPC64_F25:
1688 return "fp25";
1689 case UNW_PPC64_F26:
1690 return "fp26";
1691 case UNW_PPC64_F27:
1692 return "fp27";
1693 case UNW_PPC64_F28:
1694 return "fp28";
1695 case UNW_PPC64_F29:
1696 return "fp29";
1697 case UNW_PPC64_F30:
1698 return "fp30";
1699 case UNW_PPC64_F31:
1700 return "fp31";
1701 case UNW_PPC64_V0:
1702 return "v0";
1703 case UNW_PPC64_V1:
1704 return "v1";
1705 case UNW_PPC64_V2:
1706 return "v2";
1707 case UNW_PPC64_V3:
1708 return "v3";
1709 case UNW_PPC64_V4:
1710 return "v4";
1711 case UNW_PPC64_V5:
1712 return "v5";
1713 case UNW_PPC64_V6:
1714 return "v6";
1715 case UNW_PPC64_V7:
1716 return "v7";
1717 case UNW_PPC64_V8:
1718 return "v8";
1719 case UNW_PPC64_V9:
1720 return "v9";
1721 case UNW_PPC64_V10:
1722 return "v10";
1723 case UNW_PPC64_V11:
1724 return "v11";
1725 case UNW_PPC64_V12:
1726 return "v12";
1727 case UNW_PPC64_V13:
1728 return "v13";
1729 case UNW_PPC64_V14:
1730 return "v14";
1731 case UNW_PPC64_V15:
1732 return "v15";
1733 case UNW_PPC64_V16:
1734 return "v16";
1735 case UNW_PPC64_V17:
1736 return "v17";
1737 case UNW_PPC64_V18:
1738 return "v18";
1739 case UNW_PPC64_V19:
1740 return "v19";
1741 case UNW_PPC64_V20:
1742 return "v20";
1743 case UNW_PPC64_V21:
1744 return "v21";
1745 case UNW_PPC64_V22:
1746 return "v22";
1747 case UNW_PPC64_V23:
1748 return "v23";
1749 case UNW_PPC64_V24:
1750 return "v24";
1751 case UNW_PPC64_V25:
1752 return "v25";
1753 case UNW_PPC64_V26:
1754 return "v26";
1755 case UNW_PPC64_V27:
1756 return "v27";
1757 case UNW_PPC64_V28:
1758 return "v28";
1759 case UNW_PPC64_V29:
1760 return "v29";
1761 case UNW_PPC64_V30:
1762 return "v30";
1763 case UNW_PPC64_V31:
1764 return "v31";
1765 }
1766 return "unknown register";
1767 }
1768 #endif // _LIBUNWIND_TARGET_PPC64
1769
1770
1771 #if defined(_LIBUNWIND_TARGET_AARCH64)
1772 /// Registers_arm64 holds the register state of a thread in a 64-bit arm
1773 /// process.
1774 class _LIBUNWIND_HIDDEN Registers_arm64 {
1775 public:
1776 Registers_arm64();
1777 Registers_arm64(const void *registers);
1778
1779 bool validRegister(int num) const;
1780 uint64_t getRegister(int num) const;
1781 void setRegister(int num, uint64_t value);
1782 bool validFloatRegister(int num) const;
1783 double getFloatRegister(int num) const;
1784 void setFloatRegister(int num, double value);
1785 bool validVectorRegister(int num) const;
1786 v128 getVectorRegister(int num) const;
1787 void setVectorRegister(int num, v128 value);
1788 static const char *getRegisterName(int num);
1789 void jumpto();
lastDwarfRegNum()1790 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64; }
getArch()1791 static int getArch() { return REGISTERS_ARM64; }
1792
getSP() const1793 uint64_t getSP() const { return _registers.__sp; }
setSP(uint64_t value)1794 void setSP(uint64_t value) { _registers.__sp = value; }
getIP() const1795 uint64_t getIP() const { return _registers.__pc; }
setIP(uint64_t value)1796 void setIP(uint64_t value) { _registers.__pc = value; }
getFP() const1797 uint64_t getFP() const { return _registers.__fp; }
setFP(uint64_t value)1798 void setFP(uint64_t value) { _registers.__fp = value; }
1799
1800 private:
1801 struct GPRs {
1802 uint64_t __x[29]; // x0-x28
1803 uint64_t __fp; // Frame pointer x29
1804 uint64_t __lr; // Link register x30
1805 uint64_t __sp; // Stack pointer x31
1806 uint64_t __pc; // Program counter
1807 uint64_t __ra_sign_state; // RA sign state register
1808 };
1809
1810 GPRs _registers;
1811 double _vectorHalfRegisters[32];
1812 // Currently only the lower double in 128-bit vectore registers
1813 // is perserved during unwinding. We could define new register
1814 // numbers (> 96) which mean whole vector registers, then this
1815 // struct would need to change to contain whole vector registers.
1816 };
1817
Registers_arm64(const void * registers)1818 inline Registers_arm64::Registers_arm64(const void *registers) {
1819 static_assert((check_fit<Registers_arm64, unw_context_t>::does_fit),
1820 "arm64 registers do not fit into unw_context_t");
1821 memcpy(&_registers, registers, sizeof(_registers));
1822 static_assert(sizeof(GPRs) == 0x110,
1823 "expected VFP registers to be at offset 272");
1824 memcpy(_vectorHalfRegisters,
1825 static_cast<const uint8_t *>(registers) + sizeof(GPRs),
1826 sizeof(_vectorHalfRegisters));
1827 }
1828
Registers_arm64()1829 inline Registers_arm64::Registers_arm64() {
1830 memset(&_registers, 0, sizeof(_registers));
1831 memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
1832 }
1833
validRegister(int regNum) const1834 inline bool Registers_arm64::validRegister(int regNum) const {
1835 if (regNum == UNW_REG_IP)
1836 return true;
1837 if (regNum == UNW_REG_SP)
1838 return true;
1839 if (regNum < 0)
1840 return false;
1841 if (regNum > 95)
1842 return false;
1843 if (regNum == UNW_ARM64_RA_SIGN_STATE)
1844 return true;
1845 if ((regNum > 31) && (regNum < 64))
1846 return false;
1847 return true;
1848 }
1849
getRegister(int regNum) const1850 inline uint64_t Registers_arm64::getRegister(int regNum) const {
1851 if (regNum == UNW_REG_IP)
1852 return _registers.__pc;
1853 if (regNum == UNW_REG_SP)
1854 return _registers.__sp;
1855 if (regNum == UNW_ARM64_RA_SIGN_STATE)
1856 return _registers.__ra_sign_state;
1857 if ((regNum >= 0) && (regNum < 32))
1858 return _registers.__x[regNum];
1859 _LIBUNWIND_ABORT("unsupported arm64 register");
1860 }
1861
setRegister(int regNum,uint64_t value)1862 inline void Registers_arm64::setRegister(int regNum, uint64_t value) {
1863 if (regNum == UNW_REG_IP)
1864 _registers.__pc = value;
1865 else if (regNum == UNW_REG_SP)
1866 _registers.__sp = value;
1867 else if (regNum == UNW_ARM64_RA_SIGN_STATE)
1868 _registers.__ra_sign_state = value;
1869 else if ((regNum >= 0) && (regNum < 32))
1870 _registers.__x[regNum] = value;
1871 else
1872 _LIBUNWIND_ABORT("unsupported arm64 register");
1873 }
1874
getRegisterName(int regNum)1875 inline const char *Registers_arm64::getRegisterName(int regNum) {
1876 switch (regNum) {
1877 case UNW_REG_IP:
1878 return "pc";
1879 case UNW_REG_SP:
1880 return "sp";
1881 case UNW_ARM64_X0:
1882 return "x0";
1883 case UNW_ARM64_X1:
1884 return "x1";
1885 case UNW_ARM64_X2:
1886 return "x2";
1887 case UNW_ARM64_X3:
1888 return "x3";
1889 case UNW_ARM64_X4:
1890 return "x4";
1891 case UNW_ARM64_X5:
1892 return "x5";
1893 case UNW_ARM64_X6:
1894 return "x6";
1895 case UNW_ARM64_X7:
1896 return "x7";
1897 case UNW_ARM64_X8:
1898 return "x8";
1899 case UNW_ARM64_X9:
1900 return "x9";
1901 case UNW_ARM64_X10:
1902 return "x10";
1903 case UNW_ARM64_X11:
1904 return "x11";
1905 case UNW_ARM64_X12:
1906 return "x12";
1907 case UNW_ARM64_X13:
1908 return "x13";
1909 case UNW_ARM64_X14:
1910 return "x14";
1911 case UNW_ARM64_X15:
1912 return "x15";
1913 case UNW_ARM64_X16:
1914 return "x16";
1915 case UNW_ARM64_X17:
1916 return "x17";
1917 case UNW_ARM64_X18:
1918 return "x18";
1919 case UNW_ARM64_X19:
1920 return "x19";
1921 case UNW_ARM64_X20:
1922 return "x20";
1923 case UNW_ARM64_X21:
1924 return "x21";
1925 case UNW_ARM64_X22:
1926 return "x22";
1927 case UNW_ARM64_X23:
1928 return "x23";
1929 case UNW_ARM64_X24:
1930 return "x24";
1931 case UNW_ARM64_X25:
1932 return "x25";
1933 case UNW_ARM64_X26:
1934 return "x26";
1935 case UNW_ARM64_X27:
1936 return "x27";
1937 case UNW_ARM64_X28:
1938 return "x28";
1939 case UNW_ARM64_X29:
1940 return "fp";
1941 case UNW_ARM64_X30:
1942 return "lr";
1943 case UNW_ARM64_X31:
1944 return "sp";
1945 case UNW_ARM64_D0:
1946 return "d0";
1947 case UNW_ARM64_D1:
1948 return "d1";
1949 case UNW_ARM64_D2:
1950 return "d2";
1951 case UNW_ARM64_D3:
1952 return "d3";
1953 case UNW_ARM64_D4:
1954 return "d4";
1955 case UNW_ARM64_D5:
1956 return "d5";
1957 case UNW_ARM64_D6:
1958 return "d6";
1959 case UNW_ARM64_D7:
1960 return "d7";
1961 case UNW_ARM64_D8:
1962 return "d8";
1963 case UNW_ARM64_D9:
1964 return "d9";
1965 case UNW_ARM64_D10:
1966 return "d10";
1967 case UNW_ARM64_D11:
1968 return "d11";
1969 case UNW_ARM64_D12:
1970 return "d12";
1971 case UNW_ARM64_D13:
1972 return "d13";
1973 case UNW_ARM64_D14:
1974 return "d14";
1975 case UNW_ARM64_D15:
1976 return "d15";
1977 case UNW_ARM64_D16:
1978 return "d16";
1979 case UNW_ARM64_D17:
1980 return "d17";
1981 case UNW_ARM64_D18:
1982 return "d18";
1983 case UNW_ARM64_D19:
1984 return "d19";
1985 case UNW_ARM64_D20:
1986 return "d20";
1987 case UNW_ARM64_D21:
1988 return "d21";
1989 case UNW_ARM64_D22:
1990 return "d22";
1991 case UNW_ARM64_D23:
1992 return "d23";
1993 case UNW_ARM64_D24:
1994 return "d24";
1995 case UNW_ARM64_D25:
1996 return "d25";
1997 case UNW_ARM64_D26:
1998 return "d26";
1999 case UNW_ARM64_D27:
2000 return "d27";
2001 case UNW_ARM64_D28:
2002 return "d28";
2003 case UNW_ARM64_D29:
2004 return "d29";
2005 case UNW_ARM64_D30:
2006 return "d30";
2007 case UNW_ARM64_D31:
2008 return "d31";
2009 default:
2010 return "unknown register";
2011 }
2012 }
2013
validFloatRegister(int regNum) const2014 inline bool Registers_arm64::validFloatRegister(int regNum) const {
2015 if (regNum < UNW_ARM64_D0)
2016 return false;
2017 if (regNum > UNW_ARM64_D31)
2018 return false;
2019 return true;
2020 }
2021
getFloatRegister(int regNum) const2022 inline double Registers_arm64::getFloatRegister(int regNum) const {
2023 assert(validFloatRegister(regNum));
2024 return _vectorHalfRegisters[regNum - UNW_ARM64_D0];
2025 }
2026
setFloatRegister(int regNum,double value)2027 inline void Registers_arm64::setFloatRegister(int regNum, double value) {
2028 assert(validFloatRegister(regNum));
2029 _vectorHalfRegisters[regNum - UNW_ARM64_D0] = value;
2030 }
2031
validVectorRegister(int) const2032 inline bool Registers_arm64::validVectorRegister(int) const {
2033 return false;
2034 }
2035
getVectorRegister(int) const2036 inline v128 Registers_arm64::getVectorRegister(int) const {
2037 _LIBUNWIND_ABORT("no arm64 vector register support yet");
2038 }
2039
setVectorRegister(int,v128)2040 inline void Registers_arm64::setVectorRegister(int, v128) {
2041 _LIBUNWIND_ABORT("no arm64 vector register support yet");
2042 }
2043 #endif // _LIBUNWIND_TARGET_AARCH64
2044
2045 #if defined(_LIBUNWIND_TARGET_ARM)
2046 /// Registers_arm holds the register state of a thread in a 32-bit arm
2047 /// process.
2048 ///
2049 /// NOTE: Assumes VFPv3. On ARM processors without a floating point unit,
2050 /// this uses more memory than required.
2051 class _LIBUNWIND_HIDDEN Registers_arm {
2052 public:
2053 Registers_arm();
2054 Registers_arm(const void *registers);
2055
2056 bool validRegister(int num) const;
2057 uint32_t getRegister(int num) const;
2058 void setRegister(int num, uint32_t value);
2059 bool validFloatRegister(int num) const;
2060 unw_fpreg_t getFloatRegister(int num);
2061 void setFloatRegister(int num, unw_fpreg_t value);
2062 bool validVectorRegister(int num) const;
2063 v128 getVectorRegister(int num) const;
2064 void setVectorRegister(int num, v128 value);
2065 static const char *getRegisterName(int num);
jumpto()2066 void jumpto() {
2067 restoreSavedFloatRegisters();
2068 restoreCoreAndJumpTo();
2069 }
lastDwarfRegNum()2070 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM; }
getArch()2071 static int getArch() { return REGISTERS_ARM; }
2072
getSP() const2073 uint32_t getSP() const { return _registers.__sp; }
setSP(uint32_t value)2074 void setSP(uint32_t value) { _registers.__sp = value; }
getIP() const2075 uint32_t getIP() const { return _registers.__pc; }
setIP(uint32_t value)2076 void setIP(uint32_t value) { _registers.__pc = value; }
2077
saveVFPAsX()2078 void saveVFPAsX() {
2079 assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15);
2080 _use_X_for_vfp_save = true;
2081 }
2082
restoreSavedFloatRegisters()2083 void restoreSavedFloatRegisters() {
2084 if (_saved_vfp_d0_d15) {
2085 if (_use_X_for_vfp_save)
2086 restoreVFPWithFLDMX(_vfp_d0_d15_pad);
2087 else
2088 restoreVFPWithFLDMD(_vfp_d0_d15_pad);
2089 }
2090 if (_saved_vfp_d16_d31)
2091 restoreVFPv3(_vfp_d16_d31);
2092 #if defined(__ARM_WMMX)
2093 if (_saved_iwmmx)
2094 restoreiWMMX(_iwmmx);
2095 if (_saved_iwmmx_control)
2096 restoreiWMMXControl(_iwmmx_control);
2097 #endif
2098 }
2099
2100 private:
2101 struct GPRs {
2102 uint32_t __r[13]; // r0-r12
2103 uint32_t __sp; // Stack pointer r13
2104 uint32_t __lr; // Link register r14
2105 uint32_t __pc; // Program counter r15
2106 };
2107
2108 static void saveVFPWithFSTMD(unw_fpreg_t*);
2109 static void saveVFPWithFSTMX(unw_fpreg_t*);
2110 static void saveVFPv3(unw_fpreg_t*);
2111 static void restoreVFPWithFLDMD(unw_fpreg_t*);
2112 static void restoreVFPWithFLDMX(unw_fpreg_t*);
2113 static void restoreVFPv3(unw_fpreg_t*);
2114 #if defined(__ARM_WMMX)
2115 static void saveiWMMX(unw_fpreg_t*);
2116 static void saveiWMMXControl(uint32_t*);
2117 static void restoreiWMMX(unw_fpreg_t*);
2118 static void restoreiWMMXControl(uint32_t*);
2119 #endif
2120 void restoreCoreAndJumpTo();
2121
2122 // ARM registers
2123 GPRs _registers;
2124
2125 // We save floating point registers lazily because we can't know ahead of
2126 // time which ones are used. See EHABI #4.7.
2127
2128 // Whether D0-D15 are saved in the FTSMX instead of FSTMD format.
2129 //
2130 // See EHABI #7.5 that explains how matching instruction sequences for load
2131 // and store need to be used to correctly restore the exact register bits.
2132 bool _use_X_for_vfp_save;
2133 // Whether VFP D0-D15 are saved.
2134 bool _saved_vfp_d0_d15;
2135 // Whether VFPv3 D16-D31 are saved.
2136 bool _saved_vfp_d16_d31;
2137 // VFP registers D0-D15, + padding if saved using FSTMX
2138 unw_fpreg_t _vfp_d0_d15_pad[17];
2139 // VFPv3 registers D16-D31, always saved using FSTMD
2140 unw_fpreg_t _vfp_d16_d31[16];
2141 #if defined(__ARM_WMMX)
2142 // Whether iWMMX data registers are saved.
2143 bool _saved_iwmmx;
2144 // Whether iWMMX control registers are saved.
2145 mutable bool _saved_iwmmx_control;
2146 // iWMMX registers
2147 unw_fpreg_t _iwmmx[16];
2148 // iWMMX control registers
2149 mutable uint32_t _iwmmx_control[4];
2150 #endif
2151 };
2152
Registers_arm(const void * registers)2153 inline Registers_arm::Registers_arm(const void *registers)
2154 : _use_X_for_vfp_save(false),
2155 _saved_vfp_d0_d15(false),
2156 _saved_vfp_d16_d31(false) {
2157 static_assert((check_fit<Registers_arm, unw_context_t>::does_fit),
2158 "arm registers do not fit into unw_context_t");
2159 // See unw_getcontext() note about data.
2160 memcpy(&_registers, registers, sizeof(_registers));
2161 memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
2162 memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
2163 #if defined(__ARM_WMMX)
2164 _saved_iwmmx = false;
2165 _saved_iwmmx_control = false;
2166 memset(&_iwmmx, 0, sizeof(_iwmmx));
2167 memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
2168 #endif
2169 }
2170
Registers_arm()2171 inline Registers_arm::Registers_arm()
2172 : _use_X_for_vfp_save(false),
2173 _saved_vfp_d0_d15(false),
2174 _saved_vfp_d16_d31(false) {
2175 memset(&_registers, 0, sizeof(_registers));
2176 memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
2177 memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
2178 #if defined(__ARM_WMMX)
2179 _saved_iwmmx = false;
2180 _saved_iwmmx_control = false;
2181 memset(&_iwmmx, 0, sizeof(_iwmmx));
2182 memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
2183 #endif
2184 }
2185
validRegister(int regNum) const2186 inline bool Registers_arm::validRegister(int regNum) const {
2187 // Returns true for all non-VFP registers supported by the EHABI
2188 // virtual register set (VRS).
2189 if (regNum == UNW_REG_IP)
2190 return true;
2191
2192 if (regNum == UNW_REG_SP)
2193 return true;
2194
2195 if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15)
2196 return true;
2197
2198 #if defined(__ARM_WMMX)
2199 if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3)
2200 return true;
2201 #endif
2202
2203 return false;
2204 }
2205
getRegister(int regNum) const2206 inline uint32_t Registers_arm::getRegister(int regNum) const {
2207 if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
2208 return _registers.__sp;
2209
2210 if (regNum == UNW_ARM_LR)
2211 return _registers.__lr;
2212
2213 if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
2214 return _registers.__pc;
2215
2216 if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
2217 return _registers.__r[regNum];
2218
2219 #if defined(__ARM_WMMX)
2220 if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
2221 if (!_saved_iwmmx_control) {
2222 _saved_iwmmx_control = true;
2223 saveiWMMXControl(_iwmmx_control);
2224 }
2225 return _iwmmx_control[regNum - UNW_ARM_WC0];
2226 }
2227 #endif
2228
2229 _LIBUNWIND_ABORT("unsupported arm register");
2230 }
2231
setRegister(int regNum,uint32_t value)2232 inline void Registers_arm::setRegister(int regNum, uint32_t value) {
2233 if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) {
2234 _registers.__sp = value;
2235 return;
2236 }
2237
2238 if (regNum == UNW_ARM_LR) {
2239 _registers.__lr = value;
2240 return;
2241 }
2242
2243 if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) {
2244 _registers.__pc = value;
2245 return;
2246 }
2247
2248 if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) {
2249 _registers.__r[regNum] = value;
2250 return;
2251 }
2252
2253 #if defined(__ARM_WMMX)
2254 if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
2255 if (!_saved_iwmmx_control) {
2256 _saved_iwmmx_control = true;
2257 saveiWMMXControl(_iwmmx_control);
2258 }
2259 _iwmmx_control[regNum - UNW_ARM_WC0] = value;
2260 return;
2261 }
2262 #endif
2263
2264 _LIBUNWIND_ABORT("unsupported arm register");
2265 }
2266
getRegisterName(int regNum)2267 inline const char *Registers_arm::getRegisterName(int regNum) {
2268 switch (regNum) {
2269 case UNW_REG_IP:
2270 case UNW_ARM_IP: // UNW_ARM_R15 is alias
2271 return "pc";
2272 case UNW_ARM_LR: // UNW_ARM_R14 is alias
2273 return "lr";
2274 case UNW_REG_SP:
2275 case UNW_ARM_SP: // UNW_ARM_R13 is alias
2276 return "sp";
2277 case UNW_ARM_R0:
2278 return "r0";
2279 case UNW_ARM_R1:
2280 return "r1";
2281 case UNW_ARM_R2:
2282 return "r2";
2283 case UNW_ARM_R3:
2284 return "r3";
2285 case UNW_ARM_R4:
2286 return "r4";
2287 case UNW_ARM_R5:
2288 return "r5";
2289 case UNW_ARM_R6:
2290 return "r6";
2291 case UNW_ARM_R7:
2292 return "r7";
2293 case UNW_ARM_R8:
2294 return "r8";
2295 case UNW_ARM_R9:
2296 return "r9";
2297 case UNW_ARM_R10:
2298 return "r10";
2299 case UNW_ARM_R11:
2300 return "r11";
2301 case UNW_ARM_R12:
2302 return "r12";
2303 case UNW_ARM_S0:
2304 return "s0";
2305 case UNW_ARM_S1:
2306 return "s1";
2307 case UNW_ARM_S2:
2308 return "s2";
2309 case UNW_ARM_S3:
2310 return "s3";
2311 case UNW_ARM_S4:
2312 return "s4";
2313 case UNW_ARM_S5:
2314 return "s5";
2315 case UNW_ARM_S6:
2316 return "s6";
2317 case UNW_ARM_S7:
2318 return "s7";
2319 case UNW_ARM_S8:
2320 return "s8";
2321 case UNW_ARM_S9:
2322 return "s9";
2323 case UNW_ARM_S10:
2324 return "s10";
2325 case UNW_ARM_S11:
2326 return "s11";
2327 case UNW_ARM_S12:
2328 return "s12";
2329 case UNW_ARM_S13:
2330 return "s13";
2331 case UNW_ARM_S14:
2332 return "s14";
2333 case UNW_ARM_S15:
2334 return "s15";
2335 case UNW_ARM_S16:
2336 return "s16";
2337 case UNW_ARM_S17:
2338 return "s17";
2339 case UNW_ARM_S18:
2340 return "s18";
2341 case UNW_ARM_S19:
2342 return "s19";
2343 case UNW_ARM_S20:
2344 return "s20";
2345 case UNW_ARM_S21:
2346 return "s21";
2347 case UNW_ARM_S22:
2348 return "s22";
2349 case UNW_ARM_S23:
2350 return "s23";
2351 case UNW_ARM_S24:
2352 return "s24";
2353 case UNW_ARM_S25:
2354 return "s25";
2355 case UNW_ARM_S26:
2356 return "s26";
2357 case UNW_ARM_S27:
2358 return "s27";
2359 case UNW_ARM_S28:
2360 return "s28";
2361 case UNW_ARM_S29:
2362 return "s29";
2363 case UNW_ARM_S30:
2364 return "s30";
2365 case UNW_ARM_S31:
2366 return "s31";
2367 case UNW_ARM_D0:
2368 return "d0";
2369 case UNW_ARM_D1:
2370 return "d1";
2371 case UNW_ARM_D2:
2372 return "d2";
2373 case UNW_ARM_D3:
2374 return "d3";
2375 case UNW_ARM_D4:
2376 return "d4";
2377 case UNW_ARM_D5:
2378 return "d5";
2379 case UNW_ARM_D6:
2380 return "d6";
2381 case UNW_ARM_D7:
2382 return "d7";
2383 case UNW_ARM_D8:
2384 return "d8";
2385 case UNW_ARM_D9:
2386 return "d9";
2387 case UNW_ARM_D10:
2388 return "d10";
2389 case UNW_ARM_D11:
2390 return "d11";
2391 case UNW_ARM_D12:
2392 return "d12";
2393 case UNW_ARM_D13:
2394 return "d13";
2395 case UNW_ARM_D14:
2396 return "d14";
2397 case UNW_ARM_D15:
2398 return "d15";
2399 case UNW_ARM_D16:
2400 return "d16";
2401 case UNW_ARM_D17:
2402 return "d17";
2403 case UNW_ARM_D18:
2404 return "d18";
2405 case UNW_ARM_D19:
2406 return "d19";
2407 case UNW_ARM_D20:
2408 return "d20";
2409 case UNW_ARM_D21:
2410 return "d21";
2411 case UNW_ARM_D22:
2412 return "d22";
2413 case UNW_ARM_D23:
2414 return "d23";
2415 case UNW_ARM_D24:
2416 return "d24";
2417 case UNW_ARM_D25:
2418 return "d25";
2419 case UNW_ARM_D26:
2420 return "d26";
2421 case UNW_ARM_D27:
2422 return "d27";
2423 case UNW_ARM_D28:
2424 return "d28";
2425 case UNW_ARM_D29:
2426 return "d29";
2427 case UNW_ARM_D30:
2428 return "d30";
2429 case UNW_ARM_D31:
2430 return "d31";
2431 default:
2432 return "unknown register";
2433 }
2434 }
2435
validFloatRegister(int regNum) const2436 inline bool Registers_arm::validFloatRegister(int regNum) const {
2437 // NOTE: Consider the intel MMX registers floating points so the
2438 // unw_get_fpreg can be used to transmit the 64-bit data back.
2439 return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31))
2440 #if defined(__ARM_WMMX)
2441 || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15))
2442 #endif
2443 ;
2444 }
2445
getFloatRegister(int regNum)2446 inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) {
2447 if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
2448 if (!_saved_vfp_d0_d15) {
2449 _saved_vfp_d0_d15 = true;
2450 if (_use_X_for_vfp_save)
2451 saveVFPWithFSTMX(_vfp_d0_d15_pad);
2452 else
2453 saveVFPWithFSTMD(_vfp_d0_d15_pad);
2454 }
2455 return _vfp_d0_d15_pad[regNum - UNW_ARM_D0];
2456 }
2457
2458 if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
2459 if (!_saved_vfp_d16_d31) {
2460 _saved_vfp_d16_d31 = true;
2461 saveVFPv3(_vfp_d16_d31);
2462 }
2463 return _vfp_d16_d31[regNum - UNW_ARM_D16];
2464 }
2465
2466 #if defined(__ARM_WMMX)
2467 if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
2468 if (!_saved_iwmmx) {
2469 _saved_iwmmx = true;
2470 saveiWMMX(_iwmmx);
2471 }
2472 return _iwmmx[regNum - UNW_ARM_WR0];
2473 }
2474 #endif
2475
2476 _LIBUNWIND_ABORT("Unknown ARM float register");
2477 }
2478
setFloatRegister(int regNum,unw_fpreg_t value)2479 inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) {
2480 if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
2481 if (!_saved_vfp_d0_d15) {
2482 _saved_vfp_d0_d15 = true;
2483 if (_use_X_for_vfp_save)
2484 saveVFPWithFSTMX(_vfp_d0_d15_pad);
2485 else
2486 saveVFPWithFSTMD(_vfp_d0_d15_pad);
2487 }
2488 _vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value;
2489 return;
2490 }
2491
2492 if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
2493 if (!_saved_vfp_d16_d31) {
2494 _saved_vfp_d16_d31 = true;
2495 saveVFPv3(_vfp_d16_d31);
2496 }
2497 _vfp_d16_d31[regNum - UNW_ARM_D16] = value;
2498 return;
2499 }
2500
2501 #if defined(__ARM_WMMX)
2502 if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
2503 if (!_saved_iwmmx) {
2504 _saved_iwmmx = true;
2505 saveiWMMX(_iwmmx);
2506 }
2507 _iwmmx[regNum - UNW_ARM_WR0] = value;
2508 return;
2509 }
2510 #endif
2511
2512 _LIBUNWIND_ABORT("Unknown ARM float register");
2513 }
2514
validVectorRegister(int) const2515 inline bool Registers_arm::validVectorRegister(int) const {
2516 return false;
2517 }
2518
getVectorRegister(int) const2519 inline v128 Registers_arm::getVectorRegister(int) const {
2520 _LIBUNWIND_ABORT("ARM vector support not implemented");
2521 }
2522
setVectorRegister(int,v128)2523 inline void Registers_arm::setVectorRegister(int, v128) {
2524 _LIBUNWIND_ABORT("ARM vector support not implemented");
2525 }
2526 #endif // _LIBUNWIND_TARGET_ARM
2527
2528
2529 #if defined(_LIBUNWIND_TARGET_OR1K)
2530 /// Registers_or1k holds the register state of a thread in an OpenRISC1000
2531 /// process.
2532 class _LIBUNWIND_HIDDEN Registers_or1k {
2533 public:
2534 Registers_or1k();
2535 Registers_or1k(const void *registers);
2536
2537 bool validRegister(int num) const;
2538 uint32_t getRegister(int num) const;
2539 void setRegister(int num, uint32_t value);
2540 bool validFloatRegister(int num) const;
2541 double getFloatRegister(int num) const;
2542 void setFloatRegister(int num, double value);
2543 bool validVectorRegister(int num) const;
2544 v128 getVectorRegister(int num) const;
2545 void setVectorRegister(int num, v128 value);
2546 static const char *getRegisterName(int num);
2547 void jumpto();
lastDwarfRegNum()2548 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K; }
getArch()2549 static int getArch() { return REGISTERS_OR1K; }
2550
getSP() const2551 uint64_t getSP() const { return _registers.__r[1]; }
setSP(uint32_t value)2552 void setSP(uint32_t value) { _registers.__r[1] = value; }
getIP() const2553 uint64_t getIP() const { return _registers.__pc; }
setIP(uint32_t value)2554 void setIP(uint32_t value) { _registers.__pc = value; }
2555
2556 private:
2557 struct or1k_thread_state_t {
2558 unsigned int __r[32]; // r0-r31
2559 unsigned int __pc; // Program counter
2560 unsigned int __epcr; // Program counter at exception
2561 };
2562
2563 or1k_thread_state_t _registers;
2564 };
2565
Registers_or1k(const void * registers)2566 inline Registers_or1k::Registers_or1k(const void *registers) {
2567 static_assert((check_fit<Registers_or1k, unw_context_t>::does_fit),
2568 "or1k registers do not fit into unw_context_t");
2569 memcpy(&_registers, static_cast<const uint8_t *>(registers),
2570 sizeof(_registers));
2571 }
2572
Registers_or1k()2573 inline Registers_or1k::Registers_or1k() {
2574 memset(&_registers, 0, sizeof(_registers));
2575 }
2576
validRegister(int regNum) const2577 inline bool Registers_or1k::validRegister(int regNum) const {
2578 if (regNum == UNW_REG_IP)
2579 return true;
2580 if (regNum == UNW_REG_SP)
2581 return true;
2582 if (regNum < 0)
2583 return false;
2584 if (regNum <= UNW_OR1K_R31)
2585 return true;
2586 if (regNum == UNW_OR1K_EPCR)
2587 return true;
2588 return false;
2589 }
2590
getRegister(int regNum) const2591 inline uint32_t Registers_or1k::getRegister(int regNum) const {
2592 if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31)
2593 return _registers.__r[regNum - UNW_OR1K_R0];
2594
2595 switch (regNum) {
2596 case UNW_REG_IP:
2597 return _registers.__pc;
2598 case UNW_REG_SP:
2599 return _registers.__r[1];
2600 case UNW_OR1K_EPCR:
2601 return _registers.__epcr;
2602 }
2603 _LIBUNWIND_ABORT("unsupported or1k register");
2604 }
2605
setRegister(int regNum,uint32_t value)2606 inline void Registers_or1k::setRegister(int regNum, uint32_t value) {
2607 if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) {
2608 _registers.__r[regNum - UNW_OR1K_R0] = value;
2609 return;
2610 }
2611
2612 switch (regNum) {
2613 case UNW_REG_IP:
2614 _registers.__pc = value;
2615 return;
2616 case UNW_REG_SP:
2617 _registers.__r[1] = value;
2618 return;
2619 case UNW_OR1K_EPCR:
2620 _registers.__epcr = value;
2621 return;
2622 }
2623 _LIBUNWIND_ABORT("unsupported or1k register");
2624 }
2625
validFloatRegister(int) const2626 inline bool Registers_or1k::validFloatRegister(int /* regNum */) const {
2627 return false;
2628 }
2629
getFloatRegister(int) const2630 inline double Registers_or1k::getFloatRegister(int /* regNum */) const {
2631 _LIBUNWIND_ABORT("or1k float support not implemented");
2632 }
2633
setFloatRegister(int,double)2634 inline void Registers_or1k::setFloatRegister(int /* regNum */,
2635 double /* value */) {
2636 _LIBUNWIND_ABORT("or1k float support not implemented");
2637 }
2638
validVectorRegister(int) const2639 inline bool Registers_or1k::validVectorRegister(int /* regNum */) const {
2640 return false;
2641 }
2642
getVectorRegister(int) const2643 inline v128 Registers_or1k::getVectorRegister(int /* regNum */) const {
2644 _LIBUNWIND_ABORT("or1k vector support not implemented");
2645 }
2646
setVectorRegister(int,v128)2647 inline void Registers_or1k::setVectorRegister(int /* regNum */, v128 /* value */) {
2648 _LIBUNWIND_ABORT("or1k vector support not implemented");
2649 }
2650
getRegisterName(int regNum)2651 inline const char *Registers_or1k::getRegisterName(int regNum) {
2652 switch (regNum) {
2653 case UNW_OR1K_R0:
2654 return "r0";
2655 case UNW_OR1K_R1:
2656 return "r1";
2657 case UNW_OR1K_R2:
2658 return "r2";
2659 case UNW_OR1K_R3:
2660 return "r3";
2661 case UNW_OR1K_R4:
2662 return "r4";
2663 case UNW_OR1K_R5:
2664 return "r5";
2665 case UNW_OR1K_R6:
2666 return "r6";
2667 case UNW_OR1K_R7:
2668 return "r7";
2669 case UNW_OR1K_R8:
2670 return "r8";
2671 case UNW_OR1K_R9:
2672 return "r9";
2673 case UNW_OR1K_R10:
2674 return "r10";
2675 case UNW_OR1K_R11:
2676 return "r11";
2677 case UNW_OR1K_R12:
2678 return "r12";
2679 case UNW_OR1K_R13:
2680 return "r13";
2681 case UNW_OR1K_R14:
2682 return "r14";
2683 case UNW_OR1K_R15:
2684 return "r15";
2685 case UNW_OR1K_R16:
2686 return "r16";
2687 case UNW_OR1K_R17:
2688 return "r17";
2689 case UNW_OR1K_R18:
2690 return "r18";
2691 case UNW_OR1K_R19:
2692 return "r19";
2693 case UNW_OR1K_R20:
2694 return "r20";
2695 case UNW_OR1K_R21:
2696 return "r21";
2697 case UNW_OR1K_R22:
2698 return "r22";
2699 case UNW_OR1K_R23:
2700 return "r23";
2701 case UNW_OR1K_R24:
2702 return "r24";
2703 case UNW_OR1K_R25:
2704 return "r25";
2705 case UNW_OR1K_R26:
2706 return "r26";
2707 case UNW_OR1K_R27:
2708 return "r27";
2709 case UNW_OR1K_R28:
2710 return "r28";
2711 case UNW_OR1K_R29:
2712 return "r29";
2713 case UNW_OR1K_R30:
2714 return "r30";
2715 case UNW_OR1K_R31:
2716 return "r31";
2717 case UNW_OR1K_EPCR:
2718 return "EPCR";
2719 default:
2720 return "unknown register";
2721 }
2722
2723 }
2724 #endif // _LIBUNWIND_TARGET_OR1K
2725
2726 #if defined(_LIBUNWIND_TARGET_RISCV)
2727 /// Registers_riscv holds the register state of a thread in a 64-bit RISC-V
2728 /// process.
2729 class _LIBUNWIND_HIDDEN Registers_riscv {
2730 public:
2731 Registers_riscv();
2732 Registers_riscv(const void *registers);
2733
2734 bool validRegister(int num) const;
2735 uint64_t getRegister(int num) const;
2736 void setRegister(int num, uint64_t value);
2737 bool validFloatRegister(int num) const;
2738 double getFloatRegister(int num) const;
2739 void setFloatRegister(int num, double value);
2740 bool validVectorRegister(int num) const;
2741 v128 getVectorRegister(int num) const;
2742 void setVectorRegister(int num, v128 value);
2743 static const char *getRegisterName(int num);
2744 void jumpto();
lastDwarfRegNum()2745 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV; }
getArch()2746 static int getArch() { return REGISTERS_RISCV; }
2747
getSP() const2748 uint64_t getSP() const { return _registers.__x[2]; }
setSP(uint64_t value)2749 void setSP(uint64_t value) { _registers.__x[2] = value; }
getIP() const2750 uint64_t getIP() const { return _registers.__x[1]; }
setIP(uint64_t value)2751 void setIP(uint64_t value) { _registers.__x[1] = value; }
2752
2753 private:
2754 struct GPRs {
2755 uint64_t __x[32]; // x0-x31
2756 };
2757
2758 GPRs _registers;
2759 double _vectorHalfRegisters[32];
2760 // Currently only the lower double in 128-bit vectore registers
2761 // is perserved during unwinding. We could define new register
2762 // numbers (> 96) which mean whole vector registers, then this
2763 // struct would need to change to contain whole vector registers.
2764 };
2765
Registers_riscv(const void * registers)2766 inline Registers_riscv::Registers_riscv(const void *registers) {
2767 static_assert((check_fit<Registers_riscv, unw_context_t>::does_fit),
2768 "riscv registers do not fit into unw_context_t");
2769 memcpy(&_registers, registers, sizeof(_registers));
2770 static_assert(sizeof(GPRs) == 0x100,
2771 "expected VFP registers to be at offset 256");
2772 memcpy(_vectorHalfRegisters,
2773 static_cast<const uint8_t *>(registers) + sizeof(GPRs),
2774 sizeof(_vectorHalfRegisters));
2775 }
2776
Registers_riscv()2777 inline Registers_riscv::Registers_riscv() {
2778 memset(&_registers, 0, sizeof(_registers));
2779 memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
2780 }
2781
validRegister(int regNum) const2782 inline bool Registers_riscv::validRegister(int regNum) const {
2783 if (regNum == UNW_REG_IP)
2784 return true;
2785 if (regNum == UNW_REG_SP)
2786 return true;
2787 if (regNum < 0)
2788 return false;
2789 if (regNum > 95)
2790 return false;
2791 if ((regNum > 31) && (regNum < 64))
2792 return false;
2793 return true;
2794 }
2795
getRegister(int regNum) const2796 inline uint64_t Registers_riscv::getRegister(int regNum) const {
2797 if (regNum == UNW_REG_IP)
2798 return _registers.__x[1];
2799 if (regNum == UNW_REG_SP)
2800 return _registers.__x[2];
2801 if ((regNum >= 0) && (regNum < 32))
2802 return _registers.__x[regNum];
2803 _LIBUNWIND_ABORT("unsupported riscv register");
2804 }
2805
setRegister(int regNum,uint64_t value)2806 inline void Registers_riscv::setRegister(int regNum, uint64_t value) {
2807 if (regNum == UNW_REG_IP)
2808 _registers.__x[1] = value;
2809 else if (regNum == UNW_REG_SP)
2810 _registers.__x[2] = value;
2811 else if ((regNum >= 0) && (regNum < 32))
2812 _registers.__x[regNum] = value;
2813 else
2814 _LIBUNWIND_ABORT("unsupported riscv register");
2815 }
2816
getRegisterName(int regNum)2817 inline const char *Registers_riscv::getRegisterName(int regNum) {
2818 switch (regNum) {
2819 case UNW_REG_IP:
2820 return "ra";
2821 case UNW_REG_SP:
2822 return "sp";
2823 case UNW_RISCV_X0:
2824 return "x0";
2825 case UNW_RISCV_X1:
2826 return "ra";
2827 case UNW_RISCV_X2:
2828 return "sp";
2829 case UNW_RISCV_X3:
2830 return "x3";
2831 case UNW_RISCV_X4:
2832 return "x4";
2833 case UNW_RISCV_X5:
2834 return "x5";
2835 case UNW_RISCV_X6:
2836 return "x6";
2837 case UNW_RISCV_X7:
2838 return "x7";
2839 case UNW_RISCV_X8:
2840 return "x8";
2841 case UNW_RISCV_X9:
2842 return "x9";
2843 case UNW_RISCV_X10:
2844 return "x10";
2845 case UNW_RISCV_X11:
2846 return "x11";
2847 case UNW_RISCV_X12:
2848 return "x12";
2849 case UNW_RISCV_X13:
2850 return "x13";
2851 case UNW_RISCV_X14:
2852 return "x14";
2853 case UNW_RISCV_X15:
2854 return "x15";
2855 case UNW_RISCV_X16:
2856 return "x16";
2857 case UNW_RISCV_X17:
2858 return "x17";
2859 case UNW_RISCV_X18:
2860 return "x18";
2861 case UNW_RISCV_X19:
2862 return "x19";
2863 case UNW_RISCV_X20:
2864 return "x20";
2865 case UNW_RISCV_X21:
2866 return "x21";
2867 case UNW_RISCV_X22:
2868 return "x22";
2869 case UNW_RISCV_X23:
2870 return "x23";
2871 case UNW_RISCV_X24:
2872 return "x24";
2873 case UNW_RISCV_X25:
2874 return "x25";
2875 case UNW_RISCV_X26:
2876 return "x26";
2877 case UNW_RISCV_X27:
2878 return "x27";
2879 case UNW_RISCV_X28:
2880 return "x28";
2881 case UNW_RISCV_X29:
2882 return "x29";
2883 case UNW_RISCV_X30:
2884 return "x30";
2885 case UNW_RISCV_X31:
2886 return "x31";
2887 case UNW_RISCV_D0:
2888 return "d0";
2889 case UNW_RISCV_D1:
2890 return "d1";
2891 case UNW_RISCV_D2:
2892 return "d2";
2893 case UNW_RISCV_D3:
2894 return "d3";
2895 case UNW_RISCV_D4:
2896 return "d4";
2897 case UNW_RISCV_D5:
2898 return "d5";
2899 case UNW_RISCV_D6:
2900 return "d6";
2901 case UNW_RISCV_D7:
2902 return "d7";
2903 case UNW_RISCV_D8:
2904 return "d8";
2905 case UNW_RISCV_D9:
2906 return "d9";
2907 case UNW_RISCV_D10:
2908 return "d10";
2909 case UNW_RISCV_D11:
2910 return "d11";
2911 case UNW_RISCV_D12:
2912 return "d12";
2913 case UNW_RISCV_D13:
2914 return "d13";
2915 case UNW_RISCV_D14:
2916 return "d14";
2917 case UNW_RISCV_D15:
2918 return "d15";
2919 case UNW_RISCV_D16:
2920 return "d16";
2921 case UNW_RISCV_D17:
2922 return "d17";
2923 case UNW_RISCV_D18:
2924 return "d18";
2925 case UNW_RISCV_D19:
2926 return "d19";
2927 case UNW_RISCV_D20:
2928 return "d20";
2929 case UNW_RISCV_D21:
2930 return "d21";
2931 case UNW_RISCV_D22:
2932 return "d22";
2933 case UNW_RISCV_D23:
2934 return "d23";
2935 case UNW_RISCV_D24:
2936 return "d24";
2937 case UNW_RISCV_D25:
2938 return "d25";
2939 case UNW_RISCV_D26:
2940 return "d26";
2941 case UNW_RISCV_D27:
2942 return "d27";
2943 case UNW_RISCV_D28:
2944 return "d28";
2945 case UNW_RISCV_D29:
2946 return "d29";
2947 case UNW_RISCV_D30:
2948 return "d30";
2949 case UNW_RISCV_D31:
2950 return "d31";
2951 default:
2952 return "unknown register";
2953 }
2954 }
2955
validFloatRegister(int regNum) const2956 inline bool Registers_riscv::validFloatRegister(int regNum) const {
2957 if (regNum < UNW_RISCV_D0)
2958 return false;
2959 if (regNum > UNW_RISCV_D31)
2960 return false;
2961 return true;
2962 }
2963
getFloatRegister(int regNum) const2964 inline double Registers_riscv::getFloatRegister(int regNum) const {
2965 assert(validFloatRegister(regNum));
2966 return _vectorHalfRegisters[regNum - UNW_RISCV_D0];
2967 }
2968
setFloatRegister(int regNum,double value)2969 inline void Registers_riscv::setFloatRegister(int regNum, double value) {
2970 assert(validFloatRegister(regNum));
2971 _vectorHalfRegisters[regNum - UNW_RISCV_D0] = value;
2972 }
2973
validVectorRegister(int) const2974 inline bool Registers_riscv::validVectorRegister(int) const {
2975 return false;
2976 }
2977
getVectorRegister(int) const2978 inline v128 Registers_riscv::getVectorRegister(int) const {
2979 _LIBUNWIND_ABORT("no riscv vector register support yet");
2980 }
2981
setVectorRegister(int,v128)2982 inline void Registers_riscv::setVectorRegister(int, v128) {
2983 _LIBUNWIND_ABORT("no riscv vector register support yet");
2984 }
2985 #endif // _LIBUNWIND_TARGET_RISCV
2986
2987 #if defined(_LIBUNWIND_TARGET_MIPS_O32)
2988 /// Registers_mips_o32 holds the register state of a thread in a 32-bit MIPS
2989 /// process.
2990 class _LIBUNWIND_HIDDEN Registers_mips_o32 {
2991 public:
2992 Registers_mips_o32();
2993 Registers_mips_o32(const void *registers);
2994
2995 bool validRegister(int num) const;
2996 uint32_t getRegister(int num) const;
2997 void setRegister(int num, uint32_t value);
2998 bool validFloatRegister(int num) const;
2999 double getFloatRegister(int num) const;
3000 void setFloatRegister(int num, double value);
3001 bool validVectorRegister(int num) const;
3002 v128 getVectorRegister(int num) const;
3003 void setVectorRegister(int num, v128 value);
3004 static const char *getRegisterName(int num);
3005 void jumpto();
lastDwarfRegNum()3006 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
getArch()3007 static int getArch() { return REGISTERS_MIPS_O32; }
3008
getSP() const3009 uint32_t getSP() const { return _registers.__r[29]; }
setSP(uint32_t value)3010 void setSP(uint32_t value) { _registers.__r[29] = value; }
getIP() const3011 uint32_t getIP() const { return _registers.__pc; }
setIP(uint32_t value)3012 void setIP(uint32_t value) { _registers.__pc = value; }
3013
3014 private:
3015 struct mips_o32_thread_state_t {
3016 uint32_t __r[32];
3017 uint32_t __pc;
3018 uint32_t __hi;
3019 uint32_t __lo;
3020 };
3021
3022 mips_o32_thread_state_t _registers;
3023 #ifdef __mips_hard_float
3024 /// O32 with 32-bit floating point registers only uses half of this
3025 /// space. However, using the same layout for 32-bit vs 64-bit
3026 /// floating point registers results in a single context size for
3027 /// O32 with hard float.
3028 uint32_t _padding;
3029 double _floats[32];
3030 #endif
3031 };
3032
Registers_mips_o32(const void * registers)3033 inline Registers_mips_o32::Registers_mips_o32(const void *registers) {
3034 static_assert((check_fit<Registers_mips_o32, unw_context_t>::does_fit),
3035 "mips_o32 registers do not fit into unw_context_t");
3036 memcpy(&_registers, static_cast<const uint8_t *>(registers),
3037 sizeof(_registers));
3038 }
3039
Registers_mips_o32()3040 inline Registers_mips_o32::Registers_mips_o32() {
3041 memset(&_registers, 0, sizeof(_registers));
3042 }
3043
validRegister(int regNum) const3044 inline bool Registers_mips_o32::validRegister(int regNum) const {
3045 if (regNum == UNW_REG_IP)
3046 return true;
3047 if (regNum == UNW_REG_SP)
3048 return true;
3049 if (regNum < 0)
3050 return false;
3051 if (regNum <= UNW_MIPS_R31)
3052 return true;
3053 #if __mips_isa_rev != 6
3054 if (regNum == UNW_MIPS_HI)
3055 return true;
3056 if (regNum == UNW_MIPS_LO)
3057 return true;
3058 #endif
3059 #if defined(__mips_hard_float) && __mips_fpr == 32
3060 if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
3061 return true;
3062 #endif
3063 // FIXME: DSP accumulator registers, MSA registers
3064 return false;
3065 }
3066
getRegister(int regNum) const3067 inline uint32_t Registers_mips_o32::getRegister(int regNum) const {
3068 if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
3069 return _registers.__r[regNum - UNW_MIPS_R0];
3070 #if defined(__mips_hard_float) && __mips_fpr == 32
3071 if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
3072 uint32_t *p;
3073
3074 if (regNum % 2 == 0)
3075 p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
3076 else
3077 p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
3078 return *p;
3079 }
3080 #endif
3081
3082 switch (regNum) {
3083 case UNW_REG_IP:
3084 return _registers.__pc;
3085 case UNW_REG_SP:
3086 return _registers.__r[29];
3087 case UNW_MIPS_HI:
3088 return _registers.__hi;
3089 case UNW_MIPS_LO:
3090 return _registers.__lo;
3091 }
3092 _LIBUNWIND_ABORT("unsupported mips_o32 register");
3093 }
3094
setRegister(int regNum,uint32_t value)3095 inline void Registers_mips_o32::setRegister(int regNum, uint32_t value) {
3096 if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
3097 _registers.__r[regNum - UNW_MIPS_R0] = value;
3098 return;
3099 }
3100 #if defined(__mips_hard_float) && __mips_fpr == 32
3101 if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
3102 uint32_t *p;
3103
3104 if (regNum % 2 == 0)
3105 p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
3106 else
3107 p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
3108 *p = value;
3109 return;
3110 }
3111 #endif
3112
3113 switch (regNum) {
3114 case UNW_REG_IP:
3115 _registers.__pc = value;
3116 return;
3117 case UNW_REG_SP:
3118 _registers.__r[29] = value;
3119 return;
3120 case UNW_MIPS_HI:
3121 _registers.__hi = value;
3122 return;
3123 case UNW_MIPS_LO:
3124 _registers.__lo = value;
3125 return;
3126 }
3127 _LIBUNWIND_ABORT("unsupported mips_o32 register");
3128 }
3129
validFloatRegister(int regNum) const3130 inline bool Registers_mips_o32::validFloatRegister(int regNum) const {
3131 #if defined(__mips_hard_float) && __mips_fpr == 64
3132 if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
3133 return true;
3134 #endif
3135 return false;
3136 }
3137
getFloatRegister(int regNum) const3138 inline double Registers_mips_o32::getFloatRegister(int regNum) const {
3139 #if defined(__mips_hard_float) && __mips_fpr == 64
3140 assert(validFloatRegister(regNum));
3141 return _floats[regNum - UNW_MIPS_F0];
3142 #else
3143 _LIBUNWIND_ABORT("mips_o32 float support not implemented");
3144 #endif
3145 }
3146
setFloatRegister(int regNum,double value)3147 inline void Registers_mips_o32::setFloatRegister(int regNum,
3148 double value) {
3149 #if defined(__mips_hard_float) && __mips_fpr == 64
3150 assert(validFloatRegister(regNum));
3151 _floats[regNum - UNW_MIPS_F0] = value;
3152 #else
3153 _LIBUNWIND_ABORT("mips_o32 float support not implemented");
3154 #endif
3155 }
3156
validVectorRegister(int) const3157 inline bool Registers_mips_o32::validVectorRegister(int /* regNum */) const {
3158 return false;
3159 }
3160
getVectorRegister(int) const3161 inline v128 Registers_mips_o32::getVectorRegister(int /* regNum */) const {
3162 _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
3163 }
3164
setVectorRegister(int,v128)3165 inline void Registers_mips_o32::setVectorRegister(int /* regNum */, v128 /* value */) {
3166 _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
3167 }
3168
getRegisterName(int regNum)3169 inline const char *Registers_mips_o32::getRegisterName(int regNum) {
3170 switch (regNum) {
3171 case UNW_MIPS_R0:
3172 return "$0";
3173 case UNW_MIPS_R1:
3174 return "$1";
3175 case UNW_MIPS_R2:
3176 return "$2";
3177 case UNW_MIPS_R3:
3178 return "$3";
3179 case UNW_MIPS_R4:
3180 return "$4";
3181 case UNW_MIPS_R5:
3182 return "$5";
3183 case UNW_MIPS_R6:
3184 return "$6";
3185 case UNW_MIPS_R7:
3186 return "$7";
3187 case UNW_MIPS_R8:
3188 return "$8";
3189 case UNW_MIPS_R9:
3190 return "$9";
3191 case UNW_MIPS_R10:
3192 return "$10";
3193 case UNW_MIPS_R11:
3194 return "$11";
3195 case UNW_MIPS_R12:
3196 return "$12";
3197 case UNW_MIPS_R13:
3198 return "$13";
3199 case UNW_MIPS_R14:
3200 return "$14";
3201 case UNW_MIPS_R15:
3202 return "$15";
3203 case UNW_MIPS_R16:
3204 return "$16";
3205 case UNW_MIPS_R17:
3206 return "$17";
3207 case UNW_MIPS_R18:
3208 return "$18";
3209 case UNW_MIPS_R19:
3210 return "$19";
3211 case UNW_MIPS_R20:
3212 return "$20";
3213 case UNW_MIPS_R21:
3214 return "$21";
3215 case UNW_MIPS_R22:
3216 return "$22";
3217 case UNW_MIPS_R23:
3218 return "$23";
3219 case UNW_MIPS_R24:
3220 return "$24";
3221 case UNW_MIPS_R25:
3222 return "$25";
3223 case UNW_MIPS_R26:
3224 return "$26";
3225 case UNW_MIPS_R27:
3226 return "$27";
3227 case UNW_MIPS_R28:
3228 return "$28";
3229 case UNW_MIPS_R29:
3230 return "$29";
3231 case UNW_MIPS_R30:
3232 return "$30";
3233 case UNW_MIPS_R31:
3234 return "$31";
3235 case UNW_MIPS_F0:
3236 return "$f0";
3237 case UNW_MIPS_F1:
3238 return "$f1";
3239 case UNW_MIPS_F2:
3240 return "$f2";
3241 case UNW_MIPS_F3:
3242 return "$f3";
3243 case UNW_MIPS_F4:
3244 return "$f4";
3245 case UNW_MIPS_F5:
3246 return "$f5";
3247 case UNW_MIPS_F6:
3248 return "$f6";
3249 case UNW_MIPS_F7:
3250 return "$f7";
3251 case UNW_MIPS_F8:
3252 return "$f8";
3253 case UNW_MIPS_F9:
3254 return "$f9";
3255 case UNW_MIPS_F10:
3256 return "$f10";
3257 case UNW_MIPS_F11:
3258 return "$f11";
3259 case UNW_MIPS_F12:
3260 return "$f12";
3261 case UNW_MIPS_F13:
3262 return "$f13";
3263 case UNW_MIPS_F14:
3264 return "$f14";
3265 case UNW_MIPS_F15:
3266 return "$f15";
3267 case UNW_MIPS_F16:
3268 return "$f16";
3269 case UNW_MIPS_F17:
3270 return "$f17";
3271 case UNW_MIPS_F18:
3272 return "$f18";
3273 case UNW_MIPS_F19:
3274 return "$f19";
3275 case UNW_MIPS_F20:
3276 return "$f20";
3277 case UNW_MIPS_F21:
3278 return "$f21";
3279 case UNW_MIPS_F22:
3280 return "$f22";
3281 case UNW_MIPS_F23:
3282 return "$f23";
3283 case UNW_MIPS_F24:
3284 return "$f24";
3285 case UNW_MIPS_F25:
3286 return "$f25";
3287 case UNW_MIPS_F26:
3288 return "$f26";
3289 case UNW_MIPS_F27:
3290 return "$f27";
3291 case UNW_MIPS_F28:
3292 return "$f28";
3293 case UNW_MIPS_F29:
3294 return "$f29";
3295 case UNW_MIPS_F30:
3296 return "$f30";
3297 case UNW_MIPS_F31:
3298 return "$f31";
3299 case UNW_MIPS_HI:
3300 return "$hi";
3301 case UNW_MIPS_LO:
3302 return "$lo";
3303 default:
3304 return "unknown register";
3305 }
3306 }
3307 #endif // _LIBUNWIND_TARGET_MIPS_O32
3308
3309 #if defined(_LIBUNWIND_TARGET_MIPS_NEWABI)
3310 /// Registers_mips_newabi holds the register state of a thread in a
3311 /// MIPS process using NEWABI (the N32 or N64 ABIs).
3312 class _LIBUNWIND_HIDDEN Registers_mips_newabi {
3313 public:
3314 Registers_mips_newabi();
3315 Registers_mips_newabi(const void *registers);
3316
3317 bool validRegister(int num) const;
3318 uint64_t getRegister(int num) const;
3319 void setRegister(int num, uint64_t value);
3320 bool validFloatRegister(int num) const;
3321 double getFloatRegister(int num) const;
3322 void setFloatRegister(int num, double value);
3323 bool validVectorRegister(int num) const;
3324 v128 getVectorRegister(int num) const;
3325 void setVectorRegister(int num, v128 value);
3326 static const char *getRegisterName(int num);
3327 void jumpto();
lastDwarfRegNum()3328 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
getArch()3329 static int getArch() { return REGISTERS_MIPS_NEWABI; }
3330
getSP() const3331 uint64_t getSP() const { return _registers.__r[29]; }
setSP(uint64_t value)3332 void setSP(uint64_t value) { _registers.__r[29] = value; }
getIP() const3333 uint64_t getIP() const { return _registers.__pc; }
setIP(uint64_t value)3334 void setIP(uint64_t value) { _registers.__pc = value; }
3335
3336 private:
3337 struct mips_newabi_thread_state_t {
3338 uint64_t __r[32];
3339 uint64_t __pc;
3340 uint64_t __hi;
3341 uint64_t __lo;
3342 };
3343
3344 mips_newabi_thread_state_t _registers;
3345 #ifdef __mips_hard_float
3346 double _floats[32];
3347 #endif
3348 };
3349
Registers_mips_newabi(const void * registers)3350 inline Registers_mips_newabi::Registers_mips_newabi(const void *registers) {
3351 static_assert((check_fit<Registers_mips_newabi, unw_context_t>::does_fit),
3352 "mips_newabi registers do not fit into unw_context_t");
3353 memcpy(&_registers, static_cast<const uint8_t *>(registers),
3354 sizeof(_registers));
3355 }
3356
Registers_mips_newabi()3357 inline Registers_mips_newabi::Registers_mips_newabi() {
3358 memset(&_registers, 0, sizeof(_registers));
3359 }
3360
validRegister(int regNum) const3361 inline bool Registers_mips_newabi::validRegister(int regNum) const {
3362 if (regNum == UNW_REG_IP)
3363 return true;
3364 if (regNum == UNW_REG_SP)
3365 return true;
3366 if (regNum < 0)
3367 return false;
3368 if (regNum <= UNW_MIPS_R31)
3369 return true;
3370 #if __mips_isa_rev != 6
3371 if (regNum == UNW_MIPS_HI)
3372 return true;
3373 if (regNum == UNW_MIPS_LO)
3374 return true;
3375 #endif
3376 // FIXME: Hard float, DSP accumulator registers, MSA registers
3377 return false;
3378 }
3379
getRegister(int regNum) const3380 inline uint64_t Registers_mips_newabi::getRegister(int regNum) const {
3381 if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
3382 return _registers.__r[regNum - UNW_MIPS_R0];
3383
3384 switch (regNum) {
3385 case UNW_REG_IP:
3386 return _registers.__pc;
3387 case UNW_REG_SP:
3388 return _registers.__r[29];
3389 case UNW_MIPS_HI:
3390 return _registers.__hi;
3391 case UNW_MIPS_LO:
3392 return _registers.__lo;
3393 }
3394 _LIBUNWIND_ABORT("unsupported mips_newabi register");
3395 }
3396
setRegister(int regNum,uint64_t value)3397 inline void Registers_mips_newabi::setRegister(int regNum, uint64_t value) {
3398 if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
3399 _registers.__r[regNum - UNW_MIPS_R0] = value;
3400 return;
3401 }
3402
3403 switch (regNum) {
3404 case UNW_REG_IP:
3405 _registers.__pc = value;
3406 return;
3407 case UNW_REG_SP:
3408 _registers.__r[29] = value;
3409 return;
3410 case UNW_MIPS_HI:
3411 _registers.__hi = value;
3412 return;
3413 case UNW_MIPS_LO:
3414 _registers.__lo = value;
3415 return;
3416 }
3417 _LIBUNWIND_ABORT("unsupported mips_newabi register");
3418 }
3419
validFloatRegister(int regNum) const3420 inline bool Registers_mips_newabi::validFloatRegister(int regNum) const {
3421 #ifdef __mips_hard_float
3422 if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
3423 return true;
3424 #endif
3425 return false;
3426 }
3427
getFloatRegister(int regNum) const3428 inline double Registers_mips_newabi::getFloatRegister(int regNum) const {
3429 #ifdef __mips_hard_float
3430 assert(validFloatRegister(regNum));
3431 return _floats[regNum - UNW_MIPS_F0];
3432 #else
3433 _LIBUNWIND_ABORT("mips_newabi float support not implemented");
3434 #endif
3435 }
3436
setFloatRegister(int regNum,double value)3437 inline void Registers_mips_newabi::setFloatRegister(int regNum,
3438 double value) {
3439 #ifdef __mips_hard_float
3440 assert(validFloatRegister(regNum));
3441 _floats[regNum - UNW_MIPS_F0] = value;
3442 #else
3443 _LIBUNWIND_ABORT("mips_newabi float support not implemented");
3444 #endif
3445 }
3446
validVectorRegister(int) const3447 inline bool Registers_mips_newabi::validVectorRegister(int /* regNum */) const {
3448 return false;
3449 }
3450
getVectorRegister(int) const3451 inline v128 Registers_mips_newabi::getVectorRegister(int /* regNum */) const {
3452 _LIBUNWIND_ABORT("mips_newabi vector support not implemented");
3453 }
3454
setVectorRegister(int,v128)3455 inline void Registers_mips_newabi::setVectorRegister(int /* regNum */, v128 /* value */) {
3456 _LIBUNWIND_ABORT("mips_newabi vector support not implemented");
3457 }
3458
getRegisterName(int regNum)3459 inline const char *Registers_mips_newabi::getRegisterName(int regNum) {
3460 switch (regNum) {
3461 case UNW_MIPS_R0:
3462 return "$0";
3463 case UNW_MIPS_R1:
3464 return "$1";
3465 case UNW_MIPS_R2:
3466 return "$2";
3467 case UNW_MIPS_R3:
3468 return "$3";
3469 case UNW_MIPS_R4:
3470 return "$4";
3471 case UNW_MIPS_R5:
3472 return "$5";
3473 case UNW_MIPS_R6:
3474 return "$6";
3475 case UNW_MIPS_R7:
3476 return "$7";
3477 case UNW_MIPS_R8:
3478 return "$8";
3479 case UNW_MIPS_R9:
3480 return "$9";
3481 case UNW_MIPS_R10:
3482 return "$10";
3483 case UNW_MIPS_R11:
3484 return "$11";
3485 case UNW_MIPS_R12:
3486 return "$12";
3487 case UNW_MIPS_R13:
3488 return "$13";
3489 case UNW_MIPS_R14:
3490 return "$14";
3491 case UNW_MIPS_R15:
3492 return "$15";
3493 case UNW_MIPS_R16:
3494 return "$16";
3495 case UNW_MIPS_R17:
3496 return "$17";
3497 case UNW_MIPS_R18:
3498 return "$18";
3499 case UNW_MIPS_R19:
3500 return "$19";
3501 case UNW_MIPS_R20:
3502 return "$20";
3503 case UNW_MIPS_R21:
3504 return "$21";
3505 case UNW_MIPS_R22:
3506 return "$22";
3507 case UNW_MIPS_R23:
3508 return "$23";
3509 case UNW_MIPS_R24:
3510 return "$24";
3511 case UNW_MIPS_R25:
3512 return "$25";
3513 case UNW_MIPS_R26:
3514 return "$26";
3515 case UNW_MIPS_R27:
3516 return "$27";
3517 case UNW_MIPS_R28:
3518 return "$28";
3519 case UNW_MIPS_R29:
3520 return "$29";
3521 case UNW_MIPS_R30:
3522 return "$30";
3523 case UNW_MIPS_R31:
3524 return "$31";
3525 case UNW_MIPS_F0:
3526 return "$f0";
3527 case UNW_MIPS_F1:
3528 return "$f1";
3529 case UNW_MIPS_F2:
3530 return "$f2";
3531 case UNW_MIPS_F3:
3532 return "$f3";
3533 case UNW_MIPS_F4:
3534 return "$f4";
3535 case UNW_MIPS_F5:
3536 return "$f5";
3537 case UNW_MIPS_F6:
3538 return "$f6";
3539 case UNW_MIPS_F7:
3540 return "$f7";
3541 case UNW_MIPS_F8:
3542 return "$f8";
3543 case UNW_MIPS_F9:
3544 return "$f9";
3545 case UNW_MIPS_F10:
3546 return "$f10";
3547 case UNW_MIPS_F11:
3548 return "$f11";
3549 case UNW_MIPS_F12:
3550 return "$f12";
3551 case UNW_MIPS_F13:
3552 return "$f13";
3553 case UNW_MIPS_F14:
3554 return "$f14";
3555 case UNW_MIPS_F15:
3556 return "$f15";
3557 case UNW_MIPS_F16:
3558 return "$f16";
3559 case UNW_MIPS_F17:
3560 return "$f17";
3561 case UNW_MIPS_F18:
3562 return "$f18";
3563 case UNW_MIPS_F19:
3564 return "$f19";
3565 case UNW_MIPS_F20:
3566 return "$f20";
3567 case UNW_MIPS_F21:
3568 return "$f21";
3569 case UNW_MIPS_F22:
3570 return "$f22";
3571 case UNW_MIPS_F23:
3572 return "$f23";
3573 case UNW_MIPS_F24:
3574 return "$f24";
3575 case UNW_MIPS_F25:
3576 return "$f25";
3577 case UNW_MIPS_F26:
3578 return "$f26";
3579 case UNW_MIPS_F27:
3580 return "$f27";
3581 case UNW_MIPS_F28:
3582 return "$f28";
3583 case UNW_MIPS_F29:
3584 return "$f29";
3585 case UNW_MIPS_F30:
3586 return "$f30";
3587 case UNW_MIPS_F31:
3588 return "$f31";
3589 case UNW_MIPS_HI:
3590 return "$hi";
3591 case UNW_MIPS_LO:
3592 return "$lo";
3593 default:
3594 return "unknown register";
3595 }
3596 }
3597 #endif // _LIBUNWIND_TARGET_MIPS_NEWABI
3598
3599 #if defined(_LIBUNWIND_TARGET_SPARC)
3600 /// Registers_sparc holds the register state of a thread in a 32-bit Sparc
3601 /// process.
3602 class _LIBUNWIND_HIDDEN Registers_sparc {
3603 public:
3604 Registers_sparc();
3605 Registers_sparc(const void *registers);
3606
3607 bool validRegister(int num) const;
3608 uint32_t getRegister(int num) const;
3609 void setRegister(int num, uint32_t value);
3610 bool validFloatRegister(int num) const;
3611 double getFloatRegister(int num) const;
3612 void setFloatRegister(int num, double value);
3613 bool validVectorRegister(int num) const;
3614 v128 getVectorRegister(int num) const;
3615 void setVectorRegister(int num, v128 value);
3616 static const char *getRegisterName(int num);
3617 void jumpto();
lastDwarfRegNum()3618 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC; }
getArch()3619 static int getArch() { return REGISTERS_SPARC; }
3620
getSP() const3621 uint64_t getSP() const { return _registers.__regs[UNW_SPARC_O6]; }
setSP(uint32_t value)3622 void setSP(uint32_t value) { _registers.__regs[UNW_SPARC_O6] = value; }
getIP() const3623 uint64_t getIP() const { return _registers.__regs[UNW_SPARC_O7]; }
setIP(uint32_t value)3624 void setIP(uint32_t value) { _registers.__regs[UNW_SPARC_O7] = value; }
3625
3626 private:
3627 struct sparc_thread_state_t {
3628 unsigned int __regs[32];
3629 };
3630
3631 sparc_thread_state_t _registers;
3632 };
3633
Registers_sparc(const void * registers)3634 inline Registers_sparc::Registers_sparc(const void *registers) {
3635 static_assert((check_fit<Registers_sparc, unw_context_t>::does_fit),
3636 "sparc registers do not fit into unw_context_t");
3637 memcpy(&_registers, static_cast<const uint8_t *>(registers),
3638 sizeof(_registers));
3639 }
3640
Registers_sparc()3641 inline Registers_sparc::Registers_sparc() {
3642 memset(&_registers, 0, sizeof(_registers));
3643 }
3644
validRegister(int regNum) const3645 inline bool Registers_sparc::validRegister(int regNum) const {
3646 if (regNum == UNW_REG_IP)
3647 return true;
3648 if (regNum == UNW_REG_SP)
3649 return true;
3650 if (regNum < 0)
3651 return false;
3652 if (regNum <= UNW_SPARC_I7)
3653 return true;
3654 return false;
3655 }
3656
getRegister(int regNum) const3657 inline uint32_t Registers_sparc::getRegister(int regNum) const {
3658 if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) {
3659 return _registers.__regs[regNum];
3660 }
3661
3662 switch (regNum) {
3663 case UNW_REG_IP:
3664 return _registers.__regs[UNW_SPARC_O7];
3665 case UNW_REG_SP:
3666 return _registers.__regs[UNW_SPARC_O6];
3667 }
3668 _LIBUNWIND_ABORT("unsupported sparc register");
3669 }
3670
setRegister(int regNum,uint32_t value)3671 inline void Registers_sparc::setRegister(int regNum, uint32_t value) {
3672 if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) {
3673 _registers.__regs[regNum] = value;
3674 return;
3675 }
3676
3677 switch (regNum) {
3678 case UNW_REG_IP:
3679 _registers.__regs[UNW_SPARC_O7] = value;
3680 return;
3681 case UNW_REG_SP:
3682 _registers.__regs[UNW_SPARC_O6] = value;
3683 return;
3684 }
3685 _LIBUNWIND_ABORT("unsupported sparc register");
3686 }
3687
validFloatRegister(int) const3688 inline bool Registers_sparc::validFloatRegister(int) const { return false; }
3689
getFloatRegister(int) const3690 inline double Registers_sparc::getFloatRegister(int) const {
3691 _LIBUNWIND_ABORT("no Sparc float registers");
3692 }
3693
setFloatRegister(int,double)3694 inline void Registers_sparc::setFloatRegister(int, double) {
3695 _LIBUNWIND_ABORT("no Sparc float registers");
3696 }
3697
validVectorRegister(int) const3698 inline bool Registers_sparc::validVectorRegister(int) const { return false; }
3699
getVectorRegister(int) const3700 inline v128 Registers_sparc::getVectorRegister(int) const {
3701 _LIBUNWIND_ABORT("no Sparc vector registers");
3702 }
3703
setVectorRegister(int,v128)3704 inline void Registers_sparc::setVectorRegister(int, v128) {
3705 _LIBUNWIND_ABORT("no Sparc vector registers");
3706 }
3707
getRegisterName(int regNum)3708 inline const char *Registers_sparc::getRegisterName(int regNum) {
3709 switch (regNum) {
3710 case UNW_REG_IP:
3711 return "pc";
3712 case UNW_SPARC_G0:
3713 return "g0";
3714 case UNW_SPARC_G1:
3715 return "g1";
3716 case UNW_SPARC_G2:
3717 return "g2";
3718 case UNW_SPARC_G3:
3719 return "g3";
3720 case UNW_SPARC_G4:
3721 return "g4";
3722 case UNW_SPARC_G5:
3723 return "g5";
3724 case UNW_SPARC_G6:
3725 return "g6";
3726 case UNW_SPARC_G7:
3727 return "g7";
3728 case UNW_SPARC_O0:
3729 return "o0";
3730 case UNW_SPARC_O1:
3731 return "o1";
3732 case UNW_SPARC_O2:
3733 return "o2";
3734 case UNW_SPARC_O3:
3735 return "o3";
3736 case UNW_SPARC_O4:
3737 return "o4";
3738 case UNW_SPARC_O5:
3739 return "o5";
3740 case UNW_REG_SP:
3741 case UNW_SPARC_O6:
3742 return "sp";
3743 case UNW_SPARC_O7:
3744 return "o7";
3745 case UNW_SPARC_L0:
3746 return "l0";
3747 case UNW_SPARC_L1:
3748 return "l1";
3749 case UNW_SPARC_L2:
3750 return "l2";
3751 case UNW_SPARC_L3:
3752 return "l3";
3753 case UNW_SPARC_L4:
3754 return "l4";
3755 case UNW_SPARC_L5:
3756 return "l5";
3757 case UNW_SPARC_L6:
3758 return "l6";
3759 case UNW_SPARC_L7:
3760 return "l7";
3761 case UNW_SPARC_I0:
3762 return "i0";
3763 case UNW_SPARC_I1:
3764 return "i1";
3765 case UNW_SPARC_I2:
3766 return "i2";
3767 case UNW_SPARC_I3:
3768 return "i3";
3769 case UNW_SPARC_I4:
3770 return "i4";
3771 case UNW_SPARC_I5:
3772 return "i5";
3773 case UNW_SPARC_I6:
3774 return "fp";
3775 case UNW_SPARC_I7:
3776 return "i7";
3777 default:
3778 return "unknown register";
3779 }
3780 }
3781 #endif // _LIBUNWIND_TARGET_SPARC
3782
3783 } // namespace libunwind
3784
3785 #endif // __REGISTERS_HPP__
3786