Build fixes for NewInstpoint merge on FreeBSD.
[dyninst.git] / dyninstAPI / src / mapped_object.C
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 // $Id: mapped_object.C,v 1.39 2008/09/03 06:08:44 jaw Exp $
33
34 #include <string>
35 #include <cctype>
36 #include <algorithm>
37
38 #include "dyninstAPI/src/mapped_object.h"
39 #include "dyninstAPI/src/mapped_module.h"
40 #include "dyninstAPI/src/symtab.h"
41 #include "dyninstAPI/src/function.h"
42 #include "dyninstAPI/src/debug.h"
43 #include "dyninstAPI/src/addressSpace.h"
44 #include "dyninstAPI/src/pcProcess.h"
45 #include "symtabAPI/h/Symtab.h"
46 #include "InstructionDecoder.h"
47 #include "Parsing.h"
48 #include "instPoint.h"
49 #include "MemoryEmulator/memEmulator.h"
50 #include <boost/tuple/tuple.hpp>
51
52 using namespace Dyninst;
53 using namespace Dyninst::ParseAPI;
54
55 #define FS_FIELD_SEPERATOR '/'
56
57 // Whee hasher...
58
59 unsigned imgFuncHash(const parse_func * const &func) {
60     return addrHash4((Address) func);
61 }
62 unsigned imgVarHash(const image_variable * const &func) 
63 {
64     return addrHash4((Address) func);
65 }
66
67 // triggered when parsing needs to check if the underlying data has changed
68 bool codeBytesUpdateCB(void *objCB, Address targ)
69 {
70     mapped_object *obj = (mapped_object*) objCB;
71     return obj->updateCodeBytesIfNeeded(targ);
72 }
73
74 mapped_object::mapped_object(fileDescriptor fileDesc,
75       image *img,
76       AddressSpace *proc,
77       BPatch_hybridMode mode):
78    desc_(fileDesc),
79    fullName_(img->getObject()->file()), 
80    everyUniqueVariable(imgVarHash),
81    allFunctionsByMangledName(::Dyninst::stringhash),
82    allFunctionsByPrettyName(::Dyninst::stringhash),
83    allVarsByMangledName(::Dyninst::stringhash),
84    allVarsByPrettyName(::Dyninst::stringhash),
85    dirty_(false),
86    dirtyCalled_(false),
87    image_(img),
88    dlopenUsed(false),
89    proc_(proc),
90    analyzed_(false),
91    analysisMode_(mode),
92    pagesUpdated_(true),
93    memEnd_(-1),
94    memoryImg_(false)
95
96    // Set occupied range (needs to be ranges)
97    codeBase_ = fileDesc.code();
98    dataBase_ = fileDesc.data();
99 #if defined(os_windows)
100    codeBase_ = fileDesc.loadAddr();
101    dataBase_ = fileDesc.loadAddr();
102 #endif
103 #if defined(os_aix)
104    // AIX defines "virtual" addresses for an a.out inside the file as
105    // well as when the system loads the object. As far as I can tell,
106    // this only happens for the a.out (for shobjs the file-addresses
107    // are 0).  The file-provided addresses are correct, but the
108    // OS-provided addresses are not. So if the file includes
109    // addresses, use those.  If it doesn't, all of the offsets are
110    // from a "section start" that isn't our start. Getting a headache
111    // yet? So _that_ needs to be adjusted. We've stored these values
112    // in the Object file. We could also adjust all addresses of
113    // symbols, but...
114    if (image_->imageOffset() >= codeBase_) {
115       codeBase_ = 0;
116    }
117    else if (image_->imageOffset() <= 0x1fffffff) {
118       // GCC-ism. This is a shared library with a a.out-like codeOffset.
119       // We need to make our base the difference between the two...
120       codeBase_ -= image_->imageOffset();
121       SymtabAPI::Region *sec;
122       image_->getObject()->findRegion(sec, ".text");
123       //fprintf(stderr, "codeBase 0x%x, rawPtr 0x%x, BaseOffset 0x%x, size %d\n",
124       //        codeBase_, (Address)sec->getPtrToRawData() , image_->getObject()->getBaseAddress());
125       codeBase_ += ((Address)sec->getPtrToRawData() - image_->getObject()->getBaseOffset());    
126       //      codeBase_ += image_->getObject()->text_reloc();
127    }
128    else {
129       // codeBase_ is the address that the chunk was loaded at; the actual interesting
130       // bits start within the chunk. So add in text_reloc (actually, "offset from start
131       // of file to interesting bits"). 
132       // Non-GCC shared libraries.
133       //codeBase_ += image_->getObject()->text_reloc();
134       SymtabAPI::Region *sec;
135       image_->getObject()->findRegion(sec, ".text");
136       //fprintf(stderr, "codeBase 0x%x, rawPtr 0x%x, BaseOffset 0x%x, size %d\n",
137       //        codeBase_, (Address)sec->getPtrToRawData() , image_->getObject()->getBaseOffset());
138       codeBase_ += ((Address)sec->getPtrToRawData()-image_->getObject()->getBaseOffset());
139    }
140    if (image_->dataOffset() >= dataBase_) {
141       dataBase_ = 0;
142    }
143    else if (image_->dataOffset() <= 0x2fffffff) {
144       // More GCC-isms. 
145       dataBase_ -= image_->dataOffset();
146    }
147    else {
148       // *laughs* You'd think this was the same way, right?
149       // Well, you're WRONG!
150       // For some reason we don't need to add in the data_reloc_...
151       //dataBase_ += image_->getObject()->data_reloc();
152    }
153 #endif
154
155 #if 0
156    fprintf(stderr, "Creating new mapped_object %s/%s\n",
157          fullName_.c_str(), getFileDesc().member().c_str());
158    fprintf(stderr, "codeBase 0x%x, codeOffset 0x%x, size %d\n",
159          codeBase_, image_->imageOffset(), image_->imageLength());
160    fprintf(stderr, "dataBase 0x%x, dataOffset 0x%x, size %d\n",
161          dataBase_, image_->dataOffset(), image_->dataLength());
162    fprintf(stderr, "fileDescriptor: code at 0x%x, data 0x%x\n",
163          fileDesc.code(), fileDesc.data());
164    fprintf(stderr, "Code: 0x%lx to 0x%lx\n",
165          codeAbs(), codeAbs() + imageSize());
166    fprintf(stderr, "Data: 0x%lx to 0x%lx\n",
167          dataAbs(), dataAbs() + dataSize());
168 #endif
169
170
171    // Sets "fileName_"
172    set_short_name();
173 }
174
175 mapped_object *mapped_object::createMappedObject(fileDescriptor &desc,
176       AddressSpace *p,
177       BPatch_hybridMode analysisMode, 
178       bool parseGaps) 
179 {
180    
181
182    if (!p) return NULL;
183
184    if ( BPatch_defensiveMode == analysisMode || 
185         ( desc.isSharedObject() && 
186           BPatch_defensiveMode == p->getAOut()->hybridMode() ) )
187    {
188        // parsing in the gaps in defensive mode is a bad idea because
189        // we mark all binary regions as possible code-containing areas
190        parseGaps = false;
191    }
192
193    startup_printf("%s[%d]:  about to parseImage\n", FILE__, __LINE__);
194    startup_printf("%s[%d]: name %s, codeBase 0x%lx, dataBase 0x%lx\n",
195                   FILE__, __LINE__, desc.file().c_str(), desc.code(), desc.data());
196    image *img = image::parseImage( desc, analysisMode, parseGaps );
197    if (!img)  {
198       startup_printf("%s[%d]:  failed to parseImage\n", FILE__, __LINE__);
199       return NULL;
200    }
201    if (img->isDyninstRTLib()) {
202        parseGaps = false;
203    }
204
205 #if defined(os_linux) && defined(arch_x86_64)
206    //Our x86_64 is actually reporting negative load addresses.  Go fig.
207    // On Linux/x86_64 with 32-bit mutatees this causes problems because we
208    // treat the load address as a unsigned 64 bit integer, and things don't
209    // correctly wrap.
210    //
211    // We'll detect this by noticing that the dynamic entry doesn't match up
212    // and then correct.
213    if (desc.dynamic() &&
214        p->getAddressWidth() == 4 && 
215        img->getObject()->getElfDynamicOffset() + desc.code() != desc.dynamic())
216    {
217       Address new_load_addr;
218       new_load_addr = desc.dynamic() - img->getObject()->getElfDynamicOffset();
219       startup_printf("[%s:%u] - Incorrect binary load address %lx, changing " 
220               "to %lx\n", FILE__, __LINE__, (unsigned long) desc.code(), 
221               (unsigned long) new_load_addr);
222       desc.setCode(new_load_addr);
223       desc.setData(new_load_addr);
224    }
225 #endif
226    if (!desc.isSharedObject()) {
227       //We've seen a case where the a.out is a shared object (RHEL4's
228       // version of ssh).  Check if the shared object flag is set in the
229       // binary (which is different from the isSharedObject()) call above.
230       // If so, we need to update the load address.
231       if (p->proc() &&
232             (img->getObject()->getObjectType() == SymtabAPI::obj_SharedLib)) {
233          //Executable is a shared lib
234          p->proc()->setAOutLoadAddress(desc);
235       }
236
237 // Used to search for main here and enable system call tracing to find out 
238 // when libc.so is loaded -- this is unnecessary now that we use ProcControlAPI
239 //
240 // This is now done on-demand when libc is loaded and main has yet to be found
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, analysisMode);
246    if (BPatch_defensiveMode == analysisMode) {
247        img->register_codeBytesUpdateCB(obj);
248    }
249    startup_printf("%s[%d]:  leaving createMappedObject(%s)\n", FILE__, __LINE__, desc.file().c_str());
250
251    return obj;
252 }
253
254 mapped_object::mapped_object(const mapped_object *s, AddressSpace *child) :
255    codeRange(),
256    desc_(s->desc_),
257    fullName_(s->fullName_),
258    fileName_(s->fileName_),
259    codeBase_(s->codeBase_),
260    dataBase_(s->dataBase_),
261    everyUniqueVariable(imgVarHash),
262    allFunctionsByMangledName(::Dyninst::stringhash),
263    allFunctionsByPrettyName(::Dyninst::stringhash),
264    allVarsByMangledName(::Dyninst::stringhash),
265    allVarsByPrettyName(::Dyninst::stringhash),
266    dirty_(s->dirty_),
267    dirtyCalled_(s->dirtyCalled_),
268    image_(s->image_),
269    dlopenUsed(s->dlopenUsed),
270    proc_(child),
271    analyzed_(s->analyzed_),
272    analysisMode_(s->analysisMode_),
273    pagesUpdated_(true),
274    memoryImg_(s->memoryImg_)
275 {
276    // Let's do modules
277    for (unsigned k = 0; k < s->everyModule.size(); k++) {
278       // Doesn't copy things like line info. Ah, well.
279       mapped_module *parMod = s->everyModule[k];
280       mapped_module *mod = mapped_module::createMappedModule(this, parMod->pmod());
281       assert(mod);
282       everyModule.push_back(mod);
283    }
284    
285    // Duplicate all copied blocks
286    for (BlockMap::const_iterator iter = s->blocks_.begin();
287         iter != s->blocks_.end(); ++iter) {
288       block_instance *newBlock = new block_instance(iter->second,
289                                                     this);
290                                                     
291       blocks_.insert(std::make_pair(iter->first, newBlock));
292    }
293
294    // And now edges
295    for (EdgeMap::const_iterator iter = s->edges_.begin();
296         iter != s->edges_.end(); ++iter) {
297       edge_instance *newEdge = new edge_instance(iter->second,
298                                                  this);
299       edges_.insert(std::make_pair(iter->first, newEdge));
300    }
301
302    // Aaand now functions
303    for (FuncMap::const_iterator iter = s->everyUniqueFunction.begin();
304        iter != s->everyUniqueFunction.end(); ++iter) {
305       func_instance *parFunc = iter->second;
306       assert(parFunc->mod());
307       mapped_module *mod = getOrCreateForkedModule(parFunc->mod());
308       func_instance *newFunc = new func_instance(parFunc,
309                                                  mod);
310       addFunction(newFunc); 
311    }
312
313    const pdvector<int_variable *> parVars = s->everyUniqueVariable.values();
314    for (unsigned j = 0; j < parVars.size(); j++) {
315       int_variable *parVar = parVars[j];
316       assert(parVar->mod());
317       mapped_module *mod = getOrCreateForkedModule(parVar->mod());
318       int_variable *newVar = new int_variable(parVar,
319             mod);
320       addVariable(newVar);
321    }
322
323    assert(BPatch_defensiveMode != analysisMode_);
324
325    image_ = s->image_->clone();
326 }
327
328
329 mapped_object::~mapped_object() 
330 {
331    // desc_ is static
332    // fullName_ is static
333    // fileName_ is static
334    // codeBase_ is static
335    // dataBase_ is static
336
337    for (unsigned i = 0; i < everyModule.size(); i++)
338       delete everyModule[i];
339    everyModule.clear();    
340
341    for (BlockMap::iterator iter = blocks_.begin(); iter != blocks_.end(); ++iter) {
342       delete iter->second;
343    }
344    blocks_.clear();
345
346    for (EdgeMap::iterator iter = edges_.begin(); iter != edges_.end(); ++iter) { 
347       delete iter->second;
348    }
349    edges_.clear();
350    
351    for (FuncMap::iterator iter = everyUniqueFunction.begin(); iter != everyUniqueFunction.end(); ++iter) {
352        delete iter->second;
353    }
354    everyUniqueFunction.clear();
355
356    pdvector<int_variable *> vars = everyUniqueVariable.values();
357    for (unsigned k = 0; k < vars.size(); k++) {
358       delete vars[k];
359    }
360    everyUniqueVariable.clear();
361
362    pdvector<pdvector<func_instance *> * > mangledFuncs = allFunctionsByMangledName.values();
363    for (unsigned i = 0; i < mangledFuncs.size(); i++) {
364       delete mangledFuncs[i];
365    }
366    allFunctionsByMangledName.clear();
367
368    pdvector<pdvector<func_instance *> * > prettyFuncs = allFunctionsByPrettyName.values();
369    for (unsigned i = 0; i < prettyFuncs.size(); i++) {
370       delete prettyFuncs[i];
371    }
372    allFunctionsByPrettyName.clear();
373
374    pdvector<pdvector<int_variable *> * > mV = allVarsByMangledName.values();
375    for (unsigned i = 0; i < mV.size(); i++) {
376       delete mV[i];
377    }
378    allVarsByMangledName.clear();
379
380    pdvector<pdvector<int_variable *> * > pV = allVarsByPrettyName.values();
381    for (unsigned i = 0; i < pV.size(); i++) {
382       delete pV[i];
383    }
384    allVarsByPrettyName.clear();
385
386    // codeRangesByAddr_ is static
387     // Remainder are static
388    image::removeImage(image_);
389 }
390
391 bool mapped_object::analyze() 
392 {
393     if (analyzed_) return true;
394   // Create a process-specific version of the image; all functions and
395   // variables at an absolute address (and modifiable).
396   
397   // At some point, we should do better handling of base
398   // addresses. Right now we assume we have one per mapped object; AIX
399   // is a special case with two (one for functions, one for
400   // variables).
401   
402   if (!image_) return false;
403
404   image_->analyzeIfNeeded();
405
406   analyzed_ = true;
407
408   // We already have exported ones. Force analysis (if needed) and get
409   // the functions we created via analysis.
410   CodeObject::funclist & allFuncs = parse_img()->getAllFunctions();
411   CodeObject::funclist::iterator fit = allFuncs.begin();
412   for( ; fit != allFuncs.end(); ++fit) {
413   // For each function, we want to add our base address
414       if((*fit)->src() != HINT)
415         findFunction((parse_func*)*fit);
416   }
417   
418   // Remember: variables don't.
419   pdvector<image_variable *> unmappedVars = image_->getCreatedVariables();
420   for (unsigned vi = 0; vi < unmappedVars.size(); vi++) {
421       findVariable(unmappedVars[vi]);
422   }
423   return true;
424 }
425
426 // TODO: this should probably not be a mapped_object method, but since
427 // for now it is only used by mapped_objects it is
428 // from a string that is a complete path name to a function in a module
429 // (ie. "/usr/lib/libc.so.1/write") return a string with the function
430 // part removed.  return 0 on error
431 char *mapped_object::getModulePart(std::string &full_path_name) {
432     
433     char *whole_name = P_strdup(full_path_name.c_str());
434     char *next=0;
435     char *last=next;
436     if((last = P_strrchr(whole_name, '/'))){
437         next = whole_name;
438         for(u_int i=0;(next!=last)&&(i<full_path_name.length()); i++){
439             next++;
440             if(next == last){
441                 u_int size = i+2;
442                 char *temp_str = new char[size];
443                 if(P_strncpy(temp_str,whole_name,size-1)){
444                     temp_str[size-1] = '\0';
445                     delete whole_name;
446                     return temp_str;
447                     temp_str = 0;
448                 } 
449             }
450         }
451     }
452     delete whole_name;
453     return 0;
454 }
455
456 mapped_module *mapped_object::findModule(string m_name, bool wildcard)
457 {
458    parsing_printf("findModule for %s (substr match %d)\n",
459          m_name.c_str(), wildcard);
460    std::string tmp = m_name.c_str();      
461    for (unsigned i = 0; i < everyModule.size(); i++) {
462       if (everyModule[i]->fileName() == m_name ||
463             everyModule[i]->fullName() == m_name ||
464             (wildcard &&
465              (wildcardEquiv(tmp, everyModule[i]->fileName()) ||
466               wildcardEquiv(tmp, everyModule[i]->fullName())))) {
467          //parsing_printf("... found!\n");
468          return everyModule[i];
469       }
470    }
471    // Create a new one IF there's one in the child pd_module
472
473    pdmodule *pdmod = image_->findModule(m_name, wildcard);
474    if (pdmod) {
475       mapped_module *mod = mapped_module::createMappedModule(this,
476             pdmod);
477       everyModule.push_back(mod);
478       //parsing_printf("... made new module!\n");
479       return mod;
480    }
481    else {
482       //parsing_printf("... error, no module found...\n");
483       return NULL;
484    }
485 }
486
487
488 mapped_module *mapped_object::findModule(pdmodule *pdmod) 
489 {
490    if (!pdmod) {
491       fprintf(stderr, "%s[%d]:  please call this findModule with nonNULL parameter\n", FILE__, __LINE__);
492       return NULL;
493    }
494
495    assert(pdmod);
496
497    if (pdmod->imExec() != parse_img()) {
498       fprintf(stderr, "%s[%d]: WARNING: lookup for module in wrong mapped object! %p != %p\n", FILE__, __LINE__, pdmod->imExec(), parse_img()); 
499       fprintf(stderr, "%s[%d]:  \t\t %s \n", FILE__, __LINE__, parse_img()->name().c_str());
500       fprintf(stderr, "%s[%d]:  \t %s != \n", FILE__, __LINE__, pdmod->imExec()->name().c_str());
501       return NULL;
502    }
503
504    //parsing_printf("findModule for pdmod %s\n",
505    //pdmod->fullName().c_str());
506
507    for (unsigned i = 0; i < everyModule.size(); i++) {
508       if (everyModule[i]->pmod() == pdmod) {
509          //parsing_printf("... found at index %d\n", i);
510          return everyModule[i];
511       }
512    }
513
514    mapped_module *mod = mapped_module::createMappedModule(this,
515          pdmod);
516    if (mod) {
517       //parsing_printf("... created new module\n");
518       everyModule.push_back(mod);
519       return mod;
520    }
521    else
522       return NULL;
523 }
524
525 // fill in "short_name" data member.  Use last component of "name" data
526 // member with FS_FIELD_SEPERATOR ("/") as field seperator....
527 void mapped_object::set_short_name() {
528    const char *name_string = fullName_.c_str();
529    const char *ptr = strrchr(name_string, FS_FIELD_SEPERATOR);
530    if (ptr != NULL) {
531       fileName_ = ptr+1;
532    } else {
533       fileName_ = fullName_;
534    }
535 }
536
537 const pdvector<func_instance *> *mapped_object::findFuncVectorByPretty(const std::string &funcname)
538 {
539    if (funcname.c_str() == 0) return NULL;
540    // First, check the underlying image.
541    const pdvector<parse_func *> *img_funcs = parse_img()->findFuncVectorByPretty(funcname);
542    if (img_funcs == NULL) {
543       return NULL;
544    }
545
546    assert(img_funcs->size());
547    // Fast path:
548    if (allFunctionsByPrettyName.defines(funcname)) {
549       // Okay, we've pulled in some of the functions before (this can happen as a
550       // side effect of adding functions). But did we get them all?
551        pdvector<func_instance *> *map_funcs = allFunctionsByPrettyName[funcname];
552        if (map_funcs->size() == img_funcs->size()) {
553            // We're allocating at the lower level....
554            delete img_funcs;
555            return map_funcs;
556        }
557    }
558    
559    // Slow path: check each img_func, add those we don't already have, and return.
560    for (unsigned i = 0; i < img_funcs->size(); i++) {
561        parse_func *func = (*img_funcs)[i];
562        if (everyUniqueFunction.find(func) == everyUniqueFunction.end()) {
563            findFunction(func);
564        }
565        assert(everyUniqueFunction[func]);
566    }
567    delete img_funcs;
568    return allFunctionsByPrettyName[funcname];
569
570
571 const pdvector <func_instance *> *mapped_object::findFuncVectorByMangled(const std::string &funcname)
572 {
573     if (funcname.c_str() == 0) return NULL;
574     
575     // First, check the underlying image.
576     const pdvector<parse_func *> *img_funcs = parse_img()->findFuncVectorByMangled(funcname);
577     if (img_funcs == NULL) return NULL;
578
579     assert(img_funcs->size());
580     // Fast path:
581     if (allFunctionsByMangledName.defines(funcname)) {
582         // Okay, we've pulled in some of the functions before (this can happen as a
583         // side effect of adding functions). But did we get them all?
584         pdvector<func_instance *> *map_funcs = allFunctionsByMangledName[funcname];
585         if (map_funcs->size() == img_funcs->size())
586             // We're allocating at the lower level...
587             delete img_funcs;
588             return map_funcs;
589     }
590     
591     // Slow path: check each img_func, add those we don't already have, and return.
592     for (unsigned i = 0; i < img_funcs->size(); i++) {
593         parse_func *func = (*img_funcs)[i];
594         if (everyUniqueFunction.find(func) == everyUniqueFunction.end()) {
595             findFunction(func);
596         }
597         assert(everyUniqueFunction[func]);
598     }
599     delete img_funcs;
600     return allFunctionsByMangledName[funcname];
601
602
603
604 const pdvector<int_variable *> *mapped_object::findVarVectorByPretty(const std::string &varname)
605 {
606     if (varname.c_str() == 0) return NULL;
607     
608     // First, check the underlying image.
609     const pdvector<image_variable *> *img_vars = parse_img()->findVarVectorByPretty(varname);
610     if (img_vars == NULL) return NULL;
611     
612     assert(img_vars->size());
613     // Fast path:
614     if (allVarsByPrettyName.defines(varname)) {
615         // Okay, we've pulled in some of the variabletions before (this can happen as a
616         // side effect of adding variabletions). But did we get them all?
617         pdvector<int_variable *> *map_variables = allVarsByPrettyName[varname];
618         if (map_variables->size() == img_vars->size()) {
619             delete img_vars;
620             return map_variables;
621         }
622     }
623     
624     // Slow path: check each img_variable, add those we don't already have, and return.
625     for (unsigned i = 0; i < img_vars->size(); i++) {
626         image_variable *var = (*img_vars)[i];
627         if (!everyUniqueVariable.defines(var)) {
628             findVariable(var);
629         }
630         assert(everyUniqueVariable[var]);
631     }
632     delete img_vars;
633     return allVarsByPrettyName[varname];
634
635
636 const pdvector <int_variable *> *mapped_object::findVarVectorByMangled(const std::string &varname)
637 {
638   if (varname.c_str() == 0) return NULL;
639
640   // First, check the underlying image.
641   const pdvector<image_variable *> *img_vars = parse_img()->findVarVectorByMangled(varname);
642   if (img_vars == NULL) return NULL;
643
644   assert(img_vars->size());
645   // Fast path:
646   if (allVarsByMangledName.defines(varname)) {
647       // Okay, we've pulled in some of the variabletions before (this can happen as a
648       // side effect of adding variabletions). But did we get them all?
649       pdvector<int_variable *> *map_variables = allVarsByMangledName[varname];
650       if (map_variables->size() == img_vars->size()) {
651           delete img_vars;
652           return map_variables;
653       }
654   }
655
656   // Slow path: check each img_variable, add those we don't already have, and return.
657   for (unsigned i = 0; i < img_vars->size(); i++) {
658       image_variable *var = (*img_vars)[i];
659       if (!everyUniqueVariable.defines(var)) {
660           findVariable(var);
661       }
662       assert(everyUniqueVariable[var]);
663   }
664   delete img_vars;
665   return allVarsByMangledName[varname];
666
667
668 //Returns one variable, doesn't search other mapped_objects.  Use carefully.
669 const int_variable *mapped_object::getVariable(const std::string &varname) {
670     const pdvector<int_variable *> *vars = NULL; 
671     vars = findVarVectorByPretty(varname);
672     if (!vars) vars = findVarVectorByMangled(varname);
673     if (vars) {
674         assert(vars->size() > 0);
675         return (*vars)[0];
676     }
677     return NULL;
678 }
679
680 block_instance *mapped_object::findBlockByEntry(Address addr)
681 {
682     std::set<block_instance *> allBlocks;
683     if (!findBlocksByAddr(addr, allBlocks)) return false;
684     for (std::set<block_instance *>::iterator iter = allBlocks.begin();
685         iter != allBlocks.end(); ++iter) 
686     {
687         if ((*iter)->start() == addr)
688         {
689            return *iter;
690         }
691     }
692     return NULL;
693 }
694
695
696 bool mapped_object::findBlocksByAddr(const Address addr, std::set<block_instance *> &blocks)
697 {
698     // Quick bounds check...
699     if (addr < codeAbs()) { 
700         return false; 
701     }
702     if (addr >= (codeAbs() + imageSize())) {
703         return false;
704     }
705
706     // Duck into the image class to see if anything matches
707     set<ParseAPI::Block *> stab;
708     parse_img()->findBlocksByAddr(addr - codeBase(), stab);
709     if (stab.empty()) return false;
710
711     for (set<ParseAPI::Block *>::iterator llb_iter = stab.begin();
712         llb_iter != stab.end(); ++llb_iter) 
713     {
714         // For each block b \in stab
715         //   For each func f \in b.funcs()
716         //     Let i_f = up_map(f)
717         //       add up_map(b, i_f)
718         std::vector<ParseAPI::Function *> ll_funcs;
719         (*llb_iter)->getFuncs(ll_funcs);
720         for (std::vector<ParseAPI::Function *>::iterator llf_iter = ll_funcs.begin();
721             llf_iter != ll_funcs.end(); ++llf_iter) {
722            block_instance *block = findBlock(*llb_iter);
723            assert(block);
724            blocks.insert(block);
725         }
726     }
727     return true;
728 }
729
730 bool mapped_object::findFuncsByAddr(const Address addr, std::set<func_instance *> &funcs) 
731 {
732     bool ret = false;
733     // Quick and dirty implementation
734     std::set<block_instance *> blocks;
735     if (!findBlocksByAddr(addr, blocks)) return false;
736     for (std::set<block_instance *>::iterator iter = blocks.begin();
737          iter != blocks.end(); ++iter) {
738        (*iter)->getFuncs(std::inserter(funcs, funcs.end()));
739        ret = true;
740     }
741     return ret;
742 }
743
744 func_instance *mapped_object::findFuncByEntry(const Address addr) {
745    std::set<func_instance *> funcs;
746    if (!findFuncsByAddr(addr, funcs)) return NULL;
747    for (std::set<func_instance *>::iterator iter = funcs.begin();
748         iter != funcs.end(); ++iter) {
749       if ((*iter)->entryBlock()->start() == addr) return *iter;
750    }
751    return NULL;
752 }
753
754
755 const pdvector<mapped_module *> &mapped_object::getModules() {
756     // everyModule may be out of date...
757     std::vector<pdmodule *> pdmods;
758     parse_img()->getModules(pdmods);
759     if (everyModule.size() == pdmods.size())
760         return everyModule;
761     for (unsigned i = 0; i < pdmods.size(); i++) {
762         findModule(pdmods[i]);
763     }
764     
765     return everyModule;
766 }
767
768 bool mapped_object::getAllFunctions(pdvector<func_instance *> &funcs) {
769     unsigned start = funcs.size();
770
771     CodeObject::funclist &img_funcs = parse_img()->getAllFunctions();
772     CodeObject::funclist::iterator fit = img_funcs.begin();
773     for( ; fit != img_funcs.end(); ++fit) {
774         if(everyUniqueFunction.find((parse_func*)*fit) == everyUniqueFunction.end()) {
775             findFunction((parse_func*)*fit);
776         }
777         funcs.push_back(everyUniqueFunction[(parse_func*)*fit]);
778     }
779     return funcs.size() > start;
780 }
781
782 bool mapped_object::getAllVariables(pdvector<int_variable *> &vars) {
783     unsigned start = vars.size();
784
785     const pdvector<image_variable *> &img_vars = parse_img()->getAllVariables();
786     
787     for (unsigned i = 0; i < img_vars.size(); i++) {
788         if (!everyUniqueVariable.defines(img_vars[i])) {
789             findVariable(img_vars[i]);
790         }
791         vars.push_back(everyUniqueVariable[img_vars[i]]);
792     }
793     return vars.size() > start;
794 }
795
796 // Enter a function in all the appropriate tables
797 func_instance *mapped_object::findFunction(ParseAPI::Function *papi_func) {
798     parse_func *img_func = static_cast<parse_func *>(papi_func);
799     if (!img_func) {
800         return NULL;
801     }
802     assert(img_func->getSymtabFunction());
803
804     mapped_module *mod = findModule(img_func->pdmod());
805     if (!mod) {
806         fprintf(stderr, "%s[%d]: ERROR: cannot find module %p\n", FILE__, __LINE__, img_func->pdmod());
807         fprintf(stderr, "%s[%d]:  ERROR:  Cannot find module %s\n", FILE__, __LINE__, img_func->pdmod()->fileName().c_str());
808     }
809     assert(mod);
810     
811
812     if (everyUniqueFunction.find(img_func) != everyUniqueFunction.end()) {
813         return everyUniqueFunction[img_func];
814     }
815
816     func_instance *func = new func_instance(static_cast<parse_func *>(img_func), 
817                                           codeBase_,
818                                           mod);
819     addFunction(func);
820     return func;
821 }
822
823 void mapped_object::addFunctionName(func_instance *func,
824                                     const std::string newName,
825                                     nameType_t nameType) {
826     // DEBUG
827     pdvector<func_instance *> *funcsByName = NULL;
828     
829     if (nameType & mangledName) {
830         if (!allFunctionsByMangledName.find(newName,
831                                             funcsByName)) {
832             funcsByName = new pdvector<func_instance *>;
833             allFunctionsByMangledName[newName] = funcsByName;
834         }
835     }
836     if (nameType & prettyName) {
837         if (!allFunctionsByPrettyName.find(newName,
838                                            funcsByName)) {
839             funcsByName = new pdvector<func_instance *>;
840             allFunctionsByPrettyName[newName] = funcsByName;
841         }
842     }
843     if (nameType & typedName) {
844         return; 
845         /*
846           // TODO add?
847         if (!allFunctionsByPrettyName.find(newName,
848                                            funcsByName)) {
849             funcsByName = new pdvector<func_instance *>;
850             allFunctionsByPrettyName[newName] = funcsByName;
851         }
852         */
853     }
854
855     assert(funcsByName != NULL);
856     funcsByName->push_back(func);
857 }
858     
859
860 void mapped_object::addFunction(func_instance *func) {
861     /*
862     fprintf(stderr, "Adding function %s/%p: %d mangled, %d pretty, %d typed names\n",
863             func->symTabName().c_str(),
864             func,
865             func->symTabNameVector().size(),
866             func->prettyNameVector().size(),
867             func->typedNameVector().size());
868     */
869
870     // Possibly multiple demangled (pretty) names...
871     // And multiple functions (different addr) with the same pretty
872     // name. So we have a many::many mapping...
873     for (unsigned pretty_iter = 0; 
874          pretty_iter < func->prettyNameVector().size();
875          pretty_iter++) {
876         string pretty_name = func->prettyNameVector()[pretty_iter];
877         addFunctionName(func, pretty_name.c_str(), prettyName);
878     }
879
880     for (unsigned typed_iter = 0; 
881          typed_iter < func->typedNameVector().size();
882          typed_iter++) {
883         string typed_name = func->typedNameVector()[typed_iter];
884         addFunctionName(func, typed_name.c_str(), typedName);
885     }
886     
887     // And multiple symtab names...
888     for (unsigned symtab_iter = 0; 
889          symtab_iter < func->symTabNameVector().size();
890          symtab_iter++) {
891         string symtab_name = func->symTabNameVector()[symtab_iter];
892         addFunctionName(func, symtab_name.c_str(), mangledName);
893     }  
894     everyUniqueFunction[func->ifunc()] = func;
895     func->mod()->addFunction(func);
896 }  
897
898 // Enter a function in all the appropriate tables
899 int_variable *mapped_object::findVariable(image_variable *img_var) {
900     if (!img_var) return NULL;
901     
902     if (everyUniqueVariable.defines(img_var))
903         return everyUniqueVariable[img_var];
904     
905     mapped_module *mod = findModule(img_var->pdmod());
906     assert(mod);
907
908     int_variable *var = new int_variable(img_var, dataBase_, mod);
909     addVariable(var);
910     return var;
911 }
912
913 void mapped_object::addVariable(int_variable *var) { 
914     
915     // Possibly multiple demangled (pretty) names...
916     // And multiple functions (different addr) with the same pretty
917     // name. So we have a many::many mapping...
918     for (unsigned pretty_iter = 0; 
919          pretty_iter < var->prettyNameVector().size();
920          pretty_iter++) {
921         string pretty_name = var->prettyNameVector()[pretty_iter];
922         pdvector<int_variable *> *varsByPrettyEntry = NULL;
923         
924         // Ensure a vector exists
925         if (!allVarsByPrettyName.find(pretty_name.c_str(),  
926                                       varsByPrettyEntry)) {
927             varsByPrettyEntry = new pdvector<int_variable *>;
928             allVarsByPrettyName[pretty_name.c_str()] = varsByPrettyEntry;
929         }
930         
931         (*varsByPrettyEntry).push_back(var);
932     }
933     
934     // And multiple symtab names...
935     for (unsigned symtab_iter = 0; 
936          symtab_iter < var->symTabNameVector().size();
937          symtab_iter++) {
938         string symtab_name = var->symTabNameVector()[symtab_iter];
939         pdvector<int_variable *> *varsBySymTabEntry = NULL;
940         
941         // Ensure a vector exists
942         if (!allVarsByMangledName.find(symtab_name.c_str(),  
943                                        varsBySymTabEntry)) {
944             varsBySymTabEntry = new pdvector<int_variable *>;
945             allVarsByMangledName[symtab_name.c_str()] = varsBySymTabEntry;
946         }
947         
948         (*varsBySymTabEntry).push_back(var);
949     }  
950     
951     everyUniqueVariable[var->ivar()] = var;
952     
953     var->mod()->addVariable(var);
954 }  
955
956 /////////// Dinky functions
957
958 // This way we don't have to cross-include every header file in the
959 // world.
960
961 AddressSpace *mapped_object::proc() const { return proc_; }
962
963 bool mapped_object::isSharedLib() const 
964 {
965     if (isMemoryImg()) return false;
966
967     return parse_img()->isSharedObj();
968     // HELL NO
969     //return desc_.isSharedObject();
970 }
971
972 bool mapped_object::isStaticExec() const
973 {
974     return parse_img()->getObject()->isStaticBinary();
975 }
976
977 const std::string mapped_object::debugString() const 
978 {
979     std::string debug;
980     debug = std::string(fileName_.c_str()) + ":" 
981        + utos(codeBase_) 
982        + "/" + utos(imageSize()); 
983     return debug;
984 }
985
986 // Search an object for heapage
987 bool mapped_object::getInfHeapList(pdvector<heapDescriptor> &infHeaps) {
988     vector<pair<string,Address> > foundHeaps;
989
990     getInferiorHeaps(foundHeaps);
991
992     for (u_int j = 0; j < foundHeaps.size(); j++) {
993         // The string layout is: DYNINSTstaticHeap_size_type_unique
994         // Can't allocate a variable-size array on NT, so malloc
995         // that sucker
996         char *temp_str = (char *)malloc(strlen(foundHeaps[j].first.c_str())+1);
997         strcpy(temp_str, foundHeaps[j].first.c_str());
998         char *garbage_str = strtok(temp_str, "_"); // Don't care about beginning
999         assert(!strcmp("DYNINSTstaticHeap", garbage_str));
1000         // Name is as is.
1001         // If address is zero, then skip (error condition)
1002         if (foundHeaps[j].second == 0) {
1003             cerr << "Skipping heap " << foundHeaps[j].first.c_str()
1004                  << "with address 0" << endl;
1005             continue;
1006         }
1007         // Size needs to be parsed out (second item)
1008         // Just to make life difficult, the heap can have an optional
1009         // trailing letter (k,K,m,M,g,G) which indicates that it's in
1010         // kilobytes, megabytes, or gigabytes. Why gigs? I was bored.
1011         char *heap_size_str = strtok(NULL, "_"); // Second element, null-terminated
1012         unsigned heap_size = (unsigned) atol(heap_size_str);
1013         if (heap_size == 0)
1014             /* Zero size or error, either way this makes no sense for a heap */
1015         {
1016             free(temp_str);
1017             continue;
1018         }
1019         switch (heap_size_str[strlen(heap_size_str)-1]) {
1020         case 'g':
1021         case 'G':
1022             heap_size *= 1024;
1023         case 'm':
1024         case 'M':
1025             heap_size *= 1024;
1026         case 'k':
1027         case 'K':
1028             heap_size *= 1024;
1029         default:
1030             break;
1031         }
1032
1033         // Type needs to be parsed out. Can someone clean this up?
1034         inferiorHeapType heap_type;
1035         char *heap_type_str = strtok(NULL, "_");
1036
1037         if (!strcmp(heap_type_str, "anyHeap"))
1038             heap_type = anyHeap;
1039         else if (!strcmp(heap_type_str, "lowmemHeap"))
1040             heap_type = lowmemHeap;
1041         else if (!strcmp(heap_type_str, "dataHeap"))
1042             heap_type = dataHeap;
1043         else if (!strcmp(heap_type_str, "textHeap"))
1044             heap_type = textHeap;
1045         else if (!strcmp(heap_type_str, "uncopiedHeap"))
1046             heap_type = uncopiedHeap;
1047         else {
1048             cerr << "Unknown heap string " << heap_type_str << " read from file!" << endl;
1049             free(temp_str);
1050             continue;
1051         }
1052         infHeaps.push_back(heapDescriptor(foundHeaps[j].first.c_str(),
1053                                           foundHeaps[j].second,
1054                                           heap_size, heap_type));
1055         free(temp_str);
1056     }
1057     return foundHeaps.size() > 0;
1058 }
1059
1060 unsigned mapped_object::memoryEnd() 
1061
1062     if ((long)memEnd_ != -1) {
1063         return memEnd_;
1064     }
1065     memEnd_ = 0;
1066     vector<SymtabAPI::Region*> regs;
1067     parse_img()->getObject()->getMappedRegions(regs);
1068     for (unsigned ridx=0; ridx < regs.size(); ridx++) {
1069         if (memEnd_ < regs[ridx]->getMemOffset() + regs[ridx]->getMemSize()) {
1070             memEnd_ = regs[ridx]->getMemOffset() + regs[ridx]->getMemSize();
1071         }
1072     }
1073     memEnd_ += codeBase();
1074     return memEnd_;
1075 }
1076
1077
1078 // This gets called once per image. Poke through to the internals;
1079 // all we care about, amusingly, is symbol table information. 
1080
1081 void mapped_object::getInferiorHeaps(vector<pair<string, Address> > &foundHeaps)
1082 {
1083     vector<pair<string, Address> > code_heaps;
1084     vector<pair<string, Address> > data_heaps;
1085
1086     if (!parse_img()->getInferiorHeaps(code_heaps, data_heaps)) {
1087 #if !defined(os_aix)
1088         // AIX: see auxiliary lookup, below.
1089         return;
1090 #endif
1091     }
1092
1093
1094     // We have a bunch of offsets, now add in the base addresses
1095     for (unsigned i = 0; i < code_heaps.size(); i++) {
1096         foundHeaps.push_back(pair<string,Address>(code_heaps[i].first,
1097                                                   code_heaps[i].second + codeBase()));
1098     }
1099     for (unsigned i = 0; i < data_heaps.size(); i++) {
1100         foundHeaps.push_back(pair<string,Address>(data_heaps[i].first,
1101                                                   data_heaps[i].second + dataBase()));
1102     }
1103     
1104     // AIX: we scavenge space. Do that here.
1105     
1106 #if defined(os_aix)
1107     // ...
1108     
1109     // a.out: from the end of the loader to 0x20000000
1110     // Anything in 0x2....: skip
1111     // Anything in 0xd....: to the next page
1112     
1113     Address start = 0;
1114     unsigned size = 0;
1115     
1116 #if 0
1117     fprintf(stderr, "Looking for inferior heap in %s/%s, codeAbs 0x%x (0x%x/0x%x)\n",
1118             getFileDesc().file().c_str(),
1119             getFileDesc().member().c_str(),
1120             codeAbs(),
1121             codeBase(),
1122             codeOffset());
1123 #endif
1124     
1125     if (codeAbs() >= 0xd0000000) {
1126         // This caused problems on sp3-01.cs.wisc.edu; apparently we were overwriting
1127         // necessary library information. For now I'm disabling it (10FEB06) until
1128         // we can get a better idea of what was going on.
1129 #if 0
1130         start = codeAbs() + imageSize();
1131         start += instruction::size() - (start % (Address)instruction::size());
1132         size = PAGESIZE - (start % PAGESIZE);
1133 #endif
1134     }
1135     else if (codeAbs() > 0x20000000) {
1136         // ...
1137     }
1138     else if (codeAbs() > 0x10000000) {
1139         // We also have the loader; there is no information on where
1140         // it goes (ARGH) so we pad the end of the code segment to
1141         // try and avoid it.
1142         
1143         SymtabAPI::Region *sec;
1144         image_->getObject()->findRegion(sec, ".loader");
1145         Address loader_end = codeAbs() + 
1146             //sec.getSecAddr() +
1147             image_->getObject()->getLoadOffset() +
1148             sec->getDiskSize();
1149         //Address loader_end = codeAbs() + 
1150         //    image_->getObject()->loader_off() +
1151         //    image_->getObject()->loader_len();
1152         // If we loaded it up in the data segment, don't use...
1153         if (loader_end > 0x20000000)
1154             loader_end = 0;
1155         Address code_end = codeAbs() + imageSize();
1156         
1157         start = (loader_end > code_end) ? loader_end : code_end;
1158         
1159         start += instruction::size() - (start % (Address)instruction::size());
1160         size = (0x20000000 - start);
1161     }
1162     
1163     
1164     if (start) {
1165         char name_scratch[1024];
1166         snprintf(name_scratch, 1023,
1167                  "DYNINSTstaticHeap_%i_uncopiedHeap_0x%lx_scratchpage_%s",
1168                  (unsigned) size,
1169                  start,
1170                  fileName().c_str());
1171
1172         foundHeaps.push_back(pair<string,Address>(string(name_scratch),start)); 
1173     }
1174 #endif
1175 }
1176     
1177
1178 void *mapped_object::getPtrToInstruction(Address addr) const 
1179 {
1180    if (addr < codeAbs()) {
1181       assert(0);
1182        return NULL;
1183    }
1184    if (addr >= (codeAbs() + imageSize())) {
1185       assert(0);
1186        return NULL;
1187    }
1188
1189    // Only subtract off the codeBase, not the codeBase plus
1190    // codeOffset -- the image class includes the codeOffset.
1191    Address offset = addr - codeBase();
1192    return image_->codeObject()->cs()->getPtrToInstruction(offset);
1193 }
1194
1195 void *mapped_object::getPtrToData(Address addr) const 
1196 {
1197    assert(addr >= dataAbs());
1198    assert(addr < (dataAbs() + dataSize()));
1199
1200    // Don't go from the code base... the image adds back in the code
1201    // offset.
1202    Address offset = addr - dataBase();
1203    return image_->codeObject()->cs()->getPtrToData(offset);
1204 }
1205
1206 // mapped objects may contain multiple Symtab::Regions, this function
1207 // should not be used, but must be included in the class because this
1208 // function is a subclass of codeRange
1209 void *mapped_object::get_local_ptr() const 
1210 {
1211     assert(0);// if you crash here, blame me. -kevin
1212     return NULL; 
1213     //   return image_->getObject()->image_ptr();
1214 }
1215
1216
1217 bool mapped_object::getSymbolInfo(const std::string &n, int_symbol &info) 
1218 {
1219     using SymtabAPI::Symbol;
1220
1221     assert(image_);
1222
1223     Symbol *lowlevel_sym = image_->symbol_info(n);
1224     if (!lowlevel_sym) {
1225         lowlevel_sym = image_->symbol_info(std::string("_") + n);
1226     }
1227     
1228     if (!lowlevel_sym) return false;
1229     
1230     if (lowlevel_sym->getType() == Symbol::ST_OBJECT)
1231         info = int_symbol(lowlevel_sym, dataBase_);
1232     else
1233         info = int_symbol(lowlevel_sym, codeBase_);
1234     
1235     return true;
1236 }
1237
1238 mapped_module *mapped_object::getOrCreateForkedModule(mapped_module *parMod) 
1239 {
1240    // Okay. We're forking, and this is the child mapped_object.
1241    // And now, given a parent module, we need to find the right one
1242    // in our little baby modules.
1243
1244    // Since we've already copied modules, we can just do a name lookup.
1245    mapped_module *childModule = findModule(parMod->fileName(), false);
1246    assert(childModule);
1247    return childModule;
1248
1249 }
1250
1251 mapped_module* mapped_object::getDefaultModule()
1252 {
1253   mapped_module* ret = findModule("DEFAULT_MODULE");
1254   if(ret) return ret;
1255
1256   // Make sure the everyModule vector is initialized
1257   getModules();
1258   
1259   assert(everyModule.size() > 0);
1260   return everyModule[0];
1261   
1262 }
1263
1264
1265 // splits int-layer blocks in response to block-splitting at the image-layer,
1266 // adds the split image-layer blocks that are newly created, 
1267 // and adjusts point->block pointers accordingly 
1268 // (original block halves are resized in addMissingBlock)
1269 //
1270 // KEVINTODO: this would be much cheaper if we stored pairs of split blocks, 
1271 bool mapped_object::splitIntLayer()
1272 {
1273     set<func_instance*> splitFuncs;
1274     using namespace InstructionAPI;
1275     // iterates through the blocks that were created during block splitting
1276     const image::SplitBlocks &splits = parse_img()->getSplitBlocks();
1277     for (image::SplitBlocks::const_iterator bIter = splits.begin(); 
1278          bIter != splits.end(); bIter++) 
1279     {
1280       // foreach function corresponding to the block
1281        // parse_block *splitImgB = bIter->first;
1282        splitBlock(bIter->first, bIter->second);
1283     }
1284
1285     return true;
1286 }
1287
1288 // Grabs all block_instances corresponding to the region, taking special care 
1289 // to get ALL block_instances corresponding to an address if it is shared 
1290 // between multiple functions
1291 bool mapped_object::findBlocksByRange(Address startAddr,
1292                                       Address endAddr,
1293                                       list<block_instance*> &rangeBlocks)//output
1294 {
1295    std::set<ParseAPI::Block *> papiBlocks;
1296    for (Address cur = startAddr; cur < endAddr; ++cur) {
1297       Address papiCur = cur - codeBase();
1298       parse_img()->codeObject()->findBlocks(NULL, papiCur, papiBlocks);
1299    }
1300    //malware_cerr << "ParseAPI reported " << papiBlocks.size() << " unique blocks in the range "
1301    //     << hex << startAddr << " -> " << endAddr << dec << endl;
1302    
1303    for (std::set<ParseAPI::Block *>::iterator iter = papiBlocks.begin();
1304         iter != papiBlocks.end(); ++iter) {
1305       // For each parseAPI block, up-map it to a set of block_instances
1306       ParseAPI::Block *pB = *iter;
1307       
1308       std::vector<ParseAPI::Function *> funcs;
1309       pB->getFuncs(funcs);
1310       for (std::vector<ParseAPI::Function *>::iterator f_iter = funcs.begin();
1311            f_iter != funcs.end(); ++f_iter) {
1312          parse_func *ifunc = static_cast<parse_func *>(*f_iter);
1313          func_instance *func = findFunction(ifunc);
1314          assert(func);
1315
1316          block_instance *bbl = findBlockByEntry(pB->start() + codeBase());
1317          assert(bbl);
1318          rangeBlocks.push_back(bbl);
1319       }
1320    }
1321    return !rangeBlocks.empty();
1322 }
1323
1324 void mapped_object::findFuncsByRange(Address startAddr,
1325                                       Address endAddr,
1326                                       std::set<func_instance*> &pageFuncs)
1327 {
1328    std::list<block_instance *> bbls;
1329    findBlocksByRange(startAddr, endAddr, bbls);
1330    for (std::list<block_instance *>::iterator iter = bbls.begin();
1331         iter != bbls.end(); ++iter) {
1332       (*iter)->getFuncs(std::inserter(pageFuncs, pageFuncs.end()));
1333    }
1334 }
1335
1336 // register functions found by recursive traversal parsing from 
1337 // new entry points that are discovered after the initial parse
1338 void mapped_object::registerNewFunctions()
1339 {
1340     CodeObject::funclist newFuncs = parse_img()->getAllFunctions();
1341     CodeObject::funclist::iterator fit = newFuncs.begin();
1342     for( ; fit != newFuncs.end(); ++fit) {
1343         parse_func *curFunc = (parse_func*) *fit;
1344         if (everyUniqueFunction.find(curFunc) == everyUniqueFunction.end()) { 
1345             //if(curFunc->src() == HINT)
1346             //    mal_printf("adding function of source type hint\n");
1347             findFunction(curFunc); // does all the work
1348         }
1349     }
1350 }
1351
1352 /* Re-trigger parsing in the object.  This function should
1353  * only be invoked if all funcEntryAddrs lie within the boundaries of
1354  * the object.  
1355  * 
1356  * Copies over the raw data if a funcEntryAddr lies in between
1357  * the region's disk size and memory size, also copies raw data 
1358  * if the memory around the entry point has changed
1359  * 
1360  * A true return value means that new functions were parsed
1361 */
1362 bool mapped_object::parseNewFunctions(vector<Address> &funcEntryAddrs)
1363 {
1364
1365     bool reparsedObject = false;
1366     Address baseAddress = codeBase();
1367     SymtabAPI::Region *reg;
1368     std::set<SymtabAPI::Region*> visitedRegions;
1369
1370     // code page bytes may need updating
1371     if (BPatch_defensiveMode == analysisMode_) {
1372         setCodeBytesUpdated(false);
1373     }
1374
1375     assert( !parse_img()->hasSplitBlocks() && !parse_img()->hasNewBlocks());
1376
1377     // update regions if necessary, check that functions not parsed already
1378     vector<Address>::iterator curEntry = funcEntryAddrs.begin();
1379     while (curEntry != funcEntryAddrs.end()) {
1380         Address entryOffset = (*curEntry)-baseAddress;
1381         reg = parse_img()->getObject()->findEnclosingRegion(entryOffset);
1382         if (reg != NULL) {
1383
1384             if (parse_img()->codeObject()->defensiveMode() && 
1385                 visitedRegions.end() == visitedRegions.find(reg))
1386             {
1387                 updateCodeBytesIfNeeded(*curEntry);
1388                 visitedRegions.insert(reg);
1389             }
1390
1391             if (parse_img()->findFuncByEntry(entryOffset)) {
1392                 fprintf(stderr,"WARNING: tried to parse at %lx, where a "
1393                         "function entry exists already %s[%d]\n",
1394                         *curEntry, FILE__,__LINE__);
1395                 curEntry = funcEntryAddrs.erase(curEntry);
1396             } 
1397             else {
1398                 curEntry++;
1399             }
1400
1401         } 
1402         else {
1403             fprintf(stderr,"ERROR: passed invalid address %lx to "
1404                     "parseNewFunctions %s[%d]\n", *curEntry,FILE__,__LINE__);
1405             assert(0);
1406             curEntry++;
1407         }
1408     }
1409
1410     // parse at funcEntryAddrs
1411     curEntry = funcEntryAddrs.begin();
1412     set<ParseAPI::Function*> tmpfuncs;
1413     while (curEntry != funcEntryAddrs.end()) {
1414         Address entryOffset = (*curEntry)  - baseAddress;
1415         parse_img()->codeObject()->parse( entryOffset, true );
1416         
1417         if ( ! parse_img()->findFuncs(entryOffset, tmpfuncs) ) {
1418             // parse failed, this can happen when the function is just a 
1419             // jump or return instruction, but it doesn't mean that we 
1420             // didn't do any parsing
1421             fprintf(stderr,"WARNING, failed to parse function at %lx, "
1422                     "%s[%d]\n", *curEntry, FILE__, __LINE__);
1423         }
1424         else {
1425             reparsedObject = true;
1426             tmpfuncs.clear();
1427         }
1428         curEntry++;
1429     }
1430
1431     // add the functions we created to mapped_object datastructures
1432     registerNewFunctions();
1433
1434     // split int layer
1435     if (parse_img()->hasSplitBlocks()) {
1436         splitIntLayer();
1437         parse_img()->clearSplitBlocks();
1438     }
1439
1440     return reparsedObject;
1441 }
1442
1443
1444 /* 0. The target and source must be in the same mapped region, make sure memory
1445  *    for the target is up to date
1446  * 1. Parse from target address, add new edge at image layer
1447  * 2. Register all newly created functions as a result of new edge parsing
1448  * 3. Add image blocks as block_instances
1449  * 4. fix up mapping of split blocks with points
1450  * 5. Add image points, as instPoints 
1451 */
1452 bool mapped_object::parseNewEdges(const std::vector<edgeStub> & /*stubs*/ )
1453 {
1454    assert(0 && "TODO");
1455    return false;
1456 #if 0
1457     using namespace SymtabAPI;
1458     using namespace ParseAPI;
1459
1460     vector<ParseAPI::CodeObject::NewEdgeToParse> edgesInThisObject;
1461
1462 /* 0. Make sure memory for the target is up to date */
1463
1464     // Do various checks and set edge types, if necessary
1465     for (unsigned idx=0; idx < stubs.size(); idx++) {
1466        mapped_object *targ_obj = proc()->findObject(stubs[idx].trg);
1467        assert(targ_obj);
1468        
1469        // update target region if needed
1470        if (BPatch_defensiveMode == hybridMode()) 
1471        {
1472           targ_obj->updateCodeBytesIfNeeded(stubs[idx].trg);
1473        }
1474        
1475        EdgeTypeEnum edgeType = stubs[idx].type;
1476        
1477        // Determine if this stub already has been parsed
1478        // Which means looking up a block at the target address
1479        if (targ_obj->findBlockByEntry(stubs[idx].trg)) {
1480           continue;
1481        }
1482
1483         // Otherwise we don't have a target block, so we need to make one.
1484         if (stubs[idx].type == ParseAPI::NOEDGE) 
1485         {
1486             using namespace InstructionAPI;
1487             // And we don't know what type of edge this is. Lovely. Let's
1488             // figure it out from the instruction class, since that's
1489             // the easy way to do things.
1490             
1491             bool indirect = false;
1492             Block::edgelist &edges = stubs[idx].src->llb()->targets();
1493             for (Block::edgelist::iterator eit = edges.begin(); eit != edges.end(); ++eit) {
1494                 if ((*eit)->sinkEdge()) {
1495                     indirect = true;
1496                     break;
1497                 }
1498             }
1499
1500             block_instance::Insns insns;
1501             stubs[idx].src->getInsns(insns);
1502             InstructionAPI::Instruction::Ptr cf = insns[stubs[idx].src->last()];
1503             assert(cf);
1504             switch (cf->getCategory()) {
1505             case c_CallInsn:
1506                 if (stubs[idx].trg == stubs[idx].src->end()) 
1507                 {
1508                     edgeType = CALL_FT;
1509                 }
1510                 else 
1511                 {
1512                     edgeType = CALL;
1513                 }
1514                 break;
1515             case c_ReturnInsn:
1516                 //edgeType = RET;
1517                 // The above doesn't work according to Nate
1518                 edgeType = INDIRECT;
1519                 break;
1520             case c_BranchInsn:
1521                 if (indirect) 
1522                 {
1523                     edgeType = INDIRECT;
1524                 }
1525                 else if (!cf->allowsFallThrough())
1526                 {
1527                     edgeType = DIRECT;
1528                 }
1529                 else if (stubs[idx].trg == stubs[idx].src->end()) 
1530                 {
1531                     edgeType = COND_NOT_TAKEN;
1532                 }
1533                 else
1534                 {
1535                     edgeType = COND_TAKEN;
1536                 }
1537                 break;
1538             default:
1539                 edgeType = FALLTHROUGH;
1540                 break;
1541             }
1542         }
1543
1544                 /* 1. Parse from target address, add new edge at image layer  */
1545                 CodeObject::NewEdgeToParse newEdge(stubs[idx].src->llb(),
1546             stubs[idx].trg - targ_obj->codeBase(),
1547             edgeType);
1548                 if (this != targ_obj) {
1549                         std::vector<ParseAPI::CodeObject::NewEdgeToParse> newEdges;
1550                         newEdges.push_back(newEdge);
1551                         targ_obj->parse_img()->codeObject()->parseNewEdges(newEdges);
1552                 }
1553                 else {
1554                         edgesInThisObject.push_back(newEdge);
1555                 }
1556         }
1557  
1558         /* 1. Clean up any edges we haven't done yet */
1559         parse_img()->codeObject()->parseNewEdges(edgesInThisObject);
1560
1561 /* 2. Register all newly created parse_funcs as a result of new edge parsing */
1562     registerNewFunctions();
1563
1564     // build list of potentially modified functions
1565     vector<ParseAPI::Function*> modIFuncs;
1566     vector<func_instance*> modFuncs;
1567     for(unsigned sidx=0; sidx < stubs.size(); sidx++) {
1568         stubs[sidx].src->llb()->getFuncs(modIFuncs);
1569     }
1570
1571     for (unsigned fidx=0; fidx < modIFuncs.size(); fidx++) 
1572     {
1573        func_instance *func = findFunction(modIFuncs[fidx]);
1574        modFuncs.push_back(func);
1575
1576 /* 3. Add img-level blocks and points to int-level datastructures */
1577        func->addMissingBlocks();
1578     }
1579
1580 /* 5. fix mapping of split blocks that have points */
1581     if (parse_img()->hasSplitBlocks()) {
1582         splitIntLayer();
1583         parse_img()->clearSplitBlocks();
1584     }
1585
1586     // update the function's liveness and PC sensitivity analysis,
1587     // and assert its consistency
1588     for (unsigned fidx=0; fidx < modFuncs.size(); fidx++) 
1589     {
1590         modFuncs[fidx]->triggerModified();
1591         assert(modFuncs[fidx]->consistency());
1592     }
1593     
1594     return true;
1595 #endif
1596 }
1597
1598
1599 /* 1. Copy the entire region in from the mutatee, 
1600  * 2. if memory emulation is not on, copy blocks back in from the
1601  * mapped file, since we don't want to copy instrumentation into
1602  * the mutatee. 
1603  */
1604 void mapped_object::expandCodeBytes(SymtabAPI::Region *reg)
1605 {
1606     assert(reg);
1607     void *mappedPtr = reg->getPtrToRawData();
1608     Address regStart = reg->getRegionAddr();
1609     ParseAPI::Block *cur = NULL;
1610     ParseAPI::CodeObject *cObj = parse_img()->codeObject();
1611     ParseAPI::CodeRegion *parseReg = NULL;
1612     Address copySize = reg->getMemSize();
1613     void* regBuf = malloc(copySize);
1614     Address initializedEnd = regStart + copySize;
1615     
1616     set<ParseAPI::CodeRegion*> parseRegs;
1617     cObj->cs()->findRegions(regStart, parseRegs);
1618     parseReg = * parseRegs.begin();
1619     parseRegs.clear();
1620
1621     // 1. copy memory into regBuf
1622     Address readAddr = regStart + codeBase();
1623     if (proc()->isMemoryEmulated()) {
1624         bool valid = false;
1625         boost::tie(valid, readAddr) = proc()->getMemEm()->translate(readAddr);
1626         assert(valid);
1627     }
1628     if (!proc()->readDataSpace((void*)readAddr, 
1629                                copySize, 
1630                                regBuf, 
1631                                true)) 
1632     {
1633         fprintf(stderr, "%s[%d] Failed to read from region [%lX %lX]\n",
1634                 __FILE__, __LINE__, (long)regStart+codeBase(), copySize);
1635         assert(0);
1636     }
1637     mal_printf("EXTEND_CB: copied to [%lx %lx)\n", codeBase()+regStart, codeBase()+regStart+copySize);
1638
1639
1640     if ( ! proc()->isMemoryEmulated() ) {
1641
1642     // 2. copy code bytes back into the regBuf to wipe out instrumentation 
1643     //    and set regBuf to be the data for the region
1644
1645         // find the first block in the region
1646         set<ParseAPI::Block*> analyzedBlocks;
1647         cObj->findBlocks(parseReg, regStart, analyzedBlocks);
1648         if (analyzedBlocks.size()) {
1649             cur = * analyzedBlocks.begin();
1650         } else {
1651             cur = cObj->findNextBlock(parseReg, regStart);
1652         }
1653
1654         // copy code ranges from old mapped data into regBuf
1655         while (cur != NULL && 
1656                cur->start() < initializedEnd)
1657         {
1658             if ( ! memcpy((void*)((Address)regBuf + cur->start() - regStart),
1659                           (void*)((Address)mappedPtr + cur->start() - regStart),
1660                           cur->size()) )
1661             {
1662                 assert(0);
1663             }
1664             mal_printf("EX: uncopy [%lx %lx)\n", codeBase()+cur->start(),codeBase()+cur->end());
1665             // advance to the next block
1666             Address prevEnd = cur->end();
1667             cur = cObj->findBlockByEntry(parseReg,prevEnd);
1668             if (!cur) {
1669                 cur = cObj->findNextBlock(parseReg,prevEnd);
1670             }
1671         }
1672         mal_printf("Expand region: %lx blocks copied back into mapped file\n", 
1673                    analyzedBlocks.size());
1674     }
1675
1676     if (reg->isDirty()) {
1677         // if isDirty is true, the pointer was created via malloc 
1678         // and we can free it.  If not, isDirty is part of a mapped
1679         // file and we can't free it
1680         free( mappedPtr );
1681     }
1682
1683     // KEVINTODO: find a cleaner solution than taking over the mapped files
1684     static_cast<SymtabCodeSource*>(cObj->cs())->
1685         resizeRegion( reg, reg->getMemSize() );
1686     reg->setPtrToRawData( regBuf , copySize );
1687
1688     // expand this mapped_object's codeRange
1689     if (codeBase() + reg->getMemOffset() + reg->getMemSize() 
1690         > 
1691         codeAbs() + get_size())
1692     {
1693         parse_img()->setImageLength( codeBase() 
1694                                      + reg->getMemOffset()
1695                                      + reg->getMemSize()
1696                                      - codeAbs() );
1697
1698     }
1699
1700     // KEVINTODO: what?  why is this necessary?, I've killed it for now, delete if no failures
1701     // 
1702     //// now update all of the other regions
1703     //std::vector<SymtabAPI::Region*> regions;
1704     //parse_img()->getObject()->getCodeRegions(regions);
1705     //for(unsigned rIdx=0; rIdx < regions.size(); rIdx++) {
1706     //    SymtabAPI::Region *curReg = regions[rIdx];
1707     //    if (curReg != reg) {
1708     //        updateCodeBytes(curReg);
1709     //    }
1710     //}
1711 }
1712
1713 // 1. use other update functions to update non-code areas of mapped files, 
1714 //    expanding them if we overwrote into unmapped areas
1715 // 2. copy overwritten regions into the mapped objects
1716 void mapped_object::updateCodeBytes(const list<pair<Address,Address> > &owRanges)
1717 {
1718     bool memEmulation = proc()->isMemoryEmulated();
1719 // 1. use other update functions to update non-code areas of mapped files, 
1720 //    expanding them if we wrote in un-initialized memory
1721     using namespace SymtabAPI;
1722     std::set<Region *> expandRegs;// so we don't update regions more than once
1723     Address baseAddress = codeBase();
1724
1725     // figure out which regions need expansion and which need updating
1726     list<pair<Address,Address> >::const_iterator rIter = owRanges.begin();
1727     for(; rIter != owRanges.end(); rIter++) {
1728         Address lastChangeOffset = (*rIter).second -1 -baseAddress;
1729         Region *curReg = parse_img()->getObject()->findEnclosingRegion
1730                                                     ( lastChangeOffset );
1731         if ( lastChangeOffset - curReg->getRegionAddr() >= curReg->getDiskSize() ) {
1732             expandRegs.insert(curReg);
1733         }
1734     }
1735     // expand and update regions
1736     for (set<Region*>::iterator regIter = expandRegs.begin();
1737          regIter != expandRegs.end(); regIter++) 
1738     {
1739         expandCodeBytes(*regIter);
1740     }
1741     std::vector<Region *> allregions;
1742     parse_img()->getObject()->getCodeRegions(allregions);
1743     for (unsigned int ridx=0; ridx < allregions.size(); ridx++) 
1744     {
1745         Region *curreg = allregions[ridx];
1746         if (expandRegs.end() == expandRegs.find(curreg)) {
1747             updateCodeBytes(curreg); // KEVINTODO: major overkill here, only update regions that had unprotected pages
1748         }
1749     }
1750
1751 // 2. copy overwritten regions into the mapped objects
1752     for(rIter = owRanges.begin(); rIter != owRanges.end(); rIter++) 
1753     {
1754         Address readAddr = rIter->first;
1755         if (memEmulation) {
1756             bool valid = false;
1757             boost::tie(valid, readAddr) = proc()->getMemEm()->translate(readAddr);
1758             assert(valid);
1759         }
1760
1761         Region *reg = parse_img()->getObject()->findEnclosingRegion
1762             ( (*rIter).first - baseAddress );
1763         unsigned char* regPtr = (unsigned char*)reg->getPtrToRawData() 
1764             + (*rIter).first - baseAddress - reg->getMemOffset();
1765
1766         if (!proc()->readDataSpace((void*)readAddr, 
1767                                    (*rIter).second - (*rIter).first, 
1768                                    regPtr, 
1769                                    true) )
1770         {
1771             assert(0);
1772         }
1773         if (0) {
1774             mal_printf("OW_CB: copied to [%lx %lx): ", rIter->first,rIter->second);
1775             for (unsigned idx=0; idx < rIter->second - rIter->first; idx++) {
1776                 mal_printf("%2x ", (unsigned) regPtr[idx]);
1777             }
1778             mal_printf("\n");
1779         }
1780     }
1781     pagesUpdated_ = true;
1782 }
1783
1784 // this is a helper function
1785 // 
1786 // update mapped data for whole object, or just one region, if specified
1787 //
1788 // Read unprotected pages into the mapped file
1789 // (not analyzed code regions so we don't get instrumentation in our parse)
1790 void mapped_object::updateCodeBytes(SymtabAPI::Region * symReg)
1791 {
1792     assert(NULL != symReg);
1793
1794     Address base = codeBase();
1795     ParseAPI::CodeObject *cObj = parse_img()->codeObject();
1796     std::vector<SymtabAPI::Region *> regions;
1797
1798     Block *curB = NULL;
1799     set<ParseAPI::Block *> analyzedBlocks;
1800     set<ParseAPI::CodeRegion*> parseRegs;
1801
1802     void *mappedPtr = symReg->getPtrToRawData();
1803     Address regStart = symReg->getRegionAddr();
1804
1805     cObj->cs()->findRegions(regStart, parseRegs);
1806     ParseAPI::CodeRegion *parseReg = * parseRegs.begin();
1807     parseRegs.clear();
1808     
1809     // find the first block in the region
1810     cObj->findBlocks(parseReg, regStart, analyzedBlocks);
1811     if (analyzedBlocks.size()) {
1812         curB = * analyzedBlocks.begin();
1813         analyzedBlocks.clear();
1814     } else {
1815         curB = cObj->findNextBlock(parseReg, regStart);
1816     }
1817
1818     Address prevEndAddr = regStart;
1819     while ( curB != NULL && 
1820             curB->start() < regStart + symReg->getDiskSize() )
1821     {
1822         // if there's a gap between previous and current block
1823         if (prevEndAddr < curB->start()) {
1824             // update the mapped file
1825             Address readAddr = prevEndAddr + base;
1826             if (proc()->isMemoryEmulated()) {
1827                 bool valid = false;
1828                 boost::tie(valid, readAddr) = proc()->getMemEm()->translate(readAddr);
1829                 assert(valid);
1830             }
1831             if (!proc()->readDataSpace(
1832                     (void*)readAddr, 
1833                     curB->start() - prevEndAddr, 
1834                     (void*)((Address)mappedPtr + prevEndAddr - regStart),
1835                     true)) 
1836             {
1837                 assert(0);//read failed
1838             }
1839             //mal_printf("UPDATE_CB: copied to [%lx %lx)\n", prevEndAddr+base,curB->start()+base);
1840         }
1841
1842         // advance curB to last adjacent block and set prevEndAddr 
1843         prevEndAddr = curB->end();
1844         Block *ftBlock = cObj->findBlockByEntry(parseReg,prevEndAddr);
1845         while (ftBlock) {
1846             curB = ftBlock;
1847             prevEndAddr = curB->end();
1848             ftBlock = cObj->findBlockByEntry(parseReg,prevEndAddr);
1849         }
1850
1851         curB = cObj->findNextBlock(parseReg, prevEndAddr);
1852
1853     }
1854     // read in from prevEndAddr to the end of the region
1855         // (will read in whole region if there are no ranges in the region)
1856     if (prevEndAddr < regStart + symReg->getDiskSize()) {
1857         Address readAddr = prevEndAddr + base;
1858         if (proc()->isMemoryEmulated()) {
1859             bool valid = false;
1860             boost::tie(valid, readAddr) = proc()->getMemEm()->translate(readAddr);
1861             assert(valid);
1862         }
1863         if (!proc()->readDataSpace(
1864                 (void*)readAddr, 
1865                 regStart + symReg->getDiskSize() - prevEndAddr, 
1866                 (void*)((Address)mappedPtr + prevEndAddr - regStart), 
1867                 true)) 
1868         {
1869             assert(0);// read failed
1870         }
1871     }
1872     // change all region pages with REPROTECTED status to PROTECTED status
1873     Address page_size = proc()->proc()->getMemoryPageSize();
1874     Address curPage = (regStart / page_size) * page_size + base;
1875     Address regEnd = base + regStart + symReg->getDiskSize();
1876     for (; protPages_.end() == protPages_.find(curPage)  && curPage < regEnd; 
1877            curPage += page_size);
1878     for (map<Address,WriteableStatus>::iterator pit = protPages_.find(curPage);
1879          pit != protPages_.end() && pit->first < regEnd;
1880          pit++) 
1881     {
1882         pit->second = PROTECTED;
1883     }
1884 }
1885
1886 // checks if update is needed by looking in the gap between the previous 
1887 // and next block for changes to the underlying bytes 
1888 //
1889 // should only be called if we've already checked that we're not on an
1890 // analyzed page that's been protected from overwrites, as this
1891 // check would not be needed
1892 bool mapped_object::isUpdateNeeded(Address entry)
1893 {
1894     using namespace ParseAPI;
1895     bool updateNeeded = false;
1896     void* regBuf = NULL;
1897     Address base = codeBase();
1898
1899     assert( BPatch_defensiveMode == hybridMode() );
1900
1901     set<CodeRegion*> cregs;
1902     CodeObject *co = parse_img()->codeObject();
1903     co->cs()->findRegions(entry-base, cregs);
1904     assert( ! co->cs()->regionsOverlap() );
1905     if (0 == cregs.size()) {
1906         mal_printf("Object update request has invalid addr[%lx] %s[%d]\n",
1907                    entry, FILE__,__LINE__);
1908         return false;
1909     }
1910     SymtabCodeRegion *creg = static_cast<SymtabCodeRegion*>( * cregs.begin() );
1911
1912     // update the range tree, if necessary
1913     set<ParseAPI::Block *> analyzedBlocks;
1914     if (parse_img()->findBlocksByAddr(entry-base, analyzedBlocks)) {
1915         return false; // don't need to update if target is in analyzed code
1916     }
1917
1918     // see if the underlying bytes have changed
1919     // 
1920     // read until the next basic block or until the end of the region
1921     // to make sure nothing has changed, otherwise we'll want to read 
1922     // the section in again
1923     Block *nextBlk = co->findNextBlock(creg, entry-base);
1924     unsigned comparison_size = 0; 
1925     if (nextBlk) {
1926         comparison_size = nextBlk->start() - (entry-base);
1927     } else {
1928         comparison_size = creg->symRegion()->getDiskSize() 
1929             - ( (entry - base) - creg->symRegion()->getRegionAddr() );
1930     }
1931
1932     // read until first difference, then see if the difference is to known
1933     // in which case the difference is due to instrumentation, as we would 
1934     // have otherwise detected the overwrite
1935     Address page_size = proc()->proc()->getMemoryPageSize();
1936     comparison_size = ( comparison_size <  page_size) 
1937                       ? comparison_size : page_size;
1938     regBuf = malloc(comparison_size);
1939     Address readAddr = entry;
1940     if (proc()->isMemoryEmulated()) {
1941         bool valid = false;
1942                 Address translated = 0;
1943                 boost::tie(valid, translated) = proc()->getMemEm()->translate(readAddr);
1944                 if (valid) readAddr = translated;
1945         }
1946
1947    // mal_printf("%s[%d] Comparing %lx bytes starting at %lx\n",
1948       //      FILE__,__LINE__,comparison_size,entry);
1949     if (!proc()->readDataSpace((void*)readAddr, comparison_size, regBuf, true)) {
1950         assert(0); 
1951     }
1952     void *mappedPtr = (void*)
1953                       ((Address)creg->symRegion()->getPtrToRawData() +
1954                         (entry - base - creg->symRegion()->getRegionAddr()) );
1955     //compare 
1956     if (0 != memcmp(mappedPtr,regBuf,comparison_size) ) {
1957         updateNeeded = true;
1958     }
1959     free(regBuf);
1960     regBuf = NULL;
1961
1962     return updateNeeded;
1963 }
1964
1965 // checks to see if expansion is needed 
1966 bool mapped_object::isExpansionNeeded(Address entry) 
1967 {
1968     using namespace SymtabAPI;
1969     Address base = codeBase();
1970     Region * reg = parse_img()->getObject()->findEnclosingRegion(entry - base);
1971     
1972     if (reg->getMemSize() <= reg->getDiskSize()) {
1973         return false;
1974     }
1975
1976     if ( ! parse_img()->getObject()->isCode(entry - base) ) {
1977         return true;
1978     } 
1979
1980     if (expansionCheckedRegions_.end() != 
1981         expansionCheckedRegions_.find(reg)) {
1982         return false;
1983     }
1984     expansionCheckedRegions_.insert(reg);
1985
1986     // if there is uninitialized space in the region, 
1987     // see if the first few bytes have been updated
1988     Address compareStart = 
1989         base + reg->getRegionAddr() + reg->getDiskSize();
1990     if (proc()->isMemoryEmulated()) {
1991         bool valid = false;
1992         boost::tie(valid, compareStart) = proc()->getMemEm()->translate(compareStart);
1993         assert(valid);
1994     }
1995 #if defined(cap_instruction_api)
1996     unsigned compareSize = InstructionAPI::InstructionDecoder::maxInstructionLength;
1997 #else
1998     unsigned compareSize = 2 * proc()->getAddressWidth(); 
1999 #endif
2000     Address uninitSize = reg->getMemSize() - reg->getDiskSize();
2001     if (compareSize > uninitSize) {
2002         compareSize = uninitSize;
2003     }
2004     unsigned char* regBuf = (unsigned char*) malloc(compareSize);
2005     if (!proc()->readDataSpace((void*)compareStart,compareSize,regBuf,true)) {
2006         fprintf(stderr, "%s[%d] Failed to read from region [%lX %lX]\n",
2007                 __FILE__, __LINE__, compareStart, compareStart+compareSize);
2008         assert(0);
2009     }
2010     // compare to zero if the region has not been expanded yet
2011     bool allZeros = true;
2012     for (unsigned idx=0; allZeros && idx < compareSize; idx++) {
2013         if (0 != regBuf[idx]) {
2014             allZeros = false;
2015         }
2016     }
2017     if (allZeros) {
2018         return false;
2019     } else {
2020         return true;
2021     }
2022 }
2023
2024 // updates the raw code bytes by fetching from memory, if needed
2025 // 
2026 // updates if we haven't updated since the last time code could have 
2027 // changed, and if the entry address is on an unprotected code page, 
2028 // or if the address is in an uninitialized memory, 
2029 bool mapped_object::updateCodeBytesIfNeeded(Address entry)
2030 {
2031         //cerr << "updateCodeBytes @ " << hex << entry << dec << endl;
2032
2033         assert( BPatch_defensiveMode == analysisMode_ );
2034
2035     Address pageAddr = entry - 
2036         (entry % proc()->proc()->getMemoryPageSize());
2037
2038     if ( pagesUpdated_ ) {
2039                 //cerr << "\t No pages have been updated in mapped_object, ret false" << endl;
2040         return false;
2041     }
2042
2043     if (protPages_.end() != protPages_.find(pageAddr) &&
2044         PROTECTED == protPages_[pageAddr]) 
2045     {
2046                 //cerr << "\t Address corresponds to protected page, ret false" << endl;
2047         return false;
2048     }
2049
2050     bool expand = isExpansionNeeded(entry);
2051     if ( ! expand ) {
2052         if ( ! isUpdateNeeded(entry) ) {
2053                         //cerr << "\t Expansion false and no update needed, ret false" << endl;
2054             return false;
2055         }
2056     }
2057
2058     SymtabAPI::Region * reg = parse_img()->getObject()->findEnclosingRegion
2059         (entry - codeBase());
2060     mal_printf("%s[%d] updating region [%lx %lx] for entry point %lx\n", 
2061                FILE__,__LINE__,
2062                reg->getRegionAddr(), 
2063                reg->getRegionAddr()+reg->getDiskSize(),
2064                entry);
2065     
2066     if ( expand ) {
2067         expandCodeBytes(reg);
2068     } 
2069     else {
2070         updateCodeBytes(reg);
2071     }
2072     pagesUpdated_ = true;
2073     return true;
2074 }
2075
2076 void mapped_object::removeFunction(func_instance *func) {
2077     // remove from func_instance vectore
2078     everyUniqueFunction.erase(func->ifunc());
2079     // remove pretty names
2080     pdvector<func_instance *> *funcsByName = NULL;
2081     for (unsigned pretty_iter = 0; 
2082          pretty_iter < func->prettyNameVector().size();
2083          pretty_iter++) 
2084     {
2085         allFunctionsByPrettyName.find
2086             (func->prettyNameVector()[pretty_iter], funcsByName);
2087         if (funcsByName) {
2088             for (unsigned fIdx=0; fIdx < funcsByName->size(); fIdx++) {
2089                 if (func == (*funcsByName)[fIdx]) {
2090                     unsigned lastIdx = funcsByName->size() -1;
2091                     (*funcsByName)[fIdx] = (*funcsByName)[lastIdx];
2092                     funcsByName->pop_back();
2093                     if (funcsByName->size() == 0) {
2094                         allFunctionsByPrettyName.undef
2095                             (func->symTabNameVector()[pretty_iter]);
2096                     }
2097                 }
2098             }
2099         }
2100     }
2101     // remove typed names
2102     for (unsigned typed_iter = 0; 
2103          typed_iter < func->typedNameVector().size();
2104          typed_iter++) 
2105     {
2106         allFunctionsByPrettyName.find
2107             (func->typedNameVector()[typed_iter], funcsByName);
2108         if (funcsByName) {
2109             for (unsigned fIdx=0; fIdx < funcsByName->size(); fIdx++) {
2110                 if (func == (*funcsByName)[fIdx]) {
2111                     unsigned lastIdx = funcsByName->size() -1;
2112                     (*funcsByName)[fIdx] = (*funcsByName)[lastIdx];
2113                     funcsByName->pop_back();
2114                     if (funcsByName->size() == 0) {
2115                         allFunctionsByPrettyName.undef
2116                             (func->symTabNameVector()[typed_iter]);
2117                     }
2118                 }
2119             }
2120         }
2121     }
2122     // remove symtab names
2123     for (unsigned symtab_iter = 0; 
2124          symtab_iter < func->symTabNameVector().size();
2125          symtab_iter++) 
2126     {
2127         allFunctionsByMangledName.find
2128             (func->symTabNameVector()[symtab_iter], funcsByName);
2129         if (funcsByName) {
2130             for (unsigned fIdx=0; fIdx < funcsByName->size(); fIdx++) {
2131                 if (func == (*funcsByName)[fIdx]) {
2132                     unsigned lastIdx = funcsByName->size() -1;
2133                     (*funcsByName)[fIdx] = (*funcsByName)[lastIdx];
2134                     funcsByName->pop_back();
2135                     if (funcsByName->size() == 0) {
2136                         allFunctionsByMangledName.undef
2137                             (func->symTabNameVector()[symtab_iter]);
2138                     }
2139                 }
2140             }
2141         }
2142     }  
2143 }
2144
2145 void mapped_object::removeEmptyPages()
2146 {
2147     // get all pages currently containing code from the mapped modules
2148     set<Address> curPages;
2149     vector<Address> emptyPages;
2150     const vector<mapped_module*> & mods = getModules();
2151     for (unsigned midx=0; midx < mods.size(); midx++) {
2152         mods[midx]->getAnalyzedCodePages(curPages);
2153     }
2154     // find entries in protPages_ that aren't in curPages, add to emptyPages
2155     for (map<Address,WriteableStatus>::iterator pit= protPages_.begin(); 
2156          pit != protPages_.end(); 
2157          pit++) 
2158     {
2159         if (curPages.end() == curPages.find(pit->first)) {
2160             emptyPages.push_back(pit->first);
2161         }
2162     }
2163     // erase emptyPages from protPages
2164     for (unsigned pidx=0; pidx < emptyPages.size(); pidx++) {
2165         protPages_.erase(emptyPages[pidx]);
2166     }
2167 }
2168
2169 bool mapped_object::isSystemLib(const std::string &objname)
2170 {
2171    std::string lowname = objname;
2172    std::transform(lowname.begin(),lowname.end(),lowname.begin(), 
2173                   (int(*)(int))std::tolower);
2174     
2175    if (std::string::npos != lowname.find("libdyninstapi_rt"))
2176       return true;
2177
2178 #if defined(os_solaris)
2179    // Solaris 2.8... we don't grab the initial func always,
2180    // so fix up this code as well...
2181    if (std::string::npos != lowname.find("libthread"))
2182       return true;
2183 #endif
2184
2185 #if defined(os_linux)
2186    if (std::string::npos != lowname.find("libc.so"))
2187       return true;
2188    if (std::string::npos != lowname.find("libpthread"))
2189       return true;
2190 #endif
2191
2192 #if defined(os_freebsd)
2193    if(std::string::npos != lowname.find("libc.so"))
2194        return true;
2195    if(std::string::npos != lowname.find("libthr"))
2196        return true;
2197 #endif
2198
2199 #if defined(os_windows)
2200    if (std::string::npos != lowname.find("windows\\system32\\") &&
2201        std::string::npos != lowname.find(".dll"))
2202        return true;
2203    if (std::string::npos != lowname.find("kernel32.dll"))
2204       return true;
2205    if (std::string::npos != lowname.find("user32.dll"))
2206       return true;
2207    if (std::string::npos != lowname.find("advapi32.dll"))
2208       return true;
2209    if (std::string::npos != lowname.find("ntdll.dll"))
2210       return true;
2211    if (std::string::npos != lowname.find("msvcrt") && 
2212        std::string::npos != lowname.find(".dll"))
2213       return true;
2214    if (std::string::npos != lowname.find(".dll"))
2215        return true; // Anything that's a library is a-ok with us! KEVIN TODO
2216
2217
2218 #endif
2219
2220    return false;
2221 }
2222
2223 bool mapped_object::isExploratoryModeOn()
2224 {
2225     return BPatch_exploratoryMode == analysisMode_ ||
2226            BPatch_defensiveMode == analysisMode_;
2227 }
2228
2229 void mapped_object::addProtectedPage(Address pageAddr)
2230 {
2231     map<Address,WriteableStatus>::iterator iter = protPages_.find(pageAddr);
2232     if (protPages_.end() == iter) {
2233         protPages_[pageAddr] = PROTECTED;
2234     }
2235     else if (PROTECTED != iter->second) {
2236         iter->second = REPROTECTED;
2237     }
2238 }
2239
2240 void mapped_object::removeProtectedPage(Address pageAddr)
2241 {
2242     map<Address,WriteableStatus>::iterator iter = protPages_.find(pageAddr);
2243     if (iter == protPages_.end()) {
2244         // sanity check, make sure there isn't any code on the page, in which
2245         // case we're unprotecting a page that was originally set to be writeable
2246         Address pageOffset = pageAddr - codeBase();
2247         SymtabAPI::Region *reg = parse_img()->getObject()->findEnclosingRegion(pageOffset);
2248         assert(reg);
2249         set<CodeRegion*> cregs;
2250         parse_img()->codeObject()->cs()->findRegions(reg->getMemOffset(), cregs);
2251         if (!cregs.empty()) { // (if empty, pageAddr is in uninitialized memory)
2252             ParseAPI::Block *blk = parse_img()->codeObject()->findNextBlock
2253                 (*cregs.begin(), pageOffset);
2254             Address pageEnd =  pageOffset + proc()->proc()->getMemoryPageSize();
2255             if (blk && blk->start() < pageEnd) {
2256                 assert(0);
2257             }
2258         }
2259         return;
2260     }
2261     iter->second = UNPROTECTED;
2262 }
2263
2264 void mapped_object::setCodeBytesUpdated(bool newval)
2265 {
2266     if (BPatch_defensiveMode == analysisMode_) {
2267         if (false == newval && newval != pagesUpdated_) {
2268             expansionCheckedRegions_.clear();
2269         }
2270         pagesUpdated_ = newval;
2271     } else {
2272         cerr << "WARNING: requesting update of code bytes from memory "
2273              <<  "on non-defensive mapped object, ignoring request " 
2274              << fileName().c_str() << " " << __FILE__ << __LINE__ << endl;
2275     }
2276 }
2277
2278 #if !( (defined(os_linux) || defined(os_freebsd)) && \
2279        (defined(arch_x86) || defined(arch_x86_64)) )
2280 func_instance *mapped_object::findGlobalConstructorFunc(const std::string &) {
2281     assert(!"Not implemented");
2282     return NULL;
2283 }
2284
2285 func_instance *mapped_object::findGlobalDestructorFunc(const std::string &) {
2286     assert(!"Not implemented");
2287     return NULL;
2288 }
2289 #endif
2290
2291 bool mapped_object::isEmulInsn(Address insnAddr)
2292 {
2293     return ( emulInsns_.end() != emulInsns_.find(insnAddr) );
2294 }
2295
2296
2297 void mapped_object::setEmulInsnVal(Address insnAddr, void * val)
2298 {
2299     assert(emulInsns_.end() != emulInsns_.find(insnAddr));
2300     emulInsns_[insnAddr] = pair<Register,void*>(emulInsns_[insnAddr].first,val);
2301 }
2302
2303 Register mapped_object::getEmulInsnReg(Address insnAddr)
2304 {
2305     assert(emulInsns_.end() != emulInsns_.find(insnAddr));
2306     return emulInsns_[insnAddr].first;
2307 }
2308
2309 void mapped_object::addEmulInsn(Address insnAddr, Register effectiveAddrReg)
2310 {
2311     emulInsns_[insnAddr] = pair<Register,void*>(effectiveAddrReg,(void *)0);
2312 }
2313
2314 std::string mapped_object::getCalleeName(block_instance *b) {
2315    std::map<block_instance *, std::string>::iterator iter = calleeNames_.find(b);
2316    if (iter != calleeNames_.end()) return iter->second;
2317    return std::string();
2318 }
2319
2320 void mapped_object::setCalleeName(block_instance *b, std::string s) {
2321    calleeNames_[b] = s;
2322 }
2323
2324 // Missing
2325 // findEdge
2326 // findBlock
2327 // findOneBlockByAddr
2328 // splitBlock
2329 // findFuncByEntry
2330 // findBlock (again)
2331
2332 edge_instance *mapped_object::findEdge(ParseAPI::Edge *e, 
2333                                        block_instance *src,
2334                                        block_instance *trg) {
2335    EdgeMap::const_iterator iter = edges_.find(e);
2336    if (iter != edges_.end()) return iter->second;
2337
2338    edge_instance *inst = new edge_instance(e,
2339                                            src ? src : findBlock(e->src()),
2340                                            trg ? trg : findBlock(e->trg()));
2341    edges_[e] = inst;
2342    return inst;
2343 }
2344
2345 block_instance *mapped_object::findBlock(ParseAPI::Block *b) {
2346    BlockMap::const_iterator iter = blocks_.find(b);
2347    if (iter != blocks_.end()) return iter->second;
2348    block_instance *inst = new block_instance(b, this);
2349    blocks_[b] = inst;
2350    return inst;
2351 }
2352
2353 block_instance *mapped_object::findOneBlockByAddr(const Address addr) {
2354    std::set<block_instance *> possibles;
2355    findBlocksByAddr(addr, possibles);
2356    for (std::set<block_instance *>::iterator iter = possibles.begin();
2357         iter != possibles.end(); ++iter) {
2358       block_instance::Insns insns;
2359       (*iter)->getInsns(insns);
2360       if (insns.find(addr) != insns.end()) {
2361          return *iter;
2362       }
2363    }
2364    return NULL;
2365 }
2366
2367 void mapped_object::splitBlock(ParseAPI::Block * /*first*/, ParseAPI::Block * /*second*/) {
2368    assert(0 && "TODO");
2369 }
2370
2371 func_instance *mapped_object::findFuncByEntry(const block_instance *blk) {
2372    parse_block *llb = static_cast<parse_block *>(blk->llb());
2373    return findFunction(llb->getEntryFunc());
2374 }