1) Reorder dwarf and elf libdirs to fix a problem with multiple libdwarves
[dyninst.git] / patchAPI / h / PatchCFG.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_DYNINST_CFG_H_
33 #define _PATCHAPI_DYNINST_CFG_H_
34
35 #include "CFG.h"
36 #include "PatchCommon.h"
37 #include "PatchObject.h"
38 #include "Point.h"
39
40 namespace Dyninst {
41 namespace PatchAPI {
42
43 class PatchParseCallback;
44
45 class PatchEdge;
46 class PatchBlock;
47 class PatchFunction;
48 class PatchCallback;
49
50 class PatchEdge {
51    friend class PatchBlock;
52    friend class PatchFunction;
53    friend class PatchObject;
54    friend class Callback;
55    friend class PatchParseCallback;
56
57   public:
58    PATCHAPI_EXPORT static PatchEdge *create(ParseAPI::Edge *,
59                                             PatchBlock *src,
60                                             PatchBlock *trg);
61    PATCHAPI_EXPORT PatchEdge(ParseAPI::Edge *internalEdge,
62              PatchBlock *source,
63              PatchBlock *target);
64    PATCHAPI_EXPORT PatchEdge(const PatchEdge *parent,
65              PatchBlock *child_src,
66              PatchBlock *child_trg);
67    PATCHAPI_EXPORT virtual ~PatchEdge();
68
69    // Getters
70    PATCHAPI_EXPORT ParseAPI::Edge *edge() const;
71    PATCHAPI_EXPORT PatchBlock *src();
72    PATCHAPI_EXPORT PatchBlock *trg();
73    PATCHAPI_EXPORT ParseAPI::EdgeTypeEnum type() const;
74    PATCHAPI_EXPORT bool sinkEdge() const;
75    PATCHAPI_EXPORT bool interproc() const;
76    PATCHAPI_EXPORT bool intraproc() const { return !interproc(); }
77
78    PATCHAPI_EXPORT void remove(Point *);
79    PATCHAPI_EXPORT PatchCallback *cb() const;
80
81    PATCHAPI_EXPORT bool consistency() const;
82
83    PATCHAPI_EXPORT std::string format() const;
84
85  protected:
86     ParseAPI::Edge *edge_;
87     PatchBlock *src_;
88     PatchBlock *trg_;
89
90     EdgePoints points_;
91 };
92
93 class PatchBlock {
94   friend class PatchEdge;
95   friend class PatchFunction;
96   friend class PatchObject;
97    friend class PatchParseCallback;
98
99   public:
100     typedef std::map<Address, InstructionAPI::Instruction::Ptr> Insns;
101     typedef std::vector<PatchEdge*> edgelist;
102
103     PATCHAPI_EXPORT static PatchBlock *create(ParseAPI::Block *, PatchFunction *);
104     PATCHAPI_EXPORT PatchBlock(const PatchBlock *parblk, PatchObject *child);
105     PATCHAPI_EXPORT PatchBlock(ParseAPI::Block *block, PatchObject *obj);
106     PATCHAPI_EXPORT virtual ~PatchBlock();
107
108     // Getters
109     PATCHAPI_EXPORT Address start() const;
110     PATCHAPI_EXPORT Address end() const;
111     PATCHAPI_EXPORT Address last() const;
112     PATCHAPI_EXPORT Address size() const;
113
114     PATCHAPI_EXPORT PatchFunction* getFunction(ParseAPI::Function*);
115     PATCHAPI_EXPORT bool isShared();
116     PATCHAPI_EXPORT int containingFuncs() const;
117     PATCHAPI_EXPORT void getInsns(Insns &insns) const;
118     PATCHAPI_EXPORT InstructionAPI::Instruction::Ptr getInsn(Address a) const;
119     PATCHAPI_EXPORT std::string disassemble() const;
120     PATCHAPI_EXPORT bool containsCall() const { return 0 < numCallEdges(); };
121     PATCHAPI_EXPORT bool containsDynamicCall();
122     PATCHAPI_EXPORT std::string format() const;
123     PATCHAPI_EXPORT std::string long_format() const;
124     PATCHAPI_EXPORT PatchFunction* getCallee();
125
126     PATCHAPI_EXPORT ParseAPI::Block *block() const;
127     PATCHAPI_EXPORT PatchObject* object() const;
128     PATCHAPI_EXPORT PatchObject *obj() const { return object(); }
129     PATCHAPI_EXPORT const edgelist &sources();
130     PATCHAPI_EXPORT const edgelist &targets();
131     
132     PATCHAPI_EXPORT PatchEdge *findSource(ParseAPI::EdgeTypeEnum type);
133     PATCHAPI_EXPORT PatchEdge *findTarget(ParseAPI::EdgeTypeEnum type);
134
135     template <class OutputIterator> 
136     void getFuncs(OutputIterator result);
137
138     PATCHAPI_EXPORT Point *findPoint(Location loc, Point::Type type, bool create = true);
139
140    PATCHAPI_EXPORT void remove(Point *);
141    PATCHAPI_EXPORT PatchCallback *cb() const;
142
143    PATCHAPI_EXPORT bool consistency() const;
144
145    PATCHAPI_EXPORT bool wasUserAdded() const;
146
147    PATCHAPI_EXPORT virtual void markModified()  {};
148
149   protected:
150     typedef enum {
151       backwards,
152       forwards } Direction;
153
154     void removeSourceEdge(PatchEdge *e);
155     void removeTargetEdge(PatchEdge *e);
156     void destroyPoints();
157
158     void addSourceEdge(PatchEdge *e, bool addIfEmpty = true);
159     void addTargetEdge(PatchEdge *e, bool addIfEmpty = true);
160
161     void splitBlock(PatchBlock *succ);
162     int numRetEdges() const;
163     int numCallEdges() const;
164
165     ParseAPI::Block *block_;
166     edgelist srclist_;
167     edgelist trglist_;
168     PatchObject* obj_;
169
170     BlockPoints points_;
171 };
172
173
174
175 class PatchFunction {
176    friend class PatchEdge;
177    friend class PatchBlock;
178    friend class PatchObject;
179    friend class PatchParseCallback;
180    friend class PatchModifier;
181
182    public:
183      struct compare {
184        bool operator()(PatchBlock * const &b1,
185                        PatchBlock * const &b2) const {
186          if(b1->start() < b2->start())
187            return true;
188          else
189            return false;
190        }
191      };
192      typedef std::set<PatchBlock *, compare> Blockset;
193
194      PATCHAPI_EXPORT static PatchFunction *create(ParseAPI::Function *, PatchObject*);
195      PATCHAPI_EXPORT PatchFunction(ParseAPI::Function *f, PatchObject* o);
196      PATCHAPI_EXPORT PatchFunction(const PatchFunction* parFunc, PatchObject* child);
197      PATCHAPI_EXPORT virtual ~PatchFunction();
198
199      const string &name() const { return func_->name(); }
200      Address addr() const { return addr_;  }
201      ParseAPI::Function *function() const { return func_; }
202      PATCHAPI_EXPORT PatchObject *obj() const { return obj_; }
203
204      PATCHAPI_EXPORT PatchBlock *entry();
205      PATCHAPI_EXPORT const Blockset &blocks();
206      PATCHAPI_EXPORT const Blockset &callBlocks();
207      //PATCHAPI_EXPORT const Blockset &returnBlocks();
208      PATCHAPI_EXPORT const Blockset &exitBlocks();
209
210      PATCHAPI_EXPORT Point *findPoint(Location loc, Point::Type type, bool create = true);
211
212      // Moved to source code because we treat non-returning calls as exits
213      bool verifyExit(PatchBlock *block) { return exitBlocks().find(block) != exitBlocks().end(); }
214      bool verifyCall(PatchBlock *block) { return callBlocks().find(block) != callBlocks().end(); }
215
216      // Const : no building the exit/call sets (returns true if set is empty)
217      bool verifyExitConst(const PatchBlock *block) const { 
218         return exit_blocks_.empty() || 
219             exit_blocks_.find(const_cast<PatchBlock *>(block)) != exit_blocks_.end(); 
220      }
221      bool verifyCallConst(const PatchBlock *block) const { 
222         return call_blocks_.empty() || 
223             call_blocks_.find(const_cast<PatchBlock *>(block)) != call_blocks_.end(); 
224      }
225
226      // Fast access to a range of instruction points
227      PATCHAPI_EXPORT bool findInsnPoints(Point::Type type, PatchBlock *block,
228                                          InsnPoints::const_iterator &start,
229                                          InsnPoints::const_iterator &end);
230
231    PATCHAPI_EXPORT void remove(Point *);
232    PATCHAPI_EXPORT PatchCallback *cb() const;
233
234    PATCHAPI_EXPORT bool consistency() const;
235
236    PATCHAPI_EXPORT virtual void markModified() {};
237
238    protected:
239      // For callbacks from ParseAPI to PatchAPI
240      void removeBlock(PatchBlock *);
241      void addBlock(PatchBlock *);
242      void splitBlock(PatchBlock *first, PatchBlock *second);
243      void destroyPoints();
244      void destroyBlockPoints(PatchBlock *block);
245      void invalidateBlocks();
246
247      ParseAPI::Function *func_;
248      PatchObject* obj_;
249      Address addr_;
250
251      Blockset all_blocks_;
252      Blockset call_blocks_;
253      Blockset return_blocks_;
254      Blockset exit_blocks_;
255
256      FuncPoints points_;
257      // For context-specific
258      std::map<PatchBlock *, BlockPoints> blockPoints_;
259      std::map<PatchEdge *, EdgePoints> edgePoints_;
260 };
261
262 template <class OutputIterator>
263 void PatchBlock::getFuncs(OutputIterator result) {
264   std::vector<ParseAPI::Function *> pFuncs;
265   block()->getFuncs(pFuncs);
266   for (unsigned i = 0; i < pFuncs.size(); ++i) {
267     PatchFunction *func = getFunction(pFuncs[i]);
268     *result = func;
269     ++result;
270   }
271 }
272
273 #define ASSERT_CONSISTENCY_FAILURE 1
274 #define CONSIST_FAIL {if (ASSERT_CONSISTENCY_FAILURE) assert(0); return false;}
275
276 };
277 };
278
279
280 #endif /* _PATCHAPI_DYNINST_CFG_H_ */