Fixes compile error and Merge branch 'Defensive' of ssh://coriander.cs.wisc.edu/u...
[dyninst.git] / dyninstAPI / h / BPatch_addressSpace.h
1 /*
2  * Copyright (c) 1996-2011 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 #ifndef _BPatch_addressSpace_h_
33 #define _BPatch_addressSpace_h_
34
35 #include "dyn_detail/boost/shared_ptr.hpp"
36 #include "BPatch_dll.h"
37 #include "BPatch_Vector.h"
38 #include "BPatch_eventLock.h"
39 #include "BPatch_enums.h"
40 #include "BPatch_instruction.h" // for register type
41
42 #include "BPatch_callbacks.h"
43
44 #include <vector>
45
46 #include <stdio.h>
47 #include <signal.h>
48
49 // PatchAPI stuffs
50 //#include "Command.h"
51
52 class BPatch_addressSpace;
53 class instPoint;
54
55 namespace Dyninst {
56 namespace PatchAPI { 
57    class PatchMgr;
58    class DynAddrSpace;
59    class Patcher;
60    typedef dyn_detail::boost::shared_ptr<PatchMgr> PatchMgrPtr;
61    typedef dyn_detail::boost::shared_ptr<DynAddrSpace> DynAddrSpacePtr;
62    PatchMgrPtr convert(const BPatch_addressSpace *);
63 };
64 namespace SymtabAPI {
65    class Symbol;
66 };
67 }
68
69
70 class BPatch_statement;
71 class BPatch_snippet;
72 class BPatch_point;
73 class BPatch_variableExpr;
74 class BPatch_type;
75 class AddressSpace;
76 class miniTrampHandle;
77 class miniTramp;
78 class BPatch;
79 class BPatch_image;
80
81 class func_instance;
82 struct batchInsertionRecord;
83 class instPoint;
84 class int_variable;
85
86 typedef enum{
87   TRADITIONAL_PROCESS, STATIC_EDITOR
88 } processType;
89
90
91 #ifdef DYNINST_CLASS_NAME
92 #undef DYNINST_CLASS_NAME
93 #endif
94 #define DYNINST_CLASS_NAME BPatchSnippetHandle
95 class BPATCH_DLL_EXPORT BPatchSnippetHandle : public BPatch_eventLock {
96     friend class BPatch_point;
97     friend class BPatch_image;
98     friend class BPatch_process;
99     friend class BPatch_binaryEdit;
100     friend class BPatch_addressSpace;
101     friend class BPatch_thread;
102
103 private:    
104     // Address Space snippet belogns to
105     BPatch_addressSpace *addSpace_;
106
107 #if defined(_MSC_VER)
108 #pragma warning(push)
109 #pragma warning(disable:4251) 
110 #endif
111     // low-level mappings for removal
112     BPatch_Vector<miniTramp *> mtHandles_;
113 #if defined(_MSC_VER)
114 #pragma warning(pop)    
115 #endif
116
117     //  a flag for catchup
118     bool catchupNeeded;
119     //  and a list of threads to apply catchup to
120     BPatch_Vector<BPatch_thread *> catchup_threads;
121     
122     BPatchSnippetHandle(BPatch_addressSpace * addSpace);
123
124     void addMiniTramp(miniTramp *m) { mtHandles_.push_back(m); }
125     
126 public:
127  
128     API_EXPORT_DTOR(_dtor, (),
129     ~,BPatchSnippetHandle,());
130
131     // Returns whether the installed miniTramps use traps.
132     // Not 100% accurate due to internal Dyninst design; we can
133     // have multiple instances of instrumentation due to function
134     // relocation.
135     API_EXPORT(Int, (), bool, usesTrap, ());
136
137     // mtHandles_ is not empty, , returns the function that the 
138     // instrumentation was added to 
139     API_EXPORT(Int, (),
140     BPatch_function *, getFunc, ());
141
142     API_EXPORT(Int, (),
143     BPatch_addressSpace *, getAddressSpace, ());
144
145     API_EXPORT(Int, (),
146     BPatch_process *, getProcess, ());
147     
148     API_EXPORT(Int, (),
149     BPatch_Vector<BPatch_thread *> &, getCatchupThreads, ());
150
151 };
152
153 #ifdef DYNINST_CLASS_NAME
154 #undef DYNINST_CLASS_NAME
155 #endif
156 #define DYNINST_CLASS_NAME BPatch_addressSpace
157
158 class BPATCH_DLL_EXPORT BPatch_addressSpace : public BPatch_eventLock {
159     friend class BPatch;
160     friend class BPatch_image;
161     friend class BPatch_function;
162     friend class BPatch_frame;
163     friend class BPatch_module;
164     friend class BPatch_basicBlock;
165     friend class BPatch_flowGraph;
166     friend class BPatch_loopTreeNode;
167     friend class BPatch_point;
168     friend class BPatch_funcCallExpr;
169     friend class BPatch_eventMailbox;
170     friend class BPatch_instruction;
171     friend Dyninst::PatchAPI::PatchMgrPtr Dyninst::PatchAPI::convert(const BPatch_addressSpace *);
172   
173  public:
174     
175   BPatch_function *findOrCreateBPFunc(func_instance *ifunc, 
176                                       BPatch_module *bpmod);
177
178   BPatch_point *findOrCreateBPPoint(BPatch_function *bpfunc, 
179                                     instPoint *ip,
180                                     BPatch_procedureLocation pointType);
181
182   BPatch_variableExpr *findOrCreateVariable(int_variable *v,
183                                             BPatch_type *type = NULL);
184
185  protected:
186   
187   
188   // These callbacks are triggered by lower-level code and forward
189   // calls up to the findOrCreate functions.
190   static BPatch_function *createBPFuncCB(AddressSpace *p, func_instance *f);
191   static BPatch_point *createBPPointCB(AddressSpace *p, func_instance *f,
192                                        instPoint *ip, int type);
193
194   BPatch_Vector<batchInsertionRecord *> *pendingInsertions;
195
196   BPatch_image *image;
197
198   //  AddressSpace * as;
199   
200   std::vector<BPatch_register> registers_;
201
202  protected:
203   virtual void getAS(std::vector<AddressSpace *> &as) = 0;
204
205  public:
206
207   BPatch_addressSpace();
208
209
210   virtual ~BPatch_addressSpace();
211
212   // Distinguishes between BPatch_process and BPatch_binaryEdit
213   virtual bool getType() = 0;  
214
215   // Returns back bools for variables that are BPatch_process member variables,
216   //   the return value is hardcoded for BPatch_binaryEdit
217   virtual bool getTerminated() = 0;
218   virtual bool getMutationsActive() = 0;
219
220   // internal functions, do not use //
221   BPatch_module *findModuleByAddr(Dyninst::Address addr);//doesn't cause parsing
222   bool findFuncsByRange(Dyninst::Address startAddr,
223                         Dyninst::Address endAddr,
224                         std::set<BPatch_function*> &funcs);
225   // end internal functions........ //
226
227
228   //  BPatch_addressSpace::insertSnippet
229   //  
230   //  Insert new code into the mutatee
231   API_EXPORT_VIRT(Int, (expr, point, order),
232                   BPatchSnippetHandle *,insertSnippet,(const BPatch_snippet &expr, 
233                                                        BPatch_point &point,
234                                                        BPatch_snippetOrder order = BPatch_firstSnippet));
235   
236     //BPatch_addressSpace::insertSnippet
237       
238     //Insert new code into the mutatee, specifying "when" (before/after point)
239
240     API_EXPORT_VIRT(When, (expr, point, when, order),
241                     BPatchSnippetHandle *,insertSnippet,(const BPatch_snippet &expr, 
242                                                          BPatch_point &point,
243                                                          BPatch_callWhen when,
244                                                          BPatch_snippetOrder order = BPatch_firstSnippet));
245     
246     //BPatch_addressSpace::insertSnippet
247       
248     //Insert new code into the mutatee at multiple points
249
250     API_EXPORT_VIRT(AtPoints, (expr, points, order),
251                     BPatchSnippetHandle *,insertSnippet,(const BPatch_snippet &expr,
252                                                          const BPatch_Vector<BPatch_point *> &points,
253                                                          BPatch_snippetOrder order = BPatch_firstSnippet));
254     
255       // BPatch_addressSpace::insertSnippet
256       
257       //Insert new code into the mutatee at multiple points, specifying "when"
258
259     API_EXPORT_VIRT(AtPointsWhen, (expr, points, when, order),
260                     BPatchSnippetHandle *,insertSnippet,(const BPatch_snippet &expr,
261                                                          const BPatch_Vector<BPatch_point *> &points,
262                                                          BPatch_callWhen when,
263                                                          BPatch_snippetOrder order = BPatch_firstSnippet));
264
265
266
267   
268   virtual void beginInsertionSet() = 0;
269
270   virtual bool finalizeInsertionSet(bool atomic, bool *modified = NULL) = 0;
271  
272
273   //  BPatch_addressSpace::deleteSnippet
274   //  
275   //  Remove instrumentation from the mutatee process
276
277   API_EXPORT(Int, (handle),
278              bool,deleteSnippet,(BPatchSnippetHandle *handle));
279
280   //  BPatch_addressSpace::replaceCode
281   //
282   //  Replace a point (must be an instruction...) with a given BPatch_snippet
283
284     API_EXPORT(Int, (point, snippet), 
285     bool, replaceCode, (BPatch_point *point, BPatch_snippet *snippet));
286
287     //  BPatch_addressSpace::replaceFunctionCall
288     //  
289     //  Replace function call at one point with another
290
291     API_EXPORT(Int, (point, newFunc),
292     bool,replaceFunctionCall,(BPatch_point &point, BPatch_function &newFunc));
293
294     //  BPatch_addressSpace::removeFunctionCall
295     //  
296     //  Remove function call at one point 
297
298     API_EXPORT(Int, (point),
299     bool,removeFunctionCall,(BPatch_point &point));
300
301     //  BPatch_addressSpace::replaceFunction
302     //  
303     //  Replace all calls to a function with calls to another
304
305     API_EXPORT(Int, (oldFunc, newFunc),
306     bool,replaceFunction,(BPatch_function &oldFunc, BPatch_function &newFunc));
307
308     // BPatch_addressSpace::wrapFunction
309     //
310     // Replace oldFunc with newFunc as above; however, also rename oldFunc
311     // to the provided name so it can still be reached. 
312
313     API_EXPORT(Int, (oldFunc, newFunc, clone),
314                bool,wrapFunction,(BPatch_function *oldFunc, BPatch_function *newFunc, Dyninst::SymtabAPI::Symbol *clone));
315
316     //  BPatch_addressSpace::getSourceLines
317     //  
318     //  Method that retrieves the line number and file name corresponding 
319     //  to an address
320
321     API_EXPORT(Int, (addr, lines),
322     bool,getSourceLines,(unsigned long addr, BPatch_Vector< BPatch_statement > & lines ));
323     
324     // BPatch_addressSpace::getAddressRanges
325     //
326     // Method that retrieves address range(s) for a given filename and line number.
327     
328     API_EXPORT(Int, (fileName, lineNo, ranges),
329     bool,getAddressRanges,(const char * fileName, unsigned int lineNo, std::vector< std::pair< unsigned long, unsigned long > > & ranges ));
330
331     //  DEPRECATED:
332     //  BPatch_addressSpace::findFunctionByAddr
333     //  
334     //  Returns the function containing an address
335
336     API_EXPORT(Int, (addr),
337     BPatch_function *,findFunctionByAddr,(void *addr));
338
339     //  BPatch_addressSpace::findFunctionByEntry
340     //  
341     //  Returns the function starting at the given address
342
343     API_EXPORT(Int, (entry),
344     BPatch_function *,findFunctionByEntry,(Dyninst::Address entry));
345
346     //  BPatch_addressSpace::findFunctionsByAddr
347     //  
348     //  Returns the functions containing an address 
349     //  (multiple functions are returned when code is shared)
350
351     API_EXPORT(Int, (addr,funcs),
352     bool, findFunctionsByAddr,(Dyninst::Address addr, 
353                                std::vector<BPatch_function*> &funcs));
354
355      //  BPatch_addressSpace::getImage
356     //
357     //  Obtain BPatch_image associated with this BPatch_addressSpace
358
359     API_EXPORT(Int, (),
360     BPatch_image *,getImage,());
361
362
363     //  BPatch_addressSpace::malloc
364     //  
365     //  Allocate memory for a new variable in the mutatee process
366
367     API_EXPORT(Int, (n, name),
368                BPatch_variableExpr *,malloc,(int n, std::string name = std::string("")));
369
370     //  BPatch_addressSpace::malloc
371     //  
372     //  Allocate memory for a new variable in the mutatee process
373
374     API_EXPORT(ByType, (type, name),
375                BPatch_variableExpr *,malloc,(const BPatch_type &type, std::string name = std::string("")));
376
377     API_EXPORT(Int, (at_addr, type, var_name, in_module),
378     BPatch_variableExpr *, createVariable,(Dyninst::Address at_addr, 
379                                            BPatch_type *type,
380                                            std::string var_name = std::string(""),
381                                            BPatch_module *in_module = NULL));
382
383     //  BPatch_addressSpace::free
384     //  
385     //  Free memory allocated by Dyninst in the mutatee process
386
387     API_EXPORT(Int, (ptr),
388     bool,free,(BPatch_variableExpr &ptr));
389
390     // BPatch_addressSpace::createVariable
391     // 
392     // Wrap an existing piece of allocated memory with a BPatch_variableExpr.
393     // Used (for instance) by the shared memory library to wrap its externally
394     // allocated memory for use by BPatch.
395     
396     API_EXPORT(Int, (name, addr, type),
397                BPatch_variableExpr *, createVariable, 
398                (std::string name, Dyninst::Address addr, BPatch_type *type = NULL));
399
400     API_EXPORT(Int, (regs),
401                bool, getRegisters, (std::vector<BPatch_register> &regs));
402
403     API_EXPORT(Int, (regName, reg),
404     bool, createRegister_NP, (std::string regName, BPatch_register &reg)); 
405
406     API_EXPORT_V(Int, (allowtraps),
407                void, allowTraps, (bool allowtraps));
408
409     //  BPatch_addressSpace::loadLibrary
410     //  
411     //  Load a shared library into the mutatee's address space
412     //  Returns true if successful
413     //
414     //  the reload argument is used by save the world to determine
415     //  if this library should be reloaded by the mutated binary
416     //  when it starts up. this is up to the user because loading
417     //  an extra shared library could hide access to the 'correct'
418     //  function by redefining a function  
419
420     API_EXPORT_VIRT(Int, (libname, reload),
421     bool, loadLibrary,(const char *libname, bool reload = false));
422
423     // BPatch_addressSpace::isStaticExecutable
424     //
425     // Returns true if the underlying image represents a 
426     // statically-linked executable, false otherwise
427     API_EXPORT(Int, (),
428             bool, isStaticExecutable,());
429
430     // HACK-TASTIC
431     // I need a workaround for the fact that PatchAPI doesn't have snippet
432     // support yet; I'm getting it by putting an external interface on the 
433     // Dyninst compiler. 
434     // BTW, while I'm at it: SCREW API_EXPORT!
435
436     void snippetToBinary(const BPatch_snippet &expr, 
437                           BPatch_point &point,
438                           BPatch_callWhen when,
439                           char *buffer,
440                           unsigned &size);
441
442 };
443
444
445 #endif