Remove incorrect export declaration
[dyninst.git] / patchAPI / h / Point.h
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  * 
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  * 
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  * 
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  * 
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  * 
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30 /* Public Interface */
31
32 #ifndef PATCHAPI_H_POINT_H_
33 #define PATCHAPI_H_POINT_H_
34
35 #include "PatchCommon.h"
36 #include "Snippet.h"
37 #include "util.h"
38
39 namespace Dyninst {
40 namespace PatchAPI {
41
42
43    class PatchCallback;
44
45 struct EntrySite_t {
46    PatchFunction *func;
47    PatchBlock *block;
48 EntrySite_t(PatchFunction *f, PatchBlock *b) : func(f), block(b) {};
49 };
50 struct CallSite_t {
51    PatchFunction *func;
52    PatchBlock *block;
53 CallSite_t(PatchFunction *f, PatchBlock *b) : func(f), block(b) {};
54 };
55 struct ExitSite_t {
56    PatchFunction *func;
57    PatchBlock *block;
58 ExitSite_t(PatchFunction *f, PatchBlock *b) : func(f), block(b) {};
59 };
60
61 struct InsnLoc_t {
62    PatchBlock *block;
63    Address addr;
64    InstructionAPI::Instruction::Ptr insn;
65 InsnLoc_t(PatchBlock *b, Address a, InstructionAPI::Instruction::Ptr i) : 
66    block(b), addr(a), insn(i) {};
67 };
68       
69      
70 // Uniquely identify the location of a point; this + a type
71 // uniquely identifies a point.
72 struct Location {
73    static Location Function(PatchFunction *f) { 
74       return Location(f, NULL, 0, InstructionAPI::Instruction::Ptr(), NULL, true, Function_); 
75    }
76    static Location Block(PatchBlock *b) { 
77       return Location(NULL, b, 0, InstructionAPI::Instruction::Ptr(), NULL, true, Block_);
78    }
79    static Location BlockInstance(PatchFunction *f, PatchBlock *b, bool trusted = false) { 
80       return Location(f, b, 0, InstructionAPI::Instruction::Ptr(), NULL, trusted, BlockInstance_); 
81    }
82    static Location Instruction(InsnLoc_t l) { 
83       return Location(NULL, l.block, l.addr, l.insn, NULL, true, Instruction_); 
84    }
85    static Location Instruction(PatchBlock *b, Address a) { 
86       return Location(NULL, b, a, InstructionAPI::Instruction::Ptr(), NULL, false, Instruction_); 
87    }
88    static Location InstructionInstance(PatchFunction *f, InsnLoc_t l, bool trusted = false) { 
89       return Location(f, l.block, l.addr, l.insn, NULL, trusted, InstructionInstance_); 
90    }
91    static Location InstructionInstance(PatchFunction *f, PatchBlock *b, Address a) { 
92       return Location(f, b, a, InstructionAPI::Instruction::Ptr(), NULL, false, InstructionInstance_); 
93    }
94    static Location InstructionInstance(PatchFunction *f, PatchBlock *b, Address a, InstructionAPI::Instruction::Ptr i, bool trusted = false) { 
95       return Location(f, b, a, i, NULL, trusted, InstructionInstance_); 
96    }
97    static Location Edge(PatchEdge *e) {
98       return Location(NULL, NULL, 0, InstructionAPI::Instruction::Ptr(), e, true, Edge_); 
99    }
100    static Location EdgeInstance(PatchFunction *f, PatchEdge *e) { 
101       return Location(f, NULL, 0, InstructionAPI::Instruction::Ptr(), e, false, EdgeInstance_);
102    }
103    static Location EntrySite(EntrySite_t e) { 
104       return Location(e.func, e.block, 0, InstructionAPI::Instruction::Ptr(), NULL, true, Entry_); 
105    }
106    static Location EntrySite(PatchFunction *f, PatchBlock *b, bool trusted = false) { 
107       return Location(f, b, 0, InstructionAPI::Instruction::Ptr(), NULL, trusted, Entry_); 
108    }
109    static Location CallSite(CallSite_t c) {
110       return Location(c.func, c.block, 0, InstructionAPI::Instruction::Ptr(), NULL, true, Call_); 
111    }
112    static Location CallSite(PatchFunction *f, PatchBlock *b) { 
113       return Location(f, b, 0, InstructionAPI::Instruction::Ptr(), NULL, false, Call_);
114    }
115    static Location ExitSite(ExitSite_t e) { 
116       return Location(e.func, e.block, 0, InstructionAPI::Instruction::Ptr(), NULL, true, Exit_);
117    }
118    static Location ExitSite(PatchFunction *f, PatchBlock *b) { 
119       return Location(f, b, 0, InstructionAPI::Instruction::Ptr(), NULL, false, Exit_); }
120
121    typedef enum {
122       Function_,
123       Block_,
124       BlockInstance_,
125       Instruction_,
126       InstructionInstance_,
127       Edge_,
128       EdgeInstance_,
129       Entry_,
130       Call_,
131       Exit_,
132       Illegal_ } type_t;
133
134    bool legal(type_t t) { return t == type; }
135
136    InsnLoc_t insnLoc() { return InsnLoc_t(block, addr, insn); }
137    
138    PatchFunction *func;
139    PatchBlock *block;
140    Address addr;
141    InstructionAPI::Instruction::Ptr insn;
142    PatchEdge *edge;
143    bool trusted;
144    type_t type;
145
146 private:
147 Location(PatchFunction *f, PatchBlock *b, Address a, InstructionAPI::Instruction::Ptr i, PatchEdge *e, bool u, type_t t) :
148    func(f), block(b), addr(a), insn(i), edge(e), trusted(u), type(t) {};
149
150 };
151
152 // Used in PointType definition
153 #define type_val(seq) (0x00000001 << seq)
154
155
156 /* A location on the CFG that acts as a container of inserted instances.  Points
157    of different types are distinct even the underlying code relocation and
158    generation engine happens to put instrumentation from them at the same
159    place */
160
161 class PATCHAPI_EXPORT Point {
162   friend class PatchMgr;
163   friend class PatchBlock;
164   friend class PatchFunction;
165
166   public:
167     // If you want to extend Type, please increment the argument passed
168     // to type_val.
169     enum Type {
170       PreInsn = type_val(0),
171       PostInsn = type_val(1),
172       //InsnTaken = type_val(2), // This should be edge instrumentation? bernat, 25JUN11
173       BlockEntry = type_val(3),
174       BlockExit = type_val(4),
175       BlockDuring = type_val(5),
176       FuncEntry = type_val(6),
177       FuncExit = type_val(7),
178       FuncDuring = type_val(8),
179       EdgeDuring = type_val(9),
180       LoopStart = type_val(10),             // TODO(wenbin)
181       LoopEnd = type_val(11),               // TODO(wenbin)
182       LoopIterStart = type_val(12),         // TODO(wenbin)
183       LoopIterEnd = type_val(13),           // TODO(wenbin)
184       PreCall = type_val(14),
185       PostCall = type_val(15),
186       OtherPoint = type_val(30),
187       None = type_val(31),
188       InsnTypes = PreInsn | PostInsn,
189       BlockTypes = BlockEntry | BlockExit | BlockDuring,
190       FuncTypes = FuncEntry | FuncExit | FuncDuring,
191       EdgeTypes = EdgeDuring,
192       LoopTypes = LoopStart | LoopEnd | LoopIterStart | LoopIterEnd,  // TODO(wenbin)
193       CallTypes = PreCall | PostCall
194     };
195
196     template <class Scope>
197     static Point* create(Address addr,
198                          Point::Type type,
199                          PatchMgrPtr mgr,
200                          Scope* scope) {
201       Point* ret = new Point(addr, type, mgr, scope);
202       return ret;
203     }
204     Point() {}
205
206     // Block instrumentation /w/ optional function context
207     Point(Point::Type t, PatchMgrPtr mgr, PatchBlock *, PatchFunction * = NULL);
208     // Insn instrumentation /w/ optional function context
209     Point(Point::Type t, PatchMgrPtr mgr, PatchBlock *, Address, InstructionAPI::Instruction::Ptr, PatchFunction * = NULL);
210     // Function entry or during
211     Point(Point::Type t, PatchMgrPtr mgr, PatchFunction *);
212     // Function call or exit site
213     Point(Point::Type t, PatchMgrPtr mgr, PatchFunction *, PatchBlock *);
214     // Edge
215     Point(Point::Type t, PatchMgrPtr mgr, PatchEdge *, PatchFunction * = NULL);
216
217     virtual ~Point();
218
219     // Point as a snippet container
220     typedef std::list<InstancePtr>::iterator instance_iter;
221     instance_iter begin() { return instanceList_.begin();}
222     instance_iter end() { return instanceList_.end();}
223     virtual InstancePtr pushBack(SnippetPtr);
224     virtual InstancePtr pushFront(SnippetPtr);
225     bool remove(InstancePtr);
226
227     // Remove all snippets in this point
228     void clear();
229
230     // Getters
231     size_t size();
232     Address addr() const { return addr_; }
233     Type type() const {return type_;}
234     bool empty() const { return instanceList_.empty();}
235
236     PatchFunction* getCallee();
237
238     PatchObject* obj() const;
239     const InstructionAPI::Instruction::Ptr insn() const { return insn_; }
240
241     PatchFunction *func() const { return the_func_; }
242     PatchBlock *block() const { return the_block_; }
243     PatchEdge *edge() const { return the_edge_; }
244     PatchMgrPtr mgr() const { return mgr_; }
245
246     // Point type utilities
247     
248     // Test whether the type contains a specific type.
249     static bool TestType(Point::Type types, Point::Type trg);
250     // Add a specific type to a set of types
251     static void AddType(Point::Type& types, Point::Type trg);
252     // Remove a specific type from a set of types
253     static void RemoveType(Point::Type& types, Point::Type trg);
254
255     PatchCallback *cb() const;
256
257     bool consistency() const;
258     
259   protected:
260     bool destroy();
261     void initCodeStructure();
262     void changeBlock(PatchBlock *newBlock);
263
264
265     InstanceList instanceList_;
266     Address addr_;
267     Type type_;
268     PatchMgrPtr mgr_;
269     PatchBlock* the_block_;
270     PatchEdge* the_edge_;
271     PatchFunction* the_func_;
272     InstructionAPI::Instruction::Ptr insn_;
273 };
274
275 inline Point::Type operator|(Point::Type a, Point::Type b) {
276   Point::Type types = a;
277   Point::AddType(types, b);
278   return types;
279 }
280
281 // Type: enum => string
282 inline const char* type_str(Point::Type type) {
283   if (type&Point::PreInsn) return "PreInsn ";
284   if (type&Point::PostInsn) return "PostInsn ";
285   //if (type&Point::InsnTaken) return "InsnTaken ";
286
287   if (type&Point::BlockEntry) return "BlockEntry ";
288   if (type&Point::BlockExit) return "BlockExit ";
289   if (type&Point::BlockDuring) return "BlockDuring ";
290
291   if (type&Point::FuncEntry) return "FuncEntry ";
292   if (type&Point::FuncExit) return "FuncExit ";
293   if (type&Point::FuncDuring) return "FuncDuring ";
294
295   if (type&Point::EdgeDuring) return "EdgeDuring ";
296
297   if (type&Point::LoopStart) return "LoopStart ";
298   if (type&Point::LoopEnd) return "LoopEnd ";
299   if (type&Point::LoopIterStart) return "LoopIterStart ";
300   if (type&Point::LoopIterEnd) return "LoopIterEnd ";
301
302   if (type&Point::PreCall) return "PreCall ";
303   if (type&Point::PostCall) return "PostCall ";
304
305   return "Unknown";
306 }
307
308 enum SnippetType {
309   SYSTEM,
310   USER
311 };
312
313 enum SnippetState {
314   FAILED,
315   PENDING,
316   INSERTED
317 };
318
319 /* A representation of a particular snippet inserted at a
320    particular point */
321 class PATCHAPI_EXPORT Instance : public boost::enable_shared_from_this<Instance> {
322   public:
323    typedef boost::shared_ptr<Instance> Ptr;
324
325   Instance(Point* point, SnippetPtr snippet)
326      : point_(point), snippet_(snippet), guarded_(true) { }
327     virtual ~Instance() {}
328     static InstancePtr create(Point*, SnippetPtr,
329                         SnippetType type = SYSTEM, SnippetState state = PENDING);
330
331     // Getters and Setters
332     SnippetState state() const { return state_;}
333     SnippetType type() const {return type_;}
334     Point* point() const {return point_;}
335     SnippetPtr snippet() const {return snippet_;}
336     void set_state(SnippetState state) { state_ = state; }
337
338     void disableRecursiveGuard() { guarded_ = false; }
339     bool recursiveGuardEnabled() const { return guarded_; }
340
341     // Destroy itself
342     // return false if this snipet instance is not associated with a point
343     bool destroy();
344
345   protected:
346     Point* point_;
347     SnippetPtr snippet_;
348     SnippetState state_;
349     SnippetType type_;
350     bool guarded_;
351 };
352
353 /* Factory class for creating a point that could be either PatchAPI::Point or
354    the subclass of PatchAPI::Point.   */
355 class PATCHAPI_EXPORT PointMaker {
356    friend class PatchMgr;
357   public:
358     PointMaker(PatchMgrPtr mgr) : mgr_(mgr) {}
359     PointMaker() {}
360     virtual ~PointMaker() {}
361
362     // Location bundles what we need to know. 
363     Point *createPoint(Location loc, Point::Type type);
364
365     void setMgr(PatchMgrPtr mgr) { mgr_ = mgr; }
366   protected:
367     // User override
368     virtual Point *mkFuncPoint(Point::Type t, PatchMgrPtr m, PatchFunction *);
369     virtual Point *mkFuncSitePoint(Point::Type t, PatchMgrPtr m, PatchFunction *, PatchBlock *);
370     virtual Point *mkBlockPoint(Point::Type t, PatchMgrPtr m, PatchBlock *, PatchFunction *context);
371     virtual Point *mkInsnPoint(Point::Type t, PatchMgrPtr m, PatchBlock *, Address, InstructionAPI::Instruction::Ptr, PatchFunction *context);
372     virtual Point *mkEdgePoint(Point::Type t, PatchMgrPtr m, PatchEdge *, PatchFunction *context);
373
374
375     PatchMgrPtr mgr_;
376 };
377
378 // Collection classes
379 typedef std::map<Address, Point *> InsnPoints;
380
381
382 struct BlockPoints {
383    Point *entry;
384    Point *during;
385    Point *exit;
386    InsnPoints preInsn;
387    InsnPoints postInsn;
388 BlockPoints() : entry(NULL), during(NULL), exit(NULL) {};
389    bool consistency(const PatchBlock *block, const PatchFunction *func) const;
390    ~BlockPoints();
391 };
392
393 struct EdgePoints {
394    Point *during;
395 EdgePoints() : during(NULL) {};
396    ~EdgePoints() { if (during) delete during; };
397    bool consistency(const PatchEdge *edge, const PatchFunction *func) const;
398 };
399
400 struct FuncPoints {
401    Point *entry;
402    Point *during;
403    std::map<PatchBlock *, Point *> exits;
404    std::map<PatchBlock *, Point *> preCalls;
405    std::map<PatchBlock *, Point *> postCalls;
406 FuncPoints() : entry(NULL), during(NULL) {};
407    ~FuncPoints();
408    bool consistency(const PatchFunction *func) const;
409 };
410
411
412 }
413 }
414
415
416 #endif  // PATCHAPI_H_POINT_H_