* Correctly open the first dependency that matches the ABI of its parent.
[dyninst.git] / dyninstAPI / src / binaryEdit.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: binaryEdit.h,v 1.15 2008/10/28 18:42:45 bernat Exp $
43
44 #ifndef BINARY_H
45 #define BINARY_H
46
47 #include "infHeap.h"
48 #include "addressSpace.h"
49 #include "codeRange.h"
50 #include "InstructionSource.h"
51 #include "ast.h"
52 #include <map>
53 #include <functional>
54 #include <queue>
55
56 class fileDescriptor;
57 class int_function;
58 class memoryTracker;
59 class depRelocation;
60
61 class BinaryEdit : public AddressSpace {
62  public:
63     // We must implement the following virtual functions
64
65     // "Read"/"Write" to an address space
66     bool readDataSpace(const void *inOther, 
67                        u_int amount, 
68                        void *inSelf, 
69                        bool showError);
70     bool readTextSpace(const void *inOther, 
71                        u_int amount, 
72                        const void *inSelf);
73     
74
75     bool writeDataSpace(void *inOther,
76                         u_int amount,
77                         const void *inSelf);
78     bool writeTextSpace(void *inOther,
79                         u_int amount,
80                         const void *inSelf);
81
82     // Memory allocation
83     // We don't specify how it should be done, only that it is. The model is
84     // that you ask for an allocation "near" a point, where "near" has an
85     // internal, platform-specific definition. The allocation mechanism does its
86     // best to give you what you want, but there are no promises - check the
87     // address of the returned buffer to be sure.
88
89     Address inferiorMalloc(unsigned size, 
90                            inferiorHeapType type=anyHeap,
91                            Address near = 0, 
92                            bool *err = NULL);
93     virtual void inferiorFree(Address item);
94     virtual bool inferiorRealloc(Address item, unsigned newSize);
95
96     // Get the pointer size of the app we're modifying
97     unsigned getAddressWidth() const;
98
99     /*
100     // Until we need these different from AddressSpace,
101     // I'm not implementing.
102     void *getPtrToInstruction(Address) const;
103     bool isValidAddress(const Address &) const;
104     */
105
106     // If true is passed for ignore_if_mt_not_set, then an error won't be
107     // initiated if we're unable to determine if the program is multi-threaded.
108     // We are unable to determine this if the daemon hasn't yet figured out
109     // what libraries are linked against the application.  Currently, we
110     // identify an application as being multi-threaded if it is linked against
111     // a thread library (eg. libpthreads.a on AIX).  There are cases where we
112     // are querying whether the app is multi-threaded, but it can't be
113     // determined yet but it also isn't necessary to know.
114     bool multithread_capable(bool ignore_if_mt_not_set = false);
115     
116     // Do we have the RT-side multithread functions available
117     bool multithread_ready(bool ignore_if_mt_not_set = false);
118
119     // Default to "nope"
120     virtual bool hasBeenBound(const relocationEntry &, 
121                               int_function *&, 
122                               Address) { return false; }
123
124     // Should be easy if the process isn't _executing_ where
125     // we're deleting...
126     virtual void deleteGeneratedCode(generatedCodeObject *del);
127
128     BinaryEdit();
129     ~BinaryEdit();
130
131     // Same usage pattern as process
132     void deleteBinaryEdit();
133
134     // And the "open" factory method.
135     static BinaryEdit *openFile(const std::string &file);
136
137     bool writeFile(const std::string &newFileName);
138     
139     virtual int_function *findOnlyOneFunction(const std::string &name,
140                                               const std::string &libname = "",
141                                               bool search_rt_lib = true);
142
143     // open a shared library and (optionally) all its dependencies
144     bool openSharedLibrary(const std::string &file, bool openDependencies = true);
145
146     // add a shared library relocation
147         void addDependentRelocation(Address to, Symbol *referring);
148
149     // search for a shared library relocation
150         Address getDependentRelocationAddr(Symbol *referring);
151
152    void setupRTLibrary(BinaryEdit *r);
153    BinaryEdit *rtLibrary();
154    bool getAllDependencies(std::map<std::string, BinaryEdit* > &deps);
155
156    void markDirty();
157    bool isDirty();
158
159    mapped_object *getMappedObject();
160    
161    int_variable* createTrampGuard();
162    void setTrampGuard(int_variable* tg); 
163
164    void setMultiThreadCapable(bool b);
165
166    void addSibling(BinaryEdit *);
167    std::vector<BinaryEdit *> &getSiblings();
168
169    bool replaceTrapHandler();
170    bool usedATrap();
171    bool isMultiThreadCapable();
172    std::pair<std::string, BinaryEdit*> openResolvedLibraryName(std::string filename);
173
174  private:
175     Address highWaterMark_;
176     Address lowWaterMark_;
177     bool isDirty_;
178
179     static bool getStatFileDescriptor(const std::string &file,
180                                       fileDescriptor &desc);
181
182     bool inferiorMallocStatic(unsigned size);
183
184     bool createMemoryBackingStore(mapped_object *obj);
185
186     bool initialize();
187
188     codeRangeTree* memoryTracker_;
189
190     mapped_object * addSharedObject(const std::string *fullPath);
191
192     std::vector<depRelocation *> dependentRelocations;
193
194     void buildDyninstSymbols(pdvector<Symbol *> &newSyms, 
195                              Region *newSec,
196                              Module *mod);
197     mapped_object *mobj;
198     BinaryEdit *rtlib;
199     std::vector<BinaryEdit *> siblings;
200     bool multithread_capable_;
201 };
202
203 class depRelocation {
204         public:
205                 depRelocation(Address a, Symbol *r) : to(a), referring(r) { }
206                 Address getAddress() const { return to; }
207                 Symbol *getReferring() const { return referring; }
208
209         private:
210                 Address to;
211                 Symbol *referring;
212 };
213
214 class memoryTracker : public codeRange {
215  public:
216     memoryTracker(Address a, unsigned s) :
217         alloced(false),  dirty(false), a_(a), s_(s) {
218         b_ = malloc(s_);
219     }
220
221     memoryTracker(Address a, unsigned s, void *b) :
222     alloced(false), dirty(false), a_(a), s_(s)
223         {
224             b_ = malloc(s_);
225             memcpy(b_, b, s_);
226         }
227     ~memoryTracker() { free(b_); }
228
229     Address get_address() const { return a_; }
230     unsigned get_size() const { return s_; }
231     void *get_local_ptr() const { return b_; }
232     void realloc(unsigned newsize) {
233       b_ = ::realloc(b_, newsize);
234       s_ = newsize;
235       assert(b_);
236     }
237
238     bool alloced;
239     bool dirty;
240
241  private:
242     Address a_;
243     unsigned s_;
244     void *b_;
245     
246 };
247
248 #endif // BINARY_H