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