Fixes to allow binary rewriter to load RT library
[dyninst.git] / dyninstAPI / src / addressSpace.h
1 /*
2  * Copyright (c) 1996-2004 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  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 // $Id: addressSpace.h,v 1.9 2008/06/20 22:00:04 legendre Exp $
43
44 #ifndef ADDRESS_SPACE_H
45 #define ADDRESS_SPACE_H
46
47 #include "infHeap.h"
48 #include "codeRange.h"
49 #include "InstructionSource.h"
50 #include "ast.h"
51 #include "symtabAPI/h/Symtab.h"
52 #include "dyninstAPI/src/trapMappings.h"
53
54 class codeRange;
55 class multiTramp;
56 class replacedFunctionCall;
57 class functionReplacement;
58
59 class int_function;
60 class int_variable;
61 class mapped_module;
62 class mapped_object;
63 class instPoint;
64
65 class BPatch_process;
66 class BPatch_function;
67 class BPatch_point;
68
69 class Emitter;
70 class generatedCodeObject;
71 class fileDescriptor;
72
73 using namespace Dyninst;
74 using namespace SymtabAPI;
75
76 class int_function;
77 class int_symbol;
78
79 class Dyn_Symbol;
80 class BinaryEdit;
81 class trampTrapMappings;
82
83 // This file serves to define an "address space", a set of routines that 
84 // code generation and instrumentation rely on to perform their duties. 
85 // This was derived from the process class and serves as a parent to that
86 // class and the static_space class for the rewriter. 
87
88 // The methods in this class were determined by what the code currently
89 // uses, not a particular design. As such, I expect this to change wildly
90 // by the time the refactoring is complete. 
91 //
92 // bernat, 5SEP07
93
94 // Note: this is a pure virtual class; it serves as an interface
95 // specification.
96
97 class AddressSpace : public InstructionSource {
98  public:
99     
100     // Down-conversion functions
101     process *proc();
102     BinaryEdit *edit();
103
104     // Read/write
105
106     // We have read/write for both "text" and "data". This comes in handy,
107     // somewhere, I'm sure
108     virtual bool readDataSpace(const void *inOther, 
109                                u_int amount, 
110                                void *inSelf, 
111                                bool showError) = 0;
112     virtual bool readTextSpace(const void *inOther, 
113                                u_int amount, 
114                                const void *inSelf) = 0;
115     
116
117     virtual bool writeDataSpace(void *inOther,
118                                 u_int amount,
119                                 const void *inSelf) = 0;
120     virtual bool writeTextSpace(void *inOther,
121                                 u_int amount,
122                                 const void *inSelf) = 0;
123
124     // Memory allocation
125     // We don't specify how it should be done, only that it is. The model is
126     // that you ask for an allocation "near" a point, where "near" has an
127     // internal, platform-specific definition. The allocation mechanism does its
128     // best to give you what you want, but there are no promises - check the
129     // address of the returned buffer to be sure.
130
131     virtual Address inferiorMalloc(unsigned size, inferiorHeapType type=anyHeap,
132                                    Address near = 0, bool *err = NULL) = 0;
133     virtual void inferiorFree(Address item) = 0;
134     void inferiorFreeInternal(Address item);
135     // And a "constrain" call to free unused memory. This is useful because our
136     // instrumentation is incredibly wasteful.
137     virtual bool inferiorRealloc(Address item, unsigned newSize) = 0;
138     bool inferiorReallocInternal(Address item, unsigned newSize);
139
140     bool isInferiorAllocated(Address block);
141
142     // Get the pointer size of the app we're modifying
143     virtual unsigned getAddressWidth() const = 0;
144
145     // We need a mechanism to track what exists at particular addresses in the
146     // address space - both for lookup and to ensure that there are no collisions.
147     // We have a multitude of ways to "muck with" the application (function replacement,
148     // instrumentation, function relocation, ...) and they can all stomp on each
149     // other. 
150
151     void addOrigRange(codeRange *range);
152     void addModifiedRange(codeRange *range);
153
154     void removeOrigRange(codeRange *range);
155     void removeModifiedRange(codeRange *range);
156
157     codeRange *findOrigByAddr(Address addr);
158     codeRange *findModByAddr(Address addr);
159
160     bool getDyninstRTLibName();
161
162     virtual void *getPtrToInstruction(Address) const;
163     virtual bool isValidAddress(const Address &) const;
164     virtual bool isExecutableAddress(const Address &) const;
165
166     // Trap address to base tramp address (for trap instrumentation)
167     trampTrapMappings trapMapping;
168     
169     // Should return iterators
170     bool getOrigRanges(pdvector<codeRange *> &);
171     bool getModifiedRanges(pdvector<codeRange *> &);
172
173     // Multitramp convenience functions
174     multiTramp *findMultiTrampByAddr(Address addr);
175     multiTramp *findMultiTrampById(unsigned int id);
176     void addMultiTramp(multiTramp *multi);
177     void removeMultiTramp(multiTramp *multi);
178
179     // Function replacement (or relocated, actually) convenience functions
180     functionReplacement *findFuncReplacement(Address addr);
181     void addFuncReplacement(functionReplacement *funcrep);
182     void removeFuncReplacement(functionReplacement *funcrep);
183
184     // Function call replacement convenience functions
185     replacedFunctionCall *findReplacedCall(Address addr);
186     void addReplacedCall(replacedFunctionCall *rep);
187     void removeReplacedCall(replacedFunctionCall *rep);
188
189     //////////////////////////////////////////////////////////////
190     // Function/variable lookup code
191     // Turns out that instrumentation needs this... so the 
192     // AddressSpace keeps growing. 
193     //////////////////////////////////////////////////////////////
194
195     // findFuncByName: returns function associated with "func_name"
196     // This routine checks both the a.out image and any shared object images 
197     // for this function
198     //int_function *findFuncByName(const std::string &func_name);
199     
200     bool findFuncsByAll(const std::string &funcname,
201                         pdvector<int_function *> &res,
202                         const std::string &libname = "");
203     
204     // Specific versions...
205     bool findFuncsByPretty(const std::string &funcname,
206                            pdvector<int_function *> &res,
207                            const std::string &libname = "");
208     bool findFuncsByMangled(const std::string &funcname, 
209                             pdvector<int_function *> &res,
210                             const std::string &libname = "");
211     
212     bool findVarsByAll(const std::string &varname,
213                        pdvector<int_variable *> &res,
214                        const std::string &libname = "");
215     
216     // And we often internally want to wrap the above to return one
217     // and only one func...
218     virtual int_function *findOnlyOneFunction(const std::string &name,
219                                               const std::string &libname = "",
220                                               bool search_rt_lib = true);
221
222
223     // This will find the named symbol in the image or in a shared object
224     // Necessary since some things don't show up as a function or variable.
225     //    bool getSymbolInfo( const std::string &name, Dyn_Symbol &ret );
226     // This gets wrapped with an int_symbol and returned.
227     bool getSymbolInfo( const std::string &name, int_symbol &ret );
228
229     // getAllFunctions: returns a vector of all functions defined in the
230     // a.out and in the shared objects
231     void getAllFunctions(pdvector<int_function *> &);
232     
233     // Find the code sequence containing an address
234     // Note: fix the name....
235     int_function *findFuncByAddr(Address addr);
236     bool findFuncsByAddr(Address addr, std::vector<int_function *> &funcs);
237
238     int_basicBlock *findBasicBlockByAddr(Address addr);
239     
240     // And a lookup by "internal" function to find clones during fork...
241     int_function *findFuncByInternalFunc(image_func *ifunc);
242     
243     //findJumpTargetFuncByAddr Acts like findFunc, but if it fails,
244     // checks if 'addr' is a jump to a function.
245     int_function *findJumpTargetFuncByAddr(Address addr);
246     
247     // findModule: returns the module associated with "mod_name" 
248     // this routine checks both the a.out image and any shared object 
249     // images for this module
250     // if check_excluded is true it checks to see if the module is excluded
251     // and if it is it returns 0.  If check_excluded is false it doesn't check
252     //  if substring_match is true, the first module whose name contains
253     //  the provided string is returned.
254     // Wildcard: handles "*" and "?"
255     mapped_module *findModule(const std::string &mod_name, bool wildcard = false);
256     // And the same for objects
257     // Wildcard: handles "*" and "?"
258     mapped_object *findObject(const std::string &obj_name, bool wildcard = false);
259     mapped_object *findObject(Address addr);
260     mapped_object *findObject(fileDescriptor desc);
261
262     mapped_object *getAOut() { assert(mapped_objects.size()); return mapped_objects[0];}
263     
264     // getAllModules: returns a vector of all modules defined in the
265     // a.out and in the shared objects
266     void getAllModules(pdvector<mapped_module *> &);
267
268     // return the list of dynamically linked libs
269     const pdvector<mapped_object *> &mappedObjects() { return mapped_objects;  } 
270
271     // And a shortcut pointer
272     mapped_object *runtime_lib;
273     // ... and keep the name around
274     std::string dyninstRT_name;
275     
276     // If true is passed for ignore_if_mt_not_set, then an error won't be
277     // initiated if we're unable to determine if the program is multi-threaded.
278     // We are unable to determine this if the daemon hasn't yet figured out
279     // what libraries are linked against the application.  Currently, we
280     // identify an application as being multi-threaded if it is linked against
281     // a thread library (eg. libpthreads.a on AIX).  There are cases where we
282     // are querying whether the app is multi-threaded, but it can't be
283     // determined yet but it also isn't necessary to know.
284     virtual bool multithread_capable(bool ignore_if_mt_not_set = false) = 0;
285     
286     // Do we have the RT-side multithread functions available
287     virtual bool multithread_ready(bool ignore_if_mt_not_set = false) = 0;
288
289     //////////////////////////////////////////////////////
290     // Process-level instrumentation (?)
291     /////////////////////////////////////////////////////
292
293     // instPoint isn't const; it may get an updated list of
294     // instances since we generate them lazily.
295     // Shouldn't this be an instPoint member function?
296     bool replaceFunctionCall(instPoint *point,const int_function *newFunc);
297     
298     // And this....
299     bool getDynamicCallSiteArgs(instPoint *callSite, 
300                                 pdvector<AstNodePtr> &args);
301
302     // Default to "nope"
303     virtual bool hasBeenBound(const relocationEntry &, 
304                               int_function *&, 
305                               Address) { return false; }
306     
307     // Trampoline guard get/set functions
308     int_variable* trampGuardBase(void) { return trampGuardBase_; }
309     AstNodePtr trampGuardAST(void);
310
311     // Get the current code generator (or emitter)
312     Emitter *getEmitter();
313
314     // Should be easy if the process isn't _executing_ where
315     // we're deleting...
316     virtual void deleteGeneratedCode(generatedCodeObject *del);
317
318     //////////////////////////////////////////////////////
319     // BPatch-level stuff
320     //////////////////////////////////////////////////////
321     // Callbacks for higher level code (like BPatch) to learn about new 
322     //  functions and InstPoints.
323  private:
324     BPatch_function *(*new_func_cb)(AddressSpace *a, int_function *f);
325     BPatch_point *(*new_instp_cb)(AddressSpace *a, int_function *f, instPoint *ip, 
326                                   int type);
327  public:
328     //Trigger the callbacks from a lower level
329     BPatch_function *newFunctionCB(int_function *f) 
330         { assert(new_func_cb); return new_func_cb(this, f); }
331     BPatch_point *newInstPointCB(int_function *f, instPoint *pt, int type)
332         { assert(new_instp_cb); return new_instp_cb(this, f, pt, type); }
333     
334     //Register callbacks from the higher level
335     void registerFunctionCallback(BPatch_function *(*f)(AddressSpace *p, 
336                                                         int_function *f))
337         { new_func_cb = f; };
338     void registerInstPointCallback(BPatch_point *(*f)(AddressSpace *p, int_function *f,
339                                                       instPoint *ip, int type))
340         { new_instp_cb = f; }
341     
342     
343     //Anonymous up pointer to the containing process.  This is BPatch_process
344     // in Dyninst.  Currently stored as an void pointer in case we do
345     // anything with this during the library split.
346     void *up_ptr() { return up_ptr_; }
347     void set_up_ptr(void *ptr) { up_ptr_ = ptr; }
348     
349     //////////////////////////////////////////////////////
350     // Internal and cleanup 
351     //////////////////////////////////////////////////////
352
353     // Clear things out (e.g., deleteProcess)
354     void deleteAddressSpace();
355     // Fork psuedo-constructor
356     void copyAddressSpace(process *parent);
357
358     // Aaand constructor/destructor
359     AddressSpace();
360     virtual ~AddressSpace();
361
362
363     //////////////////////////////////////////////////////
364     // Yuck
365     //////////////////////////////////////////////////////
366     Address getObservedCostAddr() const { return costAddr_; }
367     void updateObservedCostAddr(Address addr) { costAddr_ = addr;}
368
369     // Can we use traps if necessary?
370     virtual bool canUseTraps() = 0;
371
372  protected:
373
374     // inferior malloc support functions
375     void inferiorFreeCompact();
376     int findFreeIndex(unsigned size, int type, Address lo, Address hi);
377     void addHeap(heapItem *h);
378     void initializeHeap();
379     
380     // Centralization of certain inferiorMalloc operations
381     Address inferiorMallocInternal(unsigned size, Address lo, Address hi, 
382                                    inferiorHeapType type);
383     void inferiorMallocAlign(unsigned &size);
384
385     bool heapInitialized_;
386     inferiorHeap heap_;
387
388     // Text sections (including added - instrumentation)
389     codeRangeTree textRanges_;
390     // Data sections
391     codeRangeTree dataRanges_;
392     // And address-space-wide patches that we've dropped in
393     codeRangeTree modifiedRanges_;
394
395     // We label multiTramps by ID
396     dictionary_hash<int, multiTramp *> multiTrampsById_;
397
398     // Loaded mapped objects (may be just 1)
399     pdvector<mapped_object *> mapped_objects;
400
401     int_variable* trampGuardBase_; // Tramp recursion index mapping
402     AstNodePtr trampGuardAST_;
403
404     void *up_ptr_;
405
406     Address costAddr_;
407 };
408
409 extern int heapItemCmpByAddr(const heapItem **A, const heapItem **B);
410
411 #endif // ADDRESS_SPACE_H