New MachRegister class: stackwalk-x86, parseDwarf, POWER IAPI integration
[dyninst.git] / common / src / dyn_regs.C
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 #define DYN_DEFINE_REGS
33 #include "dynutil/h/dyn_regs.h"
34
35 namespace Dyninst {
36
37 std::map<signed int, const char *> *Dyninst::MachRegister::names;
38
39 MachRegister::MachRegister() :
40    reg(0)
41
42 }
43
44 MachRegister::MachRegister(signed int r) :
45    reg(r)
46 {
47 }
48  
49 MachRegister::MachRegister(signed int r, const char *n) :
50    reg(r)
51 {
52    if (!names) {
53       names = new std::map<signed int, const char *>();
54    }
55    (*names)[r] = n;
56 }
57
58 MachRegister::~MachRegister() {
59 }
60
61 MachRegister MachRegister::getBaseRegister() const { 
62    switch (getArchitecture()) {
63       case Arch_x86:
64       case Arch_x86_64:
65          return reg & 0xffff00ff;
66       case Arch_ppc32:
67       case Arch_ppc64:
68          return reg;
69       case Arch_none:
70          return reg;
71    }
72    return InvalidReg;
73 }
74    
75 Architecture MachRegister::getArchitecture() const { 
76    return (Architecture) (reg & 0xff000000);
77 }
78
79 bool MachRegister::isValid() const {
80    return (reg != InvalidReg.reg);
81 }
82
83 MachRegisterVal MachRegister::getSubRegValue(const MachRegister subreg, 
84                                              MachRegisterVal &orig) const
85 {
86    if (subreg.reg == reg || 
87        getArchitecture() == Arch_ppc32 ||
88        getArchitecture() == Arch_ppc64)
89       return orig;
90
91    assert(subreg.getBaseRegister() == getBaseRegister());
92    switch ((subreg.reg & 0x0000ff00) >> 8) {
93       case 0x0: return orig;
94       case 0x1: return (orig & 0xff);
95       case 0x2: return (orig & 0xff00) >> 8;              
96       case 0x3: return (orig & 0xffff);
97       case 0xf: return (orig & 0xffffffff);
98       default: assert(0);
99    }
100 }
101
102 const char *MachRegister::name() const { 
103    return (*names)[reg];
104 }
105
106 unsigned int MachRegister::size() const {
107    switch (getArchitecture())
108    {
109       case Arch_x86:
110          switch (reg & 0x0000ff00) {
111             case 0x0100: //L_REG
112             case 0x0200: //H_REG
113                return 1;
114             case 0x0300: //W_REG
115                return 2;
116             case 0x0000: //FULL
117                return 4;
118             default:
119                assert(0);
120          }
121       case Arch_x86_64:
122          switch (reg & 0x0000ff00) {
123             case 0x0100: //L_REG
124             case 0x0200: //H_REG
125                return 1;
126             case 0x0300: //W_REG
127                return 2;
128             case 0x0f00: //D_REG
129                return 4;
130             case 0x0000: //FULL
131                return 8;
132             default:
133                assert(0);
134          }
135       case Arch_ppc32: {
136          int reg_class = reg & 0x00ff0000;
137          if (reg_class == ppc32::FPR || reg_class == ppc32::FSR)
138             return 8;
139          return 4;
140       }
141       case Arch_ppc64:
142          return 8;
143       case Arch_none:
144          return 0;
145    }
146    return 0; //Unreachable, but disable warnings
147 }
148    
149 bool MachRegister::operator<(const MachRegister &a) const { 
150    return (reg < a.reg);
151 }
152  
153 bool MachRegister::operator==(const MachRegister &a) const { 
154    return (reg == a.reg);
155 }
156  
157 MachRegister::operator signed int() const {
158    return reg;
159 }
160
161 signed int MachRegister::val() const {
162    return reg;
163 }
164
165
166 MachRegister MachRegister::getPC(Dyninst::Architecture arch)
167 {
168    switch (arch)
169    {
170       case Arch_x86:
171          return x86::eip;
172       case Arch_x86_64:
173          return x86_64::rip;
174       case Arch_ppc32:
175          return ppc32::pc;
176       case Arch_ppc64:
177          return ppc64::pc;
178       case Arch_none:
179          return InvalidReg;
180    }
181    return InvalidReg;
182 }
183
184 MachRegister MachRegister::getFramePointer(Dyninst::Architecture arch)
185 {
186    switch (arch)
187    {
188       case Arch_x86:
189          return x86::ebp;
190       case Arch_x86_64:
191          return x86_64::rbp;
192       case Arch_ppc32:
193       case Arch_ppc64:
194          return FrameBase;
195       case Arch_none:
196          return InvalidReg;
197    }
198    return InvalidReg;
199 }
200
201 MachRegister MachRegister::getStackPointer(Dyninst::Architecture arch)
202 {
203    switch (arch)
204    {
205       case Arch_x86:
206          return x86::esp;
207       case Arch_x86_64:
208          return x86_64::rsp;
209       case Arch_ppc32:
210          return ppc32::r1;
211       case Arch_ppc64:
212          return ppc64::r1;
213       case Arch_none:
214          return InvalidReg;
215    }
216    return InvalidReg;
217 }
218
219 bool MachRegister::isPC() const
220 {
221    return (reg == x86_64::rip || reg == x86::eip || 
222            reg == ppc32::pc || reg == ppc64::pc);
223 }
224
225 bool MachRegister::isFramePointer() const
226 {
227    return (reg == x86_64::rbp || reg == x86::ebp ||
228            reg == FrameBase);
229 }
230
231 bool MachRegister::isStackPointer() const
232 {
233    return (reg == x86_64::rsp || reg == x86::esp ||
234            reg == ppc32::r1 || reg == ppc64::r1);
235 }
236
237 }