Merge branch 'master' into devel
[dyninst.git] / symEval / h / Absloc.h
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 // Base representations for locations in program memory and registers
33 // We use a two-layered model consisting of AbsLocs (abstract locations)
34 // and AbsRegions (abstract regions). 
35 //
36 // An Absloc defines a unique location in memory or a register. We 
37 // consider the stack to be a separate, indexed-from-zero memory location.
38 //
39 // An AbsRegion is a set of Abslocs. In essence it is a set, though we
40 // may be able to use a more efficient internal representation than a
41 // set. As a TODO, we wish to provide shortcuts for comparing one type
42 // of AbsRegion to another type more efficiently than the fallback
43 // point-wise comparison.
44
45 #if !defined(ABSLOC_H)
46 #define ABSLOC_H
47
48 #if !defined(_MSC_VER)
49 #include <values.h>
50 #endif
51
52 #include "Instruction.h"
53 #include "dynutil/h/AST.h"
54
55 namespace Dyninst {
56
57   namespace ParseAPI {
58     class Function;
59   };
60
61 class Absloc {
62  public:
63   typedef enum {
64     Register,
65     Stack,
66     Heap,
67     Unknown } Type;
68
69   SYMEVAL_EXPORT static Absloc makePC(Dyninst::Architecture arch);
70   SYMEVAL_EXPORT static Absloc makeSP(Dyninst::Architecture arch);
71   SYMEVAL_EXPORT static Absloc makeFP(Dyninst::Architecture arch);
72   
73   // Some static functions for "well-known" Abslocs
74   SYMEVAL_EXPORT bool isPC() const;
75   SYMEVAL_EXPORT bool isSPR() const;
76   
77   SYMEVAL_EXPORT bool isSP() const;
78   SYMEVAL_EXPORT bool isFP() const;
79
80  SYMEVAL_EXPORT Absloc() :
81   type_(Unknown),
82     reg_(),
83     off_(-1),
84     region_(-1),
85     addr_(-1) {};
86  SYMEVAL_EXPORT Absloc(MachRegister reg) :
87   type_(Register),
88     reg_(reg) {};
89     
90  SYMEVAL_EXPORT Absloc(Address addr) :
91   type_(Heap),
92     addr_(addr) {};
93  SYMEVAL_EXPORT Absloc(int o,
94         int r,
95         const std::string &f) :
96     type_(Stack),
97       off_(o),
98       region_(r),
99       func_(f) {};
100     
101   SYMEVAL_EXPORT std::string format() const;
102
103   SYMEVAL_EXPORT const Type &type() const { return type_; };
104
105   SYMEVAL_EXPORT const MachRegister &reg() const { assert(type_ == Register); return reg_; };
106
107   SYMEVAL_EXPORT int off() const { assert(type_ == Stack); return off_; };
108   SYMEVAL_EXPORT int region() const { assert(type_ == Stack); return region_; };
109   SYMEVAL_EXPORT const std::string &func() const { assert(type_ == Stack); return func_; };
110
111   SYMEVAL_EXPORT Address addr() const { assert(type_ == Heap); return addr_; };
112   
113   SYMEVAL_EXPORT bool operator<(const Absloc &rhs) const {
114     if (type_ != rhs.type_) 
115       return type_ < rhs.type_;
116     switch(type_) {
117     case Register:
118       return reg_ < rhs.reg_;
119     case Stack:
120       if (off_ != rhs.off_)
121         return off_ < rhs.off_;
122       // Now we get arbitrary
123       if (region_ != rhs.region_)
124         return region_ < rhs.region_;
125       return func_ < rhs.func_;
126     case Heap:
127       return addr_ < rhs.addr_;
128     default:
129       return true;
130     }
131   }
132
133   SYMEVAL_EXPORT bool operator==(const Absloc &rhs) const {
134     if (type_ != rhs.type_) return false;
135     switch(type_) {
136     case Register:
137       return reg_ == rhs.reg_;
138     case Stack:
139       return ((off_ == rhs.off_) &&
140               (region_ == rhs.region_) &&
141               (func_ == rhs.func_));
142     case Heap:
143       return addr_ == rhs.addr_;
144     default:
145       return true;
146     }
147   }
148
149   SYMEVAL_EXPORT bool operator!=(const Absloc &rhs) const {
150     return !(*this == rhs);
151   }
152
153   SYMEVAL_EXPORT static char typeToChar(const Type t) {
154     switch(t) {
155     case Register:
156       return 'r';
157     case Stack:
158       return 's';
159     case Heap:
160       return 'h';
161     default:
162       return 'u';
163     }
164   };
165
166  private:
167   Type type_;
168
169   MachRegister reg_;
170
171   int off_;
172   int region_;  
173   std::string func_;
174
175   Address addr_;
176 };
177
178 class AbsRegion {
179  public:
180   // Set operations get included here? Or third-party
181   // functions?
182   
183   SYMEVAL_EXPORT bool contains(const Absloc::Type t) const;
184   SYMEVAL_EXPORT bool contains(const Absloc &abs) const;
185   SYMEVAL_EXPORT bool contains(const AbsRegion &rhs) const;
186   // Logically, "intersect(rhs) != 0"
187   //bool overlaps(const AbsRegion &rhs) const;
188
189   SYMEVAL_EXPORT bool containsOfType(Absloc::Type t) const;
190
191   //iterator &begin();
192   //iterator &end();
193
194   SYMEVAL_EXPORT bool operator==(const AbsRegion &rhs) const;
195   SYMEVAL_EXPORT bool operator!=(const AbsRegion &rhs) const;
196   SYMEVAL_EXPORT bool operator<(const AbsRegion &rhs) const;
197
198   SYMEVAL_EXPORT const std::string format() const;
199
200   SYMEVAL_EXPORT void insert(const Absloc &abs);
201   SYMEVAL_EXPORT void insert(const AbsRegion &reg);
202
203   SYMEVAL_EXPORT void erase(const Absloc &abs);
204   SYMEVAL_EXPORT void erase(const AbsRegion &reg);
205
206   SYMEVAL_EXPORT AbsRegion() :
207     type_(Absloc::Unknown),
208     size_(0) {};
209
210   SYMEVAL_EXPORT AbsRegion(Absloc::Type t) :
211     type_(t),
212     size_(0) {}
213
214   SYMEVAL_EXPORT AbsRegion(Absloc a) :
215     type_(Absloc::Unknown),
216       absloc_(a),
217       size_(0) {}
218
219
220         SYMEVAL_EXPORT void setGenerator(AST::Ptr generator) {
221       generator_ = generator;
222   }
223
224   SYMEVAL_EXPORT void setSize(size_t size) {
225     size_ = size;
226   }
227
228   SYMEVAL_EXPORT static bool equivalent(const AbsRegion &lhs,
229                          const AbsRegion &rhs,
230                          Address addr,
231                          ParseAPI::Function *caller,
232                          ParseAPI::Function *callee);
233
234   SYMEVAL_EXPORT const Absloc absloc() const { return absloc_; }
235   SYMEVAL_EXPORT const Absloc::Type type() const { return type_; }
236   SYMEVAL_EXPORT size_t size() const { return size_; }
237
238  private:
239   // Type is for "we're on the stack but we don't know where".
240   // Effectively, it's a wildcard.
241   Absloc::Type type_;
242
243   // For specific knowledge.
244   Absloc absloc_;
245
246   // And the AST that gave rise to this Absloc. We use this
247   // as a generating function (if present and not overridden)
248   AST::Ptr generator_;
249
250   // Size in bits
251   size_t size_;
252 };
253
254
255 class Assignment {
256  public:
257   typedef dyn_detail::boost::shared_ptr<Assignment> Ptr;
258   typedef std::set<AbsRegion> Aliases;
259
260   SYMEVAL_EXPORT const std::vector<AbsRegion> &inputs() const { return inputs_; }
261   SYMEVAL_EXPORT std::vector<AbsRegion> &inputs() { return inputs_; }
262
263   SYMEVAL_EXPORT const InstructionAPI::Instruction::Ptr insn() const { return insn_; }
264   SYMEVAL_EXPORT const Address addr() const { return addr_; }
265
266   SYMEVAL_EXPORT const AbsRegion &out() const { return out_; }
267   SYMEVAL_EXPORT AbsRegion &out() { return out_; }
268
269   SYMEVAL_EXPORT const std::string format() const;
270
271   // FIXME
272   Aliases aliases;
273
274   // Factory functions. 
275   SYMEVAL_EXPORT static std::set<Assignment::Ptr> create(InstructionAPI::Instruction::Ptr insn,
276                                           Address addr);
277
278   SYMEVAL_EXPORT Assignment(const InstructionAPI::Instruction::Ptr i,
279              const Address a,
280              ParseAPI::Function *f,
281              const std::vector<AbsRegion> &ins,
282              const AbsRegion &o) : 
283     insn_(i),
284     addr_(a),
285       func_(f),
286     inputs_(ins),
287     out_(o) {};
288
289   SYMEVAL_EXPORT Assignment(const InstructionAPI::Instruction::Ptr i,
290              const Address a,
291              ParseAPI::Function *f,
292              const AbsRegion &o) : 
293     insn_(i),
294     addr_(a),
295       func_(f),
296     out_(o) {};
297
298   // Internally used method; add a dependence on 
299   // a new abstract region. If this is a new region
300   // we'll add it to the dependence list. Otherwise 
301   // we'll join the provided input set to the known
302   // inputs.
303   SYMEVAL_EXPORT void addInput(const AbsRegion &reg);
304   SYMEVAL_EXPORT void addInputs(const std::vector<AbsRegion> &regions);
305
306   SYMEVAL_EXPORT ParseAPI::Function *func() const { return func_; }
307
308  private:
309   InstructionAPI::Instruction::Ptr insn_;
310   Address addr_;
311
312   ParseAPI::Function *func_;
313
314   std::vector<AbsRegion> inputs_;
315   AbsRegion out_;
316 };
317
318 // Dyninst namespace
319 };
320
321
322 std::ostream &operator<<(std::ostream &os, const Dyninst::Absloc &a);
323 std::ostream &operator<<(std::ostream &os, const Dyninst::AbsRegion &a);
324 std::ostream &operator<<(std::ostream &os, const Dyninst::Assignment::Ptr &a);
325
326 #endif
327