Update copyright to LGPL on all files
[dyninst.git] / dyninstAPI / src / mapped_object.h
1 /*
2  * Copyright (c) 1996-2009 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 // $Id: mapped_object.h,v 1.23 2008/10/27 17:23:53 mlam Exp $
33
34 #if !defined(_mapped_object_h)
35 #define _mapped_object_h
36
37 #include <string>
38 #include "common/h/Types.h"
39 #include "dyninstAPI/src/symtab.h"
40
41 //  we really do not want to have this defined, but I'm defining it for the moment to get thru paradyn seperation
42 #define CHECK_ALL_CALL_POINTS  // we depend on this for Paradyn
43
44 class mapped_module;
45
46 class int_symbol {
47  public:
48     int_symbol(Symbol *sym, Address base) : addr_(base + sym->getOffset()), sym_(sym) {}
49     int_symbol() : addr_(0), sym_(NULL) {};
50
51     Address getAddr() const { return addr_; }
52     unsigned getSize() const { return sym_->getSize(); }
53     const string &symTabName() const { return sym_->getMangledName(); }
54     const string &prettyName() const { return sym_->getPrettyName(); }
55     const string &typedName() const { return sym_->getTypedName(); }
56     const Symbol *sym() const { return sym_; }
57
58  private:
59     Address addr_;
60     const Symbol *sym_;
61 };
62
63
64 class int_variable {
65     // Should subclass this and function off the same thing...
66
67  private:
68     int_variable() {};
69  public:
70     int_variable(image_variable *var, 
71                  Address base,
72                  mapped_module *mod);
73
74     int_variable(int_variable *parVar, mapped_module *child);
75
76     Address getAddress() const { return addr_; }
77     // Can variables have multiple names?
78     const string &symTabName() const;
79     const vector<string>& prettyNameVector() const;
80     const vector<string>& symTabNameVector() const;
81     mapped_module *mod() const { return mod_; };
82     //AddressSpace *as() const { return mod()->proc(); }
83     const image_variable *ivar() const { return ivar_; }
84
85     Address addr_;
86     unsigned size_;
87     // type?
88     image_variable *ivar_;
89
90     mapped_module *mod_;
91 };
92
93
94 /*
95  * A class for link map information about a shared object that is mmapped 
96  * by the dynamic linker into the applications address space at runtime. 
97  */
98 #define         SHAREDOBJECT_NOCHANGE   0
99 #define         SHAREDOBJECT_ADDED      1
100 #define         SHAREDOBJECT_REMOVED    2
101
102 // mapped_object represents a file in memory. It will be a collection
103 // of modules (basically, .o's) that are referred to as a unit and
104 // loaded as a unit.  The big reason for this is 1) per-process
105 // specialization and 2) a way to reduce memory; to create objects for
106 // all functions ahead of time is wasteful and expensive. So
107 // basically, the mapped_object "wins" if it can return useful
108 // information without having to allocate memory.
109
110 class mapped_object : public codeRange {
111     friend class mapped_module; // for findFunction
112     friend class int_function;
113     friend class bblInstance; // Adds to codeRangesByAddr_
114  private:
115     mapped_object();
116     mapped_object(fileDescriptor fileDesc, 
117                   image *img,
118                   AddressSpace *proc);
119
120  public:
121     // We need a way to check for errors; hence a "get" method
122     static mapped_object *createMappedObject(fileDescriptor &desc,
123                                              AddressSpace *p,
124 #if defined (os_windows)
125                                              bool parseGaps = false);
126 #else 
127                                              bool parseGaps = true);
128 #endif
129
130     // Copy constructor: for forks
131     mapped_object(const mapped_object *par_obj, process *child);
132
133     // Will delete all int_functions which were originally part of this object; including 
134     // any that were relocated (we can always follow the "I was relocated" pointer).
135     ~mapped_object();
136
137     bool analyze();
138     bool isAnalyzed() { return analyzed_; }
139
140     const fileDescriptor &getFileDesc() const { return desc_; }
141     // Full name, including path
142     const string &fullName() const { return fullName_; }
143     const string &fileName() const { return fileName_; }
144     Address codeAbs() const { return codeBase() + imageOffset(); }
145     Address codeBase() const { return codeBase_; }
146     Address imageOffset() const { return parse_img()->imageOffset(); }
147     unsigned imageSize() const { return parse_img()->imageLength(); }
148
149     // Deprecated...
150     Address getBaseAddress() const { return codeBase(); }
151
152     Address dataAbs() const { return dataBase() + dataOffset(); }
153     Address dataBase() const { return dataBase_; }
154     Address dataOffset() const { return parse_img()->dataOffset(); }
155     unsigned dataSize() const { return parse_img()->dataLength(); }
156
157     image *parse_img() const { return image_; }
158     bool isSharedLib() const;
159
160     // Return an appropriate identification string for debug purposes.
161     // Will eventually be required by a debug base class.
162     const std::string debugString() const;
163
164     // Used for codeRange ONLY! DON'T USE THIS! BAD USER!
165     Address get_address() const { return codeAbs(); }
166     void *get_local_ptr() const;
167     unsigned get_size() const { return imageSize(); }
168
169     AddressSpace *proc() const;
170
171     mapped_module *findModule(string m_name, bool wildcard = false);
172     mapped_module *findModule(pdmodule *mod);
173
174     mapped_module *getDefaultModule();
175
176
177     void getInferiorHeaps(vector<pair<string, Address> > &infHeaps);
178
179
180     // codeRange method
181     void *getPtrToInstruction(Address addr) const;
182     void *getPtrToData(Address addr) const;
183
184     // Try to avoid using these if you can, since they'll trigger
185     // parsing and allocation. 
186     bool getAllFunctions(pdvector<int_function *> &funcs);
187     bool getAllVariables(pdvector<int_variable *> &vars);
188
189     const pdvector<mapped_module *> &getModules();
190
191 #if defined(cap_save_the_world)
192     bool isinText(Address addr){ 
193         return ((addr >= codeBase_) && (addr < (codeBase_ + imageSize())));
194     }
195     void openedWithdlopen() { dlopenUsed = true; }; 
196     bool isopenedWithdlopen() { return dlopenUsed; };
197 #endif
198
199     bool  getSymbolInfo(const std::string &n, int_symbol &sym);
200
201     // All name lookup functions are vectorized, because you can have
202     // multiple overlapping names for all sorts of reasons.
203     // Demangled/"pretty": easy overlap (overloaded funcs, etc.).
204     // Mangled: multiple modules with static/private functions and
205     // we've lost the module name.
206
207     const pdvector<int_function *> *findFuncVectorByPretty(const std::string &funcname);
208     const pdvector<int_function *> *findFuncVectorByMangled(const std::string &funcname); 
209
210     int_function *findFuncByAddr(const Address &address);
211     codeRange *findCodeRangeByAddress(const Address &address);
212
213     const pdvector<int_variable *> *findVarVectorByPretty(const std::string &varname);
214     const pdvector<int_variable *> *findVarVectorByMangled(const std::string &varname); 
215     const int_variable *getVariable(const std::string &varname);
216     
217     // After analysis has taken place, trigger control-flow traversal
218     // parsing of new function and add it to the mapped_object
219     bool analyzeNewFunctions(vector<image_func*> *func);
220
221         //this marks the shared object as dirty, mutated
222         //so it needs saved back to disk
223         void setDirty(){ dirty_=true;}
224         bool isDirty() { return dirty_; }
225
226
227 #if defined(cap_save_the_world)
228         //ccw 24 jul 2003
229         //This marks the shared library as one that contains functions
230         //that are called by instrumentation.  These functions, and hence
231         //this shared library, MUST be reloaded in the same place.  The
232         //shared library is not necessarily mutated itself, so it may not
233         //need to be saved (as dirty_ would imply).
234         void setDirtyCalled() { dirtyCalled_ = true; }
235         bool isDirtyCalled() { return dirtyCalled_; }
236 #endif
237
238     int_function *findFunction(image_func *img_func);
239     int_variable *findVariable(image_variable *img_var);
240
241     //
242     //     PRIVATE DATA MEMBERS
243     //                          
244 private:
245     fileDescriptor desc_; // full file descriptor
246
247     string  fullName_;  // full file name of the shared object
248     string  fileName_; // name of shared object as it should be identified
249                         //  in mdl, e.g. as used for "exclude"....
250     Address   codeBase_; // The OS offset where the text segment is loaded;
251     // there is a corresponding codeOffset_ in the image class.
252
253     // For example, an a.out often has a codeBase of 0, and a
254     // codeOffset of 0x<valid>. Libraries are the reverse; codeBase_
255     // of <valid>, codeOffset of 0. All of our incoming functions,
256     // etc. from the image class have codeOffset built in.
257
258     Address   dataBase_; // Where the data starts...
259
260     void set_short_name();
261
262     pdvector<mapped_module *> everyModule;
263
264     dictionary_hash<const image_func *, int_function *> everyUniqueFunction;
265     dictionary_hash<const image_variable *, int_variable *> everyUniqueVariable;
266
267     dictionary_hash< std::string, pdvector<int_function *> * > allFunctionsByMangledName;
268     dictionary_hash< std::string, pdvector<int_function *> * > allFunctionsByPrettyName;
269
270     dictionary_hash< std::string, pdvector<int_variable *> * > allVarsByMangledName;
271     dictionary_hash< std::string, pdvector<int_variable *> * > allVarsByPrettyName;
272
273     codeRangeTree codeRangesByAddr_;
274
275     // And those call...
276     void addFunction(int_function *func);
277     void addVariable(int_variable *var);
278
279     // Add a name after-the-fact
280     typedef enum {
281         mangledName = 1,
282         prettyName = 2,
283         typedName = 4 } nameType_t;
284     void addFunctionName(int_function *func, const std::string newName, nameType_t nameType);
285
286     bool dirty_; // marks the shared object as dirty 
287     bool dirtyCalled_;//see comment for setDirtyCalled
288     
289     image  *image_; // pointer to image if processed is true 
290     bool dlopenUsed; //mark this shared object as opened by dlopen
291     AddressSpace *proc_; // Parent process
292
293     bool analyzed_; // Prevent multiple adds
294
295     mapped_module *getOrCreateForkedModule(mapped_module *mod);
296
297     // from a string that is a complete path name to a function in a module
298     // (ie. "/usr/lib/libc.so.1/write") return a string with the function
299     // part removed.  return 0 on error
300     char *getModulePart(std::string &full_path_name) ;
301
302 };
303
304 // Aggravation: a mapped object might very well occupy multiple "ranges". 
305 class mappedObjData : public codeRange {
306  public:
307     mappedObjData(mapped_object *obj_) : obj(obj_) {};
308     Address get_address() const { return obj->dataAbs(); }
309     unsigned get_size() const { return obj->dataSize(); }
310     mapped_object *obj;
311 };
312
313
314 #endif