Fixes compile error and Merge branch 'Defensive' of ssh://coriander.cs.wisc.edu/u...
[dyninst.git] / patchAPI / h / PatchCFG.h
1 /* Public Interface */
2
3 #ifndef _PATCHAPI_DYNINST_CFG_H_
4 #define _PATCHAPI_DYNINST_CFG_H_
5
6 #include "CFG.h"
7 //#include "common.h"
8 #include "PatchObject.h"
9 #include "Point.h"
10
11 namespace Dyninst {
12 namespace PatchAPI {
13
14 class PatchParseCallback;
15
16 class PatchEdge;
17 class PatchBlock;
18 class PatchFunction;
19 class PatchCallback;
20
21 class PatchEdge {
22    friend class PatchBlock;
23    friend class PatchFunction;
24    friend class PatchObject;
25    friend class Callback;
26    friend class PatchParseCallback;
27
28   public:
29    PATCHAPI_EXPORT static PatchEdge *create(ParseAPI::Edge *,
30                                             PatchBlock *src,
31                                             PatchBlock *trg);
32    PATCHAPI_EXPORT PatchEdge(ParseAPI::Edge *internalEdge,
33              PatchBlock *source,
34              PatchBlock *target);
35    PATCHAPI_EXPORT PatchEdge(const PatchEdge *parent,
36              PatchBlock *child_src,
37              PatchBlock *child_trg);
38    PATCHAPI_EXPORT virtual ~PatchEdge();
39
40    // Getters
41    PATCHAPI_EXPORT ParseAPI::Edge *edge() const;
42    PATCHAPI_EXPORT PatchBlock *source();
43    PATCHAPI_EXPORT PatchBlock *target();
44    PATCHAPI_EXPORT ParseAPI::EdgeTypeEnum type() const;
45    PATCHAPI_EXPORT bool sinkEdge() const;
46    PATCHAPI_EXPORT bool interproc() const;
47
48    PATCHAPI_EXPORT void remove(Point *);
49    PATCHAPI_EXPORT PatchCallback *cb() const;
50
51    PATCHAPI_EXPORT bool consistency() const;
52
53  protected:
54     ParseAPI::Edge *edge_;
55     PatchBlock *src_;
56     PatchBlock *trg_;
57
58     EdgePoints points_;
59 };
60
61 class PatchBlock {
62   friend class PatchEdge;
63   friend class PatchFunction;
64   friend class PatchObject;
65    friend class PatchParseCallback;
66
67   public:
68     typedef std::map<Address, InstructionAPI::Instruction::Ptr> Insns;
69     typedef std::vector<PatchEdge*> edgelist;
70
71     PATCHAPI_EXPORT static PatchBlock *create(ParseAPI::Block *, PatchFunction *);
72     PATCHAPI_EXPORT PatchBlock(const PatchBlock *parblk, PatchObject *child);
73     PATCHAPI_EXPORT PatchBlock(ParseAPI::Block *block, PatchObject *obj);
74     PATCHAPI_EXPORT virtual ~PatchBlock();
75
76     // Getters
77     PATCHAPI_EXPORT Address start() const;
78     PATCHAPI_EXPORT Address end() const;
79     PATCHAPI_EXPORT Address last() const;
80     PATCHAPI_EXPORT Address size() const;
81
82     PATCHAPI_EXPORT PatchFunction* getFunction(ParseAPI::Function*);
83     PATCHAPI_EXPORT bool isShared();
84     PATCHAPI_EXPORT int containingFuncs() const;
85     PATCHAPI_EXPORT void getInsns(Insns &insns) const;
86     PATCHAPI_EXPORT InstructionAPI::Instruction::Ptr getInsn(Address a) const;
87     PATCHAPI_EXPORT std::string disassemble() const;
88     PATCHAPI_EXPORT bool containsCall() const { return 0 < numCallEdges(); };
89     PATCHAPI_EXPORT bool containsDynamicCall();
90     PATCHAPI_EXPORT std::string format() const;
91     PATCHAPI_EXPORT std::string long_format() const;
92     PATCHAPI_EXPORT PatchFunction* getCallee();
93
94     PATCHAPI_EXPORT ParseAPI::Block *block() const;
95     PATCHAPI_EXPORT PatchObject* object() const;
96     PATCHAPI_EXPORT PatchObject *obj() const { return object(); }
97     PATCHAPI_EXPORT const edgelist &getSources();
98     PATCHAPI_EXPORT const edgelist &getTargets();
99     
100     PATCHAPI_EXPORT PatchEdge *findSource(ParseAPI::EdgeTypeEnum type);
101     PATCHAPI_EXPORT PatchEdge *findTarget(ParseAPI::EdgeTypeEnum type);
102
103     template <class OutputIterator> 
104     void getFunctions(OutputIterator result);
105
106     PATCHAPI_EXPORT Point *findPoint(Location loc, Point::Type type, bool create = true);
107
108    PATCHAPI_EXPORT void remove(Point *);
109    PATCHAPI_EXPORT PatchCallback *cb() const;
110
111    PATCHAPI_EXPORT bool consistency() const;
112
113   protected:
114     typedef enum {
115       backwards,
116       forwards } Direction;
117
118     void removeSourceEdge(PatchEdge *e);
119     void removeTargetEdge(PatchEdge *e);
120     void destroyPoints();
121
122     void addSourceEdge(PatchEdge *e, bool addIfEmpty = true);
123     void addTargetEdge(PatchEdge *e, bool addIfEmpty = true);
124
125     void splitBlock(PatchBlock *succ);
126     int numRetEdges() const;
127     int numCallEdges() const;
128
129     ParseAPI::Block *block_;
130     edgelist srclist_;
131     edgelist trglist_;
132     PatchObject* obj_;
133
134     BlockPoints points_;
135 };
136
137
138
139 class PatchFunction {
140    friend class PatchEdge;
141    friend class PatchBlock;
142    friend class PatchObject;
143    friend class PatchParseCallback;
144
145    public:
146      struct compare {
147        bool operator()(PatchBlock * const &b1,
148                        PatchBlock * const &b2) const {
149          if(b1->start() < b2->start())
150            return true;
151          else
152            return false;
153        }
154      };
155      typedef std::set<PatchBlock *, compare> Blockset;
156
157      PATCHAPI_EXPORT static PatchFunction *create(ParseAPI::Function *, PatchObject*);
158      PATCHAPI_EXPORT PatchFunction(ParseAPI::Function *f, PatchObject* o);
159      PATCHAPI_EXPORT PatchFunction(const PatchFunction* parFunc, PatchObject* child);
160      PATCHAPI_EXPORT virtual ~PatchFunction();
161
162      const string &name() const { return func_->name(); }
163      Address addr() const { return addr_;  }
164      ParseAPI::Function *function() const { return func_; }
165      PATCHAPI_EXPORT PatchObject *obj() const { return obj_; }
166
167      PATCHAPI_EXPORT const Blockset &getAllBlocks();
168      PATCHAPI_EXPORT PatchBlock *getEntryBlock();
169      PATCHAPI_EXPORT const Blockset &getExitBlocks();
170      PATCHAPI_EXPORT const Blockset &getCallBlocks();
171
172      // Shorter aliases
173      PATCHAPI_EXPORT const Blockset &blocks() { return getAllBlocks(); }
174      PATCHAPI_EXPORT PatchBlock *entry() { return getEntryBlock(); }
175      PATCHAPI_EXPORT const Blockset &exits() { return getExitBlocks(); }
176      PATCHAPI_EXPORT const Blockset &calls() { return getCallBlocks(); }
177
178      PATCHAPI_EXPORT Point *findPoint(Location loc, Point::Type type, bool create = true);
179
180      bool verifyExit(PatchBlock *block) { return exits().find(block) != exits().end(); }
181      bool verifyCall(PatchBlock *block) { return calls().find(block) != calls().end(); }
182
183      // Const : no building the exit/call sets (returns true if set is empty)
184      bool verifyExitConst(const PatchBlock *block) const { 
185         return exit_blocks_.empty() || 
186             exit_blocks_.find(const_cast<PatchBlock *>(block)) != exit_blocks_.end(); 
187      }
188      bool verifyCallConst(const PatchBlock *block) const { 
189         return call_blocks_.empty() || 
190             call_blocks_.find(const_cast<PatchBlock *>(block)) != call_blocks_.end(); 
191      }
192
193      // Fast access to a range of instruction points
194      PATCHAPI_EXPORT bool findInsnPoints(Point::Type type, PatchBlock *block,
195                                          InsnPoints::const_iterator &start,
196                                          InsnPoints::const_iterator &end);
197
198    PATCHAPI_EXPORT void remove(Point *);
199    PATCHAPI_EXPORT PatchCallback *cb() const;
200
201    PATCHAPI_EXPORT bool consistency() const;
202
203    protected:
204      // For callbacks from ParseAPI to PatchAPI
205      void removeBlock(PatchBlock *);
206      void addBlock(PatchBlock *);
207      void splitBlock(PatchBlock *first, PatchBlock *second);
208      void destroyPoints();
209      void destroyBlockPoints(PatchBlock *block);
210
211      ParseAPI::Function *func_;
212      PatchObject* obj_;
213      Address addr_;
214
215      Blockset all_blocks_;
216      Blockset exit_blocks_;
217      Blockset call_blocks_;
218
219      FuncPoints points_;
220      // For context-specific
221      std::map<PatchBlock *, BlockPoints> blockPoints_;
222      std::map<PatchEdge *, EdgePoints> edgePoints_;
223 };
224
225 template <class OutputIterator>
226 void PatchBlock::getFunctions(OutputIterator result) {
227   std::vector<ParseAPI::Function *> pFuncs;
228   block()->getFuncs(pFuncs);
229   for (unsigned i = 0; i < pFuncs.size(); ++i) {
230     PatchFunction *func = getFunction(pFuncs[i]);
231     *result = func;
232     ++result;
233   }
234 }
235
236 #define ASSERT_CONSISTENCY_FAILURE 1
237 #define CONSIST_FAIL {if (ASSERT_CONSISTENCY_FAILURE) assert(0); return false;}
238
239 };
240 };
241
242
243 #endif /* _PATCHAPI_DYNINST_CFG_H_ */