Remove dyndwarf, dynelf and symlite public includes.
[dyninst.git] / dwarf / src / dwarfResult.C
1 #include "dwarf/h/dwarfResult.h"
2 #include "dynutil/h/VariableLocation.h"
3 #include "dwarf/h/dwarfFrameParser.h"
4 #include "dynutil/h/ProcReader.h"
5 #include "dynutil/h/dyntypes.h"
6 #include "dynutil/h/dyn_regs.h"
7 #include "common/h/Types.h"
8 #include <iostream>
9
10 using namespace Dyninst;
11 using namespace Dwarf;
12 using namespace std;
13
14 #define CHECK_OPER(n) if (operands.size() < n) { error = true; break; }
15
16 void SymbolicDwarfResult::pushReg(MachRegister reg) {
17    if (var.stClass != storageUnset) { error = true; }
18    var.stClass = storageReg;
19    var.refClass = storageNoRef;
20    var.frameOffset = 0;
21    var.mr_reg = reg;
22 }
23
24 void SymbolicDwarfResult::readReg(MachRegister reg) {
25    if (var.stClass != storageUnset) { error = true; }
26    var.stClass = storageRegOffset;
27    var.refClass = storageNoRef;
28    // frameOffset will be set with an add operation
29    var.frameOffset = 0;
30    var.mr_reg = reg;
31 }
32
33 void SymbolicDwarfResult::pushUnsignedVal(MachRegisterVal val) {
34    if (var.stClass == storageUnset) {
35       // No register, so default to StorageAddr
36       var.stClass = storageAddr;
37    }
38    operands.push(val);
39 }
40
41 void SymbolicDwarfResult::pushSignedVal(MachRegisterVal val) {
42    operands.push(val);
43 }
44
45 void SymbolicDwarfResult::pushOp(Operator op) {
46    // This is "fill in as we see examples" code. 
47    // Right now, the only use I know of is add. 
48    switch (op) {
49       case Add:
50          CHECK_OPER(1);
51          if (var.stClass == storageUnset) { error = true; }
52          var.frameOffset += operands.top(); 
53          operands.pop();
54          break;
55       default:
56          error = true;
57    }         
58 }
59
60 void SymbolicDwarfResult::pushOp(Operator op, 
61                                  unsigned u) {
62    switch(op) {
63       case Add:
64          var.frameOffset += u;
65          break;
66       default:
67          error = true;
68    }
69 }
70
71 void SymbolicDwarfResult::pushFrameBase() {
72    readReg(FrameBase);
73 }
74
75 void SymbolicDwarfResult::pushCFA() {
76    readReg(CFA);
77 }
78
79 VariableLocation &SymbolicDwarfResult::val() {
80    if (!operands.empty()) {
81       var.frameOffset += operands.top(); 
82       operands.pop();
83    }
84    return var;
85 }
86
87 void ConcreteDwarfResult::pushReg(MachRegister) {
88    // I don't believe this is legal
89    error = true;
90 }
91
92 void ConcreteDwarfResult::readReg(MachRegister reg) {
93    Dyninst::MachRegisterVal v;
94    if (!reader->GetReg(reg, v)) error = true;
95    push(v);
96 }
97
98 void ConcreteDwarfResult::pushUnsignedVal(MachRegisterVal v) {
99    // Someday this will matter...
100    push(v);
101 }
102
103 void ConcreteDwarfResult::pushSignedVal(MachRegisterVal v) {
104    // Someday this will matter...
105    push(v);
106 }
107
108
109 void ConcreteDwarfResult::pushOp(Operator op) {
110    MachRegisterVal v;
111    MachRegisterVal first;
112    MachRegisterVal second;
113
114    switch (op) {
115       case Add:
116          CHECK_OPER(2);
117          v = peek(1) + peek(0);
118          popRange(0, 1);
119          push(v);
120          break;
121       case Sub:
122          CHECK_OPER(2);
123          v = peek(1) - peek(0);
124          popRange(0, 1);
125          push(v);
126          break;
127       case Mul:
128          CHECK_OPER(2);
129          v = peek(1) * peek(0);
130          popRange(0, 1);
131          push(v);
132          break;
133       case Div:
134          CHECK_OPER(2);
135          if (peek(0) == 0) { error = true; break; }
136          v = peek(1) / peek(0);
137          popRange(0, 1);
138          push(v);
139          break;
140       case Mod:
141          CHECK_OPER(2);
142          if (peek(0) == 0) { error = true; break; }
143          v = peek(1) % peek(0);
144          popRange(0, 1);
145          push(v);
146          break;
147       case And:
148          CHECK_OPER(2);
149          v = peek(1) & peek(0);
150          popRange(0, 1);
151          push(v);
152          break;
153       case Or:
154          CHECK_OPER(2);
155          v = peek(1) | peek(0);
156          popRange(0, 1);
157          push(v);
158          break; 
159       case Not:
160          CHECK_OPER(1);
161          v = ~peek(0);
162          pop(0);
163          push(v);
164          break;
165       case Xor:
166          CHECK_OPER(2);
167          v = peek(0) ^ peek(0);
168          popRange(0, 1);
169          push(v);
170          break;
171       case Abs:
172          CHECK_OPER(1);
173          v = ::abs((long) peek(0));
174          pop(0);
175          push(v);
176          break;
177       case Shl:
178          CHECK_OPER(2);
179          v = peek(1) << peek(0);
180          popRange(0, 1);
181          push(v);
182          break;
183       case Shr:
184          CHECK_OPER(2);
185          v = ((unsigned long) peek(1)) >> ((unsigned long) peek(0));
186          popRange(0, 1);
187          push(v);
188          break;
189       case ShrArith:
190          CHECK_OPER(2);
191          v = ((long) peek(1)) + ((long) peek(0));
192          popRange(0, 1);
193          push(v);
194          break;
195       case GE:
196          CHECK_OPER(2);
197          second = peek(1);
198          first = peek(0);
199          popRange(0, 1);
200          push((second >= first) ? 1 : 0);
201          break;
202       case LE:
203          CHECK_OPER(2);
204          second = peek(1);
205          first = peek(0);
206          popRange(0, 1);
207          push((second <= first) ? 1 : 0);
208          break;
209       case GT:
210          CHECK_OPER(2);
211          second = peek(1);
212          first = peek(0);
213          popRange(0, 1);
214          push((second > first) ? 1 : 0);
215          break;
216       case LT:
217          CHECK_OPER(2);
218          second = peek(1);
219          first = peek(0);
220          popRange(0, 1);
221          push((second < first) ? 1 : 0);
222          break;
223       case Eq:
224          CHECK_OPER(2);
225          second = peek(1);
226          first = peek(0);
227          popRange(0, 1);
228          push((second == first) ? 1 : 0);
229          break;
230       case Neq:
231          CHECK_OPER(2);
232          second = peek(1);
233          first = peek(0);
234          popRange(0, 1);
235          push((second != first) ? 1 : 0);
236          break;
237       case Deref:         
238       case Pick:
239       case Drop:
240       default:
241          // 2 argument
242          error = true;
243          break;
244    }
245 }
246
247 void ConcreteDwarfResult::pushOp(Operator op, unsigned ref) {
248    switch (op) {
249       case Add: 
250          pushUnsignedVal(ref);
251          pushOp(Add);
252          break;
253       case Deref: {
254          CHECK_OPER(1);
255          MachRegisterVal v;
256          switch(ref) {
257             case 1: {
258                unsigned char c;
259                if (!reader->ReadMem(peek(0), &c, sizeof(c))) error = true;
260                v = c;
261                break;
262             }
263             case 2: {
264                unsigned short s;
265                if (!reader->ReadMem(peek(0), &s, sizeof(s))) error = true;
266                v = s;
267                break;
268             }
269             case 4: {
270                uint32_t u;
271                if (!reader->ReadMem(peek(0), &u, sizeof(u))) error = true;
272                v = u;
273                break;
274             }
275             case 8: {
276                uint64_t u;
277                if (!reader->ReadMem(peek(0), &u, sizeof(u))) error = true;
278                v = u;
279                break;
280             }
281             default:
282                error = true;
283                v = 0;
284                break;
285          }
286          push(v);
287          break;
288       }
289       case Pick:
290          CHECK_OPER(ref);
291          push(peek(ref));
292          break;
293       case Drop:
294          CHECK_OPER(ref);
295          pop(ref);
296          break;
297       default:
298          error = true;
299          break;
300    }
301 }
302
303 void ConcreteDwarfResult::pushFrameBase() {
304    error = true;
305 }
306
307 void ConcreteDwarfResult::pushCFA() {
308    DwarfFrameParser::Ptr cfaParser = DwarfFrameParser::create(dbg, arch);
309    MachRegisterVal cfa;
310    FrameErrors_t err;
311    if (!cfaParser->getRegValueAtFrame(pc, 
312                                       CFA, 
313                                       cfa, 
314                                       reader,
315                                       err)) error = true;
316    pushUnsignedVal(cfa);
317 }
318
319 MachRegisterVal ConcreteDwarfResult::peek(int index) {
320    return operands[operands.size() - (index + 1)];
321 }
322
323 void ConcreteDwarfResult::pop(int num) {
324    operands.erase(operands.begin() + (operands.size() - (num + 1)));
325 }
326
327 void ConcreteDwarfResult::popRange(int start, int end) {
328    std::vector<MachRegisterVal>::iterator b, e;
329    if (start > end) {
330       b = operands.begin() + (operands.size() - (start + 1));
331       e = operands.begin() + (operands.size() - end);
332    }
333    else {
334       b = operands.begin() + (operands.size() - (end + 1));
335       e = operands.begin() + (operands.size() - start);
336    }
337    operands.erase(b, e);
338 }
339
340 void ConcreteDwarfResult::push(MachRegisterVal v) {
341    operands.push_back(v);
342 }
343
344 bool ConcreteDwarfResult::eval(MachRegisterVal &v) {
345    if (err()) return false;
346    v = val();
347    return true;
348 }
349
350 MachRegisterVal ConcreteDwarfResult::val() {
351    return operands.back();
352 }