After tested under windows.
[dyninst.git] / patchAPI / h / Point.h
1 /* Public Interface */
2
3 #ifndef PATCHAPI_H_POINT_H_
4 #define PATCHAPI_H_POINT_H_
5
6 #include "common.h"
7 #include "Snippet.h"
8
9 namespace Dyninst {
10 namespace PatchAPI {
11
12 // Used in PointType definition
13 #define type_val(seq) (0x00000001 << seq)
14
15
16 /* A location on the CFG that acts as a container of inserted instances.  Points
17    of different types are distinct even the underlying code relocation and
18    generation engine happens to put instrumentation from them at the same
19    place */
20
21 class Point {
22   friend class PatchMgr;
23
24   public:
25     // If you want to extend Type, please increment the argument passed
26     // to type_val.
27     enum Type {
28       PreInsn = type_val(0),
29       PostInsn = type_val(1),
30       InsnTaken = type_val(2),
31       BlockEntry = type_val(3),
32       BlockExit = type_val(4),
33       BlockDuring = type_val(5),
34       FuncEntry = type_val(6),
35       FuncExit = type_val(7),
36       FuncDuring = type_val(8),
37       EdgeDuring = type_val(9),
38       LoopStart = type_val(10),             // TODO(wenbin)
39       LoopEnd = type_val(11),               // TODO(wenbin)
40       LoopIterStart = type_val(12),         // TODO(wenbin)
41       LoopIterEnd = type_val(13),           // TODO(wenbin)
42       PreCall = type_val(14),
43       PostCall = type_val(15),
44       OtherPoint = type_val(30),
45       None = type_val(31),
46       InsnTypes = PreInsn | PostInsn | InsnTaken,
47       BlockTypes = BlockEntry | BlockExit | BlockDuring,
48       FuncTypes = FuncEntry | FuncExit | FuncDuring,
49       EdgeTypes = EdgeDuring,
50       LoopTypes = LoopStart | LoopEnd | LoopIterStart | LoopIterEnd,  // TODO(wenbin)
51       CallTypes = PreCall | PostCall
52     };
53
54     template <class Scope>
55     static Point* create(Address addr,
56                                      Point::Type type,
57                                                  PatchMgrPtr mgr,
58                                                  Scope* scope) {
59       Point* ret = new Point(addr, type, mgr, scope);
60       return ret;
61     }
62     Point() {}
63     PATCHAPI_EXPORT Point(Address addr, Point::Type type, PatchMgrPtr mgr, Address*);
64     PATCHAPI_EXPORT Point(Address addr, Point::Type type, PatchMgrPtr mgr, PatchBlock* blk);
65     PATCHAPI_EXPORT Point(Address addr, Point::Type type, PatchMgrPtr mgr, PatchEdge* edge);
66     PATCHAPI_EXPORT Point(Address addr, Point::Type type, PatchMgrPtr mgr, PatchFunction* func);
67     PATCHAPI_EXPORT virtual ~Point();
68
69     // Point as a snippet container
70     typedef std::list<InstancePtr>::iterator instance_iter;
71     instance_iter begin() { return instanceList_.begin();}
72     instance_iter end() { return instanceList_.end();}
73     PATCHAPI_EXPORT InstancePtr pushBack(SnippetPtr);
74     PATCHAPI_EXPORT InstancePtr pushFront(SnippetPtr);
75     PATCHAPI_EXPORT bool remove(InstancePtr);
76
77     // Remove all snippets in this point
78     PATCHAPI_EXPORT void clear();
79
80     // Getters
81     PATCHAPI_EXPORT size_t size();
82     Address address() const { return addr_; }
83     Type type() const {return type_;}
84     bool empty() const { return instanceList_.empty();}
85
86     typedef std::set<PatchFunction*> FuncSet;
87     typedef std::set<PatchBlock*> BlockSet;
88     const Point::FuncSet& getInstFuncs() const { return inst_funcs_; }
89     const Point::BlockSet& getInstBlocks() const { return inst_blks_; }
90     PATCHAPI_EXPORT PatchFunction* getCallee();
91
92     const ParseAPI::CodeObject* co() const { return co_; }
93     const ParseAPI::CodeSource* cs() const { return cs_; }
94     const PatchObject* obj() const { return obj_; }
95     const InstructionAPI::Instruction::Ptr insn() const { return insn_; }
96
97     PatchFunction* getFunction() const { return the_func_; }
98     PatchBlock* getBlock() const { return the_block_; }
99     PatchEdge* getEdge() const { return the_edge_; }
100
101     // Point type utilities
102
103     // Test whether the type contains a specific type.
104     PATCHAPI_EXPORT static bool TestType(Point::Type types, Point::Type trg);
105     // Add a specific type to a set of types
106     PATCHAPI_EXPORT static void AddType(Point::Type& types, Point::Type trg);
107     // Remove a specific type from a set of types
108     PATCHAPI_EXPORT static void RemoveType(Point::Type& types, Point::Type trg);
109
110
111   protected:
112     bool destroy();
113     void initCodeStructure();
114
115     InstanceList instanceList_;
116     Address addr_;
117     Type type_;
118     PatchMgrPtr mgr_;
119     PatchBlock* the_block_;
120     PatchEdge* the_edge_;
121     PatchFunction* the_func_;
122     InstructionAPI::Instruction::Ptr insn_;
123     ParseAPI::CodeObject* co_;
124     ParseAPI::CodeSource* cs_;
125     PatchObject* obj_;
126     Point::FuncSet inst_funcs_;
127     Point::BlockSet inst_blks_;
128 };
129
130 inline Point::Type operator|(Point::Type a, Point::Type b) {
131   Point::Type types = a;
132   Point::AddType(types, b);
133   return types;
134 }
135
136 // Type: enum => string
137 inline const char* type_str(Point::Type type) {
138   if (type&Point::PreInsn) return "PreInsn ";
139   if (type&Point::PostInsn) return "PostInsn ";
140   if (type&Point::InsnTaken) return "InsnTaken ";
141
142   if (type&Point::BlockEntry) return "BlockEntry ";
143   if (type&Point::BlockExit) return "BlockExit ";
144   if (type&Point::BlockDuring) return "BlockDuring ";
145
146   if (type&Point::FuncEntry) return "FuncEntry ";
147   if (type&Point::FuncExit) return "FuncExit ";
148   if (type&Point::FuncDuring) return "FuncDuring ";
149
150   if (type&Point::EdgeDuring) return "EdgeDuring ";
151
152   if (type&Point::LoopStart) return "LoopStart ";
153   if (type&Point::LoopEnd) return "LoopEnd ";
154   if (type&Point::LoopIterStart) return "LoopIterStart ";
155   if (type&Point::LoopIterEnd) return "LoopIterEnd ";
156
157   if (type&Point::PreCall) return "PreCall ";
158   if (type&Point::PostCall) return "PostCall ";
159
160   return "Unknown";
161 }
162
163 enum SnippetType {
164   SYSTEM,
165   USER
166 };
167
168 enum SnippetState {
169   FAILED,
170   PENDING,
171   INSERTED
172 };
173
174 /* A representation of a particular snippet inserted at a
175    particular point */
176 class Instance : public dyn_detail::boost::enable_shared_from_this<Instance> {
177   public:
178     Instance(Point* point, SnippetPtr snippet)
179               : point_(point), snippet_(snippet) { }
180     virtual ~Instance() {}
181     static InstancePtr create(Point*, SnippetPtr,
182                     SnippetType type = SYSTEM, SnippetState state = PENDING);
183
184     // Getters and Setters
185     SnippetState state() const { return state_;}
186     SnippetType type() const {return type_;}
187     Point* point() const {return point_;}
188     SnippetPtr snippet() const {return snippet_;}
189     void set_state(SnippetState state) { state_ = state; }
190
191     // Destroy itself
192     // return false if this snipet instance is not associated with a point
193     bool destroy();
194
195   protected:
196     Point* point_;
197     SnippetPtr snippet_;
198     SnippetState state_;
199     SnippetType type_;
200 };
201
202 /* Factory class for creating a point that could be either PatchAPI::Point or
203    the subclass of PatchAPI::Point.   */
204 class PointMaker {
205   public:
206     PointMaker(PatchMgrPtr mgr) : mgr_(mgr) {}
207     PointMaker() {}
208     virtual ~PointMaker() {}
209
210     PATCHAPI_EXPORT virtual Point* createPoint(Address addr, Point::Type type,
211                                Address* scope);
212     PATCHAPI_EXPORT virtual Point* createPoint(Address addr, Point::Type type,
213                                PatchBlock* scope);
214     PATCHAPI_EXPORT virtual Point* createPoint(Address addr, Point::Type type,
215                                PatchEdge* scope);
216     PATCHAPI_EXPORT virtual Point* createPoint(Address addr, Point::Type type,
217                                PatchFunction* scope);
218
219     void setMgr(PatchMgrPtr mgr) { mgr_ = mgr; }
220   protected:
221     PatchMgrPtr mgr_;
222 };
223
224 }
225 }
226 #endif  // PATCHAPI_H_POINT_H_