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