]> git.saurik.com Git - apple/ld64.git/blame - src/ld/parsers/libunwind/Registers.hpp
ld64-127.2.tar.gz
[apple/ld64.git] / src / ld / parsers / libunwind / Registers.hpp
CommitLineData
afe874b1
A
1/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
2 *
3 * Copyright (c) 2007-2009 Apple Inc. All rights reserved.
4 *
5 * @APPLE_LICENSE_HEADER_START@
6 *
7 * This file contains Original Code and/or Modifications of Original Code
8 * as defined in and that are subject to the Apple Public Source License
9 * Version 2.0 (the 'License'). You may not use this file except in
10 * compliance with the License. Please obtain a copy of the License at
11 * http://www.opensource.apple.com/apsl/ and read it before using this
12 * file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19 * Please see the License for the specific language governing rights and
20 * limitations under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24
25//
26// C++ interface to lower levels of libuwind
27//
28
29#ifndef __REGISTERS_HPP__
30#define __REGISTERS_HPP__
31
32#include <stdint.h>
33#include <stdio.h>
34#include <stdlib.h>
35#include <dlfcn.h>
36#include <mach-o/loader.h>
37#include <mach-o/getsect.h>
38#include <mach/i386/thread_status.h>
39
40#include "libunwind.h"
41#include "InternalMacros.h"
42
43namespace libunwind {
44
45
46///
47/// Registers_x86 holds the register state of a thread in a 32-bit intel process.
48///
49class Registers_x86
50{
51public:
52 Registers_x86();
53 Registers_x86(const void* registers);
54
55 bool validRegister(int num) const;
56 uint32_t getRegister(int num) const;
57 void setRegister(int num, uint32_t value);
58 bool validFloatRegister(int num) const { return false; }
59 double getFloatRegister(int num) const;
60 void setFloatRegister(int num, double value);
61 bool validVectorRegister(int num) const { return false; }
62 v128 getVectorRegister(int num) const;
63 void setVectorRegister(int num, v128 value);
64 const char* getRegisterName(int num);
65 void jumpto();
66
67 uint32_t getSP() const { return fRegisters.__esp; }
68 void setSP(uint32_t value) { fRegisters.__esp = value; }
69 uint32_t getIP() const { return fRegisters.__eip; }
70 void setIP(uint32_t value) { fRegisters.__eip = value; }
71 uint32_t getEBP() const { return fRegisters.__ebp; }
72 void setEBP(uint32_t value) { fRegisters.__ebp = value; }
73 uint32_t getEBX() const { return fRegisters.__ebx; }
74 void setEBX(uint32_t value) { fRegisters.__ebx = value; }
75 uint32_t getECX() const { return fRegisters.__ecx; }
76 void setECX(uint32_t value) { fRegisters.__ecx = value; }
77 uint32_t getEDX() const { return fRegisters.__edx; }
78 void setEDX(uint32_t value) { fRegisters.__edx = value; }
79 uint32_t getESI() const { return fRegisters.__esi; }
80 void setESI(uint32_t value) { fRegisters.__esi = value; }
81 uint32_t getEDI() const { return fRegisters.__edi; }
82 void setEDI(uint32_t value) { fRegisters.__edi = value; }
83
84private:
85 i386_thread_state_t fRegisters;
86};
87
88inline Registers_x86::Registers_x86(const void* registers)
89{
90 COMPILE_TIME_ASSERT( sizeof(Registers_x86) < sizeof(unw_context_t) );
91 fRegisters = *((i386_thread_state_t*)registers);
92}
93
94inline Registers_x86::Registers_x86()
95{
96 bzero(&fRegisters, sizeof(fRegisters));
97}
98
99
100inline bool Registers_x86::validRegister(int regNum) const
101{
102 if ( regNum == UNW_REG_IP )
103 return true;
104 if ( regNum == UNW_REG_SP )
105 return true;
106 if ( regNum < 0 )
107 return false;
108 if ( regNum > 7 )
109 return false;
110 return true;
111}
112
113inline uint32_t Registers_x86::getRegister(int regNum) const
114{
115 switch ( regNum ) {
116 case UNW_REG_IP:
117 return fRegisters.__eip;
118 case UNW_REG_SP:
119 return fRegisters.__esp;
120 case UNW_X86_EAX:
121 return fRegisters.__eax;
122 case UNW_X86_ECX:
123 return fRegisters.__ecx;
124 case UNW_X86_EDX:
125 return fRegisters.__edx;
126 case UNW_X86_EBX:
127 return fRegisters.__ebx;
128 case UNW_X86_EBP:
129 return fRegisters.__ebp;
130 case UNW_X86_ESP:
131 return fRegisters.__esp;
132 case UNW_X86_ESI:
133 return fRegisters.__esi;
134 case UNW_X86_EDI:
135 return fRegisters.__edi;
136 }
137 ABORT("unsupported x86 register");
138}
139
140inline void Registers_x86::setRegister(int regNum, uint32_t value)
141{
142 switch ( regNum ) {
143 case UNW_REG_IP:
144 fRegisters.__eip = value;
145 return;
146 case UNW_REG_SP:
147 fRegisters.__esp = value;
148 return;
149 case UNW_X86_EAX:
150 fRegisters.__eax = value;
151 return;
152 case UNW_X86_ECX:
153 fRegisters.__ecx = value;
154 return;
155 case UNW_X86_EDX:
156 fRegisters.__edx = value;
157 return;
158 case UNW_X86_EBX:
159 fRegisters.__ebx = value;
160 return;
161 case UNW_X86_EBP:
162 fRegisters.__ebp = value;
163 return;
164 case UNW_X86_ESP:
165 fRegisters.__esp = value;
166 return;
167 case UNW_X86_ESI:
168 fRegisters.__esi = value;
169 return;
170 case UNW_X86_EDI:
171 fRegisters.__edi = value;
172 return;
173 }
174 ABORT("unsupported x86 register");
175}
176
177inline const char* Registers_x86::getRegisterName(int regNum)
178{
179 switch ( regNum ) {
180 case UNW_REG_IP:
181 return "ip";
182 case UNW_REG_SP:
183 return "esp";
184 case UNW_X86_EAX:
185 return "eax";
186 case UNW_X86_ECX:
187 return "ecx";
188 case UNW_X86_EDX:
189 return "edx";
190 case UNW_X86_EBX:
191 return "ebx";
192 case UNW_X86_EBP:
193 return "ebp";
194 case UNW_X86_ESP:
195 return "esp";
196 case UNW_X86_ESI:
197 return "esi";
198 case UNW_X86_EDI:
199 return "edi";
200 default:
201 return "unknown register";
202 }
203}
204
205inline double Registers_x86::getFloatRegister(int num) const
206{
207 ABORT("no x86 float registers");
208}
209
210inline void Registers_x86::setFloatRegister(int num, double value)
211{
212 ABORT("no x86 float registers");
213}
214
215inline v128 Registers_x86::getVectorRegister(int num) const
216{
217 ABORT("no x86 vector registers");
218}
219
220inline void Registers_x86::setVectorRegister(int num, v128 value)
221{
222 ABORT("no x86 vector registers");
223}
224
225
226
227
228///
229/// Registers_x86_64 holds the register state of a thread in a 64-bit intel process.
230///
231class Registers_x86_64
232{
233public:
234 Registers_x86_64();
235 Registers_x86_64(const void* registers);
236
237 bool validRegister(int num) const;
238 uint64_t getRegister(int num) const;
239 void setRegister(int num, uint64_t value);
240 bool validFloatRegister(int num) const{ return false; }
241 double getFloatRegister(int num) const;
242 void setFloatRegister(int num, double value);
243 bool validVectorRegister(int num) const { return false; }
244 v128 getVectorRegister(int num) const;
245 void setVectorRegister(int num, v128 value);
246 const char* getRegisterName(int num);
247 void jumpto();
248 uint64_t getSP() const { return fRegisters.__rsp; }
249 void setSP(uint64_t value) { fRegisters.__rsp = value; }
250 uint64_t getIP() const { return fRegisters.__rip; }
251 void setIP(uint64_t value) { fRegisters.__rip = value; }
252 uint64_t getRBP() const { return fRegisters.__rbp; }
253 void setRBP(uint64_t value) { fRegisters.__rbp = value; }
254 uint64_t getRBX() const { return fRegisters.__rbx; }
255 void setRBX(uint64_t value) { fRegisters.__rbx = value; }
256 uint64_t getR12() const { return fRegisters.__r12; }
257 void setR12(uint64_t value) { fRegisters.__r12 = value; }
258 uint64_t getR13() const { return fRegisters.__r13; }
259 void setR13(uint64_t value) { fRegisters.__r13 = value; }
260 uint64_t getR14() const { return fRegisters.__r14; }
261 void setR14(uint64_t value) { fRegisters.__r14 = value; }
262 uint64_t getR15() const { return fRegisters.__r15; }
263 void setR15(uint64_t value) { fRegisters.__r15 = value; }
264private:
265 x86_thread_state64_t fRegisters;
266};
267
268inline Registers_x86_64::Registers_x86_64(const void* registers)
269{
270 COMPILE_TIME_ASSERT( sizeof(Registers_x86_64) < sizeof(unw_context_t) );
271 fRegisters = *((x86_thread_state64_t*)registers);
272}
273
274inline Registers_x86_64::Registers_x86_64()
275{
276 bzero(&fRegisters, sizeof(fRegisters));
277}
278
279
280inline bool Registers_x86_64::validRegister(int regNum) const
281{
282 if ( regNum == UNW_REG_IP )
283 return true;
284 if ( regNum == UNW_REG_SP )
285 return true;
286 if ( regNum < 0 )
287 return false;
288 if ( regNum > 15 )
289 return false;
290 return true;
291}
292
293inline uint64_t Registers_x86_64::getRegister(int regNum) const
294{
295 switch ( regNum ) {
296 case UNW_REG_IP:
297 return fRegisters.__rip;
298 case UNW_REG_SP:
299 return fRegisters.__rsp;
300 case UNW_X86_64_RAX:
301 return fRegisters.__rax;
302 case UNW_X86_64_RDX:
303 return fRegisters.__rdx;
304 case UNW_X86_64_RCX:
305 return fRegisters.__rcx;
306 case UNW_X86_64_RBX:
307 return fRegisters.__rbx;
308 case UNW_X86_64_RSI:
309 return fRegisters.__rsi;
310 case UNW_X86_64_RDI:
311 return fRegisters.__rdi;
312 case UNW_X86_64_RBP:
313 return fRegisters.__rbp;
314 case UNW_X86_64_RSP:
315 return fRegisters.__rsp;
316 case UNW_X86_64_R8:
317 return fRegisters.__r8;
318 case UNW_X86_64_R9:
319 return fRegisters.__r9;
320 case UNW_X86_64_R10:
321 return fRegisters.__r10;
322 case UNW_X86_64_R11:
323 return fRegisters.__r11;
324 case UNW_X86_64_R12:
325 return fRegisters.__r12;
326 case UNW_X86_64_R13:
327 return fRegisters.__r13;
328 case UNW_X86_64_R14:
329 return fRegisters.__r14;
330 case UNW_X86_64_R15:
331 return fRegisters.__r15;
332 }
333 ABORT("unsupported x86_64 register");
334}
335
336inline void Registers_x86_64::setRegister(int regNum, uint64_t value)
337{
338 switch ( regNum ) {
339 case UNW_REG_IP:
340 fRegisters.__rip = value;
341 return;
342 case UNW_REG_SP:
343 fRegisters.__rsp = value;
344 return;
345 case UNW_X86_64_RAX:
346 fRegisters.__rax = value;
347 return;
348 case UNW_X86_64_RDX:
349 fRegisters.__rdx = value;
350 return;
351 case UNW_X86_64_RCX:
352 fRegisters.__rcx = value;
353 return;
354 case UNW_X86_64_RBX:
355 fRegisters.__rbx = value;
356 return;
357 case UNW_X86_64_RSI:
358 fRegisters.__rsi = value;
359 return;
360 case UNW_X86_64_RDI:
361 fRegisters.__rdi = value;
362 return;
363 case UNW_X86_64_RBP:
364 fRegisters.__rbp = value;
365 return;
366 case UNW_X86_64_RSP:
367 fRegisters.__rsp = value;
368 return;
369 case UNW_X86_64_R8:
370 fRegisters.__r8 = value;
371 return;
372 case UNW_X86_64_R9:
373 fRegisters.__r9 = value;
374 return;
375 case UNW_X86_64_R10:
376 fRegisters.__r10 = value;
377 return;
378 case UNW_X86_64_R11:
379 fRegisters.__r11 = value;
380 return;
381 case UNW_X86_64_R12:
382 fRegisters.__r12 = value;
383 return;
384 case UNW_X86_64_R13:
385 fRegisters.__r13 = value;
386 return;
387 case UNW_X86_64_R14:
388 fRegisters.__r14 = value;
389 return;
390 case UNW_X86_64_R15:
391 fRegisters.__r15 = value;
392 return;
393 }
394 ABORT("unsupported x86_64 register");
395}
396
397inline const char* Registers_x86_64::getRegisterName(int regNum)
398{
399 switch ( regNum ) {
400 case UNW_REG_IP:
401 return "rip";
402 case UNW_REG_SP:
403 return "rsp";
404 case UNW_X86_64_RAX:
405 return "rax";
406 case UNW_X86_64_RDX:
407 return "rdx";
408 case UNW_X86_64_RCX:
409 return "rcx";
410 case UNW_X86_64_RBX:
411 return "rbx";
412 case UNW_X86_64_RSI:
413 return "rsi";
414 case UNW_X86_64_RDI:
415 return "rdi";
416 case UNW_X86_64_RBP:
417 return "rbp";
418 case UNW_X86_64_RSP:
419 return "rsp";
420 case UNW_X86_64_R8:
421 return "r8";
422 case UNW_X86_64_R9:
423 return "r9";
424 case UNW_X86_64_R10:
425 return "r10";
426 case UNW_X86_64_R11:
427 return "r11";
428 case UNW_X86_64_R12:
429 return "r12";
430 case UNW_X86_64_R13:
431 return "r13";
432 case UNW_X86_64_R14:
433 return "r14";
434 case UNW_X86_64_R15:
435 return "r15";
436 default:
437 return "unknown register";
438 }
439}
440
441double Registers_x86_64::getFloatRegister(int num) const
442{
443 ABORT("no x86_64 float registers");
444}
445
446void Registers_x86_64::setFloatRegister(int num, double value)
447{
448 ABORT("no x86_64 float registers");
449}
450
451inline v128 Registers_x86_64::getVectorRegister(int num) const
452{
453 ABORT("no x86_64 vector registers");
454}
455
456inline void Registers_x86_64::setVectorRegister(int num, v128 value)
457{
458 ABORT("no x86_64 vector registers");
459}
460
461
462///
463/// Registers_ppc holds the register state of a thread in a 32-bit PowerPC process.
464///
465class Registers_ppc
466{
467public:
468 Registers_ppc();
469 Registers_ppc(const void* registers);
470
471 bool validRegister(int num) const;
472 uint32_t getRegister(int num) const;
473 void setRegister(int num, uint32_t value);
474 bool validFloatRegister(int num) const;
475 double getFloatRegister(int num) const;
476 void setFloatRegister(int num, double value);
477 bool validVectorRegister(int num) const;
478 v128 getVectorRegister(int num) const;
479 void setVectorRegister(int num, v128 value);
480 void jumpto();
481 const char* getRegisterName(int num);
482 uint64_t getSP() const { return fRegisters.__r1; }
483 void setSP(uint64_t value) { fRegisters.__r1 = value; }
484 uint64_t getIP() const { return fRegisters.__srr0; }
485 void setIP(uint64_t value) { fRegisters.__srr0 = value; }
486private:
487 struct ppc_thread_state_t
488 {
489 unsigned int __srr0; /* Instruction address register (PC) */
490 unsigned int __srr1; /* Machine state register (supervisor) */
491 unsigned int __r0;
492 unsigned int __r1;
493 unsigned int __r2;
494 unsigned int __r3;
495 unsigned int __r4;
496 unsigned int __r5;
497 unsigned int __r6;
498 unsigned int __r7;
499 unsigned int __r8;
500 unsigned int __r9;
501 unsigned int __r10;
502 unsigned int __r11;
503 unsigned int __r12;
504 unsigned int __r13;
505 unsigned int __r14;
506 unsigned int __r15;
507 unsigned int __r16;
508 unsigned int __r17;
509 unsigned int __r18;
510 unsigned int __r19;
511 unsigned int __r20;
512 unsigned int __r21;
513 unsigned int __r22;
514 unsigned int __r23;
515 unsigned int __r24;
516 unsigned int __r25;
517 unsigned int __r26;
518 unsigned int __r27;
519 unsigned int __r28;
520 unsigned int __r29;
521 unsigned int __r30;
522 unsigned int __r31;
523 unsigned int __cr; /* Condition register */
524 unsigned int __xer; /* User's integer exception register */
525 unsigned int __lr; /* Link register */
526 unsigned int __ctr; /* Count register */
527 unsigned int __mq; /* MQ register (601 only) */
528 unsigned int __vrsave; /* Vector Save Register */
529 };
530
531 struct ppc_float_state_t
532 {
533 double __fpregs[32];
534
535 unsigned int __fpscr_pad; /* fpscr is 64 bits, 32 bits of rubbish */
536 unsigned int __fpscr; /* floating point status register */
537 };
538
539 ppc_thread_state_t fRegisters;
540 ppc_float_state_t fFloatRegisters;
541 v128 fVectorRegisters[32]; // offset 424
542};
543
544
545
546inline Registers_ppc::Registers_ppc(const void* registers)
547{
548 COMPILE_TIME_ASSERT( sizeof(Registers_ppc) < sizeof(unw_context_t) );
549 fRegisters = *((ppc_thread_state_t*)registers);
550 fFloatRegisters = *((ppc_float_state_t*)((char*)registers+160));
551 memcpy(fVectorRegisters, ((char*)registers+424), sizeof(fVectorRegisters));
552}
553
554inline Registers_ppc::Registers_ppc()
555{
556 bzero(&fRegisters, sizeof(fRegisters));
557 bzero(&fFloatRegisters, sizeof(fFloatRegisters));
558 bzero(&fVectorRegisters, sizeof(fVectorRegisters));
559}
560
561
562inline bool Registers_ppc::validRegister(int regNum) const
563{
564 if ( regNum == UNW_REG_IP )
565 return true;
566 if ( regNum == UNW_REG_SP )
567 return true;
568 if ( regNum == UNW_PPC_VRSAVE )
569 return true;
570 if ( regNum < 0 )
571 return false;
572 if ( regNum <= UNW_PPC_R31 )
573 return true;
574 if ( regNum == UNW_PPC_MQ )
575 return true;
576 if ( regNum == UNW_PPC_LR )
577 return true;
578 if ( regNum == UNW_PPC_CTR )
579 return true;
580 if ( (UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7) )
581 return true;
582 return false;
583}
584
585
586inline uint32_t Registers_ppc::getRegister(int regNum) const
587{
588 switch ( regNum ) {
589 case UNW_REG_IP:
590 return fRegisters.__srr0;
591 case UNW_REG_SP:
592 return fRegisters.__r1;
593 case UNW_PPC_R0:
594 return fRegisters.__r0;
595 case UNW_PPC_R1:
596 return fRegisters.__r1;
597 case UNW_PPC_R2:
598 return fRegisters.__r2;
599 case UNW_PPC_R3:
600 return fRegisters.__r3;
601 case UNW_PPC_R4:
602 return fRegisters.__r4;
603 case UNW_PPC_R5:
604 return fRegisters.__r5;
605 case UNW_PPC_R6:
606 return fRegisters.__r6;
607 case UNW_PPC_R7:
608 return fRegisters.__r7;
609 case UNW_PPC_R8:
610 return fRegisters.__r8;
611 case UNW_PPC_R9:
612 return fRegisters.__r9;
613 case UNW_PPC_R10:
614 return fRegisters.__r10;
615 case UNW_PPC_R11:
616 return fRegisters.__r11;
617 case UNW_PPC_R12:
618 return fRegisters.__r12;
619 case UNW_PPC_R13:
620 return fRegisters.__r13;
621 case UNW_PPC_R14:
622 return fRegisters.__r14;
623 case UNW_PPC_R15:
624 return fRegisters.__r15;
625 case UNW_PPC_R16:
626 return fRegisters.__r16;
627 case UNW_PPC_R17:
628 return fRegisters.__r17;
629 case UNW_PPC_R18:
630 return fRegisters.__r18;
631 case UNW_PPC_R19:
632 return fRegisters.__r19;
633 case UNW_PPC_R20:
634 return fRegisters.__r20;
635 case UNW_PPC_R21:
636 return fRegisters.__r21;
637 case UNW_PPC_R22:
638 return fRegisters.__r22;
639 case UNW_PPC_R23:
640 return fRegisters.__r23;
641 case UNW_PPC_R24:
642 return fRegisters.__r24;
643 case UNW_PPC_R25:
644 return fRegisters.__r25;
645 case UNW_PPC_R26:
646 return fRegisters.__r26;
647 case UNW_PPC_R27:
648 return fRegisters.__r27;
649 case UNW_PPC_R28:
650 return fRegisters.__r28;
651 case UNW_PPC_R29:
652 return fRegisters.__r29;
653 case UNW_PPC_R30:
654 return fRegisters.__r30;
655 case UNW_PPC_R31:
656 return fRegisters.__r31;
657 case UNW_PPC_LR:
658 return fRegisters.__lr;
659 case UNW_PPC_CR0:
660 return (fRegisters.__cr & 0xF0000000);
661 case UNW_PPC_CR1:
662 return (fRegisters.__cr & 0x0F000000);
663 case UNW_PPC_CR2:
664 return (fRegisters.__cr & 0x00F00000);
665 case UNW_PPC_CR3:
666 return (fRegisters.__cr & 0x000F0000);
667 case UNW_PPC_CR4:
668 return (fRegisters.__cr & 0x0000F000);
669 case UNW_PPC_CR5:
670 return (fRegisters.__cr & 0x00000F00);
671 case UNW_PPC_CR6:
672 return (fRegisters.__cr & 0x000000F0);
673 case UNW_PPC_CR7:
674 return (fRegisters.__cr & 0x0000000F);
675 case UNW_PPC_VRSAVE:
676 return fRegisters.__vrsave;
677 }
678 ABORT("unsupported ppc register");
679}
680
681
682inline void Registers_ppc::setRegister(int regNum, uint32_t value)
683{
684 //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value);
685 switch ( regNum ) {
686 case UNW_REG_IP:
687 fRegisters.__srr0 = value;
688 return;
689 case UNW_REG_SP:
690 fRegisters.__r1 = value;
691 return;
692 case UNW_PPC_R0:
693 fRegisters.__r0 = value;
694 return;
695 case UNW_PPC_R1:
696 fRegisters.__r1 = value;
697 return;
698 case UNW_PPC_R2:
699 fRegisters.__r2 = value;
700 return;
701 case UNW_PPC_R3:
702 fRegisters.__r3 = value;
703 return;
704 case UNW_PPC_R4:
705 fRegisters.__r4 = value;
706 return;
707 case UNW_PPC_R5:
708 fRegisters.__r5 = value;
709 return;
710 case UNW_PPC_R6:
711 fRegisters.__r6 = value;
712 return;
713 case UNW_PPC_R7:
714 fRegisters.__r7 = value;
715 return;
716 case UNW_PPC_R8:
717 fRegisters.__r8 = value;
718 return;
719 case UNW_PPC_R9:
720 fRegisters.__r9 = value;
721 return;
722 case UNW_PPC_R10:
723 fRegisters.__r10 = value;
724 return;
725 case UNW_PPC_R11:
726 fRegisters.__r11 = value;
727 return;
728 case UNW_PPC_R12:
729 fRegisters.__r12 = value;
730 return;
731 case UNW_PPC_R13:
732 fRegisters.__r13 = value;
733 return;
734 case UNW_PPC_R14:
735 fRegisters.__r14 = value;
736 return;
737 case UNW_PPC_R15:
738 fRegisters.__r15 = value;
739 return;
740 case UNW_PPC_R16:
741 fRegisters.__r16 = value;
742 return;
743 case UNW_PPC_R17:
744 fRegisters.__r17 = value;
745 return;
746 case UNW_PPC_R18:
747 fRegisters.__r18 = value;
748 return;
749 case UNW_PPC_R19:
750 fRegisters.__r19 = value;
751 return;
752 case UNW_PPC_R20:
753 fRegisters.__r20 = value;
754 return;
755 case UNW_PPC_R21:
756 fRegisters.__r21 = value;
757 return;
758 case UNW_PPC_R22:
759 fRegisters.__r22 = value;
760 return;
761 case UNW_PPC_R23:
762 fRegisters.__r23 = value;
763 return;
764 case UNW_PPC_R24:
765 fRegisters.__r24 = value;
766 return;
767 case UNW_PPC_R25:
768 fRegisters.__r25 = value;
769 return;
770 case UNW_PPC_R26:
771 fRegisters.__r26 = value;
772 return;
773 case UNW_PPC_R27:
774 fRegisters.__r27 = value;
775 return;
776 case UNW_PPC_R28:
777 fRegisters.__r28 = value;
778 return;
779 case UNW_PPC_R29:
780 fRegisters.__r29 = value;
781 return;
782 case UNW_PPC_R30:
783 fRegisters.__r30 = value;
784 return;
785 case UNW_PPC_R31:
786 fRegisters.__r31 = value;
787 return;
788 case UNW_PPC_MQ:
789 fRegisters.__mq = value;
790 return;
791 case UNW_PPC_LR:
792 fRegisters.__lr = value;
793 return;
794 case UNW_PPC_CTR:
795 fRegisters.__ctr = value;
796 return;
797 case UNW_PPC_CR0:
798 fRegisters.__cr &= 0x0FFFFFFF;
799 fRegisters.__cr |= (value & 0xF0000000);
800 return;
801 case UNW_PPC_CR1:
802 fRegisters.__cr &= 0xF0FFFFFF;
803 fRegisters.__cr |= (value & 0x0F000000);
804 return;
805 case UNW_PPC_CR2:
806 fRegisters.__cr &= 0xFF0FFFFF;
807 fRegisters.__cr |= (value & 0x00F00000);
808 return;
809 case UNW_PPC_CR3:
810 fRegisters.__cr &= 0xFFF0FFFF;
811 fRegisters.__cr |= (value & 0x000F0000);
812 return;
813 case UNW_PPC_CR4:
814 fRegisters.__cr &= 0xFFFF0FFF;
815 fRegisters.__cr |= (value & 0x0000F000);
816 return;
817 case UNW_PPC_CR5:
818 fRegisters.__cr &= 0xFFFFF0FF;
819 fRegisters.__cr |= (value & 0x00000F00);
820 return;
821 case UNW_PPC_CR6:
822 fRegisters.__cr &= 0xFFFFFF0F;
823 fRegisters.__cr |= (value & 0x000000F0);
824 return;
825 case UNW_PPC_CR7:
826 fRegisters.__cr &= 0xFFFFFFF0;
827 fRegisters.__cr |= (value & 0x0000000F);
828 return;
829 case UNW_PPC_VRSAVE:
830 fRegisters.__vrsave = value;
831 return;
832 // not saved
833 return;
834 case UNW_PPC_XER:
835 fRegisters.__xer = value;
836 return;
837 case UNW_PPC_AP:
838 case UNW_PPC_VSCR:
839 case UNW_PPC_SPEFSCR:
840 // not saved
841 return;
842 }
843 ABORT("unsupported ppc register");
844}
845
846inline bool Registers_ppc::validFloatRegister(int regNum) const
847{
848 if ( regNum < UNW_PPC_F0 )
849 return false;
850 if ( regNum > UNW_PPC_F31 )
851 return false;
852 return true;
853}
854
855inline double Registers_ppc::getFloatRegister(int regNum) const
856{
857 assert(validFloatRegister(regNum));
858 return fFloatRegisters.__fpregs[regNum-UNW_PPC_F0];
859}
860
861inline void Registers_ppc::setFloatRegister(int regNum, double value)
862{
863 //fprintf(stderr, "Registers_ppc::setFloatRegister(%d, %g))\n", regNum, value);
864 assert(validFloatRegister(regNum));
865 fFloatRegisters.__fpregs[regNum-UNW_PPC_F0] = value;
866}
867
868
869inline bool Registers_ppc::validVectorRegister(int regNum) const
870{
871 if ( regNum < UNW_PPC_V0 )
872 return false;
873 if ( regNum > UNW_PPC_V31 )
874 return false;
875 return true;
876}
877
878v128 Registers_ppc::getVectorRegister(int regNum) const
879{
880 assert(validVectorRegister(regNum));
881 v128 result = fVectorRegisters[regNum-UNW_PPC_V0];
882 //fprintf(stderr, "Registers_ppc::getVectorRegister(this=%p, %d) => <0x%08X, 0x%08X, 0x%08X, 0x%08X> \n",
883 // this, regNum, result.vec[0], result.vec[1], result.vec[2], result.vec[3]);
884 return result;
885}
886
887void Registers_ppc::setVectorRegister(int regNum, v128 value)
888{
889 assert(validVectorRegister(regNum));
890 //fprintf(stderr, "Registers_ppc::setVectorRegister(this=%p, %d) <0x%08X, 0x%08X, 0x%08X, 0x%08X> => <0x%08X, 0x%08X, 0x%08X, 0x%08X> \n",
891 // this, regNum, fVectorRegisters[regNum-UNW_PPC_V0].vec[0], fVectorRegisters[regNum-UNW_PPC_V0].vec[1], fVectorRegisters[regNum-UNW_PPC_V0].vec[2],
892 // fVectorRegisters[regNum-UNW_PPC_V0].vec[3], value.vec[0], value.vec[1], value.vec[2], value.vec[3]);
893 fVectorRegisters[regNum-UNW_PPC_V0] = value;
894}
895
896
897inline const char* Registers_ppc::getRegisterName(int regNum)
898{
899 switch ( regNum ) {
900 case UNW_REG_IP:
901 return "ip";
902 case UNW_REG_SP:
903 return "sp";
904 case UNW_PPC_R0:
905 return "r0";
906 case UNW_PPC_R1:
907 return "r1";
908 case UNW_PPC_R2:
909 return "r2";
910 case UNW_PPC_R3:
911 return "r3";
912 case UNW_PPC_R4:
913 return "r4";
914 case UNW_PPC_R5:
915 return "r5";
916 case UNW_PPC_R6:
917 return "r6";
918 case UNW_PPC_R7:
919 return "r7";
920 case UNW_PPC_R8:
921 return "r8";
922 case UNW_PPC_R9:
923 return "r9";
924 case UNW_PPC_R10:
925 return "r10";
926 case UNW_PPC_R11:
927 return "r11";
928 case UNW_PPC_R12:
929 return "r12";
930 case UNW_PPC_R13:
931 return "r13";
932 case UNW_PPC_R14:
933 return "r14";
934 case UNW_PPC_R15:
935 return "r15";
936 case UNW_PPC_R16:
937 return "r16";
938 case UNW_PPC_R17:
939 return "r17";
940 case UNW_PPC_R18:
941 return "r18";
942 case UNW_PPC_R19:
943 return "r19";
944 case UNW_PPC_R20:
945 return "r20";
946 case UNW_PPC_R21:
947 return "r21";
948 case UNW_PPC_R22:
949 return "r22";
950 case UNW_PPC_R23:
951 return "r23";
952 case UNW_PPC_R24:
953 return "r24";
954 case UNW_PPC_R25:
955 return "r25";
956 case UNW_PPC_R26:
957 return "r26";
958 case UNW_PPC_R27:
959 return "r27";
960 case UNW_PPC_R28:
961 return "r28";
962 case UNW_PPC_R29:
963 return "r29";
964 case UNW_PPC_R30:
965 return "r30";
966 case UNW_PPC_R31:
967 return "r31";
968 case UNW_PPC_F0:
969 return "fp0";
970 case UNW_PPC_F1:
971 return "fp1";
972 case UNW_PPC_F2:
973 return "fp2";
974 case UNW_PPC_F3:
975 return "fp3";
976 case UNW_PPC_F4:
977 return "fp4";
978 case UNW_PPC_F5:
979 return "fp5";
980 case UNW_PPC_F6:
981 return "fp6";
982 case UNW_PPC_F7:
983 return "fp7";
984 case UNW_PPC_F8:
985 return "fp8";
986 case UNW_PPC_F9:
987 return "fp9";
988 case UNW_PPC_F10:
989 return "fp10";
990 case UNW_PPC_F11:
991 return "fp11";
992 case UNW_PPC_F12:
993 return "fp12";
994 case UNW_PPC_F13:
995 return "fp13";
996 case UNW_PPC_F14:
997 return "fp14";
998 case UNW_PPC_F15:
999 return "fp15";
1000 case UNW_PPC_F16:
1001 return "fp16";
1002 case UNW_PPC_F17:
1003 return "fp17";
1004 case UNW_PPC_F18:
1005 return "fp18";
1006 case UNW_PPC_F19:
1007 return "fp19";
1008 case UNW_PPC_F20:
1009 return "fp20";
1010 case UNW_PPC_F21:
1011 return "fp21";
1012 case UNW_PPC_F22:
1013 return "fp22";
1014 case UNW_PPC_F23:
1015 return "fp23";
1016 case UNW_PPC_F24:
1017 return "fp24";
1018 case UNW_PPC_F25:
1019 return "fp25";
1020 case UNW_PPC_F26:
1021 return "fp26";
1022 case UNW_PPC_F27:
1023 return "fp27";
1024 case UNW_PPC_F28:
1025 return "fp28";
1026 case UNW_PPC_F29:
1027 return "fp29";
1028 case UNW_PPC_F30:
1029 return "fp30";
1030 case UNW_PPC_F31:
1031 return "fp31";
1032 case UNW_PPC_LR:
1033 return "lr";
1034 default:
1035 return "unknown register";
1036 }
1037
1038
1039}
1040
1041
1042} // namespace libunwind
1043
1044
1045
1046#endif // __REGISTERS_HPP__
1047
1048
1049
1050