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