Update copyright to LGPL on all files
[dyninst.git] / dyninstAPI / src / mapped_object.C
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.C,v 1.39 2008/09/03 06:08:44 jaw Exp $
33
34 #include <string>
35
36 #include "dyninstAPI/src/mapped_object.h"
37 #include "dyninstAPI/src/mapped_module.h"
38 #include "dyninstAPI/src/symtab.h"
39 #include "dyninstAPI/src/debug.h"
40 #include "symtabAPI/h/Symtab.h"
41 #include "process.h"
42
43 using namespace Dyninst;
44
45 #define FS_FIELD_SEPERATOR '/'
46
47 // Whee hasher...
48
49 unsigned imgFuncHash(const image_func * const &func) {
50     return addrHash4((Address) func);
51 }
52 unsigned imgVarHash(const image_variable * const &func) 
53 {
54     return addrHash4((Address) func);
55 }
56
57 mapped_object::mapped_object(fileDescriptor fileDesc,
58       image *img,
59       AddressSpace *proc):
60    desc_(fileDesc),
61    fullName_(fileDesc.file()), 
62    everyUniqueFunction(imgFuncHash),
63    everyUniqueVariable(imgVarHash),
64    allFunctionsByMangledName(::Dyninst::stringhash),
65    allFunctionsByPrettyName(::Dyninst::stringhash),
66    allVarsByMangledName(::Dyninst::stringhash),
67    allVarsByPrettyName(::Dyninst::stringhash),
68    dirty_(false),
69    dirtyCalled_(false),
70    image_(img),
71    dlopenUsed(false),
72    proc_(proc),
73    analyzed_(false)
74
75    // Set occupied range (needs to be ranges)
76    codeBase_ = fileDesc.code();
77    dataBase_ = fileDesc.data();
78 #if defined(os_windows)
79    codeBase_ = fileDesc.loadAddr();
80    dataBase_ = fileDesc.loadAddr();
81 #endif
82 #if defined(os_aix)
83    // AIX defines "virtual" addresses for an a.out inside the file as
84    // well as when the system loads the object. As far as I can tell,
85    // this only happens for the a.out (for shobjs the file-addresses
86    // are 0).  The file-provided addresses are correct, but the
87    // OS-provided addresses are not. So if the file includes
88    // addresses, use those.  If it doesn't, all of the offsets are
89    // from a "section start" that isn't our start. Getting a headache
90    // yet? So _that_ needs to be adjusted. We've stored these values
91    // in the Object file. We could also adjust all addresses of
92    // symbols, but...
93    if (image_->imageOffset() >= codeBase_) {
94       codeBase_ = 0;
95    }
96    else if (image_->imageOffset() <= 0x1fffffff) {
97       // GCC-ism. This is a shared library with a a.out-like codeOffset.
98       // We need to make our base the difference between the two...
99       codeBase_ -= image_->imageOffset();
100       Region *sec;
101       image_->getObject()->findRegion(sec, ".text");
102       //fprintf(stderr, "codeBase 0x%x, rawPtr 0x%x, BaseOffset 0x%x, size %d\n",
103       //        codeBase_, (Address)sec->getPtrToRawData() , image_->getObject()->getBaseAddress());
104       codeBase_ += ((Address)sec->getPtrToRawData() - image_->getObject()->getBaseOffset());    
105       //      codeBase_ += image_->getObject()->text_reloc();
106    }
107    else {
108       // codeBase_ is the address that the chunk was loaded at; the actual interesting
109       // bits start within the chunk. So add in text_reloc (actually, "offset from start
110       // of file to interesting bits"). 
111       // Non-GCC shared libraries.
112       //codeBase_ += image_->getObject()->text_reloc();
113       Region *sec;
114       image_->getObject()->findRegion(sec, ".text");
115       //fprintf(stderr, "codeBase 0x%x, rawPtr 0x%x, BaseOffset 0x%x, size %d\n",
116       //        codeBase_, (Address)sec->getPtrToRawData() , image_->getObject()->getBaseOffset());
117       codeBase_ += ((Address)sec->getPtrToRawData()-image_->getObject()->getBaseOffset());
118    }
119    if (image_->dataOffset() >= dataBase_) {
120       dataBase_ = 0;
121    }
122    else if (image_->dataOffset() <= 0x2fffffff) {
123       // More GCC-isms. 
124       dataBase_ -= image_->dataOffset();
125    }
126    else {
127       // *laughs* You'd think this was the same way, right?
128       // Well, you're WRONG!
129       // For some reason we don't need to add in the data_reloc_...
130       //dataBase_ += image_->getObject()->data_reloc();
131    }
132 #endif
133
134 #if 0
135    fprintf(stderr, "Creating new mapped_object %s/%s\n",
136          fullName_.c_str(), getFileDesc().member().c_str());
137    fprintf(stderr, "codeBase 0x%x, codeOffset 0x%x, size %d\n",
138          codeBase_, image_->imageOffset(), image_->imageLength());
139    fprintf(stderr, "dataBase 0x%x, dataOffset 0x%x, size %d\n",
140          dataBase_, image_->dataOffset(), image_->dataLength());
141    fprintf(stderr, "fileDescriptor: code at 0x%x, data 0x%x\n",
142          fileDesc.code(), fileDesc.data());
143    fprintf(stderr, "Code: 0x%lx to 0x%lx\n",
144          codeAbs(), codeAbs() + imageSize());
145    fprintf(stderr, "Data: 0x%lx to 0x%lx\n",
146          dataAbs(), dataAbs() + dataSize());
147 #endif
148
149
150    // Sets "fileName_"
151    set_short_name();
152
153 #if 0
154    // Let's try delayed parsing, shall we?
155
156    const pdvector<image_func *> &exportedFuncs = image_->getExportedFunctions();
157    //fprintf(stderr, "%d exported functions\n", exportedFuncs.size());
158     for (unsigned fi = 0; fi < exportedFuncs.size(); fi++) {
159         addFunction(exportedFuncs[fi]);
160     }
161     const pdvector<image_variable *> &exportedVars = image_->getExportedVariables();
162     //fprintf(stderr, "%d exported variables\n", exportedVars.size());
163     for (unsigned vi = 0; vi < exportedVars.size(); vi++) {
164         addVariable(exportedVars[vi]);
165
166     }
167 #endif
168 }
169
170 mapped_object *mapped_object::createMappedObject(fileDescriptor &desc,
171       AddressSpace *p,
172       bool parseGaps) 
173 {
174
175    if (!p) return NULL;
176
177    startup_printf("%s[%d]:  about to parseImage\n", FILE__, __LINE__);
178    startup_printf("%s[%d]: name %s, codeBase 0x%lx, dataBase 0x%lx\n",
179                   FILE__, __LINE__, desc.file().c_str(), desc.code(), desc.data());
180    image *img = image::parseImage(desc, parseGaps);
181    if (!img)  {
182       startup_printf("%s[%d]:  failed to parseImage\n", FILE__, __LINE__);
183       return NULL;
184    }
185
186 #if defined(os_linux) && defined(arch_x86_64)
187    //Our x86_64 is actually reporting negative load addresses.  Go fig.
188    // On Linux/x86_64 with 32-bit mutatees this causes problems because we
189    // treat the load address as a unsigned 64 bit integer, and things don't
190    // correctly wrap.
191    //
192    // We'll detect this by noticing that the dynamic entry doesn't match up
193    // and then correct.
194    if (desc.dynamic() &&
195        p->getAddressWidth() == 4 && 
196        img->getObject()->getElfDynamicOffset() + desc.code() != desc.dynamic())
197    {
198       Address new_load_addr;
199       new_load_addr = desc.dynamic() - img->getObject()->getElfDynamicOffset();
200       startup_printf("[%s:%u] - Incorrect binary load address %lx, changing " 
201               "to %lx\n", FILE__, __LINE__, (unsigned long) desc.code(), 
202               (unsigned long) new_load_addr);
203       desc.setCode(new_load_addr);
204       desc.setData(new_load_addr);
205    }
206 #endif
207    if (!desc.isSharedObject()) {
208       //We've seen a case where the a.out is a shared object (RHEL4's
209       // version of ssh).  Check if the shared object flag is set in the
210       // binary (which is different from the isSharedObject()) call above.
211       // If so, we need to update the load address.
212       if (p->proc() &&
213             (img->getObject()->getObjectType() == obj_SharedLib)) {
214          //Executable is a shared lib
215          p->proc()->setAOutLoadAddress(desc);
216       }
217       // Search for main, if we can't find it, and we're creating the process, 
218       // and not attaching to it, we can find it by instrumenting libc.so
219       // Currently this has only been implemented for linux 
220 #if defined(os_linux)
221       // More specifically, x86 and x86_64 linux
222 #if defined(arch_x86) || defined(arch_x86_64)
223
224       vector <Function *> main;
225       if (p->proc() && 
226           (p->proc()->getTraceState() == noTracing_ts) &&
227           !p->proc()->wasCreatedViaAttach() &&
228           (!img->getObject()->findFunctionsByName(main,"main") &&
229            !img->getObject()->findFunctionsByName(main,"_main"))) {
230           fprintf(stderr, "[%s][%d] Module: %s in process %d:\n"
231                "\t  is not a shared object so it should contain a symbol for \n"
232                "\t  function main. Initial attempt to locate main failed,\n"
233                "\t  possibly due to the lack of a .text section\n",
234                __FILE__,__LINE__,desc.file().c_str(), p->proc()->getPid());
235          p->proc()->setTraceSysCalls(true);
236          p->proc()->setTraceState(libcOpenCall_ts);
237       }
238
239 #endif // arch_x86 || arch_x86_64
240 #endif // os_linux
241    }
242
243    // Adds exported functions and variables..
244    startup_printf("%s[%d]:  creating mapped object\n", FILE__, __LINE__);
245    mapped_object *obj = new mapped_object(desc, img, p);
246    startup_printf("%s[%d]:  leaving createMappedObject(%s)\n", FILE__, __LINE__, desc.file().c_str());
247
248    return obj;
249 }
250
251 mapped_object::mapped_object(const mapped_object *s, process *child) :
252    codeRange(),
253    desc_(s->desc_),
254    fullName_(s->fullName_),
255    fileName_(s->fileName_),
256    codeBase_(s->codeBase_),
257    dataBase_(s->dataBase_),
258    everyUniqueFunction(imgFuncHash),
259    everyUniqueVariable(imgVarHash),
260    allFunctionsByMangledName(::Dyninst::stringhash),
261    allFunctionsByPrettyName(::Dyninst::stringhash),
262    allVarsByMangledName(::Dyninst::stringhash),
263    allVarsByPrettyName(::Dyninst::stringhash),
264    dirty_(s->dirty_),
265    dirtyCalled_(s->dirtyCalled_),
266    image_(s->image_),
267    dlopenUsed(s->dlopenUsed),
268    proc_(child),
269    analyzed_(s->analyzed_)
270 {
271    // Let's do modules
272    for (unsigned k = 0; k < s->everyModule.size(); k++) {
273       // Doesn't copy things like line info. Ah, well.
274       mapped_module *parMod = s->everyModule[k];
275       mapped_module *mod = mapped_module::createMappedModule(this, parMod->pmod());
276       assert(mod);
277       everyModule.push_back(mod);
278    }
279
280    const pdvector<int_function *> parFuncs = s->everyUniqueFunction.values();
281    for (unsigned i = 0; i < parFuncs.size(); i++) {
282       int_function *parFunc = parFuncs[i];
283       assert(parFunc->mod());
284       mapped_module *mod = getOrCreateForkedModule(parFunc->mod());
285       int_function *newFunc = new int_function(parFunc,
286             mod,
287             child);
288       addFunction(newFunc);
289    }
290
291    const pdvector<int_variable *> parVars = s->everyUniqueVariable.values();
292    for (unsigned j = 0; j < parVars.size(); j++) {
293       int_variable *parVar = parVars[j];
294       assert(parVar->mod());
295       mapped_module *mod = getOrCreateForkedModule(parVar->mod());
296       int_variable *newVar = new int_variable(parVar,
297             mod);
298       addVariable(newVar);
299    }
300
301    image_ = s->image_->clone();
302 }
303
304
305 mapped_object::~mapped_object() 
306 {
307    // desc_ is static
308    // fullName_ is static
309    // fileName_ is static
310    // codeBase_ is static
311    // dataBase_ is static
312
313    for (unsigned i = 0; i < everyModule.size(); i++)
314       delete everyModule[i];
315    everyModule.clear();    
316
317    pdvector<int_function *> funcs = everyUniqueFunction.values();
318    for (unsigned j = 0; j < funcs.size(); j++) {
319       delete funcs[j];
320    }
321    everyUniqueFunction.clear();
322
323    pdvector<int_variable *> vars = everyUniqueVariable.values();
324    for (unsigned k = 0; k < vars.size(); k++) {
325       delete vars[k];
326    }
327    everyUniqueVariable.clear();
328
329    pdvector<pdvector<int_function *> * > mangledFuncs = allFunctionsByMangledName.values();
330    for (unsigned i = 0; i < mangledFuncs.size(); i++) {
331       delete mangledFuncs[i];
332    }
333    allFunctionsByMangledName.clear();
334
335    pdvector<pdvector<int_function *> * > prettyFuncs = allFunctionsByPrettyName.values();
336    for (unsigned i = 0; i < prettyFuncs.size(); i++) {
337       delete prettyFuncs[i];
338    }
339    allFunctionsByPrettyName.clear();
340
341    pdvector<pdvector<int_variable *> * > mV = allVarsByMangledName.values();
342    for (unsigned i = 0; i < mV.size(); i++) {
343       delete mV[i];
344    }
345    allVarsByMangledName.clear();
346
347    pdvector<pdvector<int_variable *> * > pV = allVarsByPrettyName.values();
348    for (unsigned i = 0; i < pV.size(); i++) {
349       delete pV[i];
350    }
351    allVarsByPrettyName.clear();
352
353    // codeRangesByAddr_ is static
354     // Remainder are static
355    image::removeImage(image_);
356 }
357
358 bool mapped_object::analyze() 
359 {
360     if (analyzed_) return true;
361   // Create a process-specific version of the image; all functions and
362   // variables at an absolute address (and modifiable).
363   
364   // At some point, we should do better handling of base
365   // addresses. Right now we assume we have one per mapped object; AIX
366   // is a special case with two (one for functions, one for
367   // variables).
368   
369   if (!image_) return false;
370
371   image_->analyzeIfNeeded();
372
373   analyzed_ = true;
374
375   // We already have exported ones. Force analysis (if needed) and get
376   // the functions we created via analysis.
377   pdvector<image_func *> unmappedFuncs = image_->getCreatedFunctions();
378   // For each function, we want to add our base address
379   for (unsigned fi = 0; fi < unmappedFuncs.size(); fi++) {
380       findFunction(unmappedFuncs[fi]);
381   }
382   
383   // Remember: variables don't.
384   pdvector<image_variable *> unmappedVars = image_->getCreatedVariables();
385   for (unsigned vi = 0; vi < unmappedVars.size(); vi++) {
386       findVariable(unmappedVars[vi]);
387   }
388   return true;
389 }
390
391 /* In the event that new functions are discovered after the analysis
392  * phase, we need to trigger analysis and enter it into the
393  * appropriate datastructures.
394  */
395 bool mapped_object::analyzeNewFunctions(vector<image_func *> *funcs)
396 {
397     if (!funcs || !funcs->size()) {
398         return false;
399     }
400
401     vector<image_func *>::iterator curfunc = funcs->begin();
402     while (curfunc != funcs->end()) {
403         if (everyUniqueFunction.defines(*curfunc)) {
404             curfunc = funcs->erase(curfunc);
405         } else {
406             // do control-flow traversal parsing starting from this function
407             if((*curfunc)->parse()) {
408                 parse_img()->recordFunction(*curfunc);
409             } // FIXME else?
410
411             curfunc++;
412         }
413     }
414     if (! funcs->size()) {
415         return true;
416     }
417
418     // add the functions we created to our datastructures
419     pdvector<image_func *> newFuncs = parse_img()->getCreatedFunctions();
420     for (unsigned i=0; i < newFuncs.size(); i++) {
421         image_func *curFunc = newFuncs[i];
422         if ( ! everyUniqueFunction.defines(curFunc) ) { 
423             curFunc->checkCallPoints();
424             // add function to datastructures
425             findFunction(curFunc);
426         }
427     }
428     return true;
429 }
430
431 // TODO: this should probably not be a mapped_object method, but since
432 // for now it is only used by mapped_objects it is
433 // from a string that is a complete path name to a function in a module
434 // (ie. "/usr/lib/libc.so.1/write") return a string with the function
435 // part removed.  return 0 on error
436 char *mapped_object::getModulePart(std::string &full_path_name) {
437     
438     char *whole_name = P_strdup(full_path_name.c_str());
439     char *next=0;
440     char *last=next;
441     if((last = P_strrchr(whole_name, '/'))){
442         next = whole_name;
443         for(u_int i=0;(next!=last)&&(i<full_path_name.length()); i++){
444             next++;
445             if(next == last){
446                 u_int size = i+2;
447                 char *temp_str = new char[size];
448                 if(P_strncpy(temp_str,whole_name,size-1)){
449                     temp_str[size-1] = '\0';
450                     delete whole_name;
451                     return temp_str;
452                     temp_str = 0;
453                 } 
454             }
455         }
456     }
457     delete whole_name;
458     return 0;
459 }
460
461 mapped_module *mapped_object::findModule(string m_name, bool wildcard)
462 {
463    parsing_printf("findModule for %s (substr match %d)\n",
464          m_name.c_str(), wildcard);
465    std::string tmp = m_name.c_str();      
466    for (unsigned i = 0; i < everyModule.size(); i++) {
467       if (everyModule[i]->fileName() == m_name ||
468             everyModule[i]->fullName() == m_name ||
469             (wildcard &&
470              (wildcardEquiv(tmp, everyModule[i]->fileName()) ||
471               wildcardEquiv(tmp, everyModule[i]->fullName())))) {
472          //parsing_printf("... found!\n");
473          return everyModule[i];
474       }
475    }
476    // Create a new one IF there's one in the child pd_module
477
478    pdmodule *pdmod = image_->findModule(m_name, wildcard);
479    if (pdmod) {
480       mapped_module *mod = mapped_module::createMappedModule(this,
481             pdmod);
482       everyModule.push_back(mod);
483       //parsing_printf("... made new module!\n");
484       return mod;
485    }
486    else {
487       //parsing_printf("... error, no module found...\n");
488       return NULL;
489    }
490 }
491
492
493 mapped_module *mapped_object::findModule(pdmodule *pdmod) 
494 {
495    if (!pdmod) {
496       fprintf(stderr, "%s[%d]:  please call this findModule with nonNULL parameter\n", FILE__, __LINE__);
497       return NULL;
498    }
499
500    assert(pdmod);
501
502    if (pdmod->imExec() != parse_img()) {
503       fprintf(stderr, "%s[%d]: WARNING: lookup for module in wrong mapped object! %p != %p\n", FILE__, __LINE__, pdmod->imExec(), parse_img()); 
504       fprintf(stderr, "%s[%d]:  \t\t %s \n", FILE__, __LINE__, parse_img()->name().c_str());
505       fprintf(stderr, "%s[%d]:  \t %s != \n", FILE__, __LINE__, pdmod->imExec()->name().c_str());
506       return NULL;
507    }
508
509    //parsing_printf("findModule for pdmod %s\n",
510    //pdmod->fullName().c_str());
511
512    for (unsigned i = 0; i < everyModule.size(); i++) {
513       if (everyModule[i]->pmod() == pdmod) {
514          //parsing_printf("... found at index %d\n", i);
515          return everyModule[i];
516       }
517    }
518
519    mapped_module *mod = mapped_module::createMappedModule(this,
520          pdmod);
521    if (mod) {
522       //parsing_printf("... created new module\n");
523       everyModule.push_back(mod);
524       return mod;
525    }
526    else
527       return NULL;
528 }
529
530 // fill in "short_name" data member.  Use last component of "name" data
531 // member with FS_FIELD_SEPERATOR ("/") as field seperator....
532 void mapped_object::set_short_name() {
533    const char *name_string = fullName_.c_str();
534    const char *ptr = strrchr(name_string, FS_FIELD_SEPERATOR);
535    if (ptr != NULL) {
536       fileName_ = ptr+1;
537    } else {
538       fileName_ = fullName_;
539    }
540 }
541
542 const pdvector<int_function *> *mapped_object::findFuncVectorByPretty(const std::string &funcname)
543 {
544    if (funcname.c_str() == 0) return NULL;
545    // First, check the underlying image.
546    const pdvector<image_func *> *img_funcs = parse_img()->findFuncVectorByPretty(funcname);
547    if (img_funcs == NULL) {
548       return NULL;
549    }
550
551    assert(img_funcs->size());
552    // Fast path:
553    if (allFunctionsByPrettyName.defines(funcname)) {
554       // Okay, we've pulled in some of the functions before (this can happen as a
555       // side effect of adding functions). But did we get them all?
556        pdvector<int_function *> *map_funcs = allFunctionsByPrettyName[funcname];
557        if (map_funcs->size() == img_funcs->size()) {
558            // We're allocating at the lower level....
559            delete img_funcs;
560            return map_funcs;
561        }
562    }
563    
564    // Slow path: check each img_func, add those we don't already have, and return.
565    for (unsigned i = 0; i < img_funcs->size(); i++) {
566        image_func *func = (*img_funcs)[i];
567        if (!everyUniqueFunction.defines(func)) {
568            findFunction(func);
569        }
570        assert(everyUniqueFunction[func]);
571    }
572    delete img_funcs;
573    return allFunctionsByPrettyName[funcname];
574
575
576 const pdvector <int_function *> *mapped_object::findFuncVectorByMangled(const std::string &funcname)
577 {
578     if (funcname.c_str() == 0) return NULL;
579     
580     // First, check the underlying image.
581     const pdvector<image_func *> *img_funcs = parse_img()->findFuncVectorByMangled(funcname);
582     if (img_funcs == NULL) return NULL;
583     
584     assert(img_funcs->size());
585     // Fast path:
586     if (allFunctionsByMangledName.defines(funcname)) {
587         // Okay, we've pulled in some of the functions before (this can happen as a
588         // side effect of adding functions). But did we get them all?
589         pdvector<int_function *> *map_funcs = allFunctionsByMangledName[funcname];
590         if (map_funcs->size() == img_funcs->size())
591             // We're allocating at the lower level...
592             delete img_funcs;
593             return map_funcs;
594     }
595     
596     // Slow path: check each img_func, add those we don't already have, and return.
597     for (unsigned i = 0; i < img_funcs->size(); i++) {
598         image_func *func = (*img_funcs)[i];
599         if (!everyUniqueFunction.defines(func)) {
600             findFunction(func);
601         }
602         assert(everyUniqueFunction[func]);
603     }
604     delete img_funcs;
605     return allFunctionsByMangledName[funcname];
606
607
608
609 const pdvector<int_variable *> *mapped_object::findVarVectorByPretty(const std::string &varname)
610 {
611     if (varname.c_str() == 0) return NULL;
612     
613     // First, check the underlying image.
614     const pdvector<image_variable *> *img_vars = parse_img()->findVarVectorByPretty(varname);
615     if (img_vars == NULL) return NULL;
616     
617     assert(img_vars->size());
618     // Fast path:
619     if (allVarsByPrettyName.defines(varname)) {
620         // Okay, we've pulled in some of the variabletions before (this can happen as a
621         // side effect of adding variabletions). But did we get them all?
622         pdvector<int_variable *> *map_variables = allVarsByPrettyName[varname];
623         if (map_variables->size() == img_vars->size()) {
624             delete img_vars;
625             return map_variables;
626         }
627     }
628     
629     // Slow path: check each img_variable, add those we don't already have, and return.
630     for (unsigned i = 0; i < img_vars->size(); i++) {
631         image_variable *var = (*img_vars)[i];
632         if (!everyUniqueVariable.defines(var)) {
633             findVariable(var);
634         }
635         assert(everyUniqueVariable[var]);
636     }
637     delete img_vars;
638     return allVarsByPrettyName[varname];
639
640
641 const pdvector <int_variable *> *mapped_object::findVarVectorByMangled(const std::string &varname)
642 {
643   if (varname.c_str() == 0) return NULL;
644
645   // First, check the underlying image.
646   const pdvector<image_variable *> *img_vars = parse_img()->findVarVectorByMangled(varname);
647   if (img_vars == NULL) return NULL;
648
649   assert(img_vars->size());
650   // Fast path:
651   if (allVarsByMangledName.defines(varname)) {
652       // Okay, we've pulled in some of the variabletions before (this can happen as a
653       // side effect of adding variabletions). But did we get them all?
654       pdvector<int_variable *> *map_variables = allVarsByMangledName[varname];
655       if (map_variables->size() == img_vars->size()) {
656           delete img_vars;
657           return map_variables;
658       }
659   }
660
661   // Slow path: check each img_variable, add those we don't already have, and return.
662   for (unsigned i = 0; i < img_vars->size(); i++) {
663       image_variable *var = (*img_vars)[i];
664       if (!everyUniqueVariable.defines(var)) {
665           findVariable(var);
666       }
667       assert(everyUniqueVariable[var]);
668   }
669   delete img_vars;
670   return allVarsByMangledName[varname];
671
672
673 //Returns one variable, doesn't search other mapped_objects.  Use carefully.
674 const int_variable *mapped_object::getVariable(const std::string &varname) {
675     const pdvector<int_variable *> *vars = NULL; 
676     vars = findVarVectorByPretty(varname);
677     if (!vars) vars = findVarVectorByMangled(varname);
678     if (vars) {
679         assert(vars->size() > 0);
680         return (*vars)[0];
681     }
682     return NULL;
683 }
684
685 codeRange *mapped_object::findCodeRangeByAddress(const Address &addr)  {
686     // Quick bounds check...
687     if (addr < codeAbs()) { 
688         return NULL; 
689     }
690     if (addr >= (codeAbs() + imageSize())) {
691         return NULL;
692     }
693
694     codeRange *range;
695     if (codeRangesByAddr_.find(addr, range)) {
696         return range;
697     }
698
699     // Duck into the image class to see if anything matches
700     codeRange *img_range = parse_img()->findCodeRangeByOffset(addr - codeBase());
701     if (!img_range)
702         return NULL;
703
704     if (img_range->is_image_func()) {
705         image_func *img_func = img_range->is_image_func();
706         int_function *func = findFunction(img_func);
707         assert(func);
708         func->blocks(); // Adds to codeRangesByAddr_...
709         // And repeat...
710         bool res = codeRangesByAddr_.find(addr, range);
711         
712         if (!res) {
713             // Possible: we do a basic-block level search at this point, and a gap (or non-symtab parsing)
714             // may skip an address.
715             return NULL;
716         }
717         return range;
718     }
719     else {
720         fprintf(stderr, "ERROR: unknown lookup type at %s/%d, findCodeRange(0x%lx)\n",
721                 __FILE__, __LINE__, addr);
722     }
723     return NULL;
724 }
725
726 int_function *mapped_object::findFuncByAddr(const Address &addr) {
727     codeRange *range = findCodeRangeByAddress(addr);
728     if (!range) return NULL;
729     return range->is_function();
730 }
731
732 const pdvector<mapped_module *> &mapped_object::getModules() {
733     // everyModule may be out of date...
734     std::vector<pdmodule *> pdmods;
735     parse_img()->getModules(pdmods);
736     if (everyModule.size() == pdmods.size())
737         return everyModule;
738     for (unsigned i = 0; i < pdmods.size(); i++) {
739         findModule(pdmods[i]);
740     }
741     
742     return everyModule;
743 }
744
745 bool mapped_object::getAllFunctions(pdvector<int_function *> &funcs) {
746     unsigned start = funcs.size();
747
748     const set<image_func *,image_func::compare> &img_funcs = 
749         parse_img()->getAllFunctions();
750     set<image_func *,image_func::compare>::const_iterator fit = 
751         img_funcs.begin();
752     for( ; fit != img_funcs.end(); ++fit) {
753         if(!everyUniqueFunction.defines(*fit)) {
754             findFunction(*fit);
755         }
756         funcs.push_back(everyUniqueFunction[*fit]);
757     }
758     return funcs.size() > start;
759 }
760
761 bool mapped_object::getAllVariables(pdvector<int_variable *> &vars) {
762     unsigned start = vars.size();
763
764     const pdvector<image_variable *> &img_vars = parse_img()->getAllVariables();
765     
766     for (unsigned i = 0; i < img_vars.size(); i++) {
767         if (!everyUniqueVariable.defines(img_vars[i])) {
768             findVariable(img_vars[i]);
769         }
770         vars.push_back(everyUniqueVariable[img_vars[i]]);
771     }
772     return vars.size() > start;
773 }
774
775 // Enter a function in all the appropriate tables
776 int_function *mapped_object::findFunction(image_func *img_func) {
777     if (!img_func) {
778         fprintf(stderr, "Warning: findFunction with null img_func\n");
779         return NULL;
780     }
781     assert(img_func->getSymtabFunction());
782
783     mapped_module *mod = findModule(img_func->pdmod());
784     if (!mod) {
785         fprintf(stderr, "%s[%d]: ERROR: cannot find module %p\n", FILE__, __LINE__, img_func->pdmod());
786         fprintf(stderr, "%s[%d]:  ERROR:  Cannot find module %s\n", FILE__, __LINE__, img_func->pdmod()->fileName().c_str());
787     }
788     assert(mod);
789     
790
791     if (everyUniqueFunction.defines(img_func)) {
792         return everyUniqueFunction[img_func];
793     }
794
795     int_function *func = new int_function(img_func, 
796                                           codeBase_,
797                                           mod);
798     addFunction(func);
799     return func;
800 }
801
802 void mapped_object::addFunctionName(int_function *func,
803                                     const std::string newName,
804                                     nameType_t nameType) {
805     // DEBUG
806     pdvector<int_function *> *funcsByName = NULL;
807     
808     if (nameType & mangledName) {
809         if (!allFunctionsByMangledName.find(newName,
810                                             funcsByName)) {
811             funcsByName = new pdvector<int_function *>;
812             allFunctionsByMangledName[newName] = funcsByName;
813         }
814     }
815     if (nameType & prettyName) {
816         if (!allFunctionsByPrettyName.find(newName,
817                                            funcsByName)) {
818             funcsByName = new pdvector<int_function *>;
819             allFunctionsByPrettyName[newName] = funcsByName;
820         }
821     }
822     if (nameType & typedName) {
823         return; 
824         /*
825           // TODO add?
826         if (!allFunctionsByPrettyName.find(newName,
827                                            funcsByName)) {
828             funcsByName = new pdvector<int_function *>;
829             allFunctionsByPrettyName[newName] = funcsByName;
830         }
831         */
832     }
833
834     assert(funcsByName != NULL);
835     funcsByName->push_back(func);
836 }
837     
838
839 void mapped_object::addFunction(int_function *func) {
840     /*
841     fprintf(stderr, "Adding function %s/%p: %d mangled, %d pretty, %d typed names\n",
842             func->symTabName().c_str(),
843             func,
844             func->symTabNameVector().size(),
845             func->prettyNameVector().size(),
846             func->typedNameVector().size());
847     */
848
849     // Possibly multiple demangled (pretty) names...
850     // And multiple functions (different addr) with the same pretty
851     // name. So we have a many::many mapping...
852     for (unsigned pretty_iter = 0; 
853          pretty_iter < func->prettyNameVector().size();
854          pretty_iter++) {
855         string pretty_name = func->prettyNameVector()[pretty_iter];
856         addFunctionName(func, pretty_name.c_str(), prettyName);
857     }
858
859     for (unsigned typed_iter = 0; 
860          typed_iter < func->typedNameVector().size();
861          typed_iter++) {
862         string typed_name = func->typedNameVector()[typed_iter];
863         addFunctionName(func, typed_name.c_str(), typedName);
864     }
865     
866     // And multiple symtab names...
867     for (unsigned symtab_iter = 0; 
868          symtab_iter < func->symTabNameVector().size();
869          symtab_iter++) {
870         string symtab_name = func->symTabNameVector()[symtab_iter];
871         addFunctionName(func, symtab_name.c_str(), mangledName);
872     }  
873     everyUniqueFunction[func->ifunc()] = func;
874     func->mod()->addFunction(func);
875 }  
876
877 // Enter a function in all the appropriate tables
878 int_variable *mapped_object::findVariable(image_variable *img_var) {
879     if (!img_var) return NULL;
880     
881     if (everyUniqueVariable.defines(img_var))
882         return everyUniqueVariable[img_var];
883     
884     mapped_module *mod = findModule(img_var->pdmod());
885     assert(mod);
886     
887     int_variable *var = new int_variable(img_var,
888                                          dataBase_,
889                                          mod);
890
891     addVariable(var);
892     return var;
893 }
894
895  void mapped_object::addVariable(int_variable *var) { 
896     
897     // Possibly multiple demangled (pretty) names...
898     // And multiple functions (different addr) with the same pretty
899     // name. So we have a many::many mapping...
900     for (unsigned pretty_iter = 0; 
901          pretty_iter < var->prettyNameVector().size();
902          pretty_iter++) {
903         string pretty_name = var->prettyNameVector()[pretty_iter];
904         pdvector<int_variable *> *varsByPrettyEntry = NULL;
905         
906         // Ensure a vector exists
907         if (!allVarsByPrettyName.find(pretty_name.c_str(),  
908                                       varsByPrettyEntry)) {
909             varsByPrettyEntry = new pdvector<int_variable *>;
910             allVarsByPrettyName[pretty_name.c_str()] = varsByPrettyEntry;
911         }
912         
913         (*varsByPrettyEntry).push_back(var);
914     }
915     
916     // And multiple symtab names...
917     for (unsigned symtab_iter = 0; 
918          symtab_iter < var->symTabNameVector().size();
919          symtab_iter++) {
920         string symtab_name = var->symTabNameVector()[symtab_iter];
921         pdvector<int_variable *> *varsBySymTabEntry = NULL;
922         
923         // Ensure a vector exists
924         if (!allVarsByMangledName.find(symtab_name.c_str(),  
925                                        varsBySymTabEntry)) {
926             varsBySymTabEntry = new pdvector<int_variable *>;
927             allVarsByMangledName[symtab_name.c_str()] = varsBySymTabEntry;
928         }
929         
930         (*varsBySymTabEntry).push_back(var);
931     }  
932     
933     everyUniqueVariable[var->ivar()] = var;
934     
935     var->mod()->addVariable(var);
936 }  
937
938 /////////// Dinky functions
939
940 // This way we don't have to cross-include every header file in the
941 // world.
942
943 AddressSpace *mapped_object::proc() const { return proc_; }
944
945 bool mapped_object::isSharedLib() const 
946 {
947     return parse_img()->isSharedObj();
948     // HELL NO
949     //return desc_.isSharedObject();
950 }
951
952 const std::string mapped_object::debugString() const 
953 {
954     std::string debug;
955     debug = std::string(fileName_.c_str()) + ":" 
956        + utos(codeBase_) 
957        + "/" + utos(imageSize()); 
958     return debug;
959 }
960
961 // This gets called once per image. Poke through to the internals;
962 // all we care about, amusingly, is symbol table information. 
963
964 void mapped_object::getInferiorHeaps(vector<pair<string, Address> > &foundHeaps)
965 {
966     vector<pair<string, Address> > code_heaps;
967     vector<pair<string, Address> > data_heaps;
968
969     if (!parse_img()->getInferiorHeaps(code_heaps, data_heaps)) {
970 #if !defined(os_aix)
971         // AIX: see auxiliary lookup, below.
972         return;
973 #endif
974     }
975
976
977     // We have a bunch of offsets, now add in the base addresses
978     for (unsigned i = 0; i < code_heaps.size(); i++) {
979         foundHeaps.push_back(pair<string,Address>(code_heaps[i].first,
980                                                   code_heaps[i].second + codeBase()));
981     }
982     for (unsigned i = 0; i < data_heaps.size(); i++) {
983         foundHeaps.push_back(pair<string,Address>(data_heaps[i].first,
984                                                   data_heaps[i].second + dataBase()));
985     }
986     
987     // AIX: we scavenge space. Do that here.
988     
989 #if defined(os_aix)
990     // ...
991     
992     // a.out: from the end of the loader to 0x20000000
993     // Anything in 0x2....: skip
994     // Anything in 0xd....: to the next page
995     
996     Address start = 0;
997     unsigned size = 0;
998     
999 #if 0
1000     fprintf(stderr, "Looking for inferior heap in %s/%s, codeAbs 0x%x (0x%x/0x%x)\n",
1001             getFileDesc().file().c_str(),
1002             getFileDesc().member().c_str(),
1003             codeAbs(),
1004             codeBase(),
1005             codeOffset());
1006 #endif
1007     
1008     if (codeAbs() >= 0xd0000000) {
1009         // This caused problems on sp3-01.cs.wisc.edu; apparently we were overwriting
1010         // necessary library information. For now I'm disabling it (10FEB06) until
1011         // we can get a better idea of what was going on.
1012 #if 0
1013         start = codeAbs() + imageSize();
1014         start += instruction::size() - (start % (Address)instruction::size());
1015         size = PAGESIZE - (start % PAGESIZE);
1016 #endif
1017     }
1018     else if (codeAbs() > 0x20000000) {
1019         // ...
1020     }
1021     else if (codeAbs() > 0x10000000) {
1022         // We also have the loader; there is no information on where
1023         // it goes (ARGH) so we pad the end of the code segment to
1024         // try and avoid it.
1025         
1026         Region *sec;
1027         image_->getObject()->findRegion(sec, ".loader");
1028         Address loader_end = codeAbs() + 
1029             //sec.getSecAddr() +
1030             image_->getObject()->getLoadOffset() +
1031             sec->getDiskSize();
1032         //Address loader_end = codeAbs() + 
1033         //    image_->getObject()->loader_off() +
1034         //    image_->getObject()->loader_len();
1035         // If we loaded it up in the data segment, don't use...
1036         if (loader_end > 0x20000000)
1037             loader_end = 0;
1038         Address code_end = codeAbs() + imageSize();
1039         
1040         start = (loader_end > code_end) ? loader_end : code_end;
1041         
1042         start += instruction::size() - (start % (Address)instruction::size());
1043         size = (0x20000000 - start);
1044     }
1045     
1046     
1047     if (start) {
1048         char name_scratch[1024];
1049         snprintf(name_scratch, 1023,
1050                  "DYNINSTstaticHeap_%i_uncopiedHeap_0x%lx_scratchpage_%s",
1051                  (unsigned) size,
1052                  start,
1053                  fileName().c_str());
1054
1055         foundHeaps.push_back(pair<string,Address>(string(name_scratch),start)); 
1056     }
1057 #endif
1058 }
1059     
1060
1061 void *mapped_object::getPtrToInstruction(Address addr) const 
1062 {
1063    if (addr < codeAbs()) {
1064        return NULL;
1065    }
1066    if (addr >= (codeAbs() + imageSize())) {
1067        return NULL;
1068    }
1069
1070    // Only subtract off the codeBase, not the codeBase plus
1071    // codeOffset -- the image class includes the codeOffset.
1072    Address offset = addr - codeBase();
1073    return image_->getPtrToInstruction(offset);
1074 }
1075
1076 void *mapped_object::getPtrToData(Address addr) const 
1077 {
1078    assert(addr >= dataAbs());
1079    assert(addr < (dataAbs() + dataSize()));
1080
1081    // Don't go from the code base... the image adds back in the code
1082    // offset.
1083    Address offset = addr - dataBase();
1084    return image_->getPtrToData(offset);
1085 }
1086
1087 // mapped objects may contain multiple Symtab::Regions, this function
1088 // should not be used, but must be included in the class because this
1089 // function is a subclass of codeRange
1090 void *mapped_object::get_local_ptr() const 
1091 {
1092     assert(0);// if you crash here, blame me. -kevin
1093     return NULL; 
1094     //   return image_->getObject()->image_ptr();
1095 }
1096
1097
1098 bool mapped_object::getSymbolInfo(const std::string &n, int_symbol &info) 
1099 {
1100     assert(image_);
1101
1102     Symbol *lowlevel_sym = image_->symbol_info(n);
1103     if (!lowlevel_sym) {
1104         lowlevel_sym = image_->symbol_info(std::string("_") + n);
1105     }
1106     
1107     if (!lowlevel_sym) return false;
1108     
1109     if (lowlevel_sym->getType() == Symbol::ST_OBJECT)
1110         info = int_symbol(lowlevel_sym, dataBase_);
1111     else
1112         info = int_symbol(lowlevel_sym, codeBase_);
1113     
1114     return true;
1115 }
1116
1117 mapped_module *mapped_object::getOrCreateForkedModule(mapped_module *parMod) 
1118 {
1119    // Okay. We're forking, and this is the child mapped_object.
1120    // And now, given a parent module, we need to find the right one
1121    // in our little baby modules.
1122
1123    // Since we've already copied modules, we can just do a name lookup.
1124    mapped_module *childModule = findModule(parMod->fileName(), false);
1125    assert(childModule);
1126    return childModule;
1127
1128 }
1129
1130 mapped_module* mapped_object::getDefaultModule()
1131 {
1132   mapped_module* ret = findModule("DEFAULT_MODULE");
1133   if(ret) return ret;
1134
1135   // Make sure the everyModule vector is initialized
1136   getModules();
1137   
1138   assert(everyModule.size() > 0);
1139   return everyModule[0];
1140   
1141 }