After tested under windows.
[dyninst.git] / patchAPI / h / PatchMgr.h
1 /* Public Interface */
2
3 #ifndef PATCHAPI_H_PATCHMGR_H_
4 #define PATCHAPI_H_PATCHMGR_H_
5
6 #include "common.h"
7 #include "Point.h"
8 #include "Instrumenter.h"
9 #include "PatchCFG.h"
10
11 namespace Dyninst {
12 namespace PatchAPI {
13
14 /* Interfaces for point query, snippet insertion and removal in batch
15    mode */
16
17 class PatchMgr : public dyn_detail::boost::enable_shared_from_this<PatchMgr> {
18   friend class Point;
19
20   public:
21     PatchMgr(AddrSpacePtr as, PointMakerPtr pf, InstrumenterPtr inst);
22     PATCHAPI_EXPORT virtual ~PatchMgr();
23     PATCHAPI_EXPORT static PatchMgrPtr create(AddrSpacePtr as,
24                               PointMakerPtr pf = PointMakerPtr(new PointMaker),
25                               InstrumenterPtr inst = InstrumenterPtr());
26
27     // Default implementation for filter function,
28     // used in findPoins and removeSnippets
29     template <class T>
30     class IdentityFilterFunc {
31       public:
32         bool operator()(Point*, T) { return true;}
33     };
34
35     // Query Points:
36     // users have the illusion that all points are already there, and
37     // they just need to grab some by specifying a scope, one or more
38     // point types, and a user-defined filter function
39     // 1) Scope: a CFG structure that contains the desired points,
40     //          e.g., Function, Block, ...
41     // 2) Point types: We define several types, e.g., block entry, exit ...
42     //                See also Point.h
43     // 3) Filter function: User-defined function that further processes
44     //                the set of condidate points
45     //
46     // return false if no any point found
47     template <class Scope, class FilterFunc, class FilterArgument, class OutputIterator>
48     bool findPoints(Scope* scope,
49                     Point::Type types,
50                     FilterFunc filter_func,
51                     FilterArgument filter_arg,
52                     OutputIterator output_iter) {
53       patch_cerr << ws2 << "Find points.\n";
54
55       PointSet candidate_points;
56       if (!findPointsByType(scope, types, candidate_points)) return false;
57       patch_cerr << ws4 << "Get candidate points within Scope: "
58                  << candidate_points.size() << " candidates found" << "\n";
59
60       int pt_count = 0;
61       for (PointIter p = candidate_points.begin();
62            p != candidate_points.end(); p++) {
63         if (filter_func(*p, filter_arg)) {
64           *output_iter = *p;
65           output_iter++;
66           ++pt_count;
67         }
68       }
69       patch_cerr << ws4 << "Apply the filter function on candidate points, "
70                  <<  pt_count << " found\n";
71       return true;
72     }
73
74     // Use default identity filter function
75     template <class Scope, class OutputIterator>
76     bool findPoints(Scope* scope,
77                     Point::Type types,
78                     OutputIterator output_iter) {
79       IdentityFilterFunc<char*> filter_func;
80       char* dummy = NULL;
81       return findPoints<Scope, IdentityFilterFunc<char*>, char*, OutputIterator>
82              (scope, types, filter_func, dummy, output_iter);
83     }
84
85     // Explicit batch mode for snippet insertion and removal.
86     // TODO(wenbin): Transactional semantics -- all succeed, or all fail
87
88     // Return false on failure:
89     //   Nested batchStart/batchFinish
90     PATCHAPI_EXPORT bool batchStart();
91
92     // Return false on failure:
93     //   1) Broken batchStart/batchFinish pair
94     //   2) Some insertion/removal fails
95     template <class OutputIterator>
96     bool batchFinish(OutputIterator /*output_iter_for_failed_instances*/) {
97       if (batch_mode_ != 1) return false;
98       batch_mode_--;
99       return patch();
100     }
101
102     // Snippet instance removal
103     // Return false if no point if found
104     PATCHAPI_EXPORT bool removeSnippet(InstancePtr);
105
106     // Delete ALL snippets at certain points.
107     // This uses the same filter-based interface as findPoints.
108     template <class Scope, class FilterFunc, class FilterArgument>
109     bool removeSnippets(Scope* scope,
110                         Point::Type types,
111                         FilterFunc filter_func,
112                         FilterArgument filter_arg) {
113       PointSet points;
114       if (!findPoints(scope, types, filter_func, filter_arg,
115           back_inserter(points) ) ) return false;
116
117        for (PointIter p = points.begin(); p != points.end(); p++) {
118          (*p)->clear();
119        }
120        return true;
121     }
122
123     // Use default identity filter function.
124     template <class Scope>
125     bool removeSnippets(Scope* scope,
126                         Point::Type types) {
127       IdentityFilterFunc<char*> filter_func;
128       return removeSnippets<Scope, IdentityFilterFunc, char*>
129                 (scope, types, filter_func);
130     }
131
132     // Getters
133     PATCHAPI_EXPORT AddrSpacePtr as() const { return as_; }
134     PATCHAPI_EXPORT InstanceSet& getCurInstances() { return current_instances_; }
135     PATCHAPI_EXPORT PointMakerPtr pointMaker() const { return point_maker_; }
136     PATCHAPI_EXPORT InstrumenterPtr instrumenter() const { return instor_; } 
137     //----------------------------------------------------
138     // Mapping order: Scope -> Type -> Point Set
139     // This order matches out filter sequence:
140     // Apply Scope filter first, Type filter second,
141     // finally filter function.
142     //----------------------------------------------------
143
144     // Type -> Point mapping
145     // In a particular scope, a type may have multiple points,
146     // e.g., function exits
147     typedef std::map<Point::Type, PointSet> TypePtMap;
148     typedef std::map<PatchFunction*, TypePtMap> FuncTypePtMap;
149     typedef std::map<PatchBlock*, TypePtMap> BlkTypePtMap;
150     typedef std::map<PatchEdge*, TypePtMap> EdgeTypePtMap;
151     typedef std::map<Address, TypePtMap> AddrTypePtMap;
152
153   private:
154     // Return false if no point is found
155     template<class Scope>
156     friend bool findPointsByScopeType(PatchMgrPtr mgr, Scope* scope,
157                                  Point::Type types, PointSet& points);
158     template<class Scope>
159     void getPointsByType(TypePtMap& type_pt_map, Point::Type types,
160                          Point::Type type, Address addr,
161                          Scope* scope, PointSet& points);
162     PATCHAPI_EXPORT bool findPointsByType(Address*, Point::Type, PointSet&);
163     PATCHAPI_EXPORT bool findPointsByType(PatchBlock*, Point::Type, PointSet&);
164     PATCHAPI_EXPORT bool findPointsByType(PatchEdge*, Point::Type, PointSet&);
165     PATCHAPI_EXPORT bool findPointsByType(PatchFunction*, Point::Type, PointSet&);
166
167     // Core instrumentation function!
168     PATCHAPI_EXPORT bool patch();
169
170     PointMakerPtr point_maker_;
171
172     BlkTypePtMap blk_type_pt_map_;
173     EdgeTypePtMap edge_type_pt_map_;
174     FuncTypePtMap func_type_pt_map_;
175     AddrTypePtMap addr_type_pt_map_;
176     PointSet del_pt_set_;
177
178     // The lifetime of it is the runtime of mutator
179     InstanceSet current_instances_;
180
181     // The lifetime of them is one batch
182     /*
183     InstanceSet insertion_set_;
184     InstanceSet deletion_set_;
185     FuncRepMap funcReplacement_;
186     CallRepMap callReplacement_;
187     CallRemoval callRemoval_;
188     */
189     InstrumenterPtr instor_;
190     AddrSpacePtr as_;
191
192     typedef int BatchMode;
193     BatchMode batch_mode_;
194 };
195
196 }
197 }
198
199 #endif  // PATCHAPI_H_PATCHMGR_H_