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