Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(503)

Side by Side Diff: third_party/libc++abi/src/Unwind/Registers.hpp

Issue 75213003: Add libc++ and libc++abi to third-party. (Closed) Base URL: https://src.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 //===----------------------------- Registers.hpp --------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //
9 // Models register sets for supported processors.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef __REGISTERS_HPP__
14 #define __REGISTERS_HPP__
15
16 #include <stdint.h>
17 #include <strings.h>
18
19 #include "libunwind.h"
20 #include "config.h"
21
22 namespace libunwind {
23
24 // For emulating 128-bit registers
25 struct v128 { uint32_t vec[4]; };
26
27
28 /// Registers_x86 holds the register state of a thread in a 32-bit intel
29 /// process.
30 class _LIBUNWIND_HIDDEN Registers_x86 {
31 public:
32 Registers_x86();
33 Registers_x86(const void *registers);
34
35 bool validRegister(int num) const;
36 uint32_t getRegister(int num) const;
37 void setRegister(int num, uint32_t value);
38 bool validFloatRegister(int) const { return false; }
39 double getFloatRegister(int num) const;
40 void setFloatRegister(int num, double value);
41 bool validVectorRegister(int) const { return false; }
42 v128 getVectorRegister(int num) const;
43 void setVectorRegister(int num, v128 value);
44 const char *getRegisterName(int num);
45 void jumpto();
46
47 uint32_t getSP() const { return _registers.__esp; }
48 void setSP(uint32_t value) { _registers.__esp = value; }
49 uint32_t getIP() const { return _registers.__eip; }
50 void setIP(uint32_t value) { _registers.__eip = value; }
51 uint32_t getEBP() const { return _registers.__ebp; }
52 void setEBP(uint32_t value) { _registers.__ebp = value; }
53 uint32_t getEBX() const { return _registers.__ebx; }
54 void setEBX(uint32_t value) { _registers.__ebx = value; }
55 uint32_t getECX() const { return _registers.__ecx; }
56 void setECX(uint32_t value) { _registers.__ecx = value; }
57 uint32_t getEDX() const { return _registers.__edx; }
58 void setEDX(uint32_t value) { _registers.__edx = value; }
59 uint32_t getESI() const { return _registers.__esi; }
60 void setESI(uint32_t value) { _registers.__esi = value; }
61 uint32_t getEDI() const { return _registers.__edi; }
62 void setEDI(uint32_t value) { _registers.__edi = value; }
63
64 private:
65 struct GPRs {
66 unsigned int __eax;
67 unsigned int __ebx;
68 unsigned int __ecx;
69 unsigned int __edx;
70 unsigned int __edi;
71 unsigned int __esi;
72 unsigned int __ebp;
73 unsigned int __esp;
74 unsigned int __ss;
75 unsigned int __eflags;
76 unsigned int __eip;
77 unsigned int __cs;
78 unsigned int __ds;
79 unsigned int __es;
80 unsigned int __fs;
81 unsigned int __gs;
82 };
83
84 GPRs _registers;
85 };
86
87 inline Registers_x86::Registers_x86(const void *registers) {
88 static_assert(sizeof(Registers_x86) < sizeof(unw_context_t),
89 "x86 registers do not fit into unw_context_t");
90 _registers = *((GPRs *)registers);
91 }
92
93 inline Registers_x86::Registers_x86() {
94 bzero(&_registers, sizeof(_registers));
95 }
96
97 inline bool Registers_x86::validRegister(int regNum) const {
98 if (regNum == UNW_REG_IP)
99 return true;
100 if (regNum == UNW_REG_SP)
101 return true;
102 if (regNum < 0)
103 return false;
104 if (regNum > 7)
105 return false;
106 return true;
107 }
108
109 inline uint32_t Registers_x86::getRegister(int regNum) const {
110 switch (regNum) {
111 case UNW_REG_IP:
112 return _registers.__eip;
113 case UNW_REG_SP:
114 return _registers.__esp;
115 case UNW_X86_EAX:
116 return _registers.__eax;
117 case UNW_X86_ECX:
118 return _registers.__ecx;
119 case UNW_X86_EDX:
120 return _registers.__edx;
121 case UNW_X86_EBX:
122 return _registers.__ebx;
123 case UNW_X86_EBP:
124 return _registers.__ebp;
125 case UNW_X86_ESP:
126 return _registers.__esp;
127 case UNW_X86_ESI:
128 return _registers.__esi;
129 case UNW_X86_EDI:
130 return _registers.__edi;
131 }
132 _LIBUNWIND_ABORT("unsupported x86 register");
133 }
134
135 inline void Registers_x86::setRegister(int regNum, uint32_t value) {
136 switch (regNum) {
137 case UNW_REG_IP:
138 _registers.__eip = value;
139 return;
140 case UNW_REG_SP:
141 _registers.__esp = value;
142 return;
143 case UNW_X86_EAX:
144 _registers.__eax = value;
145 return;
146 case UNW_X86_ECX:
147 _registers.__ecx = value;
148 return;
149 case UNW_X86_EDX:
150 _registers.__edx = value;
151 return;
152 case UNW_X86_EBX:
153 _registers.__ebx = value;
154 return;
155 case UNW_X86_EBP:
156 _registers.__ebp = value;
157 return;
158 case UNW_X86_ESP:
159 _registers.__esp = value;
160 return;
161 case UNW_X86_ESI:
162 _registers.__esi = value;
163 return;
164 case UNW_X86_EDI:
165 _registers.__edi = value;
166 return;
167 }
168 _LIBUNWIND_ABORT("unsupported x86 register");
169 }
170
171 inline const char *Registers_x86::getRegisterName(int regNum) {
172 switch (regNum) {
173 case UNW_REG_IP:
174 return "ip";
175 case UNW_REG_SP:
176 return "esp";
177 case UNW_X86_EAX:
178 return "eax";
179 case UNW_X86_ECX:
180 return "ecx";
181 case UNW_X86_EDX:
182 return "edx";
183 case UNW_X86_EBX:
184 return "ebx";
185 case UNW_X86_EBP:
186 return "ebp";
187 case UNW_X86_ESP:
188 return "esp";
189 case UNW_X86_ESI:
190 return "esi";
191 case UNW_X86_EDI:
192 return "edi";
193 default:
194 return "unknown register";
195 }
196 }
197
198 inline double Registers_x86::getFloatRegister(int) const {
199 _LIBUNWIND_ABORT("no x86 float registers");
200 }
201
202 inline void Registers_x86::setFloatRegister(int, double) {
203 _LIBUNWIND_ABORT("no x86 float registers");
204 }
205
206 inline v128 Registers_x86::getVectorRegister(int) const {
207 _LIBUNWIND_ABORT("no x86 vector registers");
208 }
209
210 inline void Registers_x86::setVectorRegister(int, v128) {
211 _LIBUNWIND_ABORT("no x86 vector registers");
212 }
213
214
215 /// Registers_x86_64 holds the register state of a thread in a 64-bit intel
216 /// process.
217 class _LIBUNWIND_HIDDEN Registers_x86_64 {
218 public:
219 Registers_x86_64();
220 Registers_x86_64(const void *registers);
221
222 bool validRegister(int num) const;
223 uint64_t getRegister(int num) const;
224 void setRegister(int num, uint64_t value);
225 bool validFloatRegister(int) const { return false; }
226 double getFloatRegister(int num) const;
227 void setFloatRegister(int num, double value);
228 bool validVectorRegister(int) const { return false; }
229 v128 getVectorRegister(int num) const;
230 void setVectorRegister(int num, v128 value);
231 const char *getRegisterName(int num);
232 void jumpto();
233
234 uint64_t getSP() const { return _registers.__rsp; }
235 void setSP(uint64_t value) { _registers.__rsp = value; }
236 uint64_t getIP() const { return _registers.__rip; }
237 void setIP(uint64_t value) { _registers.__rip = value; }
238 uint64_t getRBP() const { return _registers.__rbp; }
239 void setRBP(uint64_t value) { _registers.__rbp = value; }
240 uint64_t getRBX() const { return _registers.__rbx; }
241 void setRBX(uint64_t value) { _registers.__rbx = value; }
242 uint64_t getR12() const { return _registers.__r12; }
243 void setR12(uint64_t value) { _registers.__r12 = value; }
244 uint64_t getR13() const { return _registers.__r13; }
245 void setR13(uint64_t value) { _registers.__r13 = value; }
246 uint64_t getR14() const { return _registers.__r14; }
247 void setR14(uint64_t value) { _registers.__r14 = value; }
248 uint64_t getR15() const { return _registers.__r15; }
249 void setR15(uint64_t value) { _registers.__r15 = value; }
250
251 private:
252 struct GPRs {
253 uint64_t __rax;
254 uint64_t __rbx;
255 uint64_t __rcx;
256 uint64_t __rdx;
257 uint64_t __rdi;
258 uint64_t __rsi;
259 uint64_t __rbp;
260 uint64_t __rsp;
261 uint64_t __r8;
262 uint64_t __r9;
263 uint64_t __r10;
264 uint64_t __r11;
265 uint64_t __r12;
266 uint64_t __r13;
267 uint64_t __r14;
268 uint64_t __r15;
269 uint64_t __rip;
270 uint64_t __rflags;
271 uint64_t __cs;
272 uint64_t __fs;
273 uint64_t __gs;
274 };
275 GPRs _registers;
276 };
277
278 inline Registers_x86_64::Registers_x86_64(const void *registers) {
279 static_assert(sizeof(Registers_x86_64) < sizeof(unw_context_t),
280 "x86_64 registers do not fit into unw_context_t");
281 _registers = *((GPRs *)registers);
282 }
283
284 inline Registers_x86_64::Registers_x86_64() {
285 bzero(&_registers, sizeof(_registers));
286 }
287
288 inline bool Registers_x86_64::validRegister(int regNum) const {
289 if (regNum == UNW_REG_IP)
290 return true;
291 if (regNum == UNW_REG_SP)
292 return true;
293 if (regNum < 0)
294 return false;
295 if (regNum > 15)
296 return false;
297 return true;
298 }
299
300 inline uint64_t Registers_x86_64::getRegister(int regNum) const {
301 switch (regNum) {
302 case UNW_REG_IP:
303 return _registers.__rip;
304 case UNW_REG_SP:
305 return _registers.__rsp;
306 case UNW_X86_64_RAX:
307 return _registers.__rax;
308 case UNW_X86_64_RDX:
309 return _registers.__rdx;
310 case UNW_X86_64_RCX:
311 return _registers.__rcx;
312 case UNW_X86_64_RBX:
313 return _registers.__rbx;
314 case UNW_X86_64_RSI:
315 return _registers.__rsi;
316 case UNW_X86_64_RDI:
317 return _registers.__rdi;
318 case UNW_X86_64_RBP:
319 return _registers.__rbp;
320 case UNW_X86_64_RSP:
321 return _registers.__rsp;
322 case UNW_X86_64_R8:
323 return _registers.__r8;
324 case UNW_X86_64_R9:
325 return _registers.__r9;
326 case UNW_X86_64_R10:
327 return _registers.__r10;
328 case UNW_X86_64_R11:
329 return _registers.__r11;
330 case UNW_X86_64_R12:
331 return _registers.__r12;
332 case UNW_X86_64_R13:
333 return _registers.__r13;
334 case UNW_X86_64_R14:
335 return _registers.__r14;
336 case UNW_X86_64_R15:
337 return _registers.__r15;
338 }
339 _LIBUNWIND_ABORT("unsupported x86_64 register");
340 }
341
342 inline void Registers_x86_64::setRegister(int regNum, uint64_t value) {
343 switch (regNum) {
344 case UNW_REG_IP:
345 _registers.__rip = value;
346 return;
347 case UNW_REG_SP:
348 _registers.__rsp = value;
349 return;
350 case UNW_X86_64_RAX:
351 _registers.__rax = value;
352 return;
353 case UNW_X86_64_RDX:
354 _registers.__rdx = value;
355 return;
356 case UNW_X86_64_RCX:
357 _registers.__rcx = value;
358 return;
359 case UNW_X86_64_RBX:
360 _registers.__rbx = value;
361 return;
362 case UNW_X86_64_RSI:
363 _registers.__rsi = value;
364 return;
365 case UNW_X86_64_RDI:
366 _registers.__rdi = value;
367 return;
368 case UNW_X86_64_RBP:
369 _registers.__rbp = value;
370 return;
371 case UNW_X86_64_RSP:
372 _registers.__rsp = value;
373 return;
374 case UNW_X86_64_R8:
375 _registers.__r8 = value;
376 return;
377 case UNW_X86_64_R9:
378 _registers.__r9 = value;
379 return;
380 case UNW_X86_64_R10:
381 _registers.__r10 = value;
382 return;
383 case UNW_X86_64_R11:
384 _registers.__r11 = value;
385 return;
386 case UNW_X86_64_R12:
387 _registers.__r12 = value;
388 return;
389 case UNW_X86_64_R13:
390 _registers.__r13 = value;
391 return;
392 case UNW_X86_64_R14:
393 _registers.__r14 = value;
394 return;
395 case UNW_X86_64_R15:
396 _registers.__r15 = value;
397 return;
398 }
399 _LIBUNWIND_ABORT("unsupported x86_64 register");
400 }
401
402 inline const char *Registers_x86_64::getRegisterName(int regNum) {
403 switch (regNum) {
404 case UNW_REG_IP:
405 return "rip";
406 case UNW_REG_SP:
407 return "rsp";
408 case UNW_X86_64_RAX:
409 return "rax";
410 case UNW_X86_64_RDX:
411 return "rdx";
412 case UNW_X86_64_RCX:
413 return "rcx";
414 case UNW_X86_64_RBX:
415 return "rbx";
416 case UNW_X86_64_RSI:
417 return "rsi";
418 case UNW_X86_64_RDI:
419 return "rdi";
420 case UNW_X86_64_RBP:
421 return "rbp";
422 case UNW_X86_64_RSP:
423 return "rsp";
424 case UNW_X86_64_R8:
425 return "r8";
426 case UNW_X86_64_R9:
427 return "r9";
428 case UNW_X86_64_R10:
429 return "r10";
430 case UNW_X86_64_R11:
431 return "r11";
432 case UNW_X86_64_R12:
433 return "r12";
434 case UNW_X86_64_R13:
435 return "r13";
436 case UNW_X86_64_R14:
437 return "r14";
438 case UNW_X86_64_R15:
439 return "r15";
440 default:
441 return "unknown register";
442 }
443 }
444
445 inline double Registers_x86_64::getFloatRegister(int) const {
446 _LIBUNWIND_ABORT("no x86_64 float registers");
447 }
448
449 inline void Registers_x86_64::setFloatRegister(int, double) {
450 _LIBUNWIND_ABORT("no x86_64 float registers");
451 }
452
453 inline v128 Registers_x86_64::getVectorRegister(int) const {
454 _LIBUNWIND_ABORT("no x86_64 vector registers");
455 }
456
457 inline void Registers_x86_64::setVectorRegister(int, v128) {
458 _LIBUNWIND_ABORT("no x86_64 vector registers");
459 }
460
461
462 /// Registers_ppc holds the register state of a thread in a 32-bit PowerPC
463 /// process.
464 class _LIBUNWIND_HIDDEN Registers_ppc {
465 public:
466 Registers_ppc();
467 Registers_ppc(const void *registers);
468
469 bool validRegister(int num) const;
470 uint32_t getRegister(int num) const;
471 void setRegister(int num, uint32_t value);
472 bool validFloatRegister(int num) const;
473 double getFloatRegister(int num) const;
474 void setFloatRegister(int num, double value);
475 bool validVectorRegister(int num) const;
476 v128 getVectorRegister(int num) const;
477 void setVectorRegister(int num, v128 value);
478 const char *getRegisterName(int num);
479 void jumpto();
480
481 uint64_t getSP() const { return _registers.__r1; }
482 void setSP(uint32_t value) { _registers.__r1 = value; }
483 uint64_t getIP() const { return _registers.__srr0; }
484 void setIP(uint32_t value) { _registers.__srr0 = value; }
485
486 private:
487 struct ppc_thread_state_t {
488 unsigned int __srr0; /* Instruction address register (PC) */
489 unsigned int __srr1; /* Machine state register (supervisor) */
490 unsigned int __r0;
491 unsigned int __r1;
492 unsigned int __r2;
493 unsigned int __r3;
494 unsigned int __r4;
495 unsigned int __r5;
496 unsigned int __r6;
497 unsigned int __r7;
498 unsigned int __r8;
499 unsigned int __r9;
500 unsigned int __r10;
501 unsigned int __r11;
502 unsigned int __r12;
503 unsigned int __r13;
504 unsigned int __r14;
505 unsigned int __r15;
506 unsigned int __r16;
507 unsigned int __r17;
508 unsigned int __r18;
509 unsigned int __r19;
510 unsigned int __r20;
511 unsigned int __r21;
512 unsigned int __r22;
513 unsigned int __r23;
514 unsigned int __r24;
515 unsigned int __r25;
516 unsigned int __r26;
517 unsigned int __r27;
518 unsigned int __r28;
519 unsigned int __r29;
520 unsigned int __r30;
521 unsigned int __r31;
522 unsigned int __cr; /* Condition register */
523 unsigned int __xer; /* User's integer exception register */
524 unsigned int __lr; /* Link register */
525 unsigned int __ctr; /* Count register */
526 unsigned int __mq; /* MQ register (601 only) */
527 unsigned int __vrsave; /* Vector Save Register */
528 };
529
530 struct ppc_float_state_t {
531 double __fpregs[32];
532
533 unsigned int __fpscr_pad; /* fpscr is 64 bits, 32 bits of rubbish */
534 unsigned int __fpscr; /* floating point status register */
535 };
536
537 ppc_thread_state_t _registers;
538 ppc_float_state_t _floatRegisters;
539 v128 _vectorRegisters[32]; // offset 424
540 };
541
542 inline Registers_ppc::Registers_ppc(const void *registers) {
543 static_assert(sizeof(Registers_ppc) < sizeof(unw_context_t),
544 "ppc registers do not fit into unw_context_t");
545 _registers = *((ppc_thread_state_t *)registers);
546 _floatRegisters = *((ppc_float_state_t *)((char *)registers + 160));
547 memcpy(_vectorRegisters, ((char *)registers + 424), sizeof(_vectorRegisters));
548 }
549
550 inline Registers_ppc::Registers_ppc() {
551 bzero(&_registers, sizeof(_registers));
552 bzero(&_floatRegisters, sizeof(_floatRegisters));
553 bzero(&_vectorRegisters, sizeof(_vectorRegisters));
554 }
555
556 inline bool Registers_ppc::validRegister(int regNum) const {
557 if (regNum == UNW_REG_IP)
558 return true;
559 if (regNum == UNW_REG_SP)
560 return true;
561 if (regNum == UNW_PPC_VRSAVE)
562 return true;
563 if (regNum < 0)
564 return false;
565 if (regNum <= UNW_PPC_R31)
566 return true;
567 if (regNum == UNW_PPC_MQ)
568 return true;
569 if (regNum == UNW_PPC_LR)
570 return true;
571 if (regNum == UNW_PPC_CTR)
572 return true;
573 if ((UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7))
574 return true;
575 return false;
576 }
577
578 inline uint32_t Registers_ppc::getRegister(int regNum) const {
579 switch (regNum) {
580 case UNW_REG_IP:
581 return _registers.__srr0;
582 case UNW_REG_SP:
583 return _registers.__r1;
584 case UNW_PPC_R0:
585 return _registers.__r0;
586 case UNW_PPC_R1:
587 return _registers.__r1;
588 case UNW_PPC_R2:
589 return _registers.__r2;
590 case UNW_PPC_R3:
591 return _registers.__r3;
592 case UNW_PPC_R4:
593 return _registers.__r4;
594 case UNW_PPC_R5:
595 return _registers.__r5;
596 case UNW_PPC_R6:
597 return _registers.__r6;
598 case UNW_PPC_R7:
599 return _registers.__r7;
600 case UNW_PPC_R8:
601 return _registers.__r8;
602 case UNW_PPC_R9:
603 return _registers.__r9;
604 case UNW_PPC_R10:
605 return _registers.__r10;
606 case UNW_PPC_R11:
607 return _registers.__r11;
608 case UNW_PPC_R12:
609 return _registers.__r12;
610 case UNW_PPC_R13:
611 return _registers.__r13;
612 case UNW_PPC_R14:
613 return _registers.__r14;
614 case UNW_PPC_R15:
615 return _registers.__r15;
616 case UNW_PPC_R16:
617 return _registers.__r16;
618 case UNW_PPC_R17:
619 return _registers.__r17;
620 case UNW_PPC_R18:
621 return _registers.__r18;
622 case UNW_PPC_R19:
623 return _registers.__r19;
624 case UNW_PPC_R20:
625 return _registers.__r20;
626 case UNW_PPC_R21:
627 return _registers.__r21;
628 case UNW_PPC_R22:
629 return _registers.__r22;
630 case UNW_PPC_R23:
631 return _registers.__r23;
632 case UNW_PPC_R24:
633 return _registers.__r24;
634 case UNW_PPC_R25:
635 return _registers.__r25;
636 case UNW_PPC_R26:
637 return _registers.__r26;
638 case UNW_PPC_R27:
639 return _registers.__r27;
640 case UNW_PPC_R28:
641 return _registers.__r28;
642 case UNW_PPC_R29:
643 return _registers.__r29;
644 case UNW_PPC_R30:
645 return _registers.__r30;
646 case UNW_PPC_R31:
647 return _registers.__r31;
648 case UNW_PPC_LR:
649 return _registers.__lr;
650 case UNW_PPC_CR0:
651 return (_registers.__cr & 0xF0000000);
652 case UNW_PPC_CR1:
653 return (_registers.__cr & 0x0F000000);
654 case UNW_PPC_CR2:
655 return (_registers.__cr & 0x00F00000);
656 case UNW_PPC_CR3:
657 return (_registers.__cr & 0x000F0000);
658 case UNW_PPC_CR4:
659 return (_registers.__cr & 0x0000F000);
660 case UNW_PPC_CR5:
661 return (_registers.__cr & 0x00000F00);
662 case UNW_PPC_CR6:
663 return (_registers.__cr & 0x000000F0);
664 case UNW_PPC_CR7:
665 return (_registers.__cr & 0x0000000F);
666 case UNW_PPC_VRSAVE:
667 return _registers.__vrsave;
668 }
669 _LIBUNWIND_ABORT("unsupported ppc register");
670 }
671
672 inline void Registers_ppc::setRegister(int regNum, uint32_t value) {
673 //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value);
674 switch (regNum) {
675 case UNW_REG_IP:
676 _registers.__srr0 = value;
677 return;
678 case UNW_REG_SP:
679 _registers.__r1 = value;
680 return;
681 case UNW_PPC_R0:
682 _registers.__r0 = value;
683 return;
684 case UNW_PPC_R1:
685 _registers.__r1 = value;
686 return;
687 case UNW_PPC_R2:
688 _registers.__r2 = value;
689 return;
690 case UNW_PPC_R3:
691 _registers.__r3 = value;
692 return;
693 case UNW_PPC_R4:
694 _registers.__r4 = value;
695 return;
696 case UNW_PPC_R5:
697 _registers.__r5 = value;
698 return;
699 case UNW_PPC_R6:
700 _registers.__r6 = value;
701 return;
702 case UNW_PPC_R7:
703 _registers.__r7 = value;
704 return;
705 case UNW_PPC_R8:
706 _registers.__r8 = value;
707 return;
708 case UNW_PPC_R9:
709 _registers.__r9 = value;
710 return;
711 case UNW_PPC_R10:
712 _registers.__r10 = value;
713 return;
714 case UNW_PPC_R11:
715 _registers.__r11 = value;
716 return;
717 case UNW_PPC_R12:
718 _registers.__r12 = value;
719 return;
720 case UNW_PPC_R13:
721 _registers.__r13 = value;
722 return;
723 case UNW_PPC_R14:
724 _registers.__r14 = value;
725 return;
726 case UNW_PPC_R15:
727 _registers.__r15 = value;
728 return;
729 case UNW_PPC_R16:
730 _registers.__r16 = value;
731 return;
732 case UNW_PPC_R17:
733 _registers.__r17 = value;
734 return;
735 case UNW_PPC_R18:
736 _registers.__r18 = value;
737 return;
738 case UNW_PPC_R19:
739 _registers.__r19 = value;
740 return;
741 case UNW_PPC_R20:
742 _registers.__r20 = value;
743 return;
744 case UNW_PPC_R21:
745 _registers.__r21 = value;
746 return;
747 case UNW_PPC_R22:
748 _registers.__r22 = value;
749 return;
750 case UNW_PPC_R23:
751 _registers.__r23 = value;
752 return;
753 case UNW_PPC_R24:
754 _registers.__r24 = value;
755 return;
756 case UNW_PPC_R25:
757 _registers.__r25 = value;
758 return;
759 case UNW_PPC_R26:
760 _registers.__r26 = value;
761 return;
762 case UNW_PPC_R27:
763 _registers.__r27 = value;
764 return;
765 case UNW_PPC_R28:
766 _registers.__r28 = value;
767 return;
768 case UNW_PPC_R29:
769 _registers.__r29 = value;
770 return;
771 case UNW_PPC_R30:
772 _registers.__r30 = value;
773 return;
774 case UNW_PPC_R31:
775 _registers.__r31 = value;
776 return;
777 case UNW_PPC_MQ:
778 _registers.__mq = value;
779 return;
780 case UNW_PPC_LR:
781 _registers.__lr = value;
782 return;
783 case UNW_PPC_CTR:
784 _registers.__ctr = value;
785 return;
786 case UNW_PPC_CR0:
787 _registers.__cr &= 0x0FFFFFFF;
788 _registers.__cr |= (value & 0xF0000000);
789 return;
790 case UNW_PPC_CR1:
791 _registers.__cr &= 0xF0FFFFFF;
792 _registers.__cr |= (value & 0x0F000000);
793 return;
794 case UNW_PPC_CR2:
795 _registers.__cr &= 0xFF0FFFFF;
796 _registers.__cr |= (value & 0x00F00000);
797 return;
798 case UNW_PPC_CR3:
799 _registers.__cr &= 0xFFF0FFFF;
800 _registers.__cr |= (value & 0x000F0000);
801 return;
802 case UNW_PPC_CR4:
803 _registers.__cr &= 0xFFFF0FFF;
804 _registers.__cr |= (value & 0x0000F000);
805 return;
806 case UNW_PPC_CR5:
807 _registers.__cr &= 0xFFFFF0FF;
808 _registers.__cr |= (value & 0x00000F00);
809 return;
810 case UNW_PPC_CR6:
811 _registers.__cr &= 0xFFFFFF0F;
812 _registers.__cr |= (value & 0x000000F0);
813 return;
814 case UNW_PPC_CR7:
815 _registers.__cr &= 0xFFFFFFF0;
816 _registers.__cr |= (value & 0x0000000F);
817 return;
818 case UNW_PPC_VRSAVE:
819 _registers.__vrsave = value;
820 return;
821 // not saved
822 return;
823 case UNW_PPC_XER:
824 _registers.__xer = value;
825 return;
826 case UNW_PPC_AP:
827 case UNW_PPC_VSCR:
828 case UNW_PPC_SPEFSCR:
829 // not saved
830 return;
831 }
832 _LIBUNWIND_ABORT("unsupported ppc register");
833 }
834
835 inline bool Registers_ppc::validFloatRegister(int regNum) const {
836 if (regNum < UNW_PPC_F0)
837 return false;
838 if (regNum > UNW_PPC_F31)
839 return false;
840 return true;
841 }
842
843 inline double Registers_ppc::getFloatRegister(int regNum) const {
844 assert(validFloatRegister(regNum));
845 return _floatRegisters.__fpregs[regNum - UNW_PPC_F0];
846 }
847
848 inline void Registers_ppc::setFloatRegister(int regNum, double value) {
849 assert(validFloatRegister(regNum));
850 _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value;
851 }
852
853 inline bool Registers_ppc::validVectorRegister(int regNum) const {
854 if (regNum < UNW_PPC_V0)
855 return false;
856 if (regNum > UNW_PPC_V31)
857 return false;
858 return true;
859 }
860
861 inline v128 Registers_ppc::getVectorRegister(int regNum) const {
862 assert(validVectorRegister(regNum));
863 v128 result = _vectorRegisters[regNum - UNW_PPC_V0];
864 return result;
865 }
866
867 inline void Registers_ppc::setVectorRegister(int regNum, v128 value) {
868 assert(validVectorRegister(regNum));
869 _vectorRegisters[regNum - UNW_PPC_V0] = value;
870 }
871
872 inline const char *Registers_ppc::getRegisterName(int regNum) {
873 switch (regNum) {
874 case UNW_REG_IP:
875 return "ip";
876 case UNW_REG_SP:
877 return "sp";
878 case UNW_PPC_R0:
879 return "r0";
880 case UNW_PPC_R1:
881 return "r1";
882 case UNW_PPC_R2:
883 return "r2";
884 case UNW_PPC_R3:
885 return "r3";
886 case UNW_PPC_R4:
887 return "r4";
888 case UNW_PPC_R5:
889 return "r5";
890 case UNW_PPC_R6:
891 return "r6";
892 case UNW_PPC_R7:
893 return "r7";
894 case UNW_PPC_R8:
895 return "r8";
896 case UNW_PPC_R9:
897 return "r9";
898 case UNW_PPC_R10:
899 return "r10";
900 case UNW_PPC_R11:
901 return "r11";
902 case UNW_PPC_R12:
903 return "r12";
904 case UNW_PPC_R13:
905 return "r13";
906 case UNW_PPC_R14:
907 return "r14";
908 case UNW_PPC_R15:
909 return "r15";
910 case UNW_PPC_R16:
911 return "r16";
912 case UNW_PPC_R17:
913 return "r17";
914 case UNW_PPC_R18:
915 return "r18";
916 case UNW_PPC_R19:
917 return "r19";
918 case UNW_PPC_R20:
919 return "r20";
920 case UNW_PPC_R21:
921 return "r21";
922 case UNW_PPC_R22:
923 return "r22";
924 case UNW_PPC_R23:
925 return "r23";
926 case UNW_PPC_R24:
927 return "r24";
928 case UNW_PPC_R25:
929 return "r25";
930 case UNW_PPC_R26:
931 return "r26";
932 case UNW_PPC_R27:
933 return "r27";
934 case UNW_PPC_R28:
935 return "r28";
936 case UNW_PPC_R29:
937 return "r29";
938 case UNW_PPC_R30:
939 return "r30";
940 case UNW_PPC_R31:
941 return "r31";
942 case UNW_PPC_F0:
943 return "fp0";
944 case UNW_PPC_F1:
945 return "fp1";
946 case UNW_PPC_F2:
947 return "fp2";
948 case UNW_PPC_F3:
949 return "fp3";
950 case UNW_PPC_F4:
951 return "fp4";
952 case UNW_PPC_F5:
953 return "fp5";
954 case UNW_PPC_F6:
955 return "fp6";
956 case UNW_PPC_F7:
957 return "fp7";
958 case UNW_PPC_F8:
959 return "fp8";
960 case UNW_PPC_F9:
961 return "fp9";
962 case UNW_PPC_F10:
963 return "fp10";
964 case UNW_PPC_F11:
965 return "fp11";
966 case UNW_PPC_F12:
967 return "fp12";
968 case UNW_PPC_F13:
969 return "fp13";
970 case UNW_PPC_F14:
971 return "fp14";
972 case UNW_PPC_F15:
973 return "fp15";
974 case UNW_PPC_F16:
975 return "fp16";
976 case UNW_PPC_F17:
977 return "fp17";
978 case UNW_PPC_F18:
979 return "fp18";
980 case UNW_PPC_F19:
981 return "fp19";
982 case UNW_PPC_F20:
983 return "fp20";
984 case UNW_PPC_F21:
985 return "fp21";
986 case UNW_PPC_F22:
987 return "fp22";
988 case UNW_PPC_F23:
989 return "fp23";
990 case UNW_PPC_F24:
991 return "fp24";
992 case UNW_PPC_F25:
993 return "fp25";
994 case UNW_PPC_F26:
995 return "fp26";
996 case UNW_PPC_F27:
997 return "fp27";
998 case UNW_PPC_F28:
999 return "fp28";
1000 case UNW_PPC_F29:
1001 return "fp29";
1002 case UNW_PPC_F30:
1003 return "fp30";
1004 case UNW_PPC_F31:
1005 return "fp31";
1006 case UNW_PPC_LR:
1007 return "lr";
1008 default:
1009 return "unknown register";
1010 }
1011
1012 }
1013
1014
1015 /// Registers_arm64 holds the register state of a thread in a 64-bit arm
1016 /// process.
1017 class _LIBUNWIND_HIDDEN Registers_arm64 {
1018 public:
1019 Registers_arm64();
1020 Registers_arm64(const void *registers);
1021
1022 bool validRegister(int num) const;
1023 uint64_t getRegister(int num) const;
1024 void setRegister(int num, uint64_t value);
1025 bool validFloatRegister(int num) const;
1026 double getFloatRegister(int num) const;
1027 void setFloatRegister(int num, double value);
1028 bool validVectorRegister(int num) const;
1029 v128 getVectorRegister(int num) const;
1030 void setVectorRegister(int num, v128 value);
1031 const char *getRegisterName(int num);
1032 void jumpto();
1033
1034 uint64_t getSP() const { return _registers.__sp; }
1035 void setSP(uint64_t value) { _registers.__sp = value; }
1036 uint64_t getIP() const { return _registers.__pc; }
1037 void setIP(uint64_t value) { _registers.__pc = value; }
1038 uint64_t getFP() const { return _registers.__fp; }
1039 void setFP(uint64_t value) { _registers.__fp = value; }
1040
1041 private:
1042 struct GPRs {
1043 uint64_t __x[29]; // x0-x28
1044 uint64_t __fp; // Frame pointer x29
1045 uint64_t __lr; // Link register x30
1046 uint64_t __sp; // Stack pointer x31
1047 uint64_t __pc; // Program counter
1048 uint64_t padding; // 16-byte align
1049 };
1050
1051 GPRs _registers;
1052 double _vectorHalfRegisters[32];
1053 // Currently only the lower double in 128-bit vectore registers
1054 // is perserved during unwinding. We could define new register
1055 // numbers (> 96) which mean whole vector registers, then this
1056 // struct would need to change to contain whole vector registers.
1057 };
1058
1059 inline Registers_arm64::Registers_arm64(const void *registers) {
1060 static_assert(sizeof(Registers_arm64) < sizeof(unw_context_t),
1061 "arm64 registers do not fit into unw_context_t");
1062 memcpy(&_registers, registers, sizeof(_registers));
1063 memcpy(_vectorHalfRegisters, (((char *)registers) + 0x110),
1064 sizeof(_vectorHalfRegisters));
1065 }
1066
1067 inline Registers_arm64::Registers_arm64() {
1068 bzero(&_registers, sizeof(_registers));
1069 bzero(&_registers, sizeof(_vectorHalfRegisters));
1070 }
1071
1072 inline bool Registers_arm64::validRegister(int regNum) const {
1073 if (regNum == UNW_REG_IP)
1074 return true;
1075 if (regNum == UNW_REG_SP)
1076 return true;
1077 if (regNum < 0)
1078 return false;
1079 if (regNum > 95)
1080 return false;
1081 if ((regNum > 31) && (regNum < 64))
1082 return false;
1083 return true;
1084 }
1085
1086 inline uint64_t Registers_arm64::getRegister(int regNum) const {
1087 if (regNum == UNW_REG_IP)
1088 return _registers.__pc;
1089 if (regNum == UNW_REG_SP)
1090 return _registers.__sp;
1091 if ((regNum >= 0) && (regNum < 32))
1092 return _registers.__x[regNum];
1093 _LIBUNWIND_ABORT("unsupported arm64 register");
1094 }
1095
1096 inline void Registers_arm64::setRegister(int regNum, uint64_t value) {
1097 if (regNum == UNW_REG_IP)
1098 _registers.__pc = value;
1099 else if (regNum == UNW_REG_SP)
1100 _registers.__sp = value;
1101 else if ((regNum >= 0) && (regNum < 32))
1102 _registers.__x[regNum] = value;
1103 else
1104 _LIBUNWIND_ABORT("unsupported arm64 register");
1105 }
1106
1107 inline const char *Registers_arm64::getRegisterName(int regNum) {
1108 switch (regNum) {
1109 case UNW_REG_IP:
1110 return "pc";
1111 case UNW_REG_SP:
1112 return "sp";
1113 case UNW_ARM64_X0:
1114 return "x0";
1115 case UNW_ARM64_X1:
1116 return "x1";
1117 case UNW_ARM64_X2:
1118 return "x2";
1119 case UNW_ARM64_X3:
1120 return "x3";
1121 case UNW_ARM64_X4:
1122 return "x4";
1123 case UNW_ARM64_X5:
1124 return "x5";
1125 case UNW_ARM64_X6:
1126 return "x6";
1127 case UNW_ARM64_X7:
1128 return "x7";
1129 case UNW_ARM64_X8:
1130 return "x8";
1131 case UNW_ARM64_X9:
1132 return "x9";
1133 case UNW_ARM64_X10:
1134 return "x10";
1135 case UNW_ARM64_X11:
1136 return "x11";
1137 case UNW_ARM64_X12:
1138 return "x12";
1139 case UNW_ARM64_X13:
1140 return "x13";
1141 case UNW_ARM64_X14:
1142 return "x14";
1143 case UNW_ARM64_X15:
1144 return "x15";
1145 case UNW_ARM64_X16:
1146 return "x16";
1147 case UNW_ARM64_X17:
1148 return "x17";
1149 case UNW_ARM64_X18:
1150 return "x18";
1151 case UNW_ARM64_X19:
1152 return "x19";
1153 case UNW_ARM64_X20:
1154 return "x20";
1155 case UNW_ARM64_X21:
1156 return "x21";
1157 case UNW_ARM64_X22:
1158 return "x22";
1159 case UNW_ARM64_X23:
1160 return "x23";
1161 case UNW_ARM64_X24:
1162 return "x24";
1163 case UNW_ARM64_X25:
1164 return "x25";
1165 case UNW_ARM64_X26:
1166 return "x26";
1167 case UNW_ARM64_X27:
1168 return "x27";
1169 case UNW_ARM64_X28:
1170 return "x28";
1171 case UNW_ARM64_X29:
1172 return "fp";
1173 case UNW_ARM64_X30:
1174 return "lr";
1175 case UNW_ARM64_X31:
1176 return "sp";
1177 case UNW_ARM64_D0:
1178 return "d0";
1179 case UNW_ARM64_D1:
1180 return "d1";
1181 case UNW_ARM64_D2:
1182 return "d2";
1183 case UNW_ARM64_D3:
1184 return "d3";
1185 case UNW_ARM64_D4:
1186 return "d4";
1187 case UNW_ARM64_D5:
1188 return "d5";
1189 case UNW_ARM64_D6:
1190 return "d6";
1191 case UNW_ARM64_D7:
1192 return "d7";
1193 case UNW_ARM64_D8:
1194 return "d8";
1195 case UNW_ARM64_D9:
1196 return "d9";
1197 case UNW_ARM64_D10:
1198 return "d10";
1199 case UNW_ARM64_D11:
1200 return "d11";
1201 case UNW_ARM64_D12:
1202 return "d12";
1203 case UNW_ARM64_D13:
1204 return "d13";
1205 case UNW_ARM64_D14:
1206 return "d14";
1207 case UNW_ARM64_D15:
1208 return "d15";
1209 case UNW_ARM64_D16:
1210 return "d16";
1211 case UNW_ARM64_D17:
1212 return "d17";
1213 case UNW_ARM64_D18:
1214 return "d18";
1215 case UNW_ARM64_D19:
1216 return "d19";
1217 case UNW_ARM64_D20:
1218 return "d20";
1219 case UNW_ARM64_D21:
1220 return "d21";
1221 case UNW_ARM64_D22:
1222 return "d22";
1223 case UNW_ARM64_D23:
1224 return "d23";
1225 case UNW_ARM64_D24:
1226 return "d24";
1227 case UNW_ARM64_D25:
1228 return "d25";
1229 case UNW_ARM64_D26:
1230 return "d26";
1231 case UNW_ARM64_D27:
1232 return "d27";
1233 case UNW_ARM64_D28:
1234 return "d28";
1235 case UNW_ARM64_D29:
1236 return "d29";
1237 case UNW_ARM64_D30:
1238 return "d30";
1239 case UNW_ARM64_D31:
1240 return "d31";
1241 default:
1242 return "unknown register";
1243 }
1244 }
1245
1246 inline bool Registers_arm64::validFloatRegister(int regNum) const {
1247 if (regNum < UNW_ARM64_D0)
1248 return false;
1249 if (regNum > UNW_ARM64_D31)
1250 return false;
1251 return true;
1252 }
1253
1254 inline double Registers_arm64::getFloatRegister(int regNum) const {
1255 assert(validFloatRegister(regNum));
1256 return _vectorHalfRegisters[regNum - UNW_ARM64_D0];
1257 }
1258
1259 inline void Registers_arm64::setFloatRegister(int regNum, double value) {
1260 assert(validFloatRegister(regNum));
1261 _vectorHalfRegisters[regNum - UNW_ARM64_D0] = value;
1262 }
1263
1264 inline bool Registers_arm64::validVectorRegister(int) const {
1265 return false;
1266 }
1267
1268 inline v128 Registers_arm64::getVectorRegister(int) const {
1269 _LIBUNWIND_ABORT("no arm64 vector register support yet");
1270 }
1271
1272 inline void Registers_arm64::setVectorRegister(int, v128) {
1273 _LIBUNWIND_ABORT("no arm64 vector register support yet");
1274 }
1275
1276 } // namespace libunwind
1277
1278 #endif // __REGISTERS_HPP__
OLDNEW
« no previous file with comments | « third_party/libc++abi/src/Unwind/DwarfParser.hpp ('k') | third_party/libc++abi/src/Unwind/Unwind-sjlj.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698