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