Function wrapping implementation and Symtab extensions for undefined symbols
[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 "BPatch_dll.h"
36 #include "BPatch_Vector.h"
37 #include "BPatch_eventLock.h"
38 #include "BPatch_enums.h"
39 #include "BPatch_instruction.h" // for register type
40
41 #include "BPatch_callbacks.h"
42
43 #include <vector>
44
45 #include <stdio.h>
46 #include <signal.h>
47
48 // PatchAPI stuffs
49 //#include "Command.h"
50
51 namespace Dyninst {
52 namespace PatchAPI { 
53   class PatchMgr;
54   class DynAddrSpace;
55   class Patcher;
56   typedef dyn_detail::boost::shared_ptr<PatchMgr> PatchMgrPtr;
57   typedef dyn_detail::boost::shared_ptr<DynAddrSpace> DynAddrSpacePtr;
58 };
59 namespace SymtabAPI {
60    class Symbol;
61 };
62 }
63
64 class BPatch_statement;
65 class BPatch_snippet;
66 class BPatch_point;
67 class BPatch_variableExpr;
68 class AddressSpace;
69 class miniTrampHandle;
70 class miniTramp;
71 class BPatch;
72 class BPatch_image;
73
74 class func_instance;
75 struct batchInsertionRecord;
76
77 typedef enum{
78   TRADITIONAL_PROCESS, STATIC_EDITOR
79 } processType;
80
81
82 #ifdef DYNINST_CLASS_NAME
83 #undef DYNINST_CLASS_NAME
84 #endif
85 #define DYNINST_CLASS_NAME BPatchSnippetHandle
86 class BPATCH_DLL_EXPORT BPatchSnippetHandle : public BPatch_eventLock {
87     friend class BPatch_point;
88     friend class BPatch_image;
89     friend class BPatch_process;
90     friend class BPatch_binaryEdit;
91     friend class BPatch_addressSpace;
92     friend class BPatch_thread;
93
94 private:    
95     // Address Space snippet belogns to
96     BPatch_addressSpace *addSpace_;
97
98 #if defined(_MSC_VER)
99 #pragma warning(push)
100 #pragma warning(disable:4251) 
101 #endif
102     // low-level mappings for removal
103     BPatch_Vector<miniTramp *> mtHandles_;
104 #if defined(_MSC_VER)
105 #pragma warning(pop)    
106 #endif
107
108     //  a flag for catchup
109     bool catchupNeeded;
110     //  and a list of threads to apply catchup to
111     BPatch_Vector<BPatch_thread *> catchup_threads;
112     
113     BPatchSnippetHandle(BPatch_addressSpace * addSpace);
114
115     void addMiniTramp(miniTramp *m) { mtHandles_.push_back(m); }
116     
117 public:
118  
119     API_EXPORT_DTOR(_dtor, (),
120     ~,BPatchSnippetHandle,());
121
122     // Returns whether the installed miniTramps use traps.
123     // Not 100% accurate due to internal Dyninst design; we can
124     // have multiple instances of instrumentation due to function
125     // relocation.
126     API_EXPORT(Int, (), bool, usesTrap, ());
127
128     API_EXPORT(Int, (),
129     BPatch_addressSpace *, getAddressSpace, ());
130
131     API_EXPORT(Int, (),
132     BPatch_process *, getProcess, ());
133     
134     API_EXPORT(Int, (),
135     BPatch_Vector<BPatch_thread *> &, getCatchupThreads, ());
136
137 };
138
139 #ifdef DYNINST_CLASS_NAME
140 #undef DYNINST_CLASS_NAME
141 #endif
142 #define DYNINST_CLASS_NAME BPatch_addressSpace
143
144 class BPATCH_DLL_EXPORT BPatch_addressSpace : public BPatch_eventLock {
145     friend class BPatch;
146     friend class BPatch_image;
147     friend class BPatch_function;
148     friend class BPatch_frame;
149     friend class BPatch_module;
150     friend class BPatch_basicBlock;
151     friend class BPatch_flowGraph;
152     friend class BPatch_loopTreeNode;
153     friend class BPatch_point;
154     friend class BPatch_funcCallExpr;
155     friend class BPatch_eventMailbox;
156     friend class BPatch_instruction;
157   
158  public:
159     
160   BPatch_function *findOrCreateBPFunc(func_instance *ifunc, 
161                                       BPatch_module *bpmod);
162
163   BPatch_point *findOrCreateBPPoint(BPatch_function *bpfunc, 
164                                     instPoint *ip,
165                                     BPatch_procedureLocation pointType = BPatch_locUnknownLocation);
166
167   BPatch_variableExpr *findOrCreateVariable(int_variable *v,
168                                             BPatch_type *type = NULL);
169
170  protected:
171   
172   
173   // These callbacks are triggered by lower-level code and forward
174   // calls up to the findOrCreate functions.
175   static BPatch_function *createBPFuncCB(AddressSpace *p, func_instance *f);
176   static BPatch_point *createBPPointCB(AddressSpace *p, func_instance *f,
177                                        instPoint *ip, int type);
178
179   BPatch_Vector<batchInsertionRecord *> *pendingInsertions;
180
181   BPatch_image *image;
182
183   //  AddressSpace * as;
184   
185   std::vector<BPatch_register> registers_;
186
187  protected:
188   virtual void getAS(std::vector<AddressSpace *> &as) = 0;
189
190  public:
191
192   BPatch_addressSpace();
193
194
195   virtual ~BPatch_addressSpace();
196
197   // Distinguishes between BPatch_process and BPatch_binaryEdit
198   virtual bool getType() = 0;  
199
200   // Returns back bools for variables that are BPatch_process member variables,
201   //   the return value is hardcoded for BPatch_binaryEdit
202   virtual bool getTerminated() = 0;
203   virtual bool getMutationsActive() = 0;
204
205   // internal functions, do not use //
206   BPatch_module *findModuleByAddr(Dyninst::Address addr);//doesn't cause parsing
207   bool findFuncsByRange(Dyninst::Address startAddr,
208                         Dyninst::Address endAddr,
209                         std::set<BPatch_function*> &funcs);
210   // end internal functions........ //
211
212
213   //  BPatch_addressSpace::insertSnippet
214   //  
215   //  Insert new code into the mutatee
216   API_EXPORT_VIRT(Int, (expr, point, order),
217                   BPatchSnippetHandle *,insertSnippet,(const BPatch_snippet &expr, 
218                                                        BPatch_point &point,
219                                                        BPatch_snippetOrder order = BPatch_firstSnippet));
220   
221     //BPatch_addressSpace::insertSnippet
222       
223     //Insert new code into the mutatee, specifying "when" (before/after point)
224
225     API_EXPORT_VIRT(When, (expr, point, when, order),
226                     BPatchSnippetHandle *,insertSnippet,(const BPatch_snippet &expr, 
227                                                          BPatch_point &point,
228                                                          BPatch_callWhen when,
229                                                          BPatch_snippetOrder order = BPatch_firstSnippet));
230     
231     //BPatch_addressSpace::insertSnippet
232       
233     //Insert new code into the mutatee at multiple points
234
235     API_EXPORT_VIRT(AtPoints, (expr, points, order),
236                     BPatchSnippetHandle *,insertSnippet,(const BPatch_snippet &expr,
237                                                          const BPatch_Vector<BPatch_point *> &points,
238                                                          BPatch_snippetOrder order = BPatch_firstSnippet));
239     
240       // BPatch_addressSpace::insertSnippet
241       
242       //Insert new code into the mutatee at multiple points, specifying "when"
243
244     API_EXPORT_VIRT(AtPointsWhen, (expr, points, when, order),
245                     BPatchSnippetHandle *,insertSnippet,(const BPatch_snippet &expr,
246                                                          const BPatch_Vector<BPatch_point *> &points,
247                                                          BPatch_callWhen when,
248                                                          BPatch_snippetOrder order = BPatch_firstSnippet));
249
250
251
252   
253   virtual void beginInsertionSet() = 0;
254
255   virtual bool finalizeInsertionSet(bool atomic, bool *modified) = 0;
256  
257
258   //  BPatch_addressSpace::deleteSnippet
259   //  
260   //  Remove instrumentation from the mutatee process
261
262   API_EXPORT(Int, (handle),
263              bool,deleteSnippet,(BPatchSnippetHandle *handle));
264
265   //  BPatch_addressSpace::replaceCode
266   //
267   //  Replace a point (must be an instruction...) with a given BPatch_snippet
268
269     API_EXPORT(Int, (point, snippet), 
270     bool, replaceCode, (BPatch_point *point, BPatch_snippet *snippet));
271
272     //  BPatch_addressSpace::replaceFunctionCall
273     //  
274     //  Replace function call at one point with another
275
276     API_EXPORT(Int, (point, newFunc),
277     bool,replaceFunctionCall,(BPatch_point &point, BPatch_function &newFunc));
278
279     //  BPatch_addressSpace::removeFunctionCall
280     //  
281     //  Remove function call at one point 
282
283     API_EXPORT(Int, (point),
284     bool,removeFunctionCall,(BPatch_point &point));
285
286     //  BPatch_addressSpace::replaceFunction
287     //  
288     //  Replace all calls to a function with calls to another
289
290     API_EXPORT(Int, (oldFunc, newFunc),
291     bool,replaceFunction,(BPatch_function &oldFunc, BPatch_function &newFunc));
292
293     // BPatch_addressSpace::wrapFunction
294     //
295     // Replace oldFunc with newFunc as above; however, also rename oldFunc
296     // to the provided name so it can still be reached. 
297
298     API_EXPORT(Int, (oldFunc, newFunc, clone),
299                bool,wrapFunction,(BPatch_function *oldFunc, BPatch_function *newFunc, Dyninst::SymtabAPI::Symbol *clone));
300
301     //  BPatch_addressSpace::getSourceLines
302     //  
303     //  Method that retrieves the line number and file name corresponding 
304     //  to an address
305
306     API_EXPORT(Int, (addr, lines),
307     bool,getSourceLines,(unsigned long addr, BPatch_Vector< BPatch_statement > & lines ));
308     
309     // BPatch_addressSpace::getAddressRanges
310     //
311     // Method that retrieves address range(s) for a given filename and line number.
312     
313     API_EXPORT(Int, (fileName, lineNo, ranges),
314     bool,getAddressRanges,(const char * fileName, unsigned int lineNo, std::vector< std::pair< unsigned long, unsigned long > > & ranges ));
315
316     //  DEPRECATED:
317     //  BPatch_addressSpace::findFunctionByAddr
318     //  
319     //  Returns the function containing an address
320
321     API_EXPORT(Int, (addr),
322     BPatch_function *,findFunctionByAddr,(void *addr));
323
324     //  BPatch_addressSpace::findFunctionByEntry
325     //  
326     //  Returns the function starting at the given address
327
328     API_EXPORT(Int, (entry),
329     BPatch_function *,findFunctionByEntry,(Dyninst::Address entry));
330
331     //  BPatch_addressSpace::findFunctionsByAddr
332     //  
333     //  Returns the functions containing an address 
334     //  (multiple functions are returned when code is shared)
335
336     API_EXPORT(Int, (addr,funcs),
337     bool, findFunctionsByAddr,(Dyninst::Address addr, 
338                                std::vector<BPatch_function*> &funcs));
339
340      //  BPatch_addressSpace::getImage
341     //
342     //  Obtain BPatch_image associated with this BPatch_addressSpace
343
344     API_EXPORT(Int, (),
345     BPatch_image *,getImage,());
346
347
348     //  BPatch_addressSpace::malloc
349     //  
350     //  Allocate memory for a new variable in the mutatee process
351
352     API_EXPORT(Int, (n, name),
353                BPatch_variableExpr *,malloc,(int n, std::string name = std::string("")));
354
355     //  BPatch_addressSpace::malloc
356     //  
357     //  Allocate memory for a new variable in the mutatee process
358
359     API_EXPORT(ByType, (type, name),
360                BPatch_variableExpr *,malloc,(const BPatch_type &type, std::string name = std::string("")));
361
362     API_EXPORT(Int, (at_addr, type, var_name, in_module),
363     BPatch_variableExpr *, createVariable,(Dyninst::Address at_addr, 
364                                            BPatch_type *type,
365                                            std::string var_name = std::string(""),
366                                            BPatch_module *in_module = NULL));
367
368     //  BPatch_addressSpace::free
369     //  
370     //  Free memory allocated by Dyninst in the mutatee process
371
372     API_EXPORT(Int, (ptr),
373     bool,free,(BPatch_variableExpr &ptr));
374
375     // BPatch_addressSpace::createVariable
376     // 
377     // Wrap an existing piece of allocated memory with a BPatch_variableExpr.
378     // Used (for instance) by the shared memory library to wrap its externally
379     // allocated memory for use by BPatch.
380     
381     API_EXPORT(Int, (name, addr, type),
382                BPatch_variableExpr *, createVariable, 
383                (std::string name, Dyninst::Address addr, BPatch_type *type = NULL));
384
385     API_EXPORT(Int, (regs),
386                bool, getRegisters, (std::vector<BPatch_register> &regs));
387
388     API_EXPORT(Int, (regName, reg),
389     bool, createRegister_NP, (std::string regName, BPatch_register &reg)); 
390
391     API_EXPORT_V(Int, (allowtraps),
392                void, allowTraps, (bool allowtraps));
393
394     //  BPatch_addressSpace::loadLibrary
395     //  
396     //  Load a shared library into the mutatee's address space
397     //  Returns true if successful
398     //
399     //  the reload argument is used by save the world to determine
400     //  if this library should be reloaded by the mutated binary
401     //  when it starts up. this is up to the user because loading
402     //  an extra shared library could hide access to the 'correct'
403     //  function by redefining a function  
404
405     API_EXPORT_VIRT(Int, (libname, reload),
406     bool, loadLibrary,(const char *libname, bool reload = false));
407
408     // BPatch_addressSpace::isStaticExecutable
409     //
410     // Returns true if the underlying image represents a 
411     // statically-linked executable, false otherwise
412     API_EXPORT(Int, (),
413             bool, isStaticExecutable,());
414
415 };
416
417 #endif