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_HEXAGON,
38 REGISTERS_RISCV,
39 REGISTERS_VE,
40 };
41
42 #if defined(_LIBUNWIND_TARGET_I386)
43 class _LIBUNWIND_HIDDEN Registers_x86;
44 extern "C" void __libunwind_Registers_x86_jumpto(Registers_x86 *);
45 /// Registers_x86 holds the register state of a thread in a 32-bit intel
46 /// process.
47 class _LIBUNWIND_HIDDEN Registers_x86 {
48 public:
49 Registers_x86();
50 Registers_x86(const void *registers);
51
52 bool validRegister(int num) const;
53 uint32_t getRegister(int num) const;
54 void setRegister(int num, uint32_t value);
validFloatRegister(int) const55 bool validFloatRegister(int) const { return false; }
56 double getFloatRegister(int num) const;
57 void setFloatRegister(int num, double value);
validVectorRegister(int) const58 bool validVectorRegister(int) const { return false; }
59 v128 getVectorRegister(int num) const;
60 void setVectorRegister(int num, v128 value);
61 static const char *getRegisterName(int num);
jumpto()62 void jumpto() { __libunwind_Registers_x86_jumpto(this); }
lastDwarfRegNum()63 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86; }
getArch()64 static int getArch() { return REGISTERS_X86; }
65
getSP() const66 uint32_t getSP() const { return _registers.__esp; }
setSP(uint32_t value)67 void setSP(uint32_t value) { _registers.__esp = value; }
getIP() const68 uint32_t getIP() const { return _registers.__eip; }
setIP(uint32_t value)69 void setIP(uint32_t value) { _registers.__eip = value; }
getEBP() const70 uint32_t getEBP() const { return _registers.__ebp; }
setEBP(uint32_t value)71 void setEBP(uint32_t value) { _registers.__ebp = value; }
getEBX() const72 uint32_t getEBX() const { return _registers.__ebx; }
setEBX(uint32_t value)73 void setEBX(uint32_t value) { _registers.__ebx = value; }
getECX() const74 uint32_t getECX() const { return _registers.__ecx; }
setECX(uint32_t value)75 void setECX(uint32_t value) { _registers.__ecx = value; }
getEDX() const76 uint32_t getEDX() const { return _registers.__edx; }
setEDX(uint32_t value)77 void setEDX(uint32_t value) { _registers.__edx = value; }
getESI() const78 uint32_t getESI() const { return _registers.__esi; }
setESI(uint32_t value)79 void setESI(uint32_t value) { _registers.__esi = value; }
getEDI() const80 uint32_t getEDI() const { return _registers.__edi; }
setEDI(uint32_t value)81 void setEDI(uint32_t value) { _registers.__edi = value; }
82
83 private:
84 struct GPRs {
85 unsigned int __eax;
86 unsigned int __ebx;
87 unsigned int __ecx;
88 unsigned int __edx;
89 unsigned int __edi;
90 unsigned int __esi;
91 unsigned int __ebp;
92 unsigned int __esp;
93 unsigned int __ss;
94 unsigned int __eflags;
95 unsigned int __eip;
96 unsigned int __cs;
97 unsigned int __ds;
98 unsigned int __es;
99 unsigned int __fs;
100 unsigned int __gs;
101 };
102
103 GPRs _registers;
104 };
105
Registers_x86(const void * registers)106 inline Registers_x86::Registers_x86(const void *registers) {
107 static_assert((check_fit<Registers_x86, unw_context_t>::does_fit),
108 "x86 registers do not fit into unw_context_t");
109 memcpy(&_registers, registers, sizeof(_registers));
110 }
111
Registers_x86()112 inline Registers_x86::Registers_x86() {
113 memset(&_registers, 0, sizeof(_registers));
114 }
115
validRegister(int regNum) const116 inline bool Registers_x86::validRegister(int regNum) const {
117 if (regNum == UNW_REG_IP)
118 return true;
119 if (regNum == UNW_REG_SP)
120 return true;
121 if (regNum < 0)
122 return false;
123 if (regNum > 7)
124 return false;
125 return true;
126 }
127
getRegister(int regNum) const128 inline uint32_t Registers_x86::getRegister(int regNum) const {
129 switch (regNum) {
130 case UNW_REG_IP:
131 return _registers.__eip;
132 case UNW_REG_SP:
133 return _registers.__esp;
134 case UNW_X86_EAX:
135 return _registers.__eax;
136 case UNW_X86_ECX:
137 return _registers.__ecx;
138 case UNW_X86_EDX:
139 return _registers.__edx;
140 case UNW_X86_EBX:
141 return _registers.__ebx;
142 #if !defined(__APPLE__)
143 case UNW_X86_ESP:
144 #else
145 case UNW_X86_EBP:
146 #endif
147 return _registers.__ebp;
148 #if !defined(__APPLE__)
149 case UNW_X86_EBP:
150 #else
151 case UNW_X86_ESP:
152 #endif
153 return _registers.__esp;
154 case UNW_X86_ESI:
155 return _registers.__esi;
156 case UNW_X86_EDI:
157 return _registers.__edi;
158 }
159 _LIBUNWIND_ABORT("unsupported x86 register");
160 }
161
setRegister(int regNum,uint32_t value)162 inline void Registers_x86::setRegister(int regNum, uint32_t value) {
163 switch (regNum) {
164 case UNW_REG_IP:
165 _registers.__eip = value;
166 return;
167 case UNW_REG_SP:
168 _registers.__esp = value;
169 return;
170 case UNW_X86_EAX:
171 _registers.__eax = value;
172 return;
173 case UNW_X86_ECX:
174 _registers.__ecx = value;
175 return;
176 case UNW_X86_EDX:
177 _registers.__edx = value;
178 return;
179 case UNW_X86_EBX:
180 _registers.__ebx = value;
181 return;
182 #if !defined(__APPLE__)
183 case UNW_X86_ESP:
184 #else
185 case UNW_X86_EBP:
186 #endif
187 _registers.__ebp = value;
188 return;
189 #if !defined(__APPLE__)
190 case UNW_X86_EBP:
191 #else
192 case UNW_X86_ESP:
193 #endif
194 _registers.__esp = value;
195 return;
196 case UNW_X86_ESI:
197 _registers.__esi = value;
198 return;
199 case UNW_X86_EDI:
200 _registers.__edi = value;
201 return;
202 }
203 _LIBUNWIND_ABORT("unsupported x86 register");
204 }
205
getRegisterName(int regNum)206 inline const char *Registers_x86::getRegisterName(int regNum) {
207 switch (regNum) {
208 case UNW_REG_IP:
209 return "ip";
210 case UNW_REG_SP:
211 return "esp";
212 case UNW_X86_EAX:
213 return "eax";
214 case UNW_X86_ECX:
215 return "ecx";
216 case UNW_X86_EDX:
217 return "edx";
218 case UNW_X86_EBX:
219 return "ebx";
220 case UNW_X86_EBP:
221 return "ebp";
222 case UNW_X86_ESP:
223 return "esp";
224 case UNW_X86_ESI:
225 return "esi";
226 case UNW_X86_EDI:
227 return "edi";
228 default:
229 return "unknown register";
230 }
231 }
232
getFloatRegister(int) const233 inline double Registers_x86::getFloatRegister(int) const {
234 _LIBUNWIND_ABORT("no x86 float registers");
235 }
236
setFloatRegister(int,double)237 inline void Registers_x86::setFloatRegister(int, double) {
238 _LIBUNWIND_ABORT("no x86 float registers");
239 }
240
getVectorRegister(int) const241 inline v128 Registers_x86::getVectorRegister(int) const {
242 _LIBUNWIND_ABORT("no x86 vector registers");
243 }
244
setVectorRegister(int,v128)245 inline void Registers_x86::setVectorRegister(int, v128) {
246 _LIBUNWIND_ABORT("no x86 vector registers");
247 }
248 #endif // _LIBUNWIND_TARGET_I386
249
250
251 #if defined(_LIBUNWIND_TARGET_X86_64)
252 /// Registers_x86_64 holds the register state of a thread in a 64-bit intel
253 /// process.
254 class _LIBUNWIND_HIDDEN Registers_x86_64;
255 extern "C" void __libunwind_Registers_x86_64_jumpto(Registers_x86_64 *);
256 class _LIBUNWIND_HIDDEN Registers_x86_64 {
257 public:
258 Registers_x86_64();
259 Registers_x86_64(const void *registers);
260
261 bool validRegister(int num) const;
262 uint64_t getRegister(int num) const;
263 void setRegister(int num, uint64_t value);
validFloatRegister(int) const264 bool validFloatRegister(int) const { return false; }
265 double getFloatRegister(int num) const;
266 void setFloatRegister(int num, double value);
267 bool validVectorRegister(int) const;
268 v128 getVectorRegister(int num) const;
269 void setVectorRegister(int num, v128 value);
270 static const char *getRegisterName(int num);
jumpto()271 void jumpto() { __libunwind_Registers_x86_64_jumpto(this); }
lastDwarfRegNum()272 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64; }
getArch()273 static int getArch() { return REGISTERS_X86_64; }
274
getSP() const275 uint64_t getSP() const { return _registers.__rsp; }
setSP(uint64_t value)276 void setSP(uint64_t value) { _registers.__rsp = value; }
getIP() const277 uint64_t getIP() const { return _registers.__rip; }
setIP(uint64_t value)278 void setIP(uint64_t value) { _registers.__rip = value; }
getRBP() const279 uint64_t getRBP() const { return _registers.__rbp; }
setRBP(uint64_t value)280 void setRBP(uint64_t value) { _registers.__rbp = value; }
getRBX() const281 uint64_t getRBX() const { return _registers.__rbx; }
setRBX(uint64_t value)282 void setRBX(uint64_t value) { _registers.__rbx = value; }
getR12() const283 uint64_t getR12() const { return _registers.__r12; }
setR12(uint64_t value)284 void setR12(uint64_t value) { _registers.__r12 = value; }
getR13() const285 uint64_t getR13() const { return _registers.__r13; }
setR13(uint64_t value)286 void setR13(uint64_t value) { _registers.__r13 = value; }
getR14() const287 uint64_t getR14() const { return _registers.__r14; }
setR14(uint64_t value)288 void setR14(uint64_t value) { _registers.__r14 = value; }
getR15() const289 uint64_t getR15() const { return _registers.__r15; }
setR15(uint64_t value)290 void setR15(uint64_t value) { _registers.__r15 = value; }
291
292 private:
293 struct GPRs {
294 uint64_t __rax;
295 uint64_t __rbx;
296 uint64_t __rcx;
297 uint64_t __rdx;
298 uint64_t __rdi;
299 uint64_t __rsi;
300 uint64_t __rbp;
301 uint64_t __rsp;
302 uint64_t __r8;
303 uint64_t __r9;
304 uint64_t __r10;
305 uint64_t __r11;
306 uint64_t __r12;
307 uint64_t __r13;
308 uint64_t __r14;
309 uint64_t __r15;
310 uint64_t __rip;
311 uint64_t __rflags;
312 uint64_t __cs;
313 uint64_t __fs;
314 uint64_t __gs;
315 #if defined(_WIN64)
316 uint64_t __padding; // 16-byte align
317 #endif
318 };
319 GPRs _registers;
320 #if defined(_WIN64)
321 v128 _xmm[16];
322 #endif
323 };
324
Registers_x86_64(const void * registers)325 inline Registers_x86_64::Registers_x86_64(const void *registers) {
326 static_assert((check_fit<Registers_x86_64, unw_context_t>::does_fit),
327 "x86_64 registers do not fit into unw_context_t");
328 memcpy(&_registers, registers, sizeof(_registers));
329 }
330
Registers_x86_64()331 inline Registers_x86_64::Registers_x86_64() {
332 memset(&_registers, 0, sizeof(_registers));
333 }
334
validRegister(int regNum) const335 inline bool Registers_x86_64::validRegister(int regNum) const {
336 if (regNum == UNW_REG_IP)
337 return true;
338 if (regNum == UNW_REG_SP)
339 return true;
340 if (regNum < 0)
341 return false;
342 if (regNum > 15)
343 return false;
344 return true;
345 }
346
getRegister(int regNum) const347 inline uint64_t Registers_x86_64::getRegister(int regNum) const {
348 switch (regNum) {
349 case UNW_REG_IP:
350 return _registers.__rip;
351 case UNW_REG_SP:
352 return _registers.__rsp;
353 case UNW_X86_64_RAX:
354 return _registers.__rax;
355 case UNW_X86_64_RDX:
356 return _registers.__rdx;
357 case UNW_X86_64_RCX:
358 return _registers.__rcx;
359 case UNW_X86_64_RBX:
360 return _registers.__rbx;
361 case UNW_X86_64_RSI:
362 return _registers.__rsi;
363 case UNW_X86_64_RDI:
364 return _registers.__rdi;
365 case UNW_X86_64_RBP:
366 return _registers.__rbp;
367 case UNW_X86_64_RSP:
368 return _registers.__rsp;
369 case UNW_X86_64_R8:
370 return _registers.__r8;
371 case UNW_X86_64_R9:
372 return _registers.__r9;
373 case UNW_X86_64_R10:
374 return _registers.__r10;
375 case UNW_X86_64_R11:
376 return _registers.__r11;
377 case UNW_X86_64_R12:
378 return _registers.__r12;
379 case UNW_X86_64_R13:
380 return _registers.__r13;
381 case UNW_X86_64_R14:
382 return _registers.__r14;
383 case UNW_X86_64_R15:
384 return _registers.__r15;
385 }
386 _LIBUNWIND_ABORT("unsupported x86_64 register");
387 }
388
setRegister(int regNum,uint64_t value)389 inline void Registers_x86_64::setRegister(int regNum, uint64_t value) {
390 switch (regNum) {
391 case UNW_REG_IP:
392 _registers.__rip = value;
393 return;
394 case UNW_REG_SP:
395 _registers.__rsp = value;
396 return;
397 case UNW_X86_64_RAX:
398 _registers.__rax = value;
399 return;
400 case UNW_X86_64_RDX:
401 _registers.__rdx = value;
402 return;
403 case UNW_X86_64_RCX:
404 _registers.__rcx = value;
405 return;
406 case UNW_X86_64_RBX:
407 _registers.__rbx = value;
408 return;
409 case UNW_X86_64_RSI:
410 _registers.__rsi = value;
411 return;
412 case UNW_X86_64_RDI:
413 _registers.__rdi = value;
414 return;
415 case UNW_X86_64_RBP:
416 _registers.__rbp = value;
417 return;
418 case UNW_X86_64_RSP:
419 _registers.__rsp = value;
420 return;
421 case UNW_X86_64_R8:
422 _registers.__r8 = value;
423 return;
424 case UNW_X86_64_R9:
425 _registers.__r9 = value;
426 return;
427 case UNW_X86_64_R10:
428 _registers.__r10 = value;
429 return;
430 case UNW_X86_64_R11:
431 _registers.__r11 = value;
432 return;
433 case UNW_X86_64_R12:
434 _registers.__r12 = value;
435 return;
436 case UNW_X86_64_R13:
437 _registers.__r13 = value;
438 return;
439 case UNW_X86_64_R14:
440 _registers.__r14 = value;
441 return;
442 case UNW_X86_64_R15:
443 _registers.__r15 = value;
444 return;
445 }
446 _LIBUNWIND_ABORT("unsupported x86_64 register");
447 }
448
getRegisterName(int regNum)449 inline const char *Registers_x86_64::getRegisterName(int regNum) {
450 switch (regNum) {
451 case UNW_REG_IP:
452 return "rip";
453 case UNW_REG_SP:
454 return "rsp";
455 case UNW_X86_64_RAX:
456 return "rax";
457 case UNW_X86_64_RDX:
458 return "rdx";
459 case UNW_X86_64_RCX:
460 return "rcx";
461 case UNW_X86_64_RBX:
462 return "rbx";
463 case UNW_X86_64_RSI:
464 return "rsi";
465 case UNW_X86_64_RDI:
466 return "rdi";
467 case UNW_X86_64_RBP:
468 return "rbp";
469 case UNW_X86_64_RSP:
470 return "rsp";
471 case UNW_X86_64_R8:
472 return "r8";
473 case UNW_X86_64_R9:
474 return "r9";
475 case UNW_X86_64_R10:
476 return "r10";
477 case UNW_X86_64_R11:
478 return "r11";
479 case UNW_X86_64_R12:
480 return "r12";
481 case UNW_X86_64_R13:
482 return "r13";
483 case UNW_X86_64_R14:
484 return "r14";
485 case UNW_X86_64_R15:
486 return "r15";
487 case UNW_X86_64_XMM0:
488 return "xmm0";
489 case UNW_X86_64_XMM1:
490 return "xmm1";
491 case UNW_X86_64_XMM2:
492 return "xmm2";
493 case UNW_X86_64_XMM3:
494 return "xmm3";
495 case UNW_X86_64_XMM4:
496 return "xmm4";
497 case UNW_X86_64_XMM5:
498 return "xmm5";
499 case UNW_X86_64_XMM6:
500 return "xmm6";
501 case UNW_X86_64_XMM7:
502 return "xmm7";
503 case UNW_X86_64_XMM8:
504 return "xmm8";
505 case UNW_X86_64_XMM9:
506 return "xmm9";
507 case UNW_X86_64_XMM10:
508 return "xmm10";
509 case UNW_X86_64_XMM11:
510 return "xmm11";
511 case UNW_X86_64_XMM12:
512 return "xmm12";
513 case UNW_X86_64_XMM13:
514 return "xmm13";
515 case UNW_X86_64_XMM14:
516 return "xmm14";
517 case UNW_X86_64_XMM15:
518 return "xmm15";
519 default:
520 return "unknown register";
521 }
522 }
523
getFloatRegister(int) const524 inline double Registers_x86_64::getFloatRegister(int) const {
525 _LIBUNWIND_ABORT("no x86_64 float registers");
526 }
527
setFloatRegister(int,double)528 inline void Registers_x86_64::setFloatRegister(int, double) {
529 _LIBUNWIND_ABORT("no x86_64 float registers");
530 }
531
validVectorRegister(int regNum) const532 inline bool Registers_x86_64::validVectorRegister(int regNum) const {
533 #if defined(_WIN64)
534 if (regNum < UNW_X86_64_XMM0)
535 return false;
536 if (regNum > UNW_X86_64_XMM15)
537 return false;
538 return true;
539 #else
540 (void)regNum; // suppress unused parameter warning
541 return false;
542 #endif
543 }
544
getVectorRegister(int regNum) const545 inline v128 Registers_x86_64::getVectorRegister(int regNum) const {
546 #if defined(_WIN64)
547 assert(validVectorRegister(regNum));
548 return _xmm[regNum - UNW_X86_64_XMM0];
549 #else
550 (void)regNum; // suppress unused parameter warning
551 _LIBUNWIND_ABORT("no x86_64 vector registers");
552 #endif
553 }
554
setVectorRegister(int regNum,v128 value)555 inline void Registers_x86_64::setVectorRegister(int regNum, v128 value) {
556 #if defined(_WIN64)
557 assert(validVectorRegister(regNum));
558 _xmm[regNum - UNW_X86_64_XMM0] = value;
559 #else
560 (void)regNum; (void)value; // suppress unused parameter warnings
561 _LIBUNWIND_ABORT("no x86_64 vector registers");
562 #endif
563 }
564 #endif // _LIBUNWIND_TARGET_X86_64
565
566
567 #if defined(_LIBUNWIND_TARGET_PPC)
568 /// Registers_ppc holds the register state of a thread in a 32-bit PowerPC
569 /// process.
570 class _LIBUNWIND_HIDDEN Registers_ppc {
571 public:
572 Registers_ppc();
573 Registers_ppc(const void *registers);
574
575 bool validRegister(int num) const;
576 uint32_t getRegister(int num) const;
577 void setRegister(int num, uint32_t value);
578 bool validFloatRegister(int num) const;
579 double getFloatRegister(int num) const;
580 void setFloatRegister(int num, double value);
581 bool validVectorRegister(int num) const;
582 v128 getVectorRegister(int num) const;
583 void setVectorRegister(int num, v128 value);
584 static const char *getRegisterName(int num);
585 void jumpto();
lastDwarfRegNum()586 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC; }
getArch()587 static int getArch() { return REGISTERS_PPC; }
588
getSP() const589 uint64_t getSP() const { return _registers.__r1; }
setSP(uint32_t value)590 void setSP(uint32_t value) { _registers.__r1 = value; }
getIP() const591 uint64_t getIP() const { return _registers.__srr0; }
setIP(uint32_t value)592 void setIP(uint32_t value) { _registers.__srr0 = value; }
593
594 private:
595 struct ppc_thread_state_t {
596 unsigned int __srr0; /* Instruction address register (PC) */
597 unsigned int __srr1; /* Machine state register (supervisor) */
598 unsigned int __r0;
599 unsigned int __r1;
600 unsigned int __r2;
601 unsigned int __r3;
602 unsigned int __r4;
603 unsigned int __r5;
604 unsigned int __r6;
605 unsigned int __r7;
606 unsigned int __r8;
607 unsigned int __r9;
608 unsigned int __r10;
609 unsigned int __r11;
610 unsigned int __r12;
611 unsigned int __r13;
612 unsigned int __r14;
613 unsigned int __r15;
614 unsigned int __r16;
615 unsigned int __r17;
616 unsigned int __r18;
617 unsigned int __r19;
618 unsigned int __r20;
619 unsigned int __r21;
620 unsigned int __r22;
621 unsigned int __r23;
622 unsigned int __r24;
623 unsigned int __r25;
624 unsigned int __r26;
625 unsigned int __r27;
626 unsigned int __r28;
627 unsigned int __r29;
628 unsigned int __r30;
629 unsigned int __r31;
630 unsigned int __cr; /* Condition register */
631 unsigned int __xer; /* User's integer exception register */
632 unsigned int __lr; /* Link register */
633 unsigned int __ctr; /* Count register */
634 unsigned int __mq; /* MQ register (601 only) */
635 unsigned int __vrsave; /* Vector Save Register */
636 };
637
638 struct ppc_float_state_t {
639 double __fpregs[32];
640
641 unsigned int __fpscr_pad; /* fpscr is 64 bits, 32 bits of rubbish */
642 unsigned int __fpscr; /* floating point status register */
643 };
644
645 ppc_thread_state_t _registers;
646 ppc_float_state_t _floatRegisters;
647 v128 _vectorRegisters[32]; // offset 424
648 };
649
Registers_ppc(const void * registers)650 inline Registers_ppc::Registers_ppc(const void *registers) {
651 static_assert((check_fit<Registers_ppc, unw_context_t>::does_fit),
652 "ppc registers do not fit into unw_context_t");
653 memcpy(&_registers, static_cast<const uint8_t *>(registers),
654 sizeof(_registers));
655 static_assert(sizeof(ppc_thread_state_t) == 160,
656 "expected float register offset to be 160");
657 memcpy(&_floatRegisters,
658 static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t),
659 sizeof(_floatRegisters));
660 static_assert(sizeof(ppc_thread_state_t) + sizeof(ppc_float_state_t) == 424,
661 "expected vector register offset to be 424 bytes");
662 memcpy(_vectorRegisters,
663 static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t) +
664 sizeof(ppc_float_state_t),
665 sizeof(_vectorRegisters));
666 }
667
Registers_ppc()668 inline Registers_ppc::Registers_ppc() {
669 memset(&_registers, 0, sizeof(_registers));
670 memset(&_floatRegisters, 0, sizeof(_floatRegisters));
671 memset(&_vectorRegisters, 0, sizeof(_vectorRegisters));
672 }
673
validRegister(int regNum) const674 inline bool Registers_ppc::validRegister(int regNum) const {
675 if (regNum == UNW_REG_IP)
676 return true;
677 if (regNum == UNW_REG_SP)
678 return true;
679 if (regNum == UNW_PPC_VRSAVE)
680 return true;
681 if (regNum < 0)
682 return false;
683 if (regNum <= UNW_PPC_R31)
684 return true;
685 if (regNum == UNW_PPC_MQ)
686 return true;
687 if (regNum == UNW_PPC_LR)
688 return true;
689 if (regNum == UNW_PPC_CTR)
690 return true;
691 if ((UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7))
692 return true;
693 return false;
694 }
695
getRegister(int regNum) const696 inline uint32_t Registers_ppc::getRegister(int regNum) const {
697 switch (regNum) {
698 case UNW_REG_IP:
699 return _registers.__srr0;
700 case UNW_REG_SP:
701 return _registers.__r1;
702 case UNW_PPC_R0:
703 return _registers.__r0;
704 case UNW_PPC_R1:
705 return _registers.__r1;
706 case UNW_PPC_R2:
707 return _registers.__r2;
708 case UNW_PPC_R3:
709 return _registers.__r3;
710 case UNW_PPC_R4:
711 return _registers.__r4;
712 case UNW_PPC_R5:
713 return _registers.__r5;
714 case UNW_PPC_R6:
715 return _registers.__r6;
716 case UNW_PPC_R7:
717 return _registers.__r7;
718 case UNW_PPC_R8:
719 return _registers.__r8;
720 case UNW_PPC_R9:
721 return _registers.__r9;
722 case UNW_PPC_R10:
723 return _registers.__r10;
724 case UNW_PPC_R11:
725 return _registers.__r11;
726 case UNW_PPC_R12:
727 return _registers.__r12;
728 case UNW_PPC_R13:
729 return _registers.__r13;
730 case UNW_PPC_R14:
731 return _registers.__r14;
732 case UNW_PPC_R15:
733 return _registers.__r15;
734 case UNW_PPC_R16:
735 return _registers.__r16;
736 case UNW_PPC_R17:
737 return _registers.__r17;
738 case UNW_PPC_R18:
739 return _registers.__r18;
740 case UNW_PPC_R19:
741 return _registers.__r19;
742 case UNW_PPC_R20:
743 return _registers.__r20;
744 case UNW_PPC_R21:
745 return _registers.__r21;
746 case UNW_PPC_R22:
747 return _registers.__r22;
748 case UNW_PPC_R23:
749 return _registers.__r23;
750 case UNW_PPC_R24:
751 return _registers.__r24;
752 case UNW_PPC_R25:
753 return _registers.__r25;
754 case UNW_PPC_R26:
755 return _registers.__r26;
756 case UNW_PPC_R27:
757 return _registers.__r27;
758 case UNW_PPC_R28:
759 return _registers.__r28;
760 case UNW_PPC_R29:
761 return _registers.__r29;
762 case UNW_PPC_R30:
763 return _registers.__r30;
764 case UNW_PPC_R31:
765 return _registers.__r31;
766 case UNW_PPC_LR:
767 return _registers.__lr;
768 case UNW_PPC_CR0:
769 return (_registers.__cr & 0xF0000000);
770 case UNW_PPC_CR1:
771 return (_registers.__cr & 0x0F000000);
772 case UNW_PPC_CR2:
773 return (_registers.__cr & 0x00F00000);
774 case UNW_PPC_CR3:
775 return (_registers.__cr & 0x000F0000);
776 case UNW_PPC_CR4:
777 return (_registers.__cr & 0x0000F000);
778 case UNW_PPC_CR5:
779 return (_registers.__cr & 0x00000F00);
780 case UNW_PPC_CR6:
781 return (_registers.__cr & 0x000000F0);
782 case UNW_PPC_CR7:
783 return (_registers.__cr & 0x0000000F);
784 case UNW_PPC_VRSAVE:
785 return _registers.__vrsave;
786 }
787 _LIBUNWIND_ABORT("unsupported ppc register");
788 }
789
setRegister(int regNum,uint32_t value)790 inline void Registers_ppc::setRegister(int regNum, uint32_t value) {
791 //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value);
792 switch (regNum) {
793 case UNW_REG_IP:
794 _registers.__srr0 = value;
795 return;
796 case UNW_REG_SP:
797 _registers.__r1 = value;
798 return;
799 case UNW_PPC_R0:
800 _registers.__r0 = value;
801 return;
802 case UNW_PPC_R1:
803 _registers.__r1 = value;
804 return;
805 case UNW_PPC_R2:
806 _registers.__r2 = value;
807 return;
808 case UNW_PPC_R3:
809 _registers.__r3 = value;
810 return;
811 case UNW_PPC_R4:
812 _registers.__r4 = value;
813 return;
814 case UNW_PPC_R5:
815 _registers.__r5 = value;
816 return;
817 case UNW_PPC_R6:
818 _registers.__r6 = value;
819 return;
820 case UNW_PPC_R7:
821 _registers.__r7 = value;
822 return;
823 case UNW_PPC_R8:
824 _registers.__r8 = value;
825 return;
826 case UNW_PPC_R9:
827 _registers.__r9 = value;
828 return;
829 case UNW_PPC_R10:
830 _registers.__r10 = value;
831 return;
832 case UNW_PPC_R11:
833 _registers.__r11 = value;
834 return;
835 case UNW_PPC_R12:
836 _registers.__r12 = value;
837 return;
838 case UNW_PPC_R13:
839 _registers.__r13 = value;
840 return;
841 case UNW_PPC_R14:
842 _registers.__r14 = value;
843 return;
844 case UNW_PPC_R15:
845 _registers.__r15 = value;
846 return;
847 case UNW_PPC_R16:
848 _registers.__r16 = value;
849 return;
850 case UNW_PPC_R17:
851 _registers.__r17 = value;
852 return;
853 case UNW_PPC_R18:
854 _registers.__r18 = value;
855 return;
856 case UNW_PPC_R19:
857 _registers.__r19 = value;
858 return;
859 case UNW_PPC_R20:
860 _registers.__r20 = value;
861 return;
862 case UNW_PPC_R21:
863 _registers.__r21 = value;
864 return;
865 case UNW_PPC_R22:
866 _registers.__r22 = value;
867 return;
868 case UNW_PPC_R23:
869 _registers.__r23 = value;
870 return;
871 case UNW_PPC_R24:
872 _registers.__r24 = value;
873 return;
874 case UNW_PPC_R25:
875 _registers.__r25 = value;
876 return;
877 case UNW_PPC_R26:
878 _registers.__r26 = value;
879 return;
880 case UNW_PPC_R27:
881 _registers.__r27 = value;
882 return;
883 case UNW_PPC_R28:
884 _registers.__r28 = value;
885 return;
886 case UNW_PPC_R29:
887 _registers.__r29 = value;
888 return;
889 case UNW_PPC_R30:
890 _registers.__r30 = value;
891 return;
892 case UNW_PPC_R31:
893 _registers.__r31 = value;
894 return;
895 case UNW_PPC_MQ:
896 _registers.__mq = value;
897 return;
898 case UNW_PPC_LR:
899 _registers.__lr = value;
900 return;
901 case UNW_PPC_CTR:
902 _registers.__ctr = value;
903 return;
904 case UNW_PPC_CR0:
905 _registers.__cr &= 0x0FFFFFFF;
906 _registers.__cr |= (value & 0xF0000000);
907 return;
908 case UNW_PPC_CR1:
909 _registers.__cr &= 0xF0FFFFFF;
910 _registers.__cr |= (value & 0x0F000000);
911 return;
912 case UNW_PPC_CR2:
913 _registers.__cr &= 0xFF0FFFFF;
914 _registers.__cr |= (value & 0x00F00000);
915 return;
916 case UNW_PPC_CR3:
917 _registers.__cr &= 0xFFF0FFFF;
918 _registers.__cr |= (value & 0x000F0000);
919 return;
920 case UNW_PPC_CR4:
921 _registers.__cr &= 0xFFFF0FFF;
922 _registers.__cr |= (value & 0x0000F000);
923 return;
924 case UNW_PPC_CR5:
925 _registers.__cr &= 0xFFFFF0FF;
926 _registers.__cr |= (value & 0x00000F00);
927 return;
928 case UNW_PPC_CR6:
929 _registers.__cr &= 0xFFFFFF0F;
930 _registers.__cr |= (value & 0x000000F0);
931 return;
932 case UNW_PPC_CR7:
933 _registers.__cr &= 0xFFFFFFF0;
934 _registers.__cr |= (value & 0x0000000F);
935 return;
936 case UNW_PPC_VRSAVE:
937 _registers.__vrsave = value;
938 return;
939 // not saved
940 return;
941 case UNW_PPC_XER:
942 _registers.__xer = value;
943 return;
944 case UNW_PPC_AP:
945 case UNW_PPC_VSCR:
946 case UNW_PPC_SPEFSCR:
947 // not saved
948 return;
949 }
950 _LIBUNWIND_ABORT("unsupported ppc register");
951 }
952
validFloatRegister(int regNum) const953 inline bool Registers_ppc::validFloatRegister(int regNum) const {
954 if (regNum < UNW_PPC_F0)
955 return false;
956 if (regNum > UNW_PPC_F31)
957 return false;
958 return true;
959 }
960
getFloatRegister(int regNum) const961 inline double Registers_ppc::getFloatRegister(int regNum) const {
962 assert(validFloatRegister(regNum));
963 return _floatRegisters.__fpregs[regNum - UNW_PPC_F0];
964 }
965
setFloatRegister(int regNum,double value)966 inline void Registers_ppc::setFloatRegister(int regNum, double value) {
967 assert(validFloatRegister(regNum));
968 _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value;
969 }
970
validVectorRegister(int regNum) const971 inline bool Registers_ppc::validVectorRegister(int regNum) const {
972 if (regNum < UNW_PPC_V0)
973 return false;
974 if (regNum > UNW_PPC_V31)
975 return false;
976 return true;
977 }
978
getVectorRegister(int regNum) const979 inline v128 Registers_ppc::getVectorRegister(int regNum) const {
980 assert(validVectorRegister(regNum));
981 v128 result = _vectorRegisters[regNum - UNW_PPC_V0];
982 return result;
983 }
984
setVectorRegister(int regNum,v128 value)985 inline void Registers_ppc::setVectorRegister(int regNum, v128 value) {
986 assert(validVectorRegister(regNum));
987 _vectorRegisters[regNum - UNW_PPC_V0] = value;
988 }
989
getRegisterName(int regNum)990 inline const char *Registers_ppc::getRegisterName(int regNum) {
991 switch (regNum) {
992 case UNW_REG_IP:
993 return "ip";
994 case UNW_REG_SP:
995 return "sp";
996 case UNW_PPC_R0:
997 return "r0";
998 case UNW_PPC_R1:
999 return "r1";
1000 case UNW_PPC_R2:
1001 return "r2";
1002 case UNW_PPC_R3:
1003 return "r3";
1004 case UNW_PPC_R4:
1005 return "r4";
1006 case UNW_PPC_R5:
1007 return "r5";
1008 case UNW_PPC_R6:
1009 return "r6";
1010 case UNW_PPC_R7:
1011 return "r7";
1012 case UNW_PPC_R8:
1013 return "r8";
1014 case UNW_PPC_R9:
1015 return "r9";
1016 case UNW_PPC_R10:
1017 return "r10";
1018 case UNW_PPC_R11:
1019 return "r11";
1020 case UNW_PPC_R12:
1021 return "r12";
1022 case UNW_PPC_R13:
1023 return "r13";
1024 case UNW_PPC_R14:
1025 return "r14";
1026 case UNW_PPC_R15:
1027 return "r15";
1028 case UNW_PPC_R16:
1029 return "r16";
1030 case UNW_PPC_R17:
1031 return "r17";
1032 case UNW_PPC_R18:
1033 return "r18";
1034 case UNW_PPC_R19:
1035 return "r19";
1036 case UNW_PPC_R20:
1037 return "r20";
1038 case UNW_PPC_R21:
1039 return "r21";
1040 case UNW_PPC_R22:
1041 return "r22";
1042 case UNW_PPC_R23:
1043 return "r23";
1044 case UNW_PPC_R24:
1045 return "r24";
1046 case UNW_PPC_R25:
1047 return "r25";
1048 case UNW_PPC_R26:
1049 return "r26";
1050 case UNW_PPC_R27:
1051 return "r27";
1052 case UNW_PPC_R28:
1053 return "r28";
1054 case UNW_PPC_R29:
1055 return "r29";
1056 case UNW_PPC_R30:
1057 return "r30";
1058 case UNW_PPC_R31:
1059 return "r31";
1060 case UNW_PPC_F0:
1061 return "fp0";
1062 case UNW_PPC_F1:
1063 return "fp1";
1064 case UNW_PPC_F2:
1065 return "fp2";
1066 case UNW_PPC_F3:
1067 return "fp3";
1068 case UNW_PPC_F4:
1069 return "fp4";
1070 case UNW_PPC_F5:
1071 return "fp5";
1072 case UNW_PPC_F6:
1073 return "fp6";
1074 case UNW_PPC_F7:
1075 return "fp7";
1076 case UNW_PPC_F8:
1077 return "fp8";
1078 case UNW_PPC_F9:
1079 return "fp9";
1080 case UNW_PPC_F10:
1081 return "fp10";
1082 case UNW_PPC_F11:
1083 return "fp11";
1084 case UNW_PPC_F12:
1085 return "fp12";
1086 case UNW_PPC_F13:
1087 return "fp13";
1088 case UNW_PPC_F14:
1089 return "fp14";
1090 case UNW_PPC_F15:
1091 return "fp15";
1092 case UNW_PPC_F16:
1093 return "fp16";
1094 case UNW_PPC_F17:
1095 return "fp17";
1096 case UNW_PPC_F18:
1097 return "fp18";
1098 case UNW_PPC_F19:
1099 return "fp19";
1100 case UNW_PPC_F20:
1101 return "fp20";
1102 case UNW_PPC_F21:
1103 return "fp21";
1104 case UNW_PPC_F22:
1105 return "fp22";
1106 case UNW_PPC_F23:
1107 return "fp23";
1108 case UNW_PPC_F24:
1109 return "fp24";
1110 case UNW_PPC_F25:
1111 return "fp25";
1112 case UNW_PPC_F26:
1113 return "fp26";
1114 case UNW_PPC_F27:
1115 return "fp27";
1116 case UNW_PPC_F28:
1117 return "fp28";
1118 case UNW_PPC_F29:
1119 return "fp29";
1120 case UNW_PPC_F30:
1121 return "fp30";
1122 case UNW_PPC_F31:
1123 return "fp31";
1124 case UNW_PPC_LR:
1125 return "lr";
1126 default:
1127 return "unknown register";
1128 }
1129
1130 }
1131 #endif // _LIBUNWIND_TARGET_PPC
1132
1133 #if defined(_LIBUNWIND_TARGET_PPC64)
1134 /// Registers_ppc64 holds the register state of a thread in a 64-bit PowerPC
1135 /// process.
1136 class _LIBUNWIND_HIDDEN Registers_ppc64 {
1137 public:
1138 Registers_ppc64();
1139 Registers_ppc64(const void *registers);
1140
1141 bool validRegister(int num) const;
1142 uint64_t getRegister(int num) const;
1143 void setRegister(int num, uint64_t value);
1144 bool validFloatRegister(int num) const;
1145 double getFloatRegister(int num) const;
1146 void setFloatRegister(int num, double value);
1147 bool validVectorRegister(int num) const;
1148 v128 getVectorRegister(int num) const;
1149 void setVectorRegister(int num, v128 value);
1150 static const char *getRegisterName(int num);
1151 void jumpto();
lastDwarfRegNum()1152 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64; }
getArch()1153 static int getArch() { return REGISTERS_PPC64; }
1154
getSP() const1155 uint64_t getSP() const { return _registers.__r1; }
setSP(uint64_t value)1156 void setSP(uint64_t value) { _registers.__r1 = value; }
getIP() const1157 uint64_t getIP() const { return _registers.__srr0; }
setIP(uint64_t value)1158 void setIP(uint64_t value) { _registers.__srr0 = value; }
1159
1160 private:
1161 struct ppc64_thread_state_t {
1162 uint64_t __srr0; // Instruction address register (PC)
1163 uint64_t __srr1; // Machine state register (supervisor)
1164 uint64_t __r0;
1165 uint64_t __r1;
1166 uint64_t __r2;
1167 uint64_t __r3;
1168 uint64_t __r4;
1169 uint64_t __r5;
1170 uint64_t __r6;
1171 uint64_t __r7;
1172 uint64_t __r8;
1173 uint64_t __r9;
1174 uint64_t __r10;
1175 uint64_t __r11;
1176 uint64_t __r12;
1177 uint64_t __r13;
1178 uint64_t __r14;
1179 uint64_t __r15;
1180 uint64_t __r16;
1181 uint64_t __r17;
1182 uint64_t __r18;
1183 uint64_t __r19;
1184 uint64_t __r20;
1185 uint64_t __r21;
1186 uint64_t __r22;
1187 uint64_t __r23;
1188 uint64_t __r24;
1189 uint64_t __r25;
1190 uint64_t __r26;
1191 uint64_t __r27;
1192 uint64_t __r28;
1193 uint64_t __r29;
1194 uint64_t __r30;
1195 uint64_t __r31;
1196 uint64_t __cr; // Condition register
1197 uint64_t __xer; // User's integer exception register
1198 uint64_t __lr; // Link register
1199 uint64_t __ctr; // Count register
1200 uint64_t __vrsave; // Vector Save Register
1201 };
1202
1203 union ppc64_vsr_t {
1204 struct asfloat_s {
1205 double f;
1206 uint64_t v2;
1207 } asfloat;
1208 v128 v;
1209 };
1210
1211 ppc64_thread_state_t _registers;
1212 ppc64_vsr_t _vectorScalarRegisters[64];
1213
1214 static int getVectorRegNum(int num);
1215 };
1216
Registers_ppc64(const void * registers)1217 inline Registers_ppc64::Registers_ppc64(const void *registers) {
1218 static_assert((check_fit<Registers_ppc64, unw_context_t>::does_fit),
1219 "ppc64 registers do not fit into unw_context_t");
1220 memcpy(&_registers, static_cast<const uint8_t *>(registers),
1221 sizeof(_registers));
1222 static_assert(sizeof(_registers) == 312,
1223 "expected vector scalar register offset to be 312");
1224 memcpy(&_vectorScalarRegisters,
1225 static_cast<const uint8_t *>(registers) + sizeof(_registers),
1226 sizeof(_vectorScalarRegisters));
1227 static_assert(sizeof(_registers) +
1228 sizeof(_vectorScalarRegisters) == 1336,
1229 "expected vector register offset to be 1336 bytes");
1230 }
1231
Registers_ppc64()1232 inline Registers_ppc64::Registers_ppc64() {
1233 memset(&_registers, 0, sizeof(_registers));
1234 memset(&_vectorScalarRegisters, 0, sizeof(_vectorScalarRegisters));
1235 }
1236
validRegister(int regNum) const1237 inline bool Registers_ppc64::validRegister(int regNum) const {
1238 switch (regNum) {
1239 case UNW_REG_IP:
1240 case UNW_REG_SP:
1241 case UNW_PPC64_XER:
1242 case UNW_PPC64_LR:
1243 case UNW_PPC64_CTR:
1244 case UNW_PPC64_VRSAVE:
1245 return true;
1246 }
1247
1248 if (regNum >= UNW_PPC64_R0 && regNum <= UNW_PPC64_R31)
1249 return true;
1250 if (regNum >= UNW_PPC64_CR0 && regNum <= UNW_PPC64_CR7)
1251 return true;
1252
1253 return false;
1254 }
1255
getRegister(int regNum) const1256 inline uint64_t Registers_ppc64::getRegister(int regNum) const {
1257 switch (regNum) {
1258 case UNW_REG_IP:
1259 return _registers.__srr0;
1260 case UNW_PPC64_R0:
1261 return _registers.__r0;
1262 case UNW_PPC64_R1:
1263 case UNW_REG_SP:
1264 return _registers.__r1;
1265 case UNW_PPC64_R2:
1266 return _registers.__r2;
1267 case UNW_PPC64_R3:
1268 return _registers.__r3;
1269 case UNW_PPC64_R4:
1270 return _registers.__r4;
1271 case UNW_PPC64_R5:
1272 return _registers.__r5;
1273 case UNW_PPC64_R6:
1274 return _registers.__r6;
1275 case UNW_PPC64_R7:
1276 return _registers.__r7;
1277 case UNW_PPC64_R8:
1278 return _registers.__r8;
1279 case UNW_PPC64_R9:
1280 return _registers.__r9;
1281 case UNW_PPC64_R10:
1282 return _registers.__r10;
1283 case UNW_PPC64_R11:
1284 return _registers.__r11;
1285 case UNW_PPC64_R12:
1286 return _registers.__r12;
1287 case UNW_PPC64_R13:
1288 return _registers.__r13;
1289 case UNW_PPC64_R14:
1290 return _registers.__r14;
1291 case UNW_PPC64_R15:
1292 return _registers.__r15;
1293 case UNW_PPC64_R16:
1294 return _registers.__r16;
1295 case UNW_PPC64_R17:
1296 return _registers.__r17;
1297 case UNW_PPC64_R18:
1298 return _registers.__r18;
1299 case UNW_PPC64_R19:
1300 return _registers.__r19;
1301 case UNW_PPC64_R20:
1302 return _registers.__r20;
1303 case UNW_PPC64_R21:
1304 return _registers.__r21;
1305 case UNW_PPC64_R22:
1306 return _registers.__r22;
1307 case UNW_PPC64_R23:
1308 return _registers.__r23;
1309 case UNW_PPC64_R24:
1310 return _registers.__r24;
1311 case UNW_PPC64_R25:
1312 return _registers.__r25;
1313 case UNW_PPC64_R26:
1314 return _registers.__r26;
1315 case UNW_PPC64_R27:
1316 return _registers.__r27;
1317 case UNW_PPC64_R28:
1318 return _registers.__r28;
1319 case UNW_PPC64_R29:
1320 return _registers.__r29;
1321 case UNW_PPC64_R30:
1322 return _registers.__r30;
1323 case UNW_PPC64_R31:
1324 return _registers.__r31;
1325 case UNW_PPC64_CR0:
1326 return (_registers.__cr & 0xF0000000);
1327 case UNW_PPC64_CR1:
1328 return (_registers.__cr & 0x0F000000);
1329 case UNW_PPC64_CR2:
1330 return (_registers.__cr & 0x00F00000);
1331 case UNW_PPC64_CR3:
1332 return (_registers.__cr & 0x000F0000);
1333 case UNW_PPC64_CR4:
1334 return (_registers.__cr & 0x0000F000);
1335 case UNW_PPC64_CR5:
1336 return (_registers.__cr & 0x00000F00);
1337 case UNW_PPC64_CR6:
1338 return (_registers.__cr & 0x000000F0);
1339 case UNW_PPC64_CR7:
1340 return (_registers.__cr & 0x0000000F);
1341 case UNW_PPC64_XER:
1342 return _registers.__xer;
1343 case UNW_PPC64_LR:
1344 return _registers.__lr;
1345 case UNW_PPC64_CTR:
1346 return _registers.__ctr;
1347 case UNW_PPC64_VRSAVE:
1348 return _registers.__vrsave;
1349 }
1350 _LIBUNWIND_ABORT("unsupported ppc64 register");
1351 }
1352
setRegister(int regNum,uint64_t value)1353 inline void Registers_ppc64::setRegister(int regNum, uint64_t value) {
1354 switch (regNum) {
1355 case UNW_REG_IP:
1356 _registers.__srr0 = value;
1357 return;
1358 case UNW_PPC64_R0:
1359 _registers.__r0 = value;
1360 return;
1361 case UNW_PPC64_R1:
1362 case UNW_REG_SP:
1363 _registers.__r1 = value;
1364 return;
1365 case UNW_PPC64_R2:
1366 _registers.__r2 = value;
1367 return;
1368 case UNW_PPC64_R3:
1369 _registers.__r3 = value;
1370 return;
1371 case UNW_PPC64_R4:
1372 _registers.__r4 = value;
1373 return;
1374 case UNW_PPC64_R5:
1375 _registers.__r5 = value;
1376 return;
1377 case UNW_PPC64_R6:
1378 _registers.__r6 = value;
1379 return;
1380 case UNW_PPC64_R7:
1381 _registers.__r7 = value;
1382 return;
1383 case UNW_PPC64_R8:
1384 _registers.__r8 = value;
1385 return;
1386 case UNW_PPC64_R9:
1387 _registers.__r9 = value;
1388 return;
1389 case UNW_PPC64_R10:
1390 _registers.__r10 = value;
1391 return;
1392 case UNW_PPC64_R11:
1393 _registers.__r11 = value;
1394 return;
1395 case UNW_PPC64_R12:
1396 _registers.__r12 = value;
1397 return;
1398 case UNW_PPC64_R13:
1399 _registers.__r13 = value;
1400 return;
1401 case UNW_PPC64_R14:
1402 _registers.__r14 = value;
1403 return;
1404 case UNW_PPC64_R15:
1405 _registers.__r15 = value;
1406 return;
1407 case UNW_PPC64_R16:
1408 _registers.__r16 = value;
1409 return;
1410 case UNW_PPC64_R17:
1411 _registers.__r17 = value;
1412 return;
1413 case UNW_PPC64_R18:
1414 _registers.__r18 = value;
1415 return;
1416 case UNW_PPC64_R19:
1417 _registers.__r19 = value;
1418 return;
1419 case UNW_PPC64_R20:
1420 _registers.__r20 = value;
1421 return;
1422 case UNW_PPC64_R21:
1423 _registers.__r21 = value;
1424 return;
1425 case UNW_PPC64_R22:
1426 _registers.__r22 = value;
1427 return;
1428 case UNW_PPC64_R23:
1429 _registers.__r23 = value;
1430 return;
1431 case UNW_PPC64_R24:
1432 _registers.__r24 = value;
1433 return;
1434 case UNW_PPC64_R25:
1435 _registers.__r25 = value;
1436 return;
1437 case UNW_PPC64_R26:
1438 _registers.__r26 = value;
1439 return;
1440 case UNW_PPC64_R27:
1441 _registers.__r27 = value;
1442 return;
1443 case UNW_PPC64_R28:
1444 _registers.__r28 = value;
1445 return;
1446 case UNW_PPC64_R29:
1447 _registers.__r29 = value;
1448 return;
1449 case UNW_PPC64_R30:
1450 _registers.__r30 = value;
1451 return;
1452 case UNW_PPC64_R31:
1453 _registers.__r31 = value;
1454 return;
1455 case UNW_PPC64_CR0:
1456 _registers.__cr &= 0x0FFFFFFF;
1457 _registers.__cr |= (value & 0xF0000000);
1458 return;
1459 case UNW_PPC64_CR1:
1460 _registers.__cr &= 0xF0FFFFFF;
1461 _registers.__cr |= (value & 0x0F000000);
1462 return;
1463 case UNW_PPC64_CR2:
1464 _registers.__cr &= 0xFF0FFFFF;
1465 _registers.__cr |= (value & 0x00F00000);
1466 return;
1467 case UNW_PPC64_CR3:
1468 _registers.__cr &= 0xFFF0FFFF;
1469 _registers.__cr |= (value & 0x000F0000);
1470 return;
1471 case UNW_PPC64_CR4:
1472 _registers.__cr &= 0xFFFF0FFF;
1473 _registers.__cr |= (value & 0x0000F000);
1474 return;
1475 case UNW_PPC64_CR5:
1476 _registers.__cr &= 0xFFFFF0FF;
1477 _registers.__cr |= (value & 0x00000F00);
1478 return;
1479 case UNW_PPC64_CR6:
1480 _registers.__cr &= 0xFFFFFF0F;
1481 _registers.__cr |= (value & 0x000000F0);
1482 return;
1483 case UNW_PPC64_CR7:
1484 _registers.__cr &= 0xFFFFFFF0;
1485 _registers.__cr |= (value & 0x0000000F);
1486 return;
1487 case UNW_PPC64_XER:
1488 _registers.__xer = value;
1489 return;
1490 case UNW_PPC64_LR:
1491 _registers.__lr = value;
1492 return;
1493 case UNW_PPC64_CTR:
1494 _registers.__ctr = value;
1495 return;
1496 case UNW_PPC64_VRSAVE:
1497 _registers.__vrsave = value;
1498 return;
1499 }
1500 _LIBUNWIND_ABORT("unsupported ppc64 register");
1501 }
1502
validFloatRegister(int regNum) const1503 inline bool Registers_ppc64::validFloatRegister(int regNum) const {
1504 return regNum >= UNW_PPC64_F0 && regNum <= UNW_PPC64_F31;
1505 }
1506
getFloatRegister(int regNum) const1507 inline double Registers_ppc64::getFloatRegister(int regNum) const {
1508 assert(validFloatRegister(regNum));
1509 return _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f;
1510 }
1511
setFloatRegister(int regNum,double value)1512 inline void Registers_ppc64::setFloatRegister(int regNum, double value) {
1513 assert(validFloatRegister(regNum));
1514 _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f = value;
1515 }
1516
validVectorRegister(int regNum) const1517 inline bool Registers_ppc64::validVectorRegister(int regNum) const {
1518 #if defined(__VSX__)
1519 if (regNum >= UNW_PPC64_VS0 && regNum <= UNW_PPC64_VS31)
1520 return true;
1521 if (regNum >= UNW_PPC64_VS32 && regNum <= UNW_PPC64_VS63)
1522 return true;
1523 #elif defined(__ALTIVEC__)
1524 if (regNum >= UNW_PPC64_V0 && regNum <= UNW_PPC64_V31)
1525 return true;
1526 #endif
1527 return false;
1528 }
1529
getVectorRegNum(int num)1530 inline int Registers_ppc64::getVectorRegNum(int num)
1531 {
1532 if (num >= UNW_PPC64_VS0 && num <= UNW_PPC64_VS31)
1533 return num - UNW_PPC64_VS0;
1534 else
1535 return num - UNW_PPC64_VS32 + 32;
1536 }
1537
getVectorRegister(int regNum) const1538 inline v128 Registers_ppc64::getVectorRegister(int regNum) const {
1539 assert(validVectorRegister(regNum));
1540 return _vectorScalarRegisters[getVectorRegNum(regNum)].v;
1541 }
1542
setVectorRegister(int regNum,v128 value)1543 inline void Registers_ppc64::setVectorRegister(int regNum, v128 value) {
1544 assert(validVectorRegister(regNum));
1545 _vectorScalarRegisters[getVectorRegNum(regNum)].v = value;
1546 }
1547
getRegisterName(int regNum)1548 inline const char *Registers_ppc64::getRegisterName(int regNum) {
1549 switch (regNum) {
1550 case UNW_REG_IP:
1551 return "ip";
1552 case UNW_REG_SP:
1553 return "sp";
1554 case UNW_PPC64_R0:
1555 return "r0";
1556 case UNW_PPC64_R1:
1557 return "r1";
1558 case UNW_PPC64_R2:
1559 return "r2";
1560 case UNW_PPC64_R3:
1561 return "r3";
1562 case UNW_PPC64_R4:
1563 return "r4";
1564 case UNW_PPC64_R5:
1565 return "r5";
1566 case UNW_PPC64_R6:
1567 return "r6";
1568 case UNW_PPC64_R7:
1569 return "r7";
1570 case UNW_PPC64_R8:
1571 return "r8";
1572 case UNW_PPC64_R9:
1573 return "r9";
1574 case UNW_PPC64_R10:
1575 return "r10";
1576 case UNW_PPC64_R11:
1577 return "r11";
1578 case UNW_PPC64_R12:
1579 return "r12";
1580 case UNW_PPC64_R13:
1581 return "r13";
1582 case UNW_PPC64_R14:
1583 return "r14";
1584 case UNW_PPC64_R15:
1585 return "r15";
1586 case UNW_PPC64_R16:
1587 return "r16";
1588 case UNW_PPC64_R17:
1589 return "r17";
1590 case UNW_PPC64_R18:
1591 return "r18";
1592 case UNW_PPC64_R19:
1593 return "r19";
1594 case UNW_PPC64_R20:
1595 return "r20";
1596 case UNW_PPC64_R21:
1597 return "r21";
1598 case UNW_PPC64_R22:
1599 return "r22";
1600 case UNW_PPC64_R23:
1601 return "r23";
1602 case UNW_PPC64_R24:
1603 return "r24";
1604 case UNW_PPC64_R25:
1605 return "r25";
1606 case UNW_PPC64_R26:
1607 return "r26";
1608 case UNW_PPC64_R27:
1609 return "r27";
1610 case UNW_PPC64_R28:
1611 return "r28";
1612 case UNW_PPC64_R29:
1613 return "r29";
1614 case UNW_PPC64_R30:
1615 return "r30";
1616 case UNW_PPC64_R31:
1617 return "r31";
1618 case UNW_PPC64_CR0:
1619 return "cr0";
1620 case UNW_PPC64_CR1:
1621 return "cr1";
1622 case UNW_PPC64_CR2:
1623 return "cr2";
1624 case UNW_PPC64_CR3:
1625 return "cr3";
1626 case UNW_PPC64_CR4:
1627 return "cr4";
1628 case UNW_PPC64_CR5:
1629 return "cr5";
1630 case UNW_PPC64_CR6:
1631 return "cr6";
1632 case UNW_PPC64_CR7:
1633 return "cr7";
1634 case UNW_PPC64_XER:
1635 return "xer";
1636 case UNW_PPC64_LR:
1637 return "lr";
1638 case UNW_PPC64_CTR:
1639 return "ctr";
1640 case UNW_PPC64_VRSAVE:
1641 return "vrsave";
1642 case UNW_PPC64_F0:
1643 return "fp0";
1644 case UNW_PPC64_F1:
1645 return "fp1";
1646 case UNW_PPC64_F2:
1647 return "fp2";
1648 case UNW_PPC64_F3:
1649 return "fp3";
1650 case UNW_PPC64_F4:
1651 return "fp4";
1652 case UNW_PPC64_F5:
1653 return "fp5";
1654 case UNW_PPC64_F6:
1655 return "fp6";
1656 case UNW_PPC64_F7:
1657 return "fp7";
1658 case UNW_PPC64_F8:
1659 return "fp8";
1660 case UNW_PPC64_F9:
1661 return "fp9";
1662 case UNW_PPC64_F10:
1663 return "fp10";
1664 case UNW_PPC64_F11:
1665 return "fp11";
1666 case UNW_PPC64_F12:
1667 return "fp12";
1668 case UNW_PPC64_F13:
1669 return "fp13";
1670 case UNW_PPC64_F14:
1671 return "fp14";
1672 case UNW_PPC64_F15:
1673 return "fp15";
1674 case UNW_PPC64_F16:
1675 return "fp16";
1676 case UNW_PPC64_F17:
1677 return "fp17";
1678 case UNW_PPC64_F18:
1679 return "fp18";
1680 case UNW_PPC64_F19:
1681 return "fp19";
1682 case UNW_PPC64_F20:
1683 return "fp20";
1684 case UNW_PPC64_F21:
1685 return "fp21";
1686 case UNW_PPC64_F22:
1687 return "fp22";
1688 case UNW_PPC64_F23:
1689 return "fp23";
1690 case UNW_PPC64_F24:
1691 return "fp24";
1692 case UNW_PPC64_F25:
1693 return "fp25";
1694 case UNW_PPC64_F26:
1695 return "fp26";
1696 case UNW_PPC64_F27:
1697 return "fp27";
1698 case UNW_PPC64_F28:
1699 return "fp28";
1700 case UNW_PPC64_F29:
1701 return "fp29";
1702 case UNW_PPC64_F30:
1703 return "fp30";
1704 case UNW_PPC64_F31:
1705 return "fp31";
1706 case UNW_PPC64_V0:
1707 return "v0";
1708 case UNW_PPC64_V1:
1709 return "v1";
1710 case UNW_PPC64_V2:
1711 return "v2";
1712 case UNW_PPC64_V3:
1713 return "v3";
1714 case UNW_PPC64_V4:
1715 return "v4";
1716 case UNW_PPC64_V5:
1717 return "v5";
1718 case UNW_PPC64_V6:
1719 return "v6";
1720 case UNW_PPC64_V7:
1721 return "v7";
1722 case UNW_PPC64_V8:
1723 return "v8";
1724 case UNW_PPC64_V9:
1725 return "v9";
1726 case UNW_PPC64_V10:
1727 return "v10";
1728 case UNW_PPC64_V11:
1729 return "v11";
1730 case UNW_PPC64_V12:
1731 return "v12";
1732 case UNW_PPC64_V13:
1733 return "v13";
1734 case UNW_PPC64_V14:
1735 return "v14";
1736 case UNW_PPC64_V15:
1737 return "v15";
1738 case UNW_PPC64_V16:
1739 return "v16";
1740 case UNW_PPC64_V17:
1741 return "v17";
1742 case UNW_PPC64_V18:
1743 return "v18";
1744 case UNW_PPC64_V19:
1745 return "v19";
1746 case UNW_PPC64_V20:
1747 return "v20";
1748 case UNW_PPC64_V21:
1749 return "v21";
1750 case UNW_PPC64_V22:
1751 return "v22";
1752 case UNW_PPC64_V23:
1753 return "v23";
1754 case UNW_PPC64_V24:
1755 return "v24";
1756 case UNW_PPC64_V25:
1757 return "v25";
1758 case UNW_PPC64_V26:
1759 return "v26";
1760 case UNW_PPC64_V27:
1761 return "v27";
1762 case UNW_PPC64_V28:
1763 return "v28";
1764 case UNW_PPC64_V29:
1765 return "v29";
1766 case UNW_PPC64_V30:
1767 return "v30";
1768 case UNW_PPC64_V31:
1769 return "v31";
1770 }
1771 return "unknown register";
1772 }
1773 #endif // _LIBUNWIND_TARGET_PPC64
1774
1775
1776 #if defined(_LIBUNWIND_TARGET_AARCH64)
1777 /// Registers_arm64 holds the register state of a thread in a 64-bit arm
1778 /// process.
1779 class _LIBUNWIND_HIDDEN Registers_arm64;
1780 extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *);
1781 class _LIBUNWIND_HIDDEN Registers_arm64 {
1782 public:
1783 Registers_arm64();
1784 Registers_arm64(const void *registers);
1785
1786 bool validRegister(int num) const;
1787 uint64_t getRegister(int num) const;
1788 void setRegister(int num, uint64_t value);
1789 bool validFloatRegister(int num) const;
1790 double getFloatRegister(int num) const;
1791 void setFloatRegister(int num, double value);
1792 bool validVectorRegister(int num) const;
1793 v128 getVectorRegister(int num) const;
1794 void setVectorRegister(int num, v128 value);
1795 static const char *getRegisterName(int num);
jumpto()1796 void jumpto() { __libunwind_Registers_arm64_jumpto(this); }
lastDwarfRegNum()1797 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64; }
getArch()1798 static int getArch() { return REGISTERS_ARM64; }
1799
getSP() const1800 uint64_t getSP() const { return _registers.__sp; }
setSP(uint64_t value)1801 void setSP(uint64_t value) { _registers.__sp = value; }
getIP() const1802 uint64_t getIP() const { return _registers.__pc; }
setIP(uint64_t value)1803 void setIP(uint64_t value) { _registers.__pc = value; }
getFP() const1804 uint64_t getFP() const { return _registers.__fp; }
setFP(uint64_t value)1805 void setFP(uint64_t value) { _registers.__fp = value; }
1806
1807 private:
1808 struct GPRs {
1809 uint64_t __x[29]; // x0-x28
1810 uint64_t __fp; // Frame pointer x29
1811 uint64_t __lr; // Link register x30
1812 uint64_t __sp; // Stack pointer x31
1813 uint64_t __pc; // Program counter
1814 uint64_t __ra_sign_state; // RA sign state register
1815 };
1816
1817 GPRs _registers;
1818 double _vectorHalfRegisters[32];
1819 // Currently only the lower double in 128-bit vectore registers
1820 // is perserved during unwinding. We could define new register
1821 // numbers (> 96) which mean whole vector registers, then this
1822 // struct would need to change to contain whole vector registers.
1823 };
1824
Registers_arm64(const void * registers)1825 inline Registers_arm64::Registers_arm64(const void *registers) {
1826 static_assert((check_fit<Registers_arm64, unw_context_t>::does_fit),
1827 "arm64 registers do not fit into unw_context_t");
1828 memcpy(&_registers, registers, sizeof(_registers));
1829 static_assert(sizeof(GPRs) == 0x110,
1830 "expected VFP registers to be at offset 272");
1831 memcpy(_vectorHalfRegisters,
1832 static_cast<const uint8_t *>(registers) + sizeof(GPRs),
1833 sizeof(_vectorHalfRegisters));
1834 }
1835
Registers_arm64()1836 inline Registers_arm64::Registers_arm64() {
1837 memset(&_registers, 0, sizeof(_registers));
1838 memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
1839 }
1840
validRegister(int regNum) const1841 inline bool Registers_arm64::validRegister(int regNum) const {
1842 if (regNum == UNW_REG_IP)
1843 return true;
1844 if (regNum == UNW_REG_SP)
1845 return true;
1846 if (regNum < 0)
1847 return false;
1848 if (regNum > 95)
1849 return false;
1850 if (regNum == UNW_ARM64_RA_SIGN_STATE)
1851 return true;
1852 if ((regNum > 32) && (regNum < 64))
1853 return false;
1854 return true;
1855 }
1856
getRegister(int regNum) const1857 inline uint64_t Registers_arm64::getRegister(int regNum) const {
1858 if (regNum == UNW_REG_IP || regNum == UNW_ARM64_PC)
1859 return _registers.__pc;
1860 if (regNum == UNW_REG_SP || regNum == UNW_ARM64_SP)
1861 return _registers.__sp;
1862 if (regNum == UNW_ARM64_RA_SIGN_STATE)
1863 return _registers.__ra_sign_state;
1864 if (regNum == UNW_ARM64_FP)
1865 return _registers.__fp;
1866 if (regNum == UNW_ARM64_LR)
1867 return _registers.__lr;
1868 if ((regNum >= 0) && (regNum < 29))
1869 return _registers.__x[regNum];
1870 _LIBUNWIND_ABORT("unsupported arm64 register");
1871 }
1872
setRegister(int regNum,uint64_t value)1873 inline void Registers_arm64::setRegister(int regNum, uint64_t value) {
1874 if (regNum == UNW_REG_IP || regNum == UNW_ARM64_PC)
1875 _registers.__pc = value;
1876 else if (regNum == UNW_REG_SP || regNum == UNW_ARM64_SP)
1877 _registers.__sp = value;
1878 else if (regNum == UNW_ARM64_RA_SIGN_STATE)
1879 _registers.__ra_sign_state = value;
1880 else if (regNum == UNW_ARM64_FP)
1881 _registers.__fp = value;
1882 else if (regNum == UNW_ARM64_LR)
1883 _registers.__lr = value;
1884 else if ((regNum >= 0) && (regNum < 29))
1885 _registers.__x[regNum] = value;
1886 else
1887 _LIBUNWIND_ABORT("unsupported arm64 register");
1888 }
1889
getRegisterName(int regNum)1890 inline const char *Registers_arm64::getRegisterName(int regNum) {
1891 switch (regNum) {
1892 case UNW_REG_IP:
1893 return "pc";
1894 case UNW_REG_SP:
1895 return "sp";
1896 case UNW_ARM64_X0:
1897 return "x0";
1898 case UNW_ARM64_X1:
1899 return "x1";
1900 case UNW_ARM64_X2:
1901 return "x2";
1902 case UNW_ARM64_X3:
1903 return "x3";
1904 case UNW_ARM64_X4:
1905 return "x4";
1906 case UNW_ARM64_X5:
1907 return "x5";
1908 case UNW_ARM64_X6:
1909 return "x6";
1910 case UNW_ARM64_X7:
1911 return "x7";
1912 case UNW_ARM64_X8:
1913 return "x8";
1914 case UNW_ARM64_X9:
1915 return "x9";
1916 case UNW_ARM64_X10:
1917 return "x10";
1918 case UNW_ARM64_X11:
1919 return "x11";
1920 case UNW_ARM64_X12:
1921 return "x12";
1922 case UNW_ARM64_X13:
1923 return "x13";
1924 case UNW_ARM64_X14:
1925 return "x14";
1926 case UNW_ARM64_X15:
1927 return "x15";
1928 case UNW_ARM64_X16:
1929 return "x16";
1930 case UNW_ARM64_X17:
1931 return "x17";
1932 case UNW_ARM64_X18:
1933 return "x18";
1934 case UNW_ARM64_X19:
1935 return "x19";
1936 case UNW_ARM64_X20:
1937 return "x20";
1938 case UNW_ARM64_X21:
1939 return "x21";
1940 case UNW_ARM64_X22:
1941 return "x22";
1942 case UNW_ARM64_X23:
1943 return "x23";
1944 case UNW_ARM64_X24:
1945 return "x24";
1946 case UNW_ARM64_X25:
1947 return "x25";
1948 case UNW_ARM64_X26:
1949 return "x26";
1950 case UNW_ARM64_X27:
1951 return "x27";
1952 case UNW_ARM64_X28:
1953 return "x28";
1954 case UNW_ARM64_FP:
1955 return "fp";
1956 case UNW_ARM64_LR:
1957 return "lr";
1958 case UNW_ARM64_SP:
1959 return "sp";
1960 case UNW_ARM64_PC:
1961 return "pc";
1962 case UNW_ARM64_D0:
1963 return "d0";
1964 case UNW_ARM64_D1:
1965 return "d1";
1966 case UNW_ARM64_D2:
1967 return "d2";
1968 case UNW_ARM64_D3:
1969 return "d3";
1970 case UNW_ARM64_D4:
1971 return "d4";
1972 case UNW_ARM64_D5:
1973 return "d5";
1974 case UNW_ARM64_D6:
1975 return "d6";
1976 case UNW_ARM64_D7:
1977 return "d7";
1978 case UNW_ARM64_D8:
1979 return "d8";
1980 case UNW_ARM64_D9:
1981 return "d9";
1982 case UNW_ARM64_D10:
1983 return "d10";
1984 case UNW_ARM64_D11:
1985 return "d11";
1986 case UNW_ARM64_D12:
1987 return "d12";
1988 case UNW_ARM64_D13:
1989 return "d13";
1990 case UNW_ARM64_D14:
1991 return "d14";
1992 case UNW_ARM64_D15:
1993 return "d15";
1994 case UNW_ARM64_D16:
1995 return "d16";
1996 case UNW_ARM64_D17:
1997 return "d17";
1998 case UNW_ARM64_D18:
1999 return "d18";
2000 case UNW_ARM64_D19:
2001 return "d19";
2002 case UNW_ARM64_D20:
2003 return "d20";
2004 case UNW_ARM64_D21:
2005 return "d21";
2006 case UNW_ARM64_D22:
2007 return "d22";
2008 case UNW_ARM64_D23:
2009 return "d23";
2010 case UNW_ARM64_D24:
2011 return "d24";
2012 case UNW_ARM64_D25:
2013 return "d25";
2014 case UNW_ARM64_D26:
2015 return "d26";
2016 case UNW_ARM64_D27:
2017 return "d27";
2018 case UNW_ARM64_D28:
2019 return "d28";
2020 case UNW_ARM64_D29:
2021 return "d29";
2022 case UNW_ARM64_D30:
2023 return "d30";
2024 case UNW_ARM64_D31:
2025 return "d31";
2026 default:
2027 return "unknown register";
2028 }
2029 }
2030
validFloatRegister(int regNum) const2031 inline bool Registers_arm64::validFloatRegister(int regNum) const {
2032 if (regNum < UNW_ARM64_D0)
2033 return false;
2034 if (regNum > UNW_ARM64_D31)
2035 return false;
2036 return true;
2037 }
2038
getFloatRegister(int regNum) const2039 inline double Registers_arm64::getFloatRegister(int regNum) const {
2040 assert(validFloatRegister(regNum));
2041 return _vectorHalfRegisters[regNum - UNW_ARM64_D0];
2042 }
2043
setFloatRegister(int regNum,double value)2044 inline void Registers_arm64::setFloatRegister(int regNum, double value) {
2045 assert(validFloatRegister(regNum));
2046 _vectorHalfRegisters[regNum - UNW_ARM64_D0] = value;
2047 }
2048
validVectorRegister(int) const2049 inline bool Registers_arm64::validVectorRegister(int) const {
2050 return false;
2051 }
2052
getVectorRegister(int) const2053 inline v128 Registers_arm64::getVectorRegister(int) const {
2054 _LIBUNWIND_ABORT("no arm64 vector register support yet");
2055 }
2056
setVectorRegister(int,v128)2057 inline void Registers_arm64::setVectorRegister(int, v128) {
2058 _LIBUNWIND_ABORT("no arm64 vector register support yet");
2059 }
2060 #endif // _LIBUNWIND_TARGET_AARCH64
2061
2062 #if defined(_LIBUNWIND_TARGET_ARM)
2063 /// Registers_arm holds the register state of a thread in a 32-bit arm
2064 /// process.
2065 ///
2066 /// NOTE: Assumes VFPv3. On ARM processors without a floating point unit,
2067 /// this uses more memory than required.
2068 class _LIBUNWIND_HIDDEN Registers_arm {
2069 public:
2070 Registers_arm();
2071 Registers_arm(const void *registers);
2072
2073 bool validRegister(int num) const;
2074 uint32_t getRegister(int num) const;
2075 void setRegister(int num, uint32_t value);
2076 bool validFloatRegister(int num) const;
2077 unw_fpreg_t getFloatRegister(int num);
2078 void setFloatRegister(int num, unw_fpreg_t value);
2079 bool validVectorRegister(int num) const;
2080 v128 getVectorRegister(int num) const;
2081 void setVectorRegister(int num, v128 value);
2082 static const char *getRegisterName(int num);
jumpto()2083 void jumpto() {
2084 restoreSavedFloatRegisters();
2085 restoreCoreAndJumpTo();
2086 }
lastDwarfRegNum()2087 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM; }
getArch()2088 static int getArch() { return REGISTERS_ARM; }
2089
getSP() const2090 uint32_t getSP() const { return _registers.__sp; }
setSP(uint32_t value)2091 void setSP(uint32_t value) { _registers.__sp = value; }
getIP() const2092 uint32_t getIP() const { return _registers.__pc; }
setIP(uint32_t value)2093 void setIP(uint32_t value) { _registers.__pc = value; }
2094
saveVFPAsX()2095 void saveVFPAsX() {
2096 assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15);
2097 _use_X_for_vfp_save = true;
2098 }
2099
restoreSavedFloatRegisters()2100 void restoreSavedFloatRegisters() {
2101 if (_saved_vfp_d0_d15) {
2102 if (_use_X_for_vfp_save)
2103 restoreVFPWithFLDMX(_vfp_d0_d15_pad);
2104 else
2105 restoreVFPWithFLDMD(_vfp_d0_d15_pad);
2106 }
2107 if (_saved_vfp_d16_d31)
2108 restoreVFPv3(_vfp_d16_d31);
2109 #if defined(__ARM_WMMX)
2110 if (_saved_iwmmx)
2111 restoreiWMMX(_iwmmx);
2112 if (_saved_iwmmx_control)
2113 restoreiWMMXControl(_iwmmx_control);
2114 #endif
2115 }
2116
2117 private:
2118 struct GPRs {
2119 uint32_t __r[13]; // r0-r12
2120 uint32_t __sp; // Stack pointer r13
2121 uint32_t __lr; // Link register r14
2122 uint32_t __pc; // Program counter r15
2123 };
2124
2125 static void saveVFPWithFSTMD(void*);
2126 static void saveVFPWithFSTMX(void*);
2127 static void saveVFPv3(void*);
2128 static void restoreVFPWithFLDMD(void*);
2129 static void restoreVFPWithFLDMX(void*);
2130 static void restoreVFPv3(void*);
2131 #if defined(__ARM_WMMX)
2132 static void saveiWMMX(void*);
2133 static void saveiWMMXControl(uint32_t*);
2134 static void restoreiWMMX(void*);
2135 static void restoreiWMMXControl(uint32_t*);
2136 #endif
2137 void restoreCoreAndJumpTo();
2138
2139 // ARM registers
2140 GPRs _registers;
2141
2142 // We save floating point registers lazily because we can't know ahead of
2143 // time which ones are used. See EHABI #4.7.
2144
2145 // Whether D0-D15 are saved in the FTSMX instead of FSTMD format.
2146 //
2147 // See EHABI #7.5 that explains how matching instruction sequences for load
2148 // and store need to be used to correctly restore the exact register bits.
2149 bool _use_X_for_vfp_save;
2150 // Whether VFP D0-D15 are saved.
2151 bool _saved_vfp_d0_d15;
2152 // Whether VFPv3 D16-D31 are saved.
2153 bool _saved_vfp_d16_d31;
2154 // VFP registers D0-D15, + padding if saved using FSTMX
2155 unw_fpreg_t _vfp_d0_d15_pad[17];
2156 // VFPv3 registers D16-D31, always saved using FSTMD
2157 unw_fpreg_t _vfp_d16_d31[16];
2158 #if defined(__ARM_WMMX)
2159 // Whether iWMMX data registers are saved.
2160 bool _saved_iwmmx;
2161 // Whether iWMMX control registers are saved.
2162 mutable bool _saved_iwmmx_control;
2163 // iWMMX registers
2164 unw_fpreg_t _iwmmx[16];
2165 // iWMMX control registers
2166 mutable uint32_t _iwmmx_control[4];
2167 #endif
2168 };
2169
Registers_arm(const void * registers)2170 inline Registers_arm::Registers_arm(const void *registers)
2171 : _use_X_for_vfp_save(false),
2172 _saved_vfp_d0_d15(false),
2173 _saved_vfp_d16_d31(false) {
2174 static_assert((check_fit<Registers_arm, unw_context_t>::does_fit),
2175 "arm registers do not fit into unw_context_t");
2176 // See __unw_getcontext() note about data.
2177 memcpy(&_registers, registers, sizeof(_registers));
2178 memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
2179 memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
2180 #if defined(__ARM_WMMX)
2181 _saved_iwmmx = false;
2182 _saved_iwmmx_control = false;
2183 memset(&_iwmmx, 0, sizeof(_iwmmx));
2184 memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
2185 #endif
2186 }
2187
Registers_arm()2188 inline Registers_arm::Registers_arm()
2189 : _use_X_for_vfp_save(false),
2190 _saved_vfp_d0_d15(false),
2191 _saved_vfp_d16_d31(false) {
2192 memset(&_registers, 0, sizeof(_registers));
2193 memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
2194 memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
2195 #if defined(__ARM_WMMX)
2196 _saved_iwmmx = false;
2197 _saved_iwmmx_control = false;
2198 memset(&_iwmmx, 0, sizeof(_iwmmx));
2199 memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
2200 #endif
2201 }
2202
validRegister(int regNum) const2203 inline bool Registers_arm::validRegister(int regNum) const {
2204 // Returns true for all non-VFP registers supported by the EHABI
2205 // virtual register set (VRS).
2206 if (regNum == UNW_REG_IP)
2207 return true;
2208
2209 if (regNum == UNW_REG_SP)
2210 return true;
2211
2212 if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15)
2213 return true;
2214
2215 #if defined(__ARM_WMMX)
2216 if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3)
2217 return true;
2218 #endif
2219
2220 return false;
2221 }
2222
getRegister(int regNum) const2223 inline uint32_t Registers_arm::getRegister(int regNum) const {
2224 if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
2225 return _registers.__sp;
2226
2227 if (regNum == UNW_ARM_LR)
2228 return _registers.__lr;
2229
2230 if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
2231 return _registers.__pc;
2232
2233 if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
2234 return _registers.__r[regNum];
2235
2236 #if defined(__ARM_WMMX)
2237 if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
2238 if (!_saved_iwmmx_control) {
2239 _saved_iwmmx_control = true;
2240 saveiWMMXControl(_iwmmx_control);
2241 }
2242 return _iwmmx_control[regNum - UNW_ARM_WC0];
2243 }
2244 #endif
2245
2246 _LIBUNWIND_ABORT("unsupported arm register");
2247 }
2248
setRegister(int regNum,uint32_t value)2249 inline void Registers_arm::setRegister(int regNum, uint32_t value) {
2250 if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) {
2251 _registers.__sp = value;
2252 return;
2253 }
2254
2255 if (regNum == UNW_ARM_LR) {
2256 _registers.__lr = value;
2257 return;
2258 }
2259
2260 if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) {
2261 _registers.__pc = value;
2262 return;
2263 }
2264
2265 if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) {
2266 _registers.__r[regNum] = value;
2267 return;
2268 }
2269
2270 #if defined(__ARM_WMMX)
2271 if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
2272 if (!_saved_iwmmx_control) {
2273 _saved_iwmmx_control = true;
2274 saveiWMMXControl(_iwmmx_control);
2275 }
2276 _iwmmx_control[regNum - UNW_ARM_WC0] = value;
2277 return;
2278 }
2279 #endif
2280
2281 _LIBUNWIND_ABORT("unsupported arm register");
2282 }
2283
getRegisterName(int regNum)2284 inline const char *Registers_arm::getRegisterName(int regNum) {
2285 switch (regNum) {
2286 case UNW_REG_IP:
2287 case UNW_ARM_IP: // UNW_ARM_R15 is alias
2288 return "pc";
2289 case UNW_ARM_LR: // UNW_ARM_R14 is alias
2290 return "lr";
2291 case UNW_REG_SP:
2292 case UNW_ARM_SP: // UNW_ARM_R13 is alias
2293 return "sp";
2294 case UNW_ARM_R0:
2295 return "r0";
2296 case UNW_ARM_R1:
2297 return "r1";
2298 case UNW_ARM_R2:
2299 return "r2";
2300 case UNW_ARM_R3:
2301 return "r3";
2302 case UNW_ARM_R4:
2303 return "r4";
2304 case UNW_ARM_R5:
2305 return "r5";
2306 case UNW_ARM_R6:
2307 return "r6";
2308 case UNW_ARM_R7:
2309 return "r7";
2310 case UNW_ARM_R8:
2311 return "r8";
2312 case UNW_ARM_R9:
2313 return "r9";
2314 case UNW_ARM_R10:
2315 return "r10";
2316 case UNW_ARM_R11:
2317 return "r11";
2318 case UNW_ARM_R12:
2319 return "r12";
2320 case UNW_ARM_S0:
2321 return "s0";
2322 case UNW_ARM_S1:
2323 return "s1";
2324 case UNW_ARM_S2:
2325 return "s2";
2326 case UNW_ARM_S3:
2327 return "s3";
2328 case UNW_ARM_S4:
2329 return "s4";
2330 case UNW_ARM_S5:
2331 return "s5";
2332 case UNW_ARM_S6:
2333 return "s6";
2334 case UNW_ARM_S7:
2335 return "s7";
2336 case UNW_ARM_S8:
2337 return "s8";
2338 case UNW_ARM_S9:
2339 return "s9";
2340 case UNW_ARM_S10:
2341 return "s10";
2342 case UNW_ARM_S11:
2343 return "s11";
2344 case UNW_ARM_S12:
2345 return "s12";
2346 case UNW_ARM_S13:
2347 return "s13";
2348 case UNW_ARM_S14:
2349 return "s14";
2350 case UNW_ARM_S15:
2351 return "s15";
2352 case UNW_ARM_S16:
2353 return "s16";
2354 case UNW_ARM_S17:
2355 return "s17";
2356 case UNW_ARM_S18:
2357 return "s18";
2358 case UNW_ARM_S19:
2359 return "s19";
2360 case UNW_ARM_S20:
2361 return "s20";
2362 case UNW_ARM_S21:
2363 return "s21";
2364 case UNW_ARM_S22:
2365 return "s22";
2366 case UNW_ARM_S23:
2367 return "s23";
2368 case UNW_ARM_S24:
2369 return "s24";
2370 case UNW_ARM_S25:
2371 return "s25";
2372 case UNW_ARM_S26:
2373 return "s26";
2374 case UNW_ARM_S27:
2375 return "s27";
2376 case UNW_ARM_S28:
2377 return "s28";
2378 case UNW_ARM_S29:
2379 return "s29";
2380 case UNW_ARM_S30:
2381 return "s30";
2382 case UNW_ARM_S31:
2383 return "s31";
2384 case UNW_ARM_D0:
2385 return "d0";
2386 case UNW_ARM_D1:
2387 return "d1";
2388 case UNW_ARM_D2:
2389 return "d2";
2390 case UNW_ARM_D3:
2391 return "d3";
2392 case UNW_ARM_D4:
2393 return "d4";
2394 case UNW_ARM_D5:
2395 return "d5";
2396 case UNW_ARM_D6:
2397 return "d6";
2398 case UNW_ARM_D7:
2399 return "d7";
2400 case UNW_ARM_D8:
2401 return "d8";
2402 case UNW_ARM_D9:
2403 return "d9";
2404 case UNW_ARM_D10:
2405 return "d10";
2406 case UNW_ARM_D11:
2407 return "d11";
2408 case UNW_ARM_D12:
2409 return "d12";
2410 case UNW_ARM_D13:
2411 return "d13";
2412 case UNW_ARM_D14:
2413 return "d14";
2414 case UNW_ARM_D15:
2415 return "d15";
2416 case UNW_ARM_D16:
2417 return "d16";
2418 case UNW_ARM_D17:
2419 return "d17";
2420 case UNW_ARM_D18:
2421 return "d18";
2422 case UNW_ARM_D19:
2423 return "d19";
2424 case UNW_ARM_D20:
2425 return "d20";
2426 case UNW_ARM_D21:
2427 return "d21";
2428 case UNW_ARM_D22:
2429 return "d22";
2430 case UNW_ARM_D23:
2431 return "d23";
2432 case UNW_ARM_D24:
2433 return "d24";
2434 case UNW_ARM_D25:
2435 return "d25";
2436 case UNW_ARM_D26:
2437 return "d26";
2438 case UNW_ARM_D27:
2439 return "d27";
2440 case UNW_ARM_D28:
2441 return "d28";
2442 case UNW_ARM_D29:
2443 return "d29";
2444 case UNW_ARM_D30:
2445 return "d30";
2446 case UNW_ARM_D31:
2447 return "d31";
2448 default:
2449 return "unknown register";
2450 }
2451 }
2452
validFloatRegister(int regNum) const2453 inline bool Registers_arm::validFloatRegister(int regNum) const {
2454 // NOTE: Consider the intel MMX registers floating points so the
2455 // __unw_get_fpreg can be used to transmit the 64-bit data back.
2456 return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31))
2457 #if defined(__ARM_WMMX)
2458 || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15))
2459 #endif
2460 ;
2461 }
2462
getFloatRegister(int regNum)2463 inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) {
2464 if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
2465 if (!_saved_vfp_d0_d15) {
2466 _saved_vfp_d0_d15 = true;
2467 if (_use_X_for_vfp_save)
2468 saveVFPWithFSTMX(_vfp_d0_d15_pad);
2469 else
2470 saveVFPWithFSTMD(_vfp_d0_d15_pad);
2471 }
2472 return _vfp_d0_d15_pad[regNum - UNW_ARM_D0];
2473 }
2474
2475 if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
2476 if (!_saved_vfp_d16_d31) {
2477 _saved_vfp_d16_d31 = true;
2478 saveVFPv3(_vfp_d16_d31);
2479 }
2480 return _vfp_d16_d31[regNum - UNW_ARM_D16];
2481 }
2482
2483 #if defined(__ARM_WMMX)
2484 if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
2485 if (!_saved_iwmmx) {
2486 _saved_iwmmx = true;
2487 saveiWMMX(_iwmmx);
2488 }
2489 return _iwmmx[regNum - UNW_ARM_WR0];
2490 }
2491 #endif
2492
2493 _LIBUNWIND_ABORT("Unknown ARM float register");
2494 }
2495
setFloatRegister(int regNum,unw_fpreg_t value)2496 inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) {
2497 if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
2498 if (!_saved_vfp_d0_d15) {
2499 _saved_vfp_d0_d15 = true;
2500 if (_use_X_for_vfp_save)
2501 saveVFPWithFSTMX(_vfp_d0_d15_pad);
2502 else
2503 saveVFPWithFSTMD(_vfp_d0_d15_pad);
2504 }
2505 _vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value;
2506 return;
2507 }
2508
2509 if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
2510 if (!_saved_vfp_d16_d31) {
2511 _saved_vfp_d16_d31 = true;
2512 saveVFPv3(_vfp_d16_d31);
2513 }
2514 _vfp_d16_d31[regNum - UNW_ARM_D16] = value;
2515 return;
2516 }
2517
2518 #if defined(__ARM_WMMX)
2519 if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
2520 if (!_saved_iwmmx) {
2521 _saved_iwmmx = true;
2522 saveiWMMX(_iwmmx);
2523 }
2524 _iwmmx[regNum - UNW_ARM_WR0] = value;
2525 return;
2526 }
2527 #endif
2528
2529 _LIBUNWIND_ABORT("Unknown ARM float register");
2530 }
2531
validVectorRegister(int) const2532 inline bool Registers_arm::validVectorRegister(int) const {
2533 return false;
2534 }
2535
getVectorRegister(int) const2536 inline v128 Registers_arm::getVectorRegister(int) const {
2537 _LIBUNWIND_ABORT("ARM vector support not implemented");
2538 }
2539
setVectorRegister(int,v128)2540 inline void Registers_arm::setVectorRegister(int, v128) {
2541 _LIBUNWIND_ABORT("ARM vector support not implemented");
2542 }
2543 #endif // _LIBUNWIND_TARGET_ARM
2544
2545
2546 #if defined(_LIBUNWIND_TARGET_OR1K)
2547 /// Registers_or1k holds the register state of a thread in an OpenRISC1000
2548 /// process.
2549 class _LIBUNWIND_HIDDEN Registers_or1k {
2550 public:
2551 Registers_or1k();
2552 Registers_or1k(const void *registers);
2553
2554 bool validRegister(int num) const;
2555 uint32_t getRegister(int num) const;
2556 void setRegister(int num, uint32_t value);
2557 bool validFloatRegister(int num) const;
2558 double getFloatRegister(int num) const;
2559 void setFloatRegister(int num, double value);
2560 bool validVectorRegister(int num) const;
2561 v128 getVectorRegister(int num) const;
2562 void setVectorRegister(int num, v128 value);
2563 static const char *getRegisterName(int num);
2564 void jumpto();
lastDwarfRegNum()2565 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K; }
getArch()2566 static int getArch() { return REGISTERS_OR1K; }
2567
getSP() const2568 uint64_t getSP() const { return _registers.__r[1]; }
setSP(uint32_t value)2569 void setSP(uint32_t value) { _registers.__r[1] = value; }
getIP() const2570 uint64_t getIP() const { return _registers.__pc; }
setIP(uint32_t value)2571 void setIP(uint32_t value) { _registers.__pc = value; }
2572
2573 private:
2574 struct or1k_thread_state_t {
2575 unsigned int __r[32]; // r0-r31
2576 unsigned int __pc; // Program counter
2577 unsigned int __epcr; // Program counter at exception
2578 };
2579
2580 or1k_thread_state_t _registers;
2581 };
2582
Registers_or1k(const void * registers)2583 inline Registers_or1k::Registers_or1k(const void *registers) {
2584 static_assert((check_fit<Registers_or1k, unw_context_t>::does_fit),
2585 "or1k registers do not fit into unw_context_t");
2586 memcpy(&_registers, static_cast<const uint8_t *>(registers),
2587 sizeof(_registers));
2588 }
2589
Registers_or1k()2590 inline Registers_or1k::Registers_or1k() {
2591 memset(&_registers, 0, sizeof(_registers));
2592 }
2593
validRegister(int regNum) const2594 inline bool Registers_or1k::validRegister(int regNum) const {
2595 if (regNum == UNW_REG_IP)
2596 return true;
2597 if (regNum == UNW_REG_SP)
2598 return true;
2599 if (regNum < 0)
2600 return false;
2601 if (regNum <= UNW_OR1K_R31)
2602 return true;
2603 if (regNum == UNW_OR1K_EPCR)
2604 return true;
2605 return false;
2606 }
2607
getRegister(int regNum) const2608 inline uint32_t Registers_or1k::getRegister(int regNum) const {
2609 if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31)
2610 return _registers.__r[regNum - UNW_OR1K_R0];
2611
2612 switch (regNum) {
2613 case UNW_REG_IP:
2614 return _registers.__pc;
2615 case UNW_REG_SP:
2616 return _registers.__r[1];
2617 case UNW_OR1K_EPCR:
2618 return _registers.__epcr;
2619 }
2620 _LIBUNWIND_ABORT("unsupported or1k register");
2621 }
2622
setRegister(int regNum,uint32_t value)2623 inline void Registers_or1k::setRegister(int regNum, uint32_t value) {
2624 if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) {
2625 _registers.__r[regNum - UNW_OR1K_R0] = value;
2626 return;
2627 }
2628
2629 switch (regNum) {
2630 case UNW_REG_IP:
2631 _registers.__pc = value;
2632 return;
2633 case UNW_REG_SP:
2634 _registers.__r[1] = value;
2635 return;
2636 case UNW_OR1K_EPCR:
2637 _registers.__epcr = value;
2638 return;
2639 }
2640 _LIBUNWIND_ABORT("unsupported or1k register");
2641 }
2642
validFloatRegister(int) const2643 inline bool Registers_or1k::validFloatRegister(int /* regNum */) const {
2644 return false;
2645 }
2646
getFloatRegister(int) const2647 inline double Registers_or1k::getFloatRegister(int /* regNum */) const {
2648 _LIBUNWIND_ABORT("or1k float support not implemented");
2649 }
2650
setFloatRegister(int,double)2651 inline void Registers_or1k::setFloatRegister(int /* regNum */,
2652 double /* value */) {
2653 _LIBUNWIND_ABORT("or1k float support not implemented");
2654 }
2655
validVectorRegister(int) const2656 inline bool Registers_or1k::validVectorRegister(int /* regNum */) const {
2657 return false;
2658 }
2659
getVectorRegister(int) const2660 inline v128 Registers_or1k::getVectorRegister(int /* regNum */) const {
2661 _LIBUNWIND_ABORT("or1k vector support not implemented");
2662 }
2663
setVectorRegister(int,v128)2664 inline void Registers_or1k::setVectorRegister(int /* regNum */, v128 /* value */) {
2665 _LIBUNWIND_ABORT("or1k vector support not implemented");
2666 }
2667
getRegisterName(int regNum)2668 inline const char *Registers_or1k::getRegisterName(int regNum) {
2669 switch (regNum) {
2670 case UNW_OR1K_R0:
2671 return "r0";
2672 case UNW_OR1K_R1:
2673 return "r1";
2674 case UNW_OR1K_R2:
2675 return "r2";
2676 case UNW_OR1K_R3:
2677 return "r3";
2678 case UNW_OR1K_R4:
2679 return "r4";
2680 case UNW_OR1K_R5:
2681 return "r5";
2682 case UNW_OR1K_R6:
2683 return "r6";
2684 case UNW_OR1K_R7:
2685 return "r7";
2686 case UNW_OR1K_R8:
2687 return "r8";
2688 case UNW_OR1K_R9:
2689 return "r9";
2690 case UNW_OR1K_R10:
2691 return "r10";
2692 case UNW_OR1K_R11:
2693 return "r11";
2694 case UNW_OR1K_R12:
2695 return "r12";
2696 case UNW_OR1K_R13:
2697 return "r13";
2698 case UNW_OR1K_R14:
2699 return "r14";
2700 case UNW_OR1K_R15:
2701 return "r15";
2702 case UNW_OR1K_R16:
2703 return "r16";
2704 case UNW_OR1K_R17:
2705 return "r17";
2706 case UNW_OR1K_R18:
2707 return "r18";
2708 case UNW_OR1K_R19:
2709 return "r19";
2710 case UNW_OR1K_R20:
2711 return "r20";
2712 case UNW_OR1K_R21:
2713 return "r21";
2714 case UNW_OR1K_R22:
2715 return "r22";
2716 case UNW_OR1K_R23:
2717 return "r23";
2718 case UNW_OR1K_R24:
2719 return "r24";
2720 case UNW_OR1K_R25:
2721 return "r25";
2722 case UNW_OR1K_R26:
2723 return "r26";
2724 case UNW_OR1K_R27:
2725 return "r27";
2726 case UNW_OR1K_R28:
2727 return "r28";
2728 case UNW_OR1K_R29:
2729 return "r29";
2730 case UNW_OR1K_R30:
2731 return "r30";
2732 case UNW_OR1K_R31:
2733 return "r31";
2734 case UNW_OR1K_EPCR:
2735 return "EPCR";
2736 default:
2737 return "unknown register";
2738 }
2739
2740 }
2741 #endif // _LIBUNWIND_TARGET_OR1K
2742
2743 #if defined(_LIBUNWIND_TARGET_MIPS_O32)
2744 /// Registers_mips_o32 holds the register state of a thread in a 32-bit MIPS
2745 /// process.
2746 class _LIBUNWIND_HIDDEN Registers_mips_o32 {
2747 public:
2748 Registers_mips_o32();
2749 Registers_mips_o32(const void *registers);
2750
2751 bool validRegister(int num) const;
2752 uint32_t getRegister(int num) const;
2753 void setRegister(int num, uint32_t value);
2754 bool validFloatRegister(int num) const;
2755 double getFloatRegister(int num) const;
2756 void setFloatRegister(int num, double value);
2757 bool validVectorRegister(int num) const;
2758 v128 getVectorRegister(int num) const;
2759 void setVectorRegister(int num, v128 value);
2760 static const char *getRegisterName(int num);
2761 void jumpto();
lastDwarfRegNum()2762 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
getArch()2763 static int getArch() { return REGISTERS_MIPS_O32; }
2764
getSP() const2765 uint32_t getSP() const { return _registers.__r[29]; }
setSP(uint32_t value)2766 void setSP(uint32_t value) { _registers.__r[29] = value; }
getIP() const2767 uint32_t getIP() const { return _registers.__pc; }
setIP(uint32_t value)2768 void setIP(uint32_t value) { _registers.__pc = value; }
2769
2770 private:
2771 struct mips_o32_thread_state_t {
2772 uint32_t __r[32];
2773 uint32_t __pc;
2774 uint32_t __hi;
2775 uint32_t __lo;
2776 };
2777
2778 mips_o32_thread_state_t _registers;
2779 #ifdef __mips_hard_float
2780 /// O32 with 32-bit floating point registers only uses half of this
2781 /// space. However, using the same layout for 32-bit vs 64-bit
2782 /// floating point registers results in a single context size for
2783 /// O32 with hard float.
2784 uint32_t _padding;
2785 double _floats[32];
2786 #endif
2787 };
2788
Registers_mips_o32(const void * registers)2789 inline Registers_mips_o32::Registers_mips_o32(const void *registers) {
2790 static_assert((check_fit<Registers_mips_o32, unw_context_t>::does_fit),
2791 "mips_o32 registers do not fit into unw_context_t");
2792 memcpy(&_registers, static_cast<const uint8_t *>(registers),
2793 sizeof(_registers));
2794 }
2795
Registers_mips_o32()2796 inline Registers_mips_o32::Registers_mips_o32() {
2797 memset(&_registers, 0, sizeof(_registers));
2798 }
2799
validRegister(int regNum) const2800 inline bool Registers_mips_o32::validRegister(int regNum) const {
2801 if (regNum == UNW_REG_IP)
2802 return true;
2803 if (regNum == UNW_REG_SP)
2804 return true;
2805 if (regNum < 0)
2806 return false;
2807 if (regNum <= UNW_MIPS_R31)
2808 return true;
2809 #if __mips_isa_rev != 6
2810 if (regNum == UNW_MIPS_HI)
2811 return true;
2812 if (regNum == UNW_MIPS_LO)
2813 return true;
2814 #endif
2815 #if defined(__mips_hard_float) && __mips_fpr == 32
2816 if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
2817 return true;
2818 #endif
2819 // FIXME: DSP accumulator registers, MSA registers
2820 return false;
2821 }
2822
getRegister(int regNum) const2823 inline uint32_t Registers_mips_o32::getRegister(int regNum) const {
2824 if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
2825 return _registers.__r[regNum - UNW_MIPS_R0];
2826 #if defined(__mips_hard_float) && __mips_fpr == 32
2827 if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
2828 uint32_t *p;
2829
2830 if (regNum % 2 == 0)
2831 p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
2832 else
2833 p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
2834 return *p;
2835 }
2836 #endif
2837
2838 switch (regNum) {
2839 case UNW_REG_IP:
2840 return _registers.__pc;
2841 case UNW_REG_SP:
2842 return _registers.__r[29];
2843 case UNW_MIPS_HI:
2844 return _registers.__hi;
2845 case UNW_MIPS_LO:
2846 return _registers.__lo;
2847 }
2848 _LIBUNWIND_ABORT("unsupported mips_o32 register");
2849 }
2850
setRegister(int regNum,uint32_t value)2851 inline void Registers_mips_o32::setRegister(int regNum, uint32_t value) {
2852 if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
2853 _registers.__r[regNum - UNW_MIPS_R0] = value;
2854 return;
2855 }
2856 #if defined(__mips_hard_float) && __mips_fpr == 32
2857 if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
2858 uint32_t *p;
2859
2860 if (regNum % 2 == 0)
2861 p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
2862 else
2863 p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
2864 *p = value;
2865 return;
2866 }
2867 #endif
2868
2869 switch (regNum) {
2870 case UNW_REG_IP:
2871 _registers.__pc = value;
2872 return;
2873 case UNW_REG_SP:
2874 _registers.__r[29] = value;
2875 return;
2876 case UNW_MIPS_HI:
2877 _registers.__hi = value;
2878 return;
2879 case UNW_MIPS_LO:
2880 _registers.__lo = value;
2881 return;
2882 }
2883 _LIBUNWIND_ABORT("unsupported mips_o32 register");
2884 }
2885
validFloatRegister(int regNum) const2886 inline bool Registers_mips_o32::validFloatRegister(int regNum) const {
2887 #if defined(__mips_hard_float) && __mips_fpr == 64
2888 if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
2889 return true;
2890 #else
2891 (void)regNum;
2892 #endif
2893 return false;
2894 }
2895
getFloatRegister(int regNum) const2896 inline double Registers_mips_o32::getFloatRegister(int regNum) const {
2897 #if defined(__mips_hard_float) && __mips_fpr == 64
2898 assert(validFloatRegister(regNum));
2899 return _floats[regNum - UNW_MIPS_F0];
2900 #else
2901 (void)regNum;
2902 _LIBUNWIND_ABORT("mips_o32 float support not implemented");
2903 #endif
2904 }
2905
setFloatRegister(int regNum,double value)2906 inline void Registers_mips_o32::setFloatRegister(int regNum,
2907 double value) {
2908 #if defined(__mips_hard_float) && __mips_fpr == 64
2909 assert(validFloatRegister(regNum));
2910 _floats[regNum - UNW_MIPS_F0] = value;
2911 #else
2912 (void)regNum;
2913 (void)value;
2914 _LIBUNWIND_ABORT("mips_o32 float support not implemented");
2915 #endif
2916 }
2917
validVectorRegister(int) const2918 inline bool Registers_mips_o32::validVectorRegister(int /* regNum */) const {
2919 return false;
2920 }
2921
getVectorRegister(int) const2922 inline v128 Registers_mips_o32::getVectorRegister(int /* regNum */) const {
2923 _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
2924 }
2925
setVectorRegister(int,v128)2926 inline void Registers_mips_o32::setVectorRegister(int /* regNum */, v128 /* value */) {
2927 _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
2928 }
2929
getRegisterName(int regNum)2930 inline const char *Registers_mips_o32::getRegisterName(int regNum) {
2931 switch (regNum) {
2932 case UNW_MIPS_R0:
2933 return "$0";
2934 case UNW_MIPS_R1:
2935 return "$1";
2936 case UNW_MIPS_R2:
2937 return "$2";
2938 case UNW_MIPS_R3:
2939 return "$3";
2940 case UNW_MIPS_R4:
2941 return "$4";
2942 case UNW_MIPS_R5:
2943 return "$5";
2944 case UNW_MIPS_R6:
2945 return "$6";
2946 case UNW_MIPS_R7:
2947 return "$7";
2948 case UNW_MIPS_R8:
2949 return "$8";
2950 case UNW_MIPS_R9:
2951 return "$9";
2952 case UNW_MIPS_R10:
2953 return "$10";
2954 case UNW_MIPS_R11:
2955 return "$11";
2956 case UNW_MIPS_R12:
2957 return "$12";
2958 case UNW_MIPS_R13:
2959 return "$13";
2960 case UNW_MIPS_R14:
2961 return "$14";
2962 case UNW_MIPS_R15:
2963 return "$15";
2964 case UNW_MIPS_R16:
2965 return "$16";
2966 case UNW_MIPS_R17:
2967 return "$17";
2968 case UNW_MIPS_R18:
2969 return "$18";
2970 case UNW_MIPS_R19:
2971 return "$19";
2972 case UNW_MIPS_R20:
2973 return "$20";
2974 case UNW_MIPS_R21:
2975 return "$21";
2976 case UNW_MIPS_R22:
2977 return "$22";
2978 case UNW_MIPS_R23:
2979 return "$23";
2980 case UNW_MIPS_R24:
2981 return "$24";
2982 case UNW_MIPS_R25:
2983 return "$25";
2984 case UNW_MIPS_R26:
2985 return "$26";
2986 case UNW_MIPS_R27:
2987 return "$27";
2988 case UNW_MIPS_R28:
2989 return "$28";
2990 case UNW_MIPS_R29:
2991 return "$29";
2992 case UNW_MIPS_R30:
2993 return "$30";
2994 case UNW_MIPS_R31:
2995 return "$31";
2996 case UNW_MIPS_F0:
2997 return "$f0";
2998 case UNW_MIPS_F1:
2999 return "$f1";
3000 case UNW_MIPS_F2:
3001 return "$f2";
3002 case UNW_MIPS_F3:
3003 return "$f3";
3004 case UNW_MIPS_F4:
3005 return "$f4";
3006 case UNW_MIPS_F5:
3007 return "$f5";
3008 case UNW_MIPS_F6:
3009 return "$f6";
3010 case UNW_MIPS_F7:
3011 return "$f7";
3012 case UNW_MIPS_F8:
3013 return "$f8";
3014 case UNW_MIPS_F9:
3015 return "$f9";
3016 case UNW_MIPS_F10:
3017 return "$f10";
3018 case UNW_MIPS_F11:
3019 return "$f11";
3020 case UNW_MIPS_F12:
3021 return "$f12";
3022 case UNW_MIPS_F13:
3023 return "$f13";
3024 case UNW_MIPS_F14:
3025 return "$f14";
3026 case UNW_MIPS_F15:
3027 return "$f15";
3028 case UNW_MIPS_F16:
3029 return "$f16";
3030 case UNW_MIPS_F17:
3031 return "$f17";
3032 case UNW_MIPS_F18:
3033 return "$f18";
3034 case UNW_MIPS_F19:
3035 return "$f19";
3036 case UNW_MIPS_F20:
3037 return "$f20";
3038 case UNW_MIPS_F21:
3039 return "$f21";
3040 case UNW_MIPS_F22:
3041 return "$f22";
3042 case UNW_MIPS_F23:
3043 return "$f23";
3044 case UNW_MIPS_F24:
3045 return "$f24";
3046 case UNW_MIPS_F25:
3047 return "$f25";
3048 case UNW_MIPS_F26:
3049 return "$f26";
3050 case UNW_MIPS_F27:
3051 return "$f27";
3052 case UNW_MIPS_F28:
3053 return "$f28";
3054 case UNW_MIPS_F29:
3055 return "$f29";
3056 case UNW_MIPS_F30:
3057 return "$f30";
3058 case UNW_MIPS_F31:
3059 return "$f31";
3060 case UNW_MIPS_HI:
3061 return "$hi";
3062 case UNW_MIPS_LO:
3063 return "$lo";
3064 default:
3065 return "unknown register";
3066 }
3067 }
3068 #endif // _LIBUNWIND_TARGET_MIPS_O32
3069
3070 #if defined(_LIBUNWIND_TARGET_MIPS_NEWABI)
3071 /// Registers_mips_newabi holds the register state of a thread in a
3072 /// MIPS process using NEWABI (the N32 or N64 ABIs).
3073 class _LIBUNWIND_HIDDEN Registers_mips_newabi {
3074 public:
3075 Registers_mips_newabi();
3076 Registers_mips_newabi(const void *registers);
3077
3078 bool validRegister(int num) const;
3079 uint64_t getRegister(int num) const;
3080 void setRegister(int num, uint64_t value);
3081 bool validFloatRegister(int num) const;
3082 double getFloatRegister(int num) const;
3083 void setFloatRegister(int num, double value);
3084 bool validVectorRegister(int num) const;
3085 v128 getVectorRegister(int num) const;
3086 void setVectorRegister(int num, v128 value);
3087 static const char *getRegisterName(int num);
3088 void jumpto();
lastDwarfRegNum()3089 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
getArch()3090 static int getArch() { return REGISTERS_MIPS_NEWABI; }
3091
getSP() const3092 uint64_t getSP() const { return _registers.__r[29]; }
setSP(uint64_t value)3093 void setSP(uint64_t value) { _registers.__r[29] = value; }
getIP() const3094 uint64_t getIP() const { return _registers.__pc; }
setIP(uint64_t value)3095 void setIP(uint64_t value) { _registers.__pc = value; }
3096
3097 private:
3098 struct mips_newabi_thread_state_t {
3099 uint64_t __r[32];
3100 uint64_t __pc;
3101 uint64_t __hi;
3102 uint64_t __lo;
3103 };
3104
3105 mips_newabi_thread_state_t _registers;
3106 #ifdef __mips_hard_float
3107 double _floats[32];
3108 #endif
3109 };
3110
Registers_mips_newabi(const void * registers)3111 inline Registers_mips_newabi::Registers_mips_newabi(const void *registers) {
3112 static_assert((check_fit<Registers_mips_newabi, unw_context_t>::does_fit),
3113 "mips_newabi registers do not fit into unw_context_t");
3114 memcpy(&_registers, static_cast<const uint8_t *>(registers),
3115 sizeof(_registers));
3116 }
3117
Registers_mips_newabi()3118 inline Registers_mips_newabi::Registers_mips_newabi() {
3119 memset(&_registers, 0, sizeof(_registers));
3120 }
3121
validRegister(int regNum) const3122 inline bool Registers_mips_newabi::validRegister(int regNum) const {
3123 if (regNum == UNW_REG_IP)
3124 return true;
3125 if (regNum == UNW_REG_SP)
3126 return true;
3127 if (regNum < 0)
3128 return false;
3129 if (regNum <= UNW_MIPS_R31)
3130 return true;
3131 #if __mips_isa_rev != 6
3132 if (regNum == UNW_MIPS_HI)
3133 return true;
3134 if (regNum == UNW_MIPS_LO)
3135 return true;
3136 #endif
3137 // FIXME: Hard float, DSP accumulator registers, MSA registers
3138 return false;
3139 }
3140
getRegister(int regNum) const3141 inline uint64_t Registers_mips_newabi::getRegister(int regNum) const {
3142 if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
3143 return _registers.__r[regNum - UNW_MIPS_R0];
3144
3145 switch (regNum) {
3146 case UNW_REG_IP:
3147 return _registers.__pc;
3148 case UNW_REG_SP:
3149 return _registers.__r[29];
3150 case UNW_MIPS_HI:
3151 return _registers.__hi;
3152 case UNW_MIPS_LO:
3153 return _registers.__lo;
3154 }
3155 _LIBUNWIND_ABORT("unsupported mips_newabi register");
3156 }
3157
setRegister(int regNum,uint64_t value)3158 inline void Registers_mips_newabi::setRegister(int regNum, uint64_t value) {
3159 if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
3160 _registers.__r[regNum - UNW_MIPS_R0] = value;
3161 return;
3162 }
3163
3164 switch (regNum) {
3165 case UNW_REG_IP:
3166 _registers.__pc = value;
3167 return;
3168 case UNW_REG_SP:
3169 _registers.__r[29] = value;
3170 return;
3171 case UNW_MIPS_HI:
3172 _registers.__hi = value;
3173 return;
3174 case UNW_MIPS_LO:
3175 _registers.__lo = value;
3176 return;
3177 }
3178 _LIBUNWIND_ABORT("unsupported mips_newabi register");
3179 }
3180
validFloatRegister(int regNum) const3181 inline bool Registers_mips_newabi::validFloatRegister(int regNum) const {
3182 #ifdef __mips_hard_float
3183 if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
3184 return true;
3185 #else
3186 (void)regNum;
3187 #endif
3188 return false;
3189 }
3190
getFloatRegister(int regNum) const3191 inline double Registers_mips_newabi::getFloatRegister(int regNum) const {
3192 #ifdef __mips_hard_float
3193 assert(validFloatRegister(regNum));
3194 return _floats[regNum - UNW_MIPS_F0];
3195 #else
3196 (void)regNum;
3197 _LIBUNWIND_ABORT("mips_newabi float support not implemented");
3198 #endif
3199 }
3200
setFloatRegister(int regNum,double value)3201 inline void Registers_mips_newabi::setFloatRegister(int regNum,
3202 double value) {
3203 #ifdef __mips_hard_float
3204 assert(validFloatRegister(regNum));
3205 _floats[regNum - UNW_MIPS_F0] = value;
3206 #else
3207 (void)regNum;
3208 (void)value;
3209 _LIBUNWIND_ABORT("mips_newabi float support not implemented");
3210 #endif
3211 }
3212
validVectorRegister(int) const3213 inline bool Registers_mips_newabi::validVectorRegister(int /* regNum */) const {
3214 return false;
3215 }
3216
getVectorRegister(int) const3217 inline v128 Registers_mips_newabi::getVectorRegister(int /* regNum */) const {
3218 _LIBUNWIND_ABORT("mips_newabi vector support not implemented");
3219 }
3220
setVectorRegister(int,v128)3221 inline void Registers_mips_newabi::setVectorRegister(int /* regNum */, v128 /* value */) {
3222 _LIBUNWIND_ABORT("mips_newabi vector support not implemented");
3223 }
3224
getRegisterName(int regNum)3225 inline const char *Registers_mips_newabi::getRegisterName(int regNum) {
3226 switch (regNum) {
3227 case UNW_MIPS_R0:
3228 return "$0";
3229 case UNW_MIPS_R1:
3230 return "$1";
3231 case UNW_MIPS_R2:
3232 return "$2";
3233 case UNW_MIPS_R3:
3234 return "$3";
3235 case UNW_MIPS_R4:
3236 return "$4";
3237 case UNW_MIPS_R5:
3238 return "$5";
3239 case UNW_MIPS_R6:
3240 return "$6";
3241 case UNW_MIPS_R7:
3242 return "$7";
3243 case UNW_MIPS_R8:
3244 return "$8";
3245 case UNW_MIPS_R9:
3246 return "$9";
3247 case UNW_MIPS_R10:
3248 return "$10";
3249 case UNW_MIPS_R11:
3250 return "$11";
3251 case UNW_MIPS_R12:
3252 return "$12";
3253 case UNW_MIPS_R13:
3254 return "$13";
3255 case UNW_MIPS_R14:
3256 return "$14";
3257 case UNW_MIPS_R15:
3258 return "$15";
3259 case UNW_MIPS_R16:
3260 return "$16";
3261 case UNW_MIPS_R17:
3262 return "$17";
3263 case UNW_MIPS_R18:
3264 return "$18";
3265 case UNW_MIPS_R19:
3266 return "$19";
3267 case UNW_MIPS_R20:
3268 return "$20";
3269 case UNW_MIPS_R21:
3270 return "$21";
3271 case UNW_MIPS_R22:
3272 return "$22";
3273 case UNW_MIPS_R23:
3274 return "$23";
3275 case UNW_MIPS_R24:
3276 return "$24";
3277 case UNW_MIPS_R25:
3278 return "$25";
3279 case UNW_MIPS_R26:
3280 return "$26";
3281 case UNW_MIPS_R27:
3282 return "$27";
3283 case UNW_MIPS_R28:
3284 return "$28";
3285 case UNW_MIPS_R29:
3286 return "$29";
3287 case UNW_MIPS_R30:
3288 return "$30";
3289 case UNW_MIPS_R31:
3290 return "$31";
3291 case UNW_MIPS_F0:
3292 return "$f0";
3293 case UNW_MIPS_F1:
3294 return "$f1";
3295 case UNW_MIPS_F2:
3296 return "$f2";
3297 case UNW_MIPS_F3:
3298 return "$f3";
3299 case UNW_MIPS_F4:
3300 return "$f4";
3301 case UNW_MIPS_F5:
3302 return "$f5";
3303 case UNW_MIPS_F6:
3304 return "$f6";
3305 case UNW_MIPS_F7:
3306 return "$f7";
3307 case UNW_MIPS_F8:
3308 return "$f8";
3309 case UNW_MIPS_F9:
3310 return "$f9";
3311 case UNW_MIPS_F10:
3312 return "$f10";
3313 case UNW_MIPS_F11:
3314 return "$f11";
3315 case UNW_MIPS_F12:
3316 return "$f12";
3317 case UNW_MIPS_F13:
3318 return "$f13";
3319 case UNW_MIPS_F14:
3320 return "$f14";
3321 case UNW_MIPS_F15:
3322 return "$f15";
3323 case UNW_MIPS_F16:
3324 return "$f16";
3325 case UNW_MIPS_F17:
3326 return "$f17";
3327 case UNW_MIPS_F18:
3328 return "$f18";
3329 case UNW_MIPS_F19:
3330 return "$f19";
3331 case UNW_MIPS_F20:
3332 return "$f20";
3333 case UNW_MIPS_F21:
3334 return "$f21";
3335 case UNW_MIPS_F22:
3336 return "$f22";
3337 case UNW_MIPS_F23:
3338 return "$f23";
3339 case UNW_MIPS_F24:
3340 return "$f24";
3341 case UNW_MIPS_F25:
3342 return "$f25";
3343 case UNW_MIPS_F26:
3344 return "$f26";
3345 case UNW_MIPS_F27:
3346 return "$f27";
3347 case UNW_MIPS_F28:
3348 return "$f28";
3349 case UNW_MIPS_F29:
3350 return "$f29";
3351 case UNW_MIPS_F30:
3352 return "$f30";
3353 case UNW_MIPS_F31:
3354 return "$f31";
3355 case UNW_MIPS_HI:
3356 return "$hi";
3357 case UNW_MIPS_LO:
3358 return "$lo";
3359 default:
3360 return "unknown register";
3361 }
3362 }
3363 #endif // _LIBUNWIND_TARGET_MIPS_NEWABI
3364
3365 #if defined(_LIBUNWIND_TARGET_SPARC)
3366 /// Registers_sparc holds the register state of a thread in a 32-bit Sparc
3367 /// process.
3368 class _LIBUNWIND_HIDDEN Registers_sparc {
3369 public:
3370 Registers_sparc();
3371 Registers_sparc(const void *registers);
3372
3373 bool validRegister(int num) const;
3374 uint32_t getRegister(int num) const;
3375 void setRegister(int num, uint32_t value);
3376 bool validFloatRegister(int num) const;
3377 double getFloatRegister(int num) const;
3378 void setFloatRegister(int num, double value);
3379 bool validVectorRegister(int num) const;
3380 v128 getVectorRegister(int num) const;
3381 void setVectorRegister(int num, v128 value);
3382 static const char *getRegisterName(int num);
3383 void jumpto();
lastDwarfRegNum()3384 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC; }
getArch()3385 static int getArch() { return REGISTERS_SPARC; }
3386
getSP() const3387 uint64_t getSP() const { return _registers.__regs[UNW_SPARC_O6]; }
setSP(uint32_t value)3388 void setSP(uint32_t value) { _registers.__regs[UNW_SPARC_O6] = value; }
getIP() const3389 uint64_t getIP() const { return _registers.__regs[UNW_SPARC_O7]; }
setIP(uint32_t value)3390 void setIP(uint32_t value) { _registers.__regs[UNW_SPARC_O7] = value; }
3391
3392 private:
3393 struct sparc_thread_state_t {
3394 unsigned int __regs[32];
3395 };
3396
3397 sparc_thread_state_t _registers;
3398 };
3399
Registers_sparc(const void * registers)3400 inline Registers_sparc::Registers_sparc(const void *registers) {
3401 static_assert((check_fit<Registers_sparc, unw_context_t>::does_fit),
3402 "sparc registers do not fit into unw_context_t");
3403 memcpy(&_registers, static_cast<const uint8_t *>(registers),
3404 sizeof(_registers));
3405 }
3406
Registers_sparc()3407 inline Registers_sparc::Registers_sparc() {
3408 memset(&_registers, 0, sizeof(_registers));
3409 }
3410
validRegister(int regNum) const3411 inline bool Registers_sparc::validRegister(int regNum) const {
3412 if (regNum == UNW_REG_IP)
3413 return true;
3414 if (regNum == UNW_REG_SP)
3415 return true;
3416 if (regNum < 0)
3417 return false;
3418 if (regNum <= UNW_SPARC_I7)
3419 return true;
3420 return false;
3421 }
3422
getRegister(int regNum) const3423 inline uint32_t Registers_sparc::getRegister(int regNum) const {
3424 if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) {
3425 return _registers.__regs[regNum];
3426 }
3427
3428 switch (regNum) {
3429 case UNW_REG_IP:
3430 return _registers.__regs[UNW_SPARC_O7];
3431 case UNW_REG_SP:
3432 return _registers.__regs[UNW_SPARC_O6];
3433 }
3434 _LIBUNWIND_ABORT("unsupported sparc register");
3435 }
3436
setRegister(int regNum,uint32_t value)3437 inline void Registers_sparc::setRegister(int regNum, uint32_t value) {
3438 if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) {
3439 _registers.__regs[regNum] = value;
3440 return;
3441 }
3442
3443 switch (regNum) {
3444 case UNW_REG_IP:
3445 _registers.__regs[UNW_SPARC_O7] = value;
3446 return;
3447 case UNW_REG_SP:
3448 _registers.__regs[UNW_SPARC_O6] = value;
3449 return;
3450 }
3451 _LIBUNWIND_ABORT("unsupported sparc register");
3452 }
3453
validFloatRegister(int) const3454 inline bool Registers_sparc::validFloatRegister(int) const { return false; }
3455
getFloatRegister(int) const3456 inline double Registers_sparc::getFloatRegister(int) const {
3457 _LIBUNWIND_ABORT("no Sparc float registers");
3458 }
3459
setFloatRegister(int,double)3460 inline void Registers_sparc::setFloatRegister(int, double) {
3461 _LIBUNWIND_ABORT("no Sparc float registers");
3462 }
3463
validVectorRegister(int) const3464 inline bool Registers_sparc::validVectorRegister(int) const { return false; }
3465
getVectorRegister(int) const3466 inline v128 Registers_sparc::getVectorRegister(int) const {
3467 _LIBUNWIND_ABORT("no Sparc vector registers");
3468 }
3469
setVectorRegister(int,v128)3470 inline void Registers_sparc::setVectorRegister(int, v128) {
3471 _LIBUNWIND_ABORT("no Sparc vector registers");
3472 }
3473
getRegisterName(int regNum)3474 inline const char *Registers_sparc::getRegisterName(int regNum) {
3475 switch (regNum) {
3476 case UNW_REG_IP:
3477 return "pc";
3478 case UNW_SPARC_G0:
3479 return "g0";
3480 case UNW_SPARC_G1:
3481 return "g1";
3482 case UNW_SPARC_G2:
3483 return "g2";
3484 case UNW_SPARC_G3:
3485 return "g3";
3486 case UNW_SPARC_G4:
3487 return "g4";
3488 case UNW_SPARC_G5:
3489 return "g5";
3490 case UNW_SPARC_G6:
3491 return "g6";
3492 case UNW_SPARC_G7:
3493 return "g7";
3494 case UNW_SPARC_O0:
3495 return "o0";
3496 case UNW_SPARC_O1:
3497 return "o1";
3498 case UNW_SPARC_O2:
3499 return "o2";
3500 case UNW_SPARC_O3:
3501 return "o3";
3502 case UNW_SPARC_O4:
3503 return "o4";
3504 case UNW_SPARC_O5:
3505 return "o5";
3506 case UNW_REG_SP:
3507 case UNW_SPARC_O6:
3508 return "sp";
3509 case UNW_SPARC_O7:
3510 return "o7";
3511 case UNW_SPARC_L0:
3512 return "l0";
3513 case UNW_SPARC_L1:
3514 return "l1";
3515 case UNW_SPARC_L2:
3516 return "l2";
3517 case UNW_SPARC_L3:
3518 return "l3";
3519 case UNW_SPARC_L4:
3520 return "l4";
3521 case UNW_SPARC_L5:
3522 return "l5";
3523 case UNW_SPARC_L6:
3524 return "l6";
3525 case UNW_SPARC_L7:
3526 return "l7";
3527 case UNW_SPARC_I0:
3528 return "i0";
3529 case UNW_SPARC_I1:
3530 return "i1";
3531 case UNW_SPARC_I2:
3532 return "i2";
3533 case UNW_SPARC_I3:
3534 return "i3";
3535 case UNW_SPARC_I4:
3536 return "i4";
3537 case UNW_SPARC_I5:
3538 return "i5";
3539 case UNW_SPARC_I6:
3540 return "fp";
3541 case UNW_SPARC_I7:
3542 return "i7";
3543 default:
3544 return "unknown register";
3545 }
3546 }
3547 #endif // _LIBUNWIND_TARGET_SPARC
3548
3549 #if defined(_LIBUNWIND_TARGET_HEXAGON)
3550 /// Registers_hexagon holds the register state of a thread in a Hexagon QDSP6
3551 /// process.
3552 class _LIBUNWIND_HIDDEN Registers_hexagon {
3553 public:
3554 Registers_hexagon();
3555 Registers_hexagon(const void *registers);
3556
3557 bool validRegister(int num) const;
3558 uint32_t getRegister(int num) const;
3559 void setRegister(int num, uint32_t value);
3560 bool validFloatRegister(int num) const;
3561 double getFloatRegister(int num) const;
3562 void setFloatRegister(int num, double value);
3563 bool validVectorRegister(int num) const;
3564 v128 getVectorRegister(int num) const;
3565 void setVectorRegister(int num, v128 value);
3566 const char *getRegisterName(int num);
3567 void jumpto();
lastDwarfRegNum()3568 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON; }
getArch()3569 static int getArch() { return REGISTERS_HEXAGON; }
3570
getSP() const3571 uint32_t getSP() const { return _registers.__r[UNW_HEXAGON_R29]; }
setSP(uint32_t value)3572 void setSP(uint32_t value) { _registers.__r[UNW_HEXAGON_R29] = value; }
getIP() const3573 uint32_t getIP() const { return _registers.__r[UNW_HEXAGON_PC]; }
setIP(uint32_t value)3574 void setIP(uint32_t value) { _registers.__r[UNW_HEXAGON_PC] = value; }
3575
3576 private:
3577 struct hexagon_thread_state_t {
3578 unsigned int __r[35];
3579 };
3580
3581 hexagon_thread_state_t _registers;
3582 };
3583
Registers_hexagon(const void * registers)3584 inline Registers_hexagon::Registers_hexagon(const void *registers) {
3585 static_assert((check_fit<Registers_hexagon, unw_context_t>::does_fit),
3586 "hexagon registers do not fit into unw_context_t");
3587 memcpy(&_registers, static_cast<const uint8_t *>(registers),
3588 sizeof(_registers));
3589 }
3590
Registers_hexagon()3591 inline Registers_hexagon::Registers_hexagon() {
3592 memset(&_registers, 0, sizeof(_registers));
3593 }
3594
validRegister(int regNum) const3595 inline bool Registers_hexagon::validRegister(int regNum) const {
3596 if (regNum <= UNW_HEXAGON_R31)
3597 return true;
3598 return false;
3599 }
3600
getRegister(int regNum) const3601 inline uint32_t Registers_hexagon::getRegister(int regNum) const {
3602 if (regNum >= UNW_HEXAGON_R0 && regNum <= UNW_HEXAGON_R31)
3603 return _registers.__r[regNum - UNW_HEXAGON_R0];
3604
3605 switch (regNum) {
3606 case UNW_REG_IP:
3607 return _registers.__r[UNW_HEXAGON_PC];
3608 case UNW_REG_SP:
3609 return _registers.__r[UNW_HEXAGON_R29];
3610 }
3611 _LIBUNWIND_ABORT("unsupported hexagon register");
3612 }
3613
setRegister(int regNum,uint32_t value)3614 inline void Registers_hexagon::setRegister(int regNum, uint32_t value) {
3615 if (regNum >= UNW_HEXAGON_R0 && regNum <= UNW_HEXAGON_R31) {
3616 _registers.__r[regNum - UNW_HEXAGON_R0] = value;
3617 return;
3618 }
3619
3620 switch (regNum) {
3621 case UNW_REG_IP:
3622 _registers.__r[UNW_HEXAGON_PC] = value;
3623 return;
3624 case UNW_REG_SP:
3625 _registers.__r[UNW_HEXAGON_R29] = value;
3626 return;
3627 }
3628 _LIBUNWIND_ABORT("unsupported hexagon register");
3629 }
3630
validFloatRegister(int) const3631 inline bool Registers_hexagon::validFloatRegister(int /* regNum */) const {
3632 return false;
3633 }
3634
getFloatRegister(int) const3635 inline double Registers_hexagon::getFloatRegister(int /* regNum */) const {
3636 _LIBUNWIND_ABORT("hexagon float support not implemented");
3637 }
3638
setFloatRegister(int,double)3639 inline void Registers_hexagon::setFloatRegister(int /* regNum */,
3640 double /* value */) {
3641 _LIBUNWIND_ABORT("hexagon float support not implemented");
3642 }
3643
validVectorRegister(int) const3644 inline bool Registers_hexagon::validVectorRegister(int /* regNum */) const {
3645 return false;
3646 }
3647
getVectorRegister(int) const3648 inline v128 Registers_hexagon::getVectorRegister(int /* regNum */) const {
3649 _LIBUNWIND_ABORT("hexagon vector support not implemented");
3650 }
3651
setVectorRegister(int,v128)3652 inline void Registers_hexagon::setVectorRegister(int /* regNum */, v128 /* value */) {
3653 _LIBUNWIND_ABORT("hexagon vector support not implemented");
3654 }
3655
getRegisterName(int regNum)3656 inline const char *Registers_hexagon::getRegisterName(int regNum) {
3657 switch (regNum) {
3658 case UNW_HEXAGON_R0:
3659 return "r0";
3660 case UNW_HEXAGON_R1:
3661 return "r1";
3662 case UNW_HEXAGON_R2:
3663 return "r2";
3664 case UNW_HEXAGON_R3:
3665 return "r3";
3666 case UNW_HEXAGON_R4:
3667 return "r4";
3668 case UNW_HEXAGON_R5:
3669 return "r5";
3670 case UNW_HEXAGON_R6:
3671 return "r6";
3672 case UNW_HEXAGON_R7:
3673 return "r7";
3674 case UNW_HEXAGON_R8:
3675 return "r8";
3676 case UNW_HEXAGON_R9:
3677 return "r9";
3678 case UNW_HEXAGON_R10:
3679 return "r10";
3680 case UNW_HEXAGON_R11:
3681 return "r11";
3682 case UNW_HEXAGON_R12:
3683 return "r12";
3684 case UNW_HEXAGON_R13:
3685 return "r13";
3686 case UNW_HEXAGON_R14:
3687 return "r14";
3688 case UNW_HEXAGON_R15:
3689 return "r15";
3690 case UNW_HEXAGON_R16:
3691 return "r16";
3692 case UNW_HEXAGON_R17:
3693 return "r17";
3694 case UNW_HEXAGON_R18:
3695 return "r18";
3696 case UNW_HEXAGON_R19:
3697 return "r19";
3698 case UNW_HEXAGON_R20:
3699 return "r20";
3700 case UNW_HEXAGON_R21:
3701 return "r21";
3702 case UNW_HEXAGON_R22:
3703 return "r22";
3704 case UNW_HEXAGON_R23:
3705 return "r23";
3706 case UNW_HEXAGON_R24:
3707 return "r24";
3708 case UNW_HEXAGON_R25:
3709 return "r25";
3710 case UNW_HEXAGON_R26:
3711 return "r26";
3712 case UNW_HEXAGON_R27:
3713 return "r27";
3714 case UNW_HEXAGON_R28:
3715 return "r28";
3716 case UNW_HEXAGON_R29:
3717 return "r29";
3718 case UNW_HEXAGON_R30:
3719 return "r30";
3720 case UNW_HEXAGON_R31:
3721 return "r31";
3722 default:
3723 return "unknown register";
3724 }
3725
3726 }
3727 #endif // _LIBUNWIND_TARGET_HEXAGON
3728
3729
3730 #if defined(_LIBUNWIND_TARGET_RISCV)
3731 /// Registers_riscv holds the register state of a thread in a RISC-V
3732 /// process.
3733
3734 // This check makes it safe when LIBUNWIND_ENABLE_CROSS_UNWINDING enabled.
3735 # ifdef __riscv
3736 # if __riscv_xlen == 32
3737 typedef uint32_t reg_t;
3738 # elif __riscv_xlen == 64
3739 typedef uint64_t reg_t;
3740 # else
3741 # error "Unsupported __riscv_xlen"
3742 # endif
3743
3744 # if defined(__riscv_flen)
3745 # if __riscv_flen == 64
3746 typedef double fp_t;
3747 # elif __riscv_flen == 32
3748 typedef float fp_t;
3749 # else
3750 # error "Unsupported __riscv_flen"
3751 # endif
3752 # else
3753 // This is just for supressing undeclared error of fp_t.
3754 typedef double fp_t;
3755 # endif
3756 # else
3757 // Use Max possible width when cross unwinding
3758 typedef uint64_t reg_t;
3759 typedef double fp_t;
3760 # define __riscv_xlen 64
3761 # define __riscv_flen 64
3762 #endif
3763
3764 /// Registers_riscv holds the register state of a thread.
3765 class _LIBUNWIND_HIDDEN Registers_riscv {
3766 public:
3767 Registers_riscv();
3768 Registers_riscv(const void *registers);
3769
3770 bool validRegister(int num) const;
3771 reg_t getRegister(int num) const;
3772 void setRegister(int num, reg_t value);
3773 bool validFloatRegister(int num) const;
3774 fp_t getFloatRegister(int num) const;
3775 void setFloatRegister(int num, fp_t value);
3776 bool validVectorRegister(int num) const;
3777 v128 getVectorRegister(int num) const;
3778 void setVectorRegister(int num, v128 value);
3779 static const char *getRegisterName(int num);
3780 void jumpto();
lastDwarfRegNum()3781 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV; }
getArch()3782 static int getArch() { return REGISTERS_RISCV; }
3783
getSP() const3784 reg_t getSP() const { return _registers[2]; }
setSP(reg_t value)3785 void setSP(reg_t value) { _registers[2] = value; }
getIP() const3786 reg_t getIP() const { return _registers[0]; }
setIP(reg_t value)3787 void setIP(reg_t value) { _registers[0] = value; }
3788
3789 private:
3790 // _registers[0] holds the pc
3791 reg_t _registers[32];
3792 # if defined(__riscv_flen)
3793 fp_t _floats[32];
3794 # endif
3795 };
3796
Registers_riscv(const void * registers)3797 inline Registers_riscv::Registers_riscv(const void *registers) {
3798 static_assert((check_fit<Registers_riscv, unw_context_t>::does_fit),
3799 "riscv registers do not fit into unw_context_t");
3800 memcpy(&_registers, registers, sizeof(_registers));
3801 # if __riscv_xlen == 32
3802 static_assert(sizeof(_registers) == 0x80,
3803 "expected float registers to be at offset 128");
3804 # elif __riscv_xlen == 64
3805 static_assert(sizeof(_registers) == 0x100,
3806 "expected float registers to be at offset 256");
3807 # else
3808 # error "Unexpected float registers."
3809 # endif
3810
3811 # if defined(__riscv_flen)
3812 memcpy(_floats,
3813 static_cast<const uint8_t *>(registers) + sizeof(_registers),
3814 sizeof(_floats));
3815 # endif
3816 }
3817
Registers_riscv()3818 inline Registers_riscv::Registers_riscv() {
3819 memset(&_registers, 0, sizeof(_registers));
3820 # if defined(__riscv_flen)
3821 memset(&_floats, 0, sizeof(_floats));
3822 # endif
3823 }
3824
validRegister(int regNum) const3825 inline bool Registers_riscv::validRegister(int regNum) const {
3826 if (regNum == UNW_REG_IP)
3827 return true;
3828 if (regNum == UNW_REG_SP)
3829 return true;
3830 if (regNum < 0)
3831 return false;
3832 if (regNum > UNW_RISCV_F31)
3833 return false;
3834 return true;
3835 }
3836
getRegister(int regNum) const3837 inline reg_t Registers_riscv::getRegister(int regNum) const {
3838 if (regNum == UNW_REG_IP)
3839 return _registers[0];
3840 if (regNum == UNW_REG_SP)
3841 return _registers[2];
3842 if (regNum == UNW_RISCV_X0)
3843 return 0;
3844 if ((regNum > 0) && (regNum < 32))
3845 return _registers[regNum];
3846 _LIBUNWIND_ABORT("unsupported riscv register");
3847 }
3848
setRegister(int regNum,reg_t value)3849 inline void Registers_riscv::setRegister(int regNum, reg_t value) {
3850 if (regNum == UNW_REG_IP)
3851 _registers[0] = value;
3852 else if (regNum == UNW_REG_SP)
3853 _registers[2] = value;
3854 else if (regNum == UNW_RISCV_X0)
3855 /* x0 is hardwired to zero */
3856 return;
3857 else if ((regNum > 0) && (regNum < 32))
3858 _registers[regNum] = value;
3859 else
3860 _LIBUNWIND_ABORT("unsupported riscv register");
3861 }
3862
getRegisterName(int regNum)3863 inline const char *Registers_riscv::getRegisterName(int regNum) {
3864 switch (regNum) {
3865 case UNW_REG_IP:
3866 return "pc";
3867 case UNW_REG_SP:
3868 return "sp";
3869 case UNW_RISCV_X0:
3870 return "zero";
3871 case UNW_RISCV_X1:
3872 return "ra";
3873 case UNW_RISCV_X2:
3874 return "sp";
3875 case UNW_RISCV_X3:
3876 return "gp";
3877 case UNW_RISCV_X4:
3878 return "tp";
3879 case UNW_RISCV_X5:
3880 return "t0";
3881 case UNW_RISCV_X6:
3882 return "t1";
3883 case UNW_RISCV_X7:
3884 return "t2";
3885 case UNW_RISCV_X8:
3886 return "s0";
3887 case UNW_RISCV_X9:
3888 return "s1";
3889 case UNW_RISCV_X10:
3890 return "a0";
3891 case UNW_RISCV_X11:
3892 return "a1";
3893 case UNW_RISCV_X12:
3894 return "a2";
3895 case UNW_RISCV_X13:
3896 return "a3";
3897 case UNW_RISCV_X14:
3898 return "a4";
3899 case UNW_RISCV_X15:
3900 return "a5";
3901 case UNW_RISCV_X16:
3902 return "a6";
3903 case UNW_RISCV_X17:
3904 return "a7";
3905 case UNW_RISCV_X18:
3906 return "s2";
3907 case UNW_RISCV_X19:
3908 return "s3";
3909 case UNW_RISCV_X20:
3910 return "s4";
3911 case UNW_RISCV_X21:
3912 return "s5";
3913 case UNW_RISCV_X22:
3914 return "s6";
3915 case UNW_RISCV_X23:
3916 return "s7";
3917 case UNW_RISCV_X24:
3918 return "s8";
3919 case UNW_RISCV_X25:
3920 return "s9";
3921 case UNW_RISCV_X26:
3922 return "s10";
3923 case UNW_RISCV_X27:
3924 return "s11";
3925 case UNW_RISCV_X28:
3926 return "t3";
3927 case UNW_RISCV_X29:
3928 return "t4";
3929 case UNW_RISCV_X30:
3930 return "t5";
3931 case UNW_RISCV_X31:
3932 return "t6";
3933 case UNW_RISCV_F0:
3934 return "ft0";
3935 case UNW_RISCV_F1:
3936 return "ft1";
3937 case UNW_RISCV_F2:
3938 return "ft2";
3939 case UNW_RISCV_F3:
3940 return "ft3";
3941 case UNW_RISCV_F4:
3942 return "ft4";
3943 case UNW_RISCV_F5:
3944 return "ft5";
3945 case UNW_RISCV_F6:
3946 return "ft6";
3947 case UNW_RISCV_F7:
3948 return "ft7";
3949 case UNW_RISCV_F8:
3950 return "fs0";
3951 case UNW_RISCV_F9:
3952 return "fs1";
3953 case UNW_RISCV_F10:
3954 return "fa0";
3955 case UNW_RISCV_F11:
3956 return "fa1";
3957 case UNW_RISCV_F12:
3958 return "fa2";
3959 case UNW_RISCV_F13:
3960 return "fa3";
3961 case UNW_RISCV_F14:
3962 return "fa4";
3963 case UNW_RISCV_F15:
3964 return "fa5";
3965 case UNW_RISCV_F16:
3966 return "fa6";
3967 case UNW_RISCV_F17:
3968 return "fa7";
3969 case UNW_RISCV_F18:
3970 return "fs2";
3971 case UNW_RISCV_F19:
3972 return "fs3";
3973 case UNW_RISCV_F20:
3974 return "fs4";
3975 case UNW_RISCV_F21:
3976 return "fs5";
3977 case UNW_RISCV_F22:
3978 return "fs6";
3979 case UNW_RISCV_F23:
3980 return "fs7";
3981 case UNW_RISCV_F24:
3982 return "fs8";
3983 case UNW_RISCV_F25:
3984 return "fs9";
3985 case UNW_RISCV_F26:
3986 return "fs10";
3987 case UNW_RISCV_F27:
3988 return "fs11";
3989 case UNW_RISCV_F28:
3990 return "ft8";
3991 case UNW_RISCV_F29:
3992 return "ft9";
3993 case UNW_RISCV_F30:
3994 return "ft10";
3995 case UNW_RISCV_F31:
3996 return "ft11";
3997 default:
3998 return "unknown register";
3999 }
4000 }
4001
validFloatRegister(int regNum) const4002 inline bool Registers_riscv::validFloatRegister(int regNum) const {
4003 # if defined(__riscv_flen)
4004 if (regNum < UNW_RISCV_F0)
4005 return false;
4006 if (regNum > UNW_RISCV_F31)
4007 return false;
4008 return true;
4009 # else
4010 (void)regNum;
4011 return false;
4012 # endif
4013 }
4014
getFloatRegister(int regNum) const4015 inline fp_t Registers_riscv::getFloatRegister(int regNum) const {
4016 # if defined(__riscv_flen)
4017 assert(validFloatRegister(regNum));
4018 return _floats[regNum - UNW_RISCV_F0];
4019 # else
4020 (void)regNum;
4021 _LIBUNWIND_ABORT("libunwind not built with float support");
4022 # endif
4023 }
4024
setFloatRegister(int regNum,fp_t value)4025 inline void Registers_riscv::setFloatRegister(int regNum, fp_t value) {
4026 # if defined(__riscv_flen)
4027 assert(validFloatRegister(regNum));
4028 _floats[regNum - UNW_RISCV_F0] = value;
4029 # else
4030 (void)regNum;
4031 (void)value;
4032 _LIBUNWIND_ABORT("libunwind not built with float support");
4033 # endif
4034 }
4035
validVectorRegister(int) const4036 inline bool Registers_riscv::validVectorRegister(int) const {
4037 return false;
4038 }
4039
getVectorRegister(int) const4040 inline v128 Registers_riscv::getVectorRegister(int) const {
4041 _LIBUNWIND_ABORT("no riscv vector register support yet");
4042 }
4043
setVectorRegister(int,v128)4044 inline void Registers_riscv::setVectorRegister(int, v128) {
4045 _LIBUNWIND_ABORT("no riscv vector register support yet");
4046 }
4047 #endif // _LIBUNWIND_TARGET_RISCV
4048
4049 #if defined(_LIBUNWIND_TARGET_VE)
4050 /// Registers_ve holds the register state of a thread in a VE process.
4051 class _LIBUNWIND_HIDDEN Registers_ve {
4052 public:
4053 Registers_ve();
4054 Registers_ve(const void *registers);
4055
4056 bool validRegister(int num) const;
4057 uint64_t getRegister(int num) const;
4058 void setRegister(int num, uint64_t value);
4059 bool validFloatRegister(int num) const;
4060 double getFloatRegister(int num) const;
4061 void setFloatRegister(int num, double value);
4062 bool validVectorRegister(int num) const;
4063 v128 getVectorRegister(int num) const;
4064 void setVectorRegister(int num, v128 value);
4065 static const char *getRegisterName(int num);
4066 void jumpto();
lastDwarfRegNum()4067 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE; }
getArch()4068 static int getArch() { return REGISTERS_VE; }
4069
getSP() const4070 uint64_t getSP() const { return _registers.__s[11]; }
setSP(uint64_t value)4071 void setSP(uint64_t value) { _registers.__s[11] = value; }
getIP() const4072 uint64_t getIP() const { return _registers.__ic; }
setIP(uint64_t value)4073 void setIP(uint64_t value) { _registers.__ic = value; }
4074
4075 private:
4076 // FIXME: Need to store not only scalar registers but also vector and vector
4077 // mask registers. VEOS uses mcontext_t defined in ucontext.h. It takes
4078 // 524288 bytes (65536*8 bytes), though. Currently, we use libunwind for
4079 // SjLj exception support only, so Registers_ve is not implemented completely.
4080 struct ve_thread_state_t {
4081 uint64_t __s[64]; // s0-s64
4082 uint64_t __ic; // Instruction counter (IC)
4083 uint64_t __vixr; // Vector Index Register
4084 uint64_t __vl; // Vector Length Register
4085 };
4086
4087 ve_thread_state_t _registers; // total 67 registers
4088
4089 // Currently no vector register is preserved.
4090 };
4091
Registers_ve(const void * registers)4092 inline Registers_ve::Registers_ve(const void *registers) {
4093 static_assert((check_fit<Registers_ve, unw_context_t>::does_fit),
4094 "ve registers do not fit into unw_context_t");
4095 memcpy(&_registers, static_cast<const uint8_t *>(registers),
4096 sizeof(_registers));
4097 static_assert(sizeof(_registers) == 536,
4098 "expected vector register offset to be 536");
4099 }
4100
Registers_ve()4101 inline Registers_ve::Registers_ve() {
4102 memset(&_registers, 0, sizeof(_registers));
4103 }
4104
validRegister(int regNum) const4105 inline bool Registers_ve::validRegister(int regNum) const {
4106 if (regNum >= UNW_VE_S0 && regNum <= UNW_VE_S63)
4107 return true;
4108
4109 switch (regNum) {
4110 case UNW_REG_IP:
4111 case UNW_REG_SP:
4112 case UNW_VE_VIXR:
4113 case UNW_VE_VL:
4114 return true;
4115 default:
4116 return false;
4117 }
4118 }
4119
getRegister(int regNum) const4120 inline uint64_t Registers_ve::getRegister(int regNum) const {
4121 if (regNum >= UNW_VE_S0 && regNum <= UNW_VE_S63)
4122 return _registers.__s[regNum - UNW_VE_S0];
4123
4124 switch (regNum) {
4125 case UNW_REG_IP:
4126 return _registers.__ic;
4127 case UNW_REG_SP:
4128 return _registers.__s[11];
4129 case UNW_VE_VIXR:
4130 return _registers.__vixr;
4131 case UNW_VE_VL:
4132 return _registers.__vl;
4133 }
4134 _LIBUNWIND_ABORT("unsupported ve register");
4135 }
4136
setRegister(int regNum,uint64_t value)4137 inline void Registers_ve::setRegister(int regNum, uint64_t value) {
4138 if (regNum >= UNW_VE_S0 && regNum <= UNW_VE_S63) {
4139 _registers.__s[regNum - UNW_VE_S0] = value;
4140 return;
4141 }
4142
4143 switch (regNum) {
4144 case UNW_REG_IP:
4145 _registers.__ic = value;
4146 return;
4147 case UNW_REG_SP:
4148 _registers.__s[11] = value;
4149 return;
4150 case UNW_VE_VIXR:
4151 _registers.__vixr = value;
4152 return;
4153 case UNW_VE_VL:
4154 _registers.__vl = value;
4155 return;
4156 }
4157 _LIBUNWIND_ABORT("unsupported ve register");
4158 }
4159
validFloatRegister(int) const4160 inline bool Registers_ve::validFloatRegister(int /* regNum */) const {
4161 return false;
4162 }
4163
getFloatRegister(int) const4164 inline double Registers_ve::getFloatRegister(int /* regNum */) const {
4165 _LIBUNWIND_ABORT("VE doesn't have float registers");
4166 }
4167
setFloatRegister(int,double)4168 inline void Registers_ve::setFloatRegister(int /* regNum */,
4169 double /* value */) {
4170 _LIBUNWIND_ABORT("VE doesn't have float registers");
4171 }
4172
validVectorRegister(int) const4173 inline bool Registers_ve::validVectorRegister(int /* regNum */) const {
4174 return false;
4175 }
4176
getVectorRegister(int) const4177 inline v128 Registers_ve::getVectorRegister(int /* regNum */) const {
4178 _LIBUNWIND_ABORT("VE vector support not implemented");
4179 }
4180
setVectorRegister(int,v128)4181 inline void Registers_ve::setVectorRegister(int /* regNum */,
4182 v128 /* value */) {
4183 _LIBUNWIND_ABORT("VE vector support not implemented");
4184 }
4185
getRegisterName(int regNum)4186 inline const char *Registers_ve::getRegisterName(int regNum) {
4187 switch (regNum) {
4188 case UNW_REG_IP:
4189 return "ip";
4190 case UNW_REG_SP:
4191 return "sp";
4192 case UNW_VE_VIXR:
4193 return "vixr";
4194 case UNW_VE_VL:
4195 return "vl";
4196 case UNW_VE_S0:
4197 return "s0";
4198 case UNW_VE_S1:
4199 return "s1";
4200 case UNW_VE_S2:
4201 return "s2";
4202 case UNW_VE_S3:
4203 return "s3";
4204 case UNW_VE_S4:
4205 return "s4";
4206 case UNW_VE_S5:
4207 return "s5";
4208 case UNW_VE_S6:
4209 return "s6";
4210 case UNW_VE_S7:
4211 return "s7";
4212 case UNW_VE_S8:
4213 return "s8";
4214 case UNW_VE_S9:
4215 return "s9";
4216 case UNW_VE_S10:
4217 return "s10";
4218 case UNW_VE_S11:
4219 return "s11";
4220 case UNW_VE_S12:
4221 return "s12";
4222 case UNW_VE_S13:
4223 return "s13";
4224 case UNW_VE_S14:
4225 return "s14";
4226 case UNW_VE_S15:
4227 return "s15";
4228 case UNW_VE_S16:
4229 return "s16";
4230 case UNW_VE_S17:
4231 return "s17";
4232 case UNW_VE_S18:
4233 return "s18";
4234 case UNW_VE_S19:
4235 return "s19";
4236 case UNW_VE_S20:
4237 return "s20";
4238 case UNW_VE_S21:
4239 return "s21";
4240 case UNW_VE_S22:
4241 return "s22";
4242 case UNW_VE_S23:
4243 return "s23";
4244 case UNW_VE_S24:
4245 return "s24";
4246 case UNW_VE_S25:
4247 return "s25";
4248 case UNW_VE_S26:
4249 return "s26";
4250 case UNW_VE_S27:
4251 return "s27";
4252 case UNW_VE_S28:
4253 return "s28";
4254 case UNW_VE_S29:
4255 return "s29";
4256 case UNW_VE_S30:
4257 return "s30";
4258 case UNW_VE_S31:
4259 return "s31";
4260 case UNW_VE_S32:
4261 return "s32";
4262 case UNW_VE_S33:
4263 return "s33";
4264 case UNW_VE_S34:
4265 return "s34";
4266 case UNW_VE_S35:
4267 return "s35";
4268 case UNW_VE_S36:
4269 return "s36";
4270 case UNW_VE_S37:
4271 return "s37";
4272 case UNW_VE_S38:
4273 return "s38";
4274 case UNW_VE_S39:
4275 return "s39";
4276 case UNW_VE_S40:
4277 return "s40";
4278 case UNW_VE_S41:
4279 return "s41";
4280 case UNW_VE_S42:
4281 return "s42";
4282 case UNW_VE_S43:
4283 return "s43";
4284 case UNW_VE_S44:
4285 return "s44";
4286 case UNW_VE_S45:
4287 return "s45";
4288 case UNW_VE_S46:
4289 return "s46";
4290 case UNW_VE_S47:
4291 return "s47";
4292 case UNW_VE_S48:
4293 return "s48";
4294 case UNW_VE_S49:
4295 return "s49";
4296 case UNW_VE_S50:
4297 return "s50";
4298 case UNW_VE_S51:
4299 return "s51";
4300 case UNW_VE_S52:
4301 return "s52";
4302 case UNW_VE_S53:
4303 return "s53";
4304 case UNW_VE_S54:
4305 return "s54";
4306 case UNW_VE_S55:
4307 return "s55";
4308 case UNW_VE_S56:
4309 return "s56";
4310 case UNW_VE_S57:
4311 return "s57";
4312 case UNW_VE_S58:
4313 return "s58";
4314 case UNW_VE_S59:
4315 return "s59";
4316 case UNW_VE_S60:
4317 return "s60";
4318 case UNW_VE_S61:
4319 return "s61";
4320 case UNW_VE_S62:
4321 return "s62";
4322 case UNW_VE_S63:
4323 return "s63";
4324 case UNW_VE_V0:
4325 return "v0";
4326 case UNW_VE_V1:
4327 return "v1";
4328 case UNW_VE_V2:
4329 return "v2";
4330 case UNW_VE_V3:
4331 return "v3";
4332 case UNW_VE_V4:
4333 return "v4";
4334 case UNW_VE_V5:
4335 return "v5";
4336 case UNW_VE_V6:
4337 return "v6";
4338 case UNW_VE_V7:
4339 return "v7";
4340 case UNW_VE_V8:
4341 return "v8";
4342 case UNW_VE_V9:
4343 return "v9";
4344 case UNW_VE_V10:
4345 return "v10";
4346 case UNW_VE_V11:
4347 return "v11";
4348 case UNW_VE_V12:
4349 return "v12";
4350 case UNW_VE_V13:
4351 return "v13";
4352 case UNW_VE_V14:
4353 return "v14";
4354 case UNW_VE_V15:
4355 return "v15";
4356 case UNW_VE_V16:
4357 return "v16";
4358 case UNW_VE_V17:
4359 return "v17";
4360 case UNW_VE_V18:
4361 return "v18";
4362 case UNW_VE_V19:
4363 return "v19";
4364 case UNW_VE_V20:
4365 return "v20";
4366 case UNW_VE_V21:
4367 return "v21";
4368 case UNW_VE_V22:
4369 return "v22";
4370 case UNW_VE_V23:
4371 return "v23";
4372 case UNW_VE_V24:
4373 return "v24";
4374 case UNW_VE_V25:
4375 return "v25";
4376 case UNW_VE_V26:
4377 return "v26";
4378 case UNW_VE_V27:
4379 return "v27";
4380 case UNW_VE_V28:
4381 return "v28";
4382 case UNW_VE_V29:
4383 return "v29";
4384 case UNW_VE_V30:
4385 return "v30";
4386 case UNW_VE_V31:
4387 return "v31";
4388 case UNW_VE_V32:
4389 return "v32";
4390 case UNW_VE_V33:
4391 return "v33";
4392 case UNW_VE_V34:
4393 return "v34";
4394 case UNW_VE_V35:
4395 return "v35";
4396 case UNW_VE_V36:
4397 return "v36";
4398 case UNW_VE_V37:
4399 return "v37";
4400 case UNW_VE_V38:
4401 return "v38";
4402 case UNW_VE_V39:
4403 return "v39";
4404 case UNW_VE_V40:
4405 return "v40";
4406 case UNW_VE_V41:
4407 return "v41";
4408 case UNW_VE_V42:
4409 return "v42";
4410 case UNW_VE_V43:
4411 return "v43";
4412 case UNW_VE_V44:
4413 return "v44";
4414 case UNW_VE_V45:
4415 return "v45";
4416 case UNW_VE_V46:
4417 return "v46";
4418 case UNW_VE_V47:
4419 return "v47";
4420 case UNW_VE_V48:
4421 return "v48";
4422 case UNW_VE_V49:
4423 return "v49";
4424 case UNW_VE_V50:
4425 return "v50";
4426 case UNW_VE_V51:
4427 return "v51";
4428 case UNW_VE_V52:
4429 return "v52";
4430 case UNW_VE_V53:
4431 return "v53";
4432 case UNW_VE_V54:
4433 return "v54";
4434 case UNW_VE_V55:
4435 return "v55";
4436 case UNW_VE_V56:
4437 return "v56";
4438 case UNW_VE_V57:
4439 return "v57";
4440 case UNW_VE_V58:
4441 return "v58";
4442 case UNW_VE_V59:
4443 return "v59";
4444 case UNW_VE_V60:
4445 return "v60";
4446 case UNW_VE_V61:
4447 return "v61";
4448 case UNW_VE_V62:
4449 return "v62";
4450 case UNW_VE_V63:
4451 return "v63";
4452 case UNW_VE_VM0:
4453 return "vm0";
4454 case UNW_VE_VM1:
4455 return "vm1";
4456 case UNW_VE_VM2:
4457 return "vm2";
4458 case UNW_VE_VM3:
4459 return "vm3";
4460 case UNW_VE_VM4:
4461 return "vm4";
4462 case UNW_VE_VM5:
4463 return "vm5";
4464 case UNW_VE_VM6:
4465 return "vm6";
4466 case UNW_VE_VM7:
4467 return "vm7";
4468 case UNW_VE_VM8:
4469 return "vm8";
4470 case UNW_VE_VM9:
4471 return "vm9";
4472 case UNW_VE_VM10:
4473 return "vm10";
4474 case UNW_VE_VM11:
4475 return "vm11";
4476 case UNW_VE_VM12:
4477 return "vm12";
4478 case UNW_VE_VM13:
4479 return "vm13";
4480 case UNW_VE_VM14:
4481 return "vm14";
4482 case UNW_VE_VM15:
4483 return "vm15";
4484 }
4485 return "unknown register";
4486 }
4487 #endif // _LIBUNWIND_TARGET_VE
4488
4489 } // namespace libunwind
4490
4491 #endif // __REGISTERS_HPP__
4492