Keep cached 'Object's after creating them
[dyninst.git] / symtabAPI / src / Symtab.C
1 /*
2  * Copyright (c) 1996-2007 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 #include <stdio.h>
33 #include <stdlib.h>
34 #include <assert.h>
35 #include <string.h>
36
37 #include "common/h/debugOstream.h"
38 #include "common/h/Timer.h"
39 #include "symtabAPI/src/Object.h"
40 #include "symtabAPI/h/Symtab.h"
41 #include "symtabAPI/src/Collections.h"
42 #include "symtabAPI/src/serialize.h"
43 #include "common/h/pathName.h"
44
45 #if defined (os_linux) | defined (os_aix)
46 //  gcc is complaining about the constness of the library-provided
47 //  typecast (XMLCHAR_CAST) (which is defined in xmlstring.h), so we make our own
48 #define XMLCHAR_CAST (const xmlChar *)
49 #else
50 #define XMLCHAR_CAST BAD_CAST
51 #endif
52
53 #if !defined(os_windows)
54 #include <dlfcn.h>
55 #else
56 #include <windows.h>
57 #include <libxml/xmlversion.h>
58 #undef LIBXML_ICONV_ENABLED
59 #endif
60
61 #include <libxml/xmlwriter.h>
62 #include <iomanip>
63
64 using namespace Dyninst;
65 using namespace Dyninst::SymtabAPI;
66 using namespace std;
67
68 static std::string errMsg;
69 extern bool parseCompilerType(Object *);
70 bool regexEquiv( const std::string &str,const std::string &them, bool checkCase );
71 bool pattern_match( const char *p, const char *s, bool checkCase );
72 void pd_log_perror(const char *msg){
73    errMsg = msg;
74 };
75
76 #include <stdarg.h>
77 int symtab_printf(const char *format, ...);
78
79 static SymtabError serr;
80
81 std::vector<Symtab *> Symtab::allSymtabs;
82 builtInTypeCollection *Symtab::builtInTypes = NULL;
83 typeCollection *Symtab::stdTypes = NULL;
84  
85 SymtabError Symtab::getLastSymtabError(){
86     return serr;
87 }
88
89 std::string Symtab::printError(SymtabError serr)
90 {
91     switch (serr){
92         case Obj_Parsing:
93             return "Failed to parse the Object"+errMsg;
94         case Syms_To_Functions:
95             return "Failed to convert Symbols to Functions";
96         case No_Such_Function:
97             return "Function does not exist";
98         case No_Such_Variable:
99             return "Variable does not exist";
100        case No_Such_Module:
101             return "Module does not exist";
102         case No_Such_Region:
103             return "Region does not exist";
104         case No_Such_Symbol:
105             return "Symbol does not exist";
106         case Not_A_File:
107             return "Not a File. Call openArchive()";
108         case Not_An_Archive:
109             return "Not an Archive. Call openFile()";
110         case Export_Error:
111             return "Error Constructing XML"+errMsg;
112         case Invalid_Flags:
113             return "Flags passed are invalid.";
114         case No_Error:
115             return "No previous Error.";
116         default:
117             return "Unknown Error";
118     }           
119 }
120
121 void Symtab::setupTypes(){
122     /*
123      * Create the "error" and "untyped" types.
124      */
125     std::string name = "<error>";
126     type_Error   = Type::createFake(name);
127     name = "<no type>";
128     type_Untyped = Type::createFake(name);
129     setupStdTypes();
130 }    
131
132 void Symtab::setupStdTypes() {
133    if(builtInTypes)
134         return;
135    builtInTypes = new builtInTypeCollection;
136    typeScalar *newType;
137
138    // NOTE: integral type  mean twos-complement
139    // -1  int, 32 bit signed integral type
140    // in stab document, size specified in bits, system size is in bytes
141    builtInTypes->addBuiltInType(newType = new typeScalar(-1, 4, "int", true));
142    newType->decrRefCount();
143    // -2  char, 8 bit type holding a character. GDB & dbx(AIX) treat as signed
144    builtInTypes->addBuiltInType(newType = new typeScalar(-2, 1, "char", true));
145    newType->decrRefCount();
146    // -3  short, 16 bit signed integral type
147    builtInTypes->addBuiltInType(newType = new typeScalar(-3, 2, "short", true));
148    newType->decrRefCount();
149    // -4  long, 32/64 bit signed integral type
150    builtInTypes->addBuiltInType(newType = new typeScalar(-4, sizeof(long), "long", true));
151    newType->decrRefCount();
152    // -5  unsigned char, 8 bit unsigned integral type
153    builtInTypes->addBuiltInType(newType = new typeScalar(-5, 1, "unsigned char"));
154    newType->decrRefCount();
155    // -6  signed char, 8 bit signed integral type
156    builtInTypes->addBuiltInType(newType = new typeScalar(-6, 1, "signed char", true));
157    newType->decrRefCount();
158    // -7  unsigned short, 16 bit unsigned integral type
159    builtInTypes->addBuiltInType(newType = new typeScalar(-7, 2, "unsigned short"));
160    newType->decrRefCount();
161    // -8  unsigned int, 32 bit unsigned integral type
162    builtInTypes->addBuiltInType(newType = new typeScalar(-8, 4, "unsigned int"));
163    newType->decrRefCount();
164    // -9  unsigned, 32 bit unsigned integral type
165    builtInTypes->addBuiltInType(newType = new typeScalar(-9, 4, "unsigned"));
166    newType->decrRefCount();
167    // -10 unsigned long, 32 bit unsigned integral type
168    builtInTypes->addBuiltInType(newType = new typeScalar(-10, sizeof(unsigned long), "unsigned long"));
169    newType->decrRefCount();
170    // -11 void, type indicating the lack of a value
171    //  XXX-size may not be correct jdd 4/22/99
172    builtInTypes->addBuiltInType(newType = new typeScalar(-11, 0, "void", false));
173    newType->decrRefCount();
174    // -12 float, IEEE single precision
175    builtInTypes->addBuiltInType(newType = new typeScalar(-12, sizeof(float), "float", true));
176    newType->decrRefCount();
177    // -13 double, IEEE double precision
178    builtInTypes->addBuiltInType(newType = new typeScalar(-13, sizeof(double), "double", true));
179    newType->decrRefCount();
180    // -14 long double, IEEE double precision, size may increase in future
181    builtInTypes->addBuiltInType(newType = new typeScalar(-14, sizeof(long double), "long double", true));
182    newType->decrRefCount();
183    // -15 integer, 32 bit signed integral type
184    builtInTypes->addBuiltInType(newType = new typeScalar(-15, 4, "integer", true));
185    newType->decrRefCount();
186    // -16 boolean, 32 bit type. GDB/GCC 0=False, 1=True, all other values
187    //  have unspecified meaning
188    builtInTypes->addBuiltInType(newType = new typeScalar(-16, sizeof(bool), "boolean"));
189    newType->decrRefCount();
190    // -17 short real, IEEE single precision
191    //  XXX-size may not be correct jdd 4/22/99
192    builtInTypes->addBuiltInType(newType = new typeScalar(-17, sizeof(float), "short real", true));
193    newType->decrRefCount();
194    // -18 real, IEEE double precision XXX-size may not be correct jdd 4/22/99
195    builtInTypes->addBuiltInType(newType = new typeScalar(-18, sizeof(double), "real", true));
196    newType->decrRefCount();
197    // -19 stringptr XXX- size of void * -- jdd 4/22/99
198    builtInTypes->addBuiltInType(newType = new typeScalar(-19, sizeof(void *), "stringptr"));
199    newType->decrRefCount();
200    // -20 character, 8 bit unsigned character type
201    builtInTypes->addBuiltInType(newType = new typeScalar(-20, 1, "character"));
202    newType->decrRefCount();
203    // -21 logical*1, 8 bit type (Fortran, used for boolean or unsigned int)
204    builtInTypes->addBuiltInType(newType = new typeScalar(-21, 1, "logical*1"));
205    newType->decrRefCount();
206    // -22 logical*2, 16 bit type (Fortran, some for boolean or unsigned int)
207    builtInTypes->addBuiltInType(newType = new typeScalar(-22, 2, "logical*2"));
208    newType->decrRefCount();
209    // -23 logical*4, 32 bit type (Fortran, some for boolean or unsigned int)
210    builtInTypes->addBuiltInType(newType = new typeScalar(-23, 4, "logical*4"));
211    newType->decrRefCount();
212    // -24 logical, 32 bit type (Fortran, some for boolean or unsigned int)
213    builtInTypes->addBuiltInType(newType = new typeScalar(-24, 4, "logical"));
214    newType->decrRefCount();
215    // -25 complex, consists of 2 IEEE single-precision floating point values
216    builtInTypes->addBuiltInType(newType = new typeScalar(-25, sizeof(float)*2, "complex", true));
217    newType->decrRefCount();
218    // -26 complex, consists of 2 IEEE double-precision floating point values
219    builtInTypes->addBuiltInType(newType = new typeScalar(-26, sizeof(double)*2, "complex*16", true));
220    newType->decrRefCount();
221    // -27 integer*1, 8 bit signed integral type
222    builtInTypes->addBuiltInType(newType = new typeScalar(-27, 1, "integer*1", true));
223    newType->decrRefCount();
224    // -28 integer*2, 16 bit signed integral type
225    builtInTypes->addBuiltInType(newType = new typeScalar(-28, 2, "integer*2", true));
226    newType->decrRefCount();
227
228    /* Quick hack to make integer*4 compatible with int for Fortran
229       jnb 6/20/01 */
230    // This seems questionable - let's try removing that hack - jmo 05/21/04
231    /*
232      builtInTypes->addBuiltInType(newType = new type("int",-29,
233      built_inType, 4));
234      newType->decrRefCount();
235    */
236    // -29 integer*4, 32 bit signed integral type
237    builtInTypes->addBuiltInType(newType = new typeScalar(-29, 4, "integer*4", true));
238    newType->decrRefCount();
239    // -30 wchar, Wide character, 16 bits wide, unsigned (unknown format)
240    builtInTypes->addBuiltInType(newType = new typeScalar(-30, 2, "wchar"));
241    newType->decrRefCount();
242 #if defined(os_windows)
243    // -31 long long, 64 bit signed integral type
244    builtInTypes->addBuiltInType(newType = new typeScalar(-31, sizeof(LONGLONG), "long long", true));
245    newType->decrRefCount();
246    // -32 unsigned long long, 64 bit unsigned integral type
247    builtInTypes->addBuiltInType(newType = new typeScalar(-32, sizeof(ULONGLONG), "unsigned long long"));
248    newType->decrRefCount();
249 #else
250    // -31 long long, 64 bit signed integral type
251    builtInTypes->addBuiltInType(newType = new typeScalar(-31, sizeof(long long), "long long", true));
252    newType->decrRefCount();
253    // -32 unsigned long long, 64 bit unsigned integral type
254    builtInTypes->addBuiltInType(newType = new typeScalar(-32, sizeof(unsigned long long), "unsigned long long"));
255    newType->decrRefCount();
256 #endif
257    // -33 logical*8, 64 bit unsigned integral type
258    builtInTypes->addBuiltInType(newType = new typeScalar(-33, 8, "logical*8"));
259    newType->decrRefCount();
260    // -34 integer*8, 64 bit signed integral type
261    builtInTypes->addBuiltInType(newType = new typeScalar(-34, 8, "integer*8", true));
262    newType->decrRefCount();
263
264         /*
265     * Initialize hash table of standard types.
266     */
267         if(stdTypes)
268         return;
269    stdTypes = typeCollection::getGlobalTypeCollection();
270    stdTypes->addType(newType = new typeScalar(-1, sizeof(int), "int"));
271    newType->decrRefCount();
272
273    Type *charType = new typeScalar(-2, sizeof(char), "char");
274    stdTypes->addType(charType);
275
276         std::string tName = "char *";
277         typePointer *newPtrType;
278    stdTypes->addType(newPtrType = new typePointer(-3, charType, tName));
279    charType->decrRefCount();
280    newPtrType->decrRefCount();
281
282    Type *voidType = new typeScalar(-11, 0, "void", false);
283    stdTypes->addType(voidType);
284
285         tName = "void *";
286    stdTypes->addType(newPtrType = new typePointer(-4, voidType, tName));
287    voidType->decrRefCount();
288    newPtrType->decrRefCount();
289
290    stdTypes->addType(newType = new typeScalar(-12, sizeof(float), "float"));
291    newType->decrRefCount();
292 #if defined(i386_unknown_nt4_0)
293    stdTypes->addType(newType = new typeScalar(-31, sizeof(LONGLONG), "long long"));    
294 #else
295    stdTypes->addType(newType = new typeScalar(-31, sizeof(long long), "long long"));
296 #endif
297         newType->decrRefCount();
298
299    return;
300 }
301
302 DLLEXPORT unsigned Symtab::getAddressWidth() const 
303 {
304    return address_width_;
305 }
306  
307 DLLEXPORT bool Symtab::isNativeCompiler() const 
308 {
309     return nativeCompiler; 
310 }
311  
312 DLLEXPORT Symtab::Symtab(MappedFile *mf_) :
313    Annotatable<Symbol *, user_funcs_a, true>(),
314    Annotatable<Region *, user_regions_a, true>(),
315    Annotatable<Type *, user_types_a, true>(),
316    Annotatable<Symbol *, user_symbols_a, true>(),
317    mf(mf_), mfForDebugInfo(mf_),
318    obj_private(NULL)
319 {   
320
321 }   
322
323
324 DLLEXPORT Symtab::Symtab() :
325    obj_private(NULL)
326 {
327   symtab_printf("%s[%d]: Created symtab via default constructor\n", FILE__, __LINE__);
328     defaultNamespacePrefix = "";
329 }
330
331 DLLEXPORT bool Symtab::isExec() const 
332 {
333     return is_a_out; 
334 }
335
336 DLLEXPORT bool Symtab::isStripped() 
337 {
338 #if defined(os_linux) || defined(os_solaris)
339     Region *sec;
340     return findRegion(sec,".symtab");
341 #else
342     return (no_of_symbols==0);
343 #endif
344 }
345
346 DLLEXPORT Offset Symtab::imageOffset() const 
347 {
348     return imageOffset_;
349 }
350
351 DLLEXPORT Offset Symtab::dataOffset() const 
352
353     return dataOffset_;
354 }
355
356 DLLEXPORT Offset Symtab::dataLength() const 
357 {
358     return dataLen_;
359
360
361 DLLEXPORT Offset Symtab::imageLength() const 
362 {
363     return imageLen_;
364 }
365
366 DLLEXPORT char* Symtab::image_ptr ()  const 
367 {
368    return code_ptr_;
369 }
370
371 DLLEXPORT char* Symtab::data_ptr ()  const 
372
373    return data_ptr_;
374 }
375
376 DLLEXPORT const char*  Symtab::getInterpreterName() const 
377 {
378    if (interpreter_name_.length())
379       return interpreter_name_.c_str();
380    return NULL;
381 }
382  
383 DLLEXPORT Offset Symtab::getEntryOffset() const 
384
385    return entry_address_;
386 }
387
388 DLLEXPORT Offset Symtab::getBaseOffset() const 
389 {
390    return base_address_;
391 }
392
393 DLLEXPORT Offset Symtab::getLoadOffset() const 
394
395    return load_address_;
396 }
397
398 DLLEXPORT Offset Symtab::getTOCoffset() const 
399 {
400    return toc_offset_;
401 }
402
403 DLLEXPORT string Symtab::getDefaultNamespacePrefix() const{
404     return defaultNamespacePrefix;
405 }
406         
407         
408 // TODO -- is this g++ specific
409 bool Symtab::buildDemangledName( const std::string &mangled, 
410       std::string &pretty,
411       std::string &typed,
412       bool nativeCompiler, 
413       supportedLanguages lang )
414 {
415    /* The C++ demangling function demangles MPI__Allgather (and other MPI__
416     * functions with start with A) into the MPI constructor.  In order to
417     * prevent this a hack needed to be made, and this seemed the cleanest
418     * approach.
419     */
420
421    if ((mangled.length()>5) && (mangled.substr(0,5)==std::string("MPI__"))) { 
422       return false;
423    }      
424
425    /* If it's Fortran, eliminate the trailing underscores, if any. */
426    if (lang == lang_Fortran 
427          || lang == lang_CMFortran 
428          || lang == lang_Fortran_with_pretty_debug )
429    {
430       if ( mangled[ mangled.length() - 1 ] == '_' ) 
431       {
432          char * demangled = strdup( mangled.c_str() );
433          demangled[ mangled.length() - 1 ] = '\0';
434          pretty = std::string( demangled );
435
436          free ( demangled );
437          return true;
438       }
439       else {
440          /* No trailing underscores, do nothing */
441          return false;
442       }
443    } /* end if it's Fortran. */
444
445    //  Check to see if we have a gnu versioned symbol on our hands.
446    //  These are of the form <symbol>@<version> or <symbol>@@<version>
447    //
448    //  If we do, we want to create a "demangled" name for the one that
449    //  is of the form <symbol>@@<version> since this is, by definition,
450    //  the default.  The "demangled" name will just be <symbol>
451
452    //  NOTE:  this is just a 0th order approach to dealing with versioned
453    //         symbols.  We may need to do something more sophisticated
454    //         in the future.  JAW 10/03
455
456 #if !defined(os_windows)
457    char *atat;
458    if (NULL != (atat = strstr(mangled.c_str(), "@@"))) 
459    {
460         pretty = mangled.substr(0 /*start pos*/, 
461                         (int)(atat - mangled.c_str())/*len*/);
462         char msg[256];
463         sprintf(msg, "%s[%d]: 'demangling' versioned symbol: %s, to %s",
464                   __FILE__, __LINE__, mangled.c_str(), pretty.c_str());
465         //cerr << msg << endl;
466         //logLine(msg);
467       
468         return true;
469     }
470 #endif
471
472     bool retval = false;
473   
474     /* Try demangling it. */
475     char * demangled = P_cplus_demangle( mangled.c_str(), nativeCompiler, false);
476     if (demangled) 
477     {
478         pretty = std::string( demangled );
479         retval = true;
480     }
481   
482     char *t_demangled = P_cplus_demangle(mangled.c_str(), nativeCompiler, true);
483     if (t_demangled && (strcmp(t_demangled, demangled) != 0)) 
484     {
485         typed = std::string(t_demangled);
486         retval = true;
487     }
488
489     if (demangled)
490         free(demangled);
491     if (t_demangled)
492         free(t_demangled);
493
494     return retval;
495 } /* end buildDemangledName() */
496
497  
498 /*
499  * Add all the functions (*) in the list of symbols to our data
500  * structures. 
501  *
502  * We do a search for a "main" symbol (a couple of variants), and
503  * if found we flag this image as the executable (a.out). 
504  */
505
506 bool Symtab::symbolsToFunctions(Object *linkedFile, std::vector<Symbol *> *raw_funcs) 
507 {
508
509 #if defined(TIMED_PARSE)
510    struct timeval starttime;
511    gettimeofday(&starttime, NULL);
512 #endif
513
514     std::vector< Symbol *> lookUps;
515     std::string symString;
516
517     // find the real functions -- those with the correct type in the symbol table
518     for (SymbolIter symIter(*linkedFile); symIter;symIter++) 
519     {
520         Symbol *lookUp = symIter.currval();
521         const char *np = lookUp->getName().c_str();
522
523         //parsing_printf("Scanning file: symbol %s\n", lookUp->getName().c_str());
524
525         //fprintf(stderr,"np %s\n",np);
526
527         if (is_eel_ && (np[0] == '.'))
528            /* ignore these EEL symbols; we don't understand their values */
529            continue; 
530         
531         // check for undefined dynamic symbols. Used when rewriting relocation section.
532         // relocation entries have references to these undefined dynamic symbols.
533         // We also have undefined symbols for the static binary case.
534         if (lookUp->getSec() == NULL) {
535         //if (lookUp->getSec() == NULL && lookUp->isInDynSymtab()) {
536             undefDynSyms[np] = lookUp;
537             continue;
538         }
539
540         if (lookUp->getType() == Symbol::ST_FUNCTION) 
541             {
542             // /* DEBUG */ fprintf( stderr, "%s[%d]: considering function symbol %s in module %s\n", FILE__, __LINE__, lookUp.getName().c_str(), lookUp.getModuleName().c_str() );
543             
544             std::string msg;
545             char tempBuffer[40];
546             if (!isValidOffset(lookUp->getAddr())) 
547             {
548                 sprintf(tempBuffer,"0x%lx",lookUp->getAddr());
549                 msg = std::string("Function ") + lookUp->getName() + std::string(" has bad address ")
550                                                                             + std::string(tempBuffer);
551                 return false;
552             }
553             // Fill in _mods.
554             Module *newMod = getOrCreateModule(lookUp->getModuleName(),lookUp->getAddr());
555             lookUp->setModule(newMod);
556             raw_funcs->push_back(lookUp);
557         }
558         if (lookUp->getType() == Symbol::ST_MODULE)
559         {
560             const std::string mangledName = symIter.currkey();
561             Module *newMod = getOrCreateModule(lookUp->getModuleName(),lookUp->getAddr());
562             lookUp->setModule(newMod);
563             char * unmangledName =
564                 P_cplus_demangle( mangledName.c_str(), nativeCompiler, false);
565             if (unmangledName)
566                 lookUp->addPrettyName(unmangledName, true);
567             else
568                 lookUp->addPrettyName(mangledName, true);
569             addModuleName(lookUp,mangledName);
570             modSyms.push_back(lookUp);
571         }
572         else if (lookUp->getType() == Symbol::ST_NOTYPE)
573         {
574             const std::string mangledName = symIter.currkey();
575             Module *newMod = getOrCreateModule(lookUp->getModuleName(),lookUp->getAddr());
576             lookUp->setModule(newMod);
577             char * unmangledName =
578                 P_cplus_demangle( mangledName.c_str(), nativeCompiler, false);
579             if (unmangledName)
580                 lookUp->addPrettyName(unmangledName, true);
581             else
582                 lookUp->addPrettyName(mangledName, true);
583             notypeSyms.push_back(lookUp);
584         }       
585         else if (lookUp->getType() == Symbol::ST_OBJECT)
586         {
587             const std::string mangledName = symIter.currkey();
588 #if !defined(os_windows)
589          // Windows: variables are created with an empty module
590             if (lookUp->getModuleName().length() == 0) 
591             {
592                 //fprintf(stderr, "SKIPPING EMPTY MODULE\n");
593                 continue;
594             }
595 #endif
596             char * unmangledName =
597                     P_cplus_demangle( mangledName.c_str(), nativeCompiler, false);
598                             
599             //Fill in _mods.
600             Module *newMod = getOrCreateModule(lookUp->getModuleName(),lookUp->getAddr());
601             lookUp->setModule(newMod);
602             Symbol *var;
603             //bool addToPretty = false;
604             if (varsByAddr.find(lookUp->getAddr())!=varsByAddr.end()) 
605             {
606                 var = varsByAddr[lookUp->getAddr()];
607                                     
608                 // Keep the new mangled name
609                 var->addMangledName(mangledName);
610                 if (unmangledName)
611                 var->addPrettyName(unmangledName, true);
612                 else
613                 var->addPrettyName(mangledName, true);
614                                     
615             }
616             else
617             {
618                 var = lookUp;
619                 varsByAddr[lookUp->getAddr()] = var;
620                 if (unmangledName)
621                     var->addPrettyName(unmangledName, true);
622                 else
623                     var->addPrettyName(mangledName, true);
624                 everyUniqueVariable.push_back(var);
625             }
626         }
627
628     }
629
630 #if defined(TIMED_PARSE)
631         struct timeval endtime;
632         gettimeofday(&endtime, NULL);
633         unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
634         unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
635         unsigned long difftime = lendtime - lstarttime;
636         double dursecs = difftime/(1000 );
637         cout << __FILE__ << ":" << __LINE__ <<": symbolsToFunctions took "<<dursecs <<" msecs" << endl;
638 #endif
639     return true;
640 }
641
642 #if defined(ppc64_linux)
643 /* Special case for ppc64 ELF binaries. Sometimes a function has a 3-byte descriptor symbol
644  * along with it in the symbol table and "." preceding its original pretty name for the correct
645  * function symbol. This checks to see if we have a corresponding 3-byte descriptor symbol existing
646  * and if it does we remove the preceding "." from the name of the symbol
647  */
648
649 void Symtab::checkPPC64DescriptorSymbols(Object *linkedFile)
650 {
651    // find the real functions -- those with the correct type in the symbol table
652    for(SymbolIter symIter(*linkedFile); symIter;symIter++)
653    {
654       Symbol *lookUp = symIter.currval();
655       const char *np = lookUp->getName().c_str();
656       if(!np)
657          continue;
658       
659       if(np[0] == '.' && (lookUp->getType() == Symbol::ST_FUNCTION))
660       {
661          std::vector<Symbol *>syms;
662          std::string newName = np+1;
663          if(linkedFile->get_symbols(newName, syms) && (syms[0]->getSize() == 24 || syms[0]->getSize() == 0))
664          {
665             //Remove the "." from the name
666             lookUp->mangledNames[0] = newName;
667
668             //Change the type of the descriptor symbol
669             syms[0]->type_ = Symbol::ST_NOTYPE;
670          }
671       }
672    }
673
674 }
675
676 #endif
677
678 //  setModuleLanguages is only called after modules have been defined.
679 //  it attempts to set each module's language, information which is needed
680 //  before names can be demangled.
681 void Symtab::setModuleLanguages(dyn_hash_map<std::string, supportedLanguages> *mod_langs)
682 {
683    if (!mod_langs->size())
684       return;  // cannot do anything here
685    //  this case will arise on non-stabs platforms until language parsing can be introduced at this level
686    std::vector<Module *> *modlist;
687    Module *currmod = NULL;
688    modlist = &_mods;
689    //int dump = 0;
690
691    for (unsigned int i = 0;  i < modlist->size(); ++i)
692    {
693       currmod = (*modlist)[i];
694       supportedLanguages currLang;
695       if (currmod->isShared()) {
696          continue;  // need to find some way to get shared object languages?
697       }
698
699       const std::string fn = currmod->fileName();
700       if (mod_langs->find(currmod->fileName()) != mod_langs->end())
701       {
702          currLang = (*mod_langs)[fn];
703       }
704       else if (fn.rfind(".s") != std::string::npos ||
705                fn.rfind(".asm") != std::string::npos)
706       {
707          currLang = lang_Assembly;
708       }
709       else if (fn.rfind(".c") != std::string::npos)
710       {
711          currLang = lang_C;
712       }
713       else if (fn.rfind(".cpp") != std::string::npos ||
714                fn.rfind(".cc") != std::string::npos ||
715                fn.rfind(".C") != std::string::npos)
716       {
717          currLang = lang_CPlusPlus;
718       }
719       else
720       {
721          continue;
722       }
723       currmod->setLanguage(currLang);
724    }
725 }
726
727 Module *Symtab::getOrCreateModule(const std::string &modName, 
728       const Offset modAddr)
729 {
730    std::string nameToUse;
731    if (modName.length() > 0)
732       nameToUse = modName;
733    else
734       nameToUse = "DEFAULT_MODULE";
735
736    Module *fm = NULL;
737    if (findModule(fm, nameToUse)) {
738         return fm;
739     }
740
741     const char *str = nameToUse.c_str();
742     int len = nameToUse.length();
743     assert(len>0);
744
745     // TODO ignore directory definitions for now
746     if (str[len-1] == '/') 
747         return NULL;
748
749     return (newModule(nameToUse, modAddr, lang_Unknown));
750 }
751  
752 Module *Symtab::newModule(const std::string &name, const Offset addr, supportedLanguages lang)
753 {
754     Module *ret = new Module();
755     // modules can be defined several times in C++ due to templates and
756     //   in-line member functions.
757     if (findModule(ret, name)) {
758         return(ret);
759     }
760     delete ret;
761
762     //parsing_printf("=== image, creating new pdmodule %s, addr 0x%x\n",
763     //                          name.c_str(), addr);
764     
765     std::string fileNm, fullNm;
766     fullNm = name;
767     fileNm = extract_pathname_tail(name);
768
769     // /* DEBUG */ fprintf( stderr, "%s[%d]: Creating new pdmodule '%s'/'%s'\n", FILE__, __LINE__, fileNm.c_str(), fullNm.c_str() );
770     ret = new Module(lang, addr, fullNm, this);
771     modsByFileName[ret->fileName()] = ret;
772     modsByFullName[ret->fullName()] = ret;
773     _mods.push_back(ret);
774     
775     return(ret);
776 }
777
778  
779 //buildFunctionLists() iterates through image_funcs and constructs demangled 
780 //names. Demangling was moved here (names used to be demangled as image_funcs 
781 //were built) so that language information could be obtained _after_ the 
782 //functions and modules were built, but before name demangling takes place.  
783 //Thus we can use language information during the demangling process.
784
785 bool Symtab::buildFunctionLists(std::vector <Symbol *> &raw_funcs)
786 {
787 #if defined(TIMED_PARSE)
788    struct timeval starttime;
789    gettimeofday(&starttime, NULL);
790 #endif
791    for (unsigned int i = 0; i < raw_funcs.size(); i++) 
792    {
793       Symbol *raw = raw_funcs[i];
794       Module *rawmod = getOrCreateModule(raw->getModuleName(),raw->getAddr());
795
796       assert(raw);
797       assert(rawmod);
798
799       // At this point we need to generate the following information:
800       // A symtab name.
801       // A pretty (demangled) name.
802       // The symtab name goes in the global list as well as the module list.
803       // Same for the pretty name.
804       // Finally, check addresses to find aliases.
805
806       std::string mangled_name = raw->getName();
807       std::string working_name = mangled_name;
808
809       std::string pretty_name = "<UNSET>";
810       std::string typed_name = "<UNSET>";
811 #if !defined(os_windows)        
812       //Remove extra stabs information
813       const char *p = strchr(working_name.c_str(), ':');
814       if( p )
815       {
816          unsigned nchars = p - mangled_name.c_str();
817          working_name = std::string(mangled_name.c_str(), nchars);
818       }
819 #endif        
820       if (!buildDemangledName(working_name, pretty_name, typed_name,
821                nativeCompiler, rawmod->language())) 
822       {
823          pretty_name = working_name;
824       }
825
826       //parsing_printf("%s: demangled %s, typed %s\n",
827       //               mangled_name.c_str(),
828       //               pretty_name.c_str(),
829       //               typed_name.c_str());
830
831       // Now, we see if there's already a function object for this
832       // address. If so, add a new name; 
833       Symbol *possiblyExistingFunction = NULL;
834       //funcsByEntryAddr.find(raw->getAddr(), possiblyExistingFunction);
835       if (funcsByEntryAddr.find(raw->getAddr())!=funcsByEntryAddr.end()) 
836       {
837          std::vector<Symbol *> &funcs = funcsByEntryAddr[raw->getAddr()];
838          unsigned flag = 0;
839          for(unsigned int j=0;j<funcs.size();j++)
840          {
841             possiblyExistingFunction = funcsByEntryAddr[raw->getAddr()][j];
842             // On some platforms we see two symbols, one in a real module
843             // and one in DEFAULT_MODULE. Replace DEFAULT_MODULE with
844             // the real one
845             Module *use = getOrCreateModule(possiblyExistingFunction->getModuleName(),
846                   possiblyExistingFunction->getAddr());
847             if(!(*rawmod == *use))
848             {
849                if (rawmod->fileName() == "DEFAULT_MODULE")
850                   rawmod = use;
851                if(use->fileName() == "DEFAULT_MODULE") 
852                {
853                   possiblyExistingFunction->setModuleName(std::string(rawmod->fullName()));
854                   use = rawmod; 
855                }
856             }
857
858             if(*rawmod == *use)
859             {
860                // Keep the new mangled name
861                possiblyExistingFunction->addMangledName(mangled_name);
862                if (pretty_name != "<UNSET>")
863                   possiblyExistingFunction->addPrettyName(pretty_name);
864                if (typed_name != "<UNSET>")
865                   possiblyExistingFunction->addTypedName(typed_name);
866                raw_funcs[i] = NULL;
867                delete raw; // Don't leak
868                flag = 1;        
869                break;
870             }   
871          }      
872          if(!flag)
873          {
874                 funcsByEntryAddr[raw->getAddr()].push_back(raw);
875                 addFunctionName(raw, mangled_name, true);
876                 if (pretty_name != "<UNSET>")
877                     raw->addPrettyName(pretty_name, true);
878                 if (typed_name != "<UNSET>")
879                     raw->addTypedName(typed_name, true);
880             }
881         }
882         else
883         {
884             funcsByEntryAddr[raw->getAddr()].push_back(raw);
885             addFunctionName(raw, mangled_name, true);
886             if (pretty_name != "<UNSET>")
887                                     raw->addPrettyName(pretty_name, true);
888             if (typed_name != "<UNSET>")
889                 raw->addTypedName(typed_name, true);
890                 
891         }
892     }
893     
894     // Now that we have a 1) unique and 2) demangled list of function
895     // names, loop through once more and build the address range tree
896     // and name lookup tables. 
897     for (unsigned j = 0; j < raw_funcs.size(); j++) 
898     {
899         Symbol *func = raw_funcs[j];
900         if (!func) continue;
901         
902         // May be NULL if it was an alias.
903         enterFunctionInTables(func, true);
904     }
905     
906     // Conspicuous lack: inst points. We're delaying.
907 #if defined(TIMED_PARSE)
908     struct timeval endtime;
909     gettimeofday(&endtime, NULL);
910     unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
911     unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
912     unsigned long difftime = lendtime - lstarttime;
913     double dursecs = difftime/(1000 );
914     cout << __FILE__ << ":" << __LINE__ <<": buildFunction Lists took "<<dursecs <<" msecs" << endl;
915 #endif
916     return true;
917
918
919 // Enter a function in all the appropriate tables
920 void Symtab::enterFunctionInTables(Symbol *func, bool wasSymtab)
921 {
922     if (!func)
923         return;
924     
925     funcsByEntryAddr[func->getAddr()].push_back(func);
926     // Functions added during symbol table parsing do not necessarily
927     // have valid sizes set, and should therefor not be added to
928     // the code range tree. They will be added after parsing. 
929     /*if(!wasSymtab)
930         {
931         // TODO: out-of-line insertion here
932         //if (func->get_size_cr())
933         //      funcsByRange.insert(func);
934         }*/
935     
936     everyUniqueFunction.push_back(func);
937     if (wasSymtab)
938         exportedFunctions.push_back(func);
939     else {
940        Annotatable<Symbol *, user_funcs_a, true> &ufA = *this;
941        ufA.addAnnotation(func);
942     }
943 }
944
945 bool Symtab::addSymbol(Symbol *newSym, Symbol *referringSymbol) {
946     if (!newSym)
947         return false;
948     string filename = referringSymbol->getModule()->exec()->name();
949     vector<string> *vers, *newSymVers = new vector<string>;
950     if(referringSymbol->getVersions(vers)){
951         newSym->setVersionFileName(filename);
952         newSymVers->push_back((*vers)[0]);
953         newSym->setVersions(*newSymVers);
954     }
955
956     //Check again. Is this an ok thing to do??
957     undefDynSyms[newSym->getPrettyName()] = newSym;
958     return addSymbol(newSym, true);
959 }
960
961 bool Symtab::addSymbol(Symbol *newSym, bool isDynamic) 
962 {
963    //  This is the public flavor of addSymbol, and just calls the private one with 
964    //  the from_user flag set...  should not be called internally
965    return addSymbolInt(newSym, true, isDynamic);
966 }
967
968 bool Symtab::addSymbolInt(Symbol *newSym,bool from_user,  bool isDynamic)
969 {
970     if (!newSym)
971         return false;
972
973     if (isDynamic) {
974         newSym->clearIsInSymtab();
975         newSym->setDynSymtab();
976     }   
977
978     std::vector<std::string> names;
979     char *unmangledName = NULL;
980     std::string sname = newSym->getName();
981
982 #if !defined(os_windows)
983     // Windows: variables are created with an empty module
984     if (newSym->getModuleName().length() == 0) 
985     {
986         //fprintf(stderr, "SKIPPING EMPTY MODULE\n");
987         return false;
988     }
989 #endif
990
991     if( ! newSym->getModule()) {
992         Module *newMod = getOrCreateModule
993             (newSym->getModuleName(), newSym->getAddr());
994     newSym->setModule(newMod);
995     }
996
997     if (newSym->getAllPrettyNames().size() == 0)
998         unmangledName = P_cplus_demangle(sname.c_str(), nativeCompiler,false);
999
1000     if (newSym->getType() == Symbol::ST_FUNCTION)
1001     {
1002         names = newSym->getAllMangledNames();
1003         for(unsigned i=0;i<names.size();i++)
1004             addFunctionName(newSym, names[i], true);
1005         names = newSym->getAllPrettyNames();
1006         for(unsigned i=0;i<names.size();i++)
1007             addFunctionName(newSym, names[i], false);
1008         names = newSym->getAllTypedNames();
1009         for(unsigned i=0;i<names.size();i++)
1010             addFunctionName(newSym, names[i], false);
1011         enterFunctionInTables(newSym,false);
1012     }
1013     else if(newSym->getType() == Symbol::ST_OBJECT)
1014     {
1015         names = newSym->getAllMangledNames();
1016         for(unsigned i=0;i<names.size();i++)
1017             addVariableName(newSym, names[i], true);
1018         names = newSym->getAllPrettyNames();
1019         for(unsigned i=0;i<names.size();i++)
1020             addVariableName(newSym, names[i], false);
1021         names = newSym->getAllTypedNames();
1022         for(unsigned i=0;i<names.size();i++)
1023             addVariableName(newSym, names[i], false);
1024         everyUniqueVariable.push_back(newSym);    
1025     }
1026     else if(newSym->getType() == Symbol::ST_MODULE)
1027     {
1028         names = newSym->getAllMangledNames();
1029         for(unsigned i=0;i<names.size();i++)
1030             addModuleName(newSym, names[i]);
1031         names = newSym->getAllPrettyNames();
1032         for(unsigned i=0;i<names.size();i++)
1033             addModuleName(newSym, names[i]);
1034         modSyms.push_back(newSym);
1035     }   
1036     else
1037         notypeSyms.push_back(newSym);
1038
1039     if (!newSym->getAllPrettyNames().size()) // add the unmangledName if there are no prettyNames
1040     {
1041         if (unmangledName)
1042             newSym->addPrettyName(unmangledName, true);
1043         else
1044             newSym->addPrettyName(sname,true);
1045     }           
1046
1047     if (from_user) {
1048        //  The case that is yet unaccounted for is if the user adds a symbols
1049        //  that causes the creation of a new module...  to be correct-ish here
1050        //  this module should be acknowledged as "different"
1051        Annotatable<Symbol *, user_symbols_a, true> &usA = *this;
1052        usA.addAnnotation(newSym);
1053     }
1054
1055     return true;
1056 }
1057
1058 void Symtab::addFunctionName(Symbol *func,
1059                                  const std::string newName,
1060                                  bool isMangled /*=false*/)
1061 {    
1062     // Ensure a std::vector exists
1063     if (isMangled == false) {
1064         if(funcsByPretty.find(newName)==funcsByPretty.end())
1065             funcsByPretty[newName] = new std::vector<Symbol *>;
1066         funcsByPretty[newName]->push_back(func);    
1067     }
1068     else {
1069         if(funcsByMangled.find(newName)==funcsByMangled.end())
1070             funcsByMangled[newName] = new std::vector<Symbol *>;
1071         funcsByMangled[newName]->push_back(func);    
1072     }
1073 }
1074
1075 void Symtab::addVariableName(Symbol *var,
1076                                  const std::string newName,
1077                                  bool isMangled /*=false*/)
1078 {    
1079    // Ensure a vector exists
1080     if (isMangled == false) {
1081         if(varsByPretty.find(newName)==varsByPretty.end())
1082             varsByPretty[newName] = new std::vector<Symbol *>;
1083         varsByPretty[newName]->push_back(var);    
1084     }
1085     else {
1086         if (varsByMangled.find(newName)==varsByMangled.end())
1087             varsByMangled[newName] = new std::vector<Symbol *>;
1088         varsByMangled[newName]->push_back(var);    
1089     }
1090 }
1091
1092  
1093 void Symtab::addModuleName(Symbol *mod, const std::string newName)
1094 {
1095     if (modsByName.find(newName)==modsByName.end())
1096         modsByName[newName] = new std::vector<Symbol *>;
1097     modsByName[newName]->push_back(mod);    
1098 }
1099
1100 Symtab::Symtab(std::string filename,bool &err) :
1101    is_a_out(false), 
1102    main_call_addr_(0),
1103    nativeCompiler(false), 
1104    isLineInfoValid_(false), 
1105    isTypeInfoValid_(false),
1106    obj_private(NULL),
1107    type_Error(NULL), 
1108    type_Untyped(NULL)
1109 {
1110    // Initialize error parameter
1111    err = false;
1112    
1113    symtab_printf("%s[%d]: created symtab for %s\n", FILE__, __LINE__, filename.c_str());
1114 #if defined (os_windows)
1115    extern void fixup_filename(std::string &);
1116    fixup_filename(filename);
1117 #endif
1118    //  createMappedFile handles reference counting
1119    mf = MappedFile::createMappedFile(filename);
1120    if (!mf) {
1121       symtab_printf("%s[%d]: WARNING: creating symtab for %s, " 
1122                     "createMappedFile() failed\n", FILE__, __LINE__, 
1123                     filename.c_str());
1124       err = true;
1125       return;
1126    }
1127    obj_private = new Object(mf, mfForDebugInfo, pd_log_perror, true);
1128    if(!extractInfo(obj_private))
1129    {
1130       symtab_printf("%s[%d]: WARNING: creating symtab for %s, extractInfo() " 
1131                     "failed\n", FILE__, __LINE__, filename.c_str());
1132       err = true;
1133    }
1134    defaultNamespacePrefix = "";
1135 }
1136
1137
1138 Symtab::Symtab(char *mem_image, size_t image_size, bool &err) :
1139    is_a_out(false), 
1140    main_call_addr_(0),
1141    nativeCompiler(false),
1142    isLineInfoValid_(false),
1143    isTypeInfoValid_(false),
1144    obj_private(NULL),
1145    type_Error(NULL), 
1146    type_Untyped(NULL)
1147 {
1148    // Initialize error parameter
1149    err = false;
1150   
1151    symtab_printf("%s[%d]: created symtab for memory image at addr %u\n", 
1152                  FILE__, __LINE__, mem_image);
1153    //  createMappedFile handles reference counting
1154    mf = MappedFile::createMappedFile(mem_image, image_size);
1155    if (!mf) {
1156       symtab_printf("%s[%d]: WARNING: creating symtab for memory image at " 
1157                     "addr %u, createMappedFile() failed\n", FILE__, __LINE__, 
1158                     mem_image);
1159       err = true;
1160       return;
1161    }
1162    obj_private = new Object(mf, mfForDebugInfo, pd_log_perror, true);
1163    if(!extractInfo(obj_private))
1164    {
1165       symtab_printf("%s[%d]: WARNING: creating symtab for memory image at addr" 
1166                     "%u, extractInfo() failed\n", FILE__, __LINE__, mem_image);
1167       err = true;
1168    }
1169    defaultNamespacePrefix = "";
1170 }
1171
1172 // Symtab constructor for archive members
1173 #if defined(os_aix) || defined(os_linux) || defined(os_solaris)
1174 Symtab::Symtab(std::string filename, std::string member_name, Offset offset, 
1175                bool &err, void *base) :
1176    member_name_(member_name), 
1177    member_offset_(offset),
1178    is_a_out(false),
1179    main_call_addr_(0), 
1180    nativeCompiler(false), 
1181    isLineInfoValid_(false),
1182    isTypeInfoValid_(false), 
1183    obj_private(NULL),
1184    type_Error(NULL), 
1185    type_Untyped(NULL)
1186 {
1187    mf = MappedFile::createMappedFile(filename);
1188    assert(mf);
1189    obj_private = new Object(mf, mfForDebugInfo, member_name, offset, pd_log_perror, base);
1190    err = extractInfo(obj_private);
1191    defaultNamespacePrefix = "";
1192 }
1193 #else
1194 Symtab::Symtab(std::string, std::string, Offset, bool &, void *base)
1195 {
1196     assert(0);
1197 }
1198 #endif
1199
1200 #if defined(os_aix) || defined(os_linux) || defined(os_solaris)
1201 Symtab::Symtab(char *mem_image, size_t image_size, std::string member_name,
1202                        Offset offset, bool &err, void *base) :
1203    member_name_(member_name), 
1204    is_a_out(false), 
1205    main_call_addr_(0),
1206    nativeCompiler(false), 
1207    isLineInfoValid_(false), 
1208    isTypeInfoValid_(false), 
1209    type_Error(NULL), 
1210    type_Untyped(NULL)
1211 {
1212    mf = MappedFile::createMappedFile(mem_image, image_size);
1213    assert(mf);
1214    obj_private = new Object(mf, mf, member_name, offset, pd_log_perror, base);
1215    err = extractInfo(obj_private);
1216    defaultNamespacePrefix = "";
1217 }
1218 #else 
1219 Symtab::Symtab(char *, size_t, std::string , Offset, bool &, void *)
1220 {
1221     assert(0);
1222 }
1223 #endif
1224
1225 bool sort_reg_by_addr(const Region* a, const Region* b)
1226 {
1227    return a->getRegionAddr() < b->getRegionAddr();
1228 }
1229
1230 bool Symtab::extractInfo(Object *linkedFile)
1231 {
1232 #if defined(TIMED_PARSE)
1233     struct timeval starttime;
1234     gettimeofday(&starttime, NULL);
1235 #endif
1236     mfForDebugInfo = linkedFile->getMappedFileForDebugInfo();
1237
1238     bool err = true;
1239     imageOffset_ = linkedFile->code_off();
1240     dataOffset_ = linkedFile->data_off();
1241
1242     imageLen_ = linkedFile->code_len();
1243     dataLen_ = linkedFile->data_len();
1244     
1245     if (0 == imageLen_ || 0 == linkedFile->code_ptr()) {
1246         // for AIX, code_ptr()==NULL is normal behavior
1247 #if !defined(os_aix)
1248        if (0 == linkedFile->code_ptr()) {
1249           //fprintf(stderr, "[%s][%d]WARNING: null code pointer in Symtab for"
1250           //" file %s, possibly due to a missing .text section.\n",
1251           //__FILE__,__LINE__, file().c_str());
1252           linkedFile->code_ptr_ = (char *) linkedFile->code_off();
1253        }
1254        else 
1255 #endif
1256        {
1257           serr = Obj_Parsing;
1258           return false;
1259        }
1260    }
1261         
1262   //  if (!imageLen_ || !linkedFile->code_ptr()) {
1263   //      serr = Obj_Parsing; 
1264   //      return false; 
1265    // }
1266
1267     no_of_sections = linkedFile->no_of_sections();
1268     newSectionInsertPoint = no_of_sections;
1269     no_of_symbols = linkedFile->no_of_symbols();
1270
1271     regions_ = linkedFile->getAllRegions();
1272     for(unsigned index=0;index<regions_.size();index++){
1273         if((regions_[index]->getRegionPermissions() == Region::RP_RX) || (regions_[index]->getRegionPermissions() == Region::RP_RWX))
1274             codeRegions_.push_back(regions_[index]);
1275         else if((regions_[index]->getRegionPermissions() == Region::RP_RW) || (regions_[index]->getRegionPermissions() == Region::RP_RWX))
1276             dataRegions_.push_back(regions_[index]);
1277         regionsByEntryAddr[regions_[index]->getRegionAddr()] = regions_[index];
1278     }
1279     // sort regions_ & codeRegions_ vectors
1280     std::sort(codeRegions_.begin(), codeRegions_.end(), sort_reg_by_addr);
1281     std::sort(regions_.begin(), regions_.end(), sort_reg_by_addr);
1282
1283         /* insert error check here. check if parsed */
1284     address_width_ = linkedFile->getAddressWidth();
1285     is_a_out = linkedFile->is_aout();
1286     code_ptr_ = linkedFile->code_ptr();
1287     data_ptr_ = linkedFile->data_ptr();
1288
1289     if (linkedFile->interpreter_name())
1290        interpreter_name_ = std::string(linkedFile->interpreter_name());
1291     entry_address_ = linkedFile->getEntryAddress();
1292     base_address_ = linkedFile->getBaseAddress();
1293     load_address_ = linkedFile->getLoadAddress();
1294     toc_offset_ = linkedFile->getTOCoffset();
1295     object_type_  = linkedFile->objType();
1296     is_eel_ = linkedFile->isEEL();
1297     linkedFile->getSegments(segments_);
1298
1299 #if !defined(os_aix) && !defined(os_windows)
1300     linkedFile->getDependencies(deps_);
1301 #endif
1302
1303 #if defined (os_aix)
1304     //  These should go away
1305     linkedFile->get_stab_info(stabstr_, nstabs_, stabs_, stringpool_);
1306     linkedFile->get_line_info(nlines_, lines_, fdptr_);
1307 #endif
1308
1309 #if defined(os_solaris) || defined(os_aix) || defined(os_linux)
1310     // make sure we're using the right demangler
1311     
1312     nativeCompiler = parseCompilerType(linkedFile);
1313     //parsing_printf("isNativeCompiler: %d\n", nativeCompiler);
1314 #endif
1315     
1316     // define all of the functions
1317     //statusLine("winnowing functions");
1318
1319 #if defined(ppc64_linux)
1320     checkPPC64DescriptorSymbols(linkedFile);
1321 #endif
1322
1323     // a vector to hold all created functions until they are properly classified
1324     std::vector<Symbol *> raw_funcs;
1325         
1326     // define all of the functions, this also defines all of the modules
1327     if (!symbolsToFunctions(linkedFile, &raw_funcs))
1328     {
1329         fprintf(stderr, "Error converting symbols to functions in file %s\n", mf->filename().c_str());
1330         err = false;
1331         serr = Syms_To_Functions;
1332         return false;
1333     }
1334     sort(raw_funcs.begin(),raw_funcs.end(),symbol_compare);
1335         
1336     // wait until all modules are defined before applying languages to
1337     // them we want to do it this way so that module information comes
1338     // from the function symbols, first and foremost, to avoid any
1339     // internal module-function mismatching.
1340             
1341     // get Information on the language each modules is written in
1342     // (prior to making modules)
1343     dyn_hash_map<std::string, supportedLanguages> mod_langs;
1344     linkedFile->getModuleLanguageInfo(&mod_langs);
1345     setModuleLanguages(&mod_langs);
1346         
1347     // Once languages are assigned, we can build demangled names (in
1348     // the wider sense of demangling which includes stripping _'s from
1349     // fortran names -- this is why language information must be
1350     // determined before this step).
1351     
1352     // Also identifies aliases (multiple names with equal addresses)
1353
1354     if (!buildFunctionLists(raw_funcs))
1355     {
1356         fprintf(stderr, "Error building function lists in file %s\n", mf->filename().c_str());
1357         err = false;
1358         serr = Build_Function_Lists;
1359         return false;
1360     }
1361     
1362     //addSymtabVariables();
1363     linkedFile->getAllExceptions(excpBlocks);
1364
1365     vector<relocationEntry >fbt;
1366     linkedFile->get_func_binding_table(fbt);
1367     for(unsigned i=0; i<fbt.size();i++)
1368         relocation_table_.push_back(fbt[i]);
1369     return true;
1370 }
1371
1372 Symtab::Symtab(const Symtab& obj) :
1373    LookupInterface(),
1374    Annotatable<Symbol *, user_funcs_a, true>(obj),
1375    Annotatable<Region *, user_regions_a, true>(obj),
1376    Annotatable<Type *, user_types_a, true> (obj),
1377    Annotatable<Symbol *, user_symbols_a, true>(obj)
1378 {
1379   symtab_printf("%s[%d]: Creating symtab 0x%p from symtab 0x%p\n", FILE__, __LINE__, this, &obj);
1380   
1381     member_name_ = obj.member_name_;
1382     imageOffset_ = obj.imageOffset_;
1383     imageLen_ = obj.imageLen_;
1384     dataOffset_ = obj.dataOffset_;
1385     dataLen_ = obj.dataLen_;
1386
1387     isLineInfoValid_ = obj.isLineInfoValid_;
1388     isTypeInfoValid_ = obj.isTypeInfoValid_;
1389
1390     is_a_out = obj.is_a_out;
1391     main_call_addr_ = obj.main_call_addr_; // address of call to main()
1392     
1393     nativeCompiler = obj.nativeCompiler;
1394     defaultNamespacePrefix = obj.defaultNamespacePrefix;
1395     
1396     //sections
1397     no_of_sections = obj.no_of_sections;
1398     unsigned i;
1399     for(i=0;i<obj.regions_.size();i++)
1400         regions_.push_back(new Region(*(obj.regions_[i])));
1401     for(i=0;i<regions_.size();i++)
1402         regionsByEntryAddr[regions_[i]->getRegionAddr()] = regions_[i];
1403     
1404     //symbols
1405     no_of_symbols = obj.no_of_symbols;
1406     
1407     for(i=0;i<obj.everyUniqueFunction.size();i++)
1408         everyUniqueFunction.push_back(new Symbol(*(obj.everyUniqueFunction[i])));
1409     for(i=0;i<everyUniqueFunction.size();i++)
1410     {
1411         funcsByEntryAddr[everyUniqueFunction[i]->getAddr()].push_back(everyUniqueFunction[i]);
1412         addFunctionName(everyUniqueFunction[i],everyUniqueFunction[i]->getName(),true);
1413         addFunctionName(everyUniqueFunction[i],everyUniqueFunction[i]->getPrettyName(),false);
1414     }   
1415     
1416     for(i=0;i<obj.everyUniqueVariable.size();i++)
1417         everyUniqueVariable.push_back(new Symbol(*(obj.everyUniqueVariable[i])));
1418     for(i=0;i<everyUniqueVariable.size();i++)
1419     {
1420         varsByAddr[everyUniqueVariable[i]->getAddr()] = everyUniqueVariable[i];
1421         addVariableName(everyUniqueVariable[i],everyUniqueVariable[i]->getName(),true);
1422         addVariableName(everyUniqueVariable[i],everyUniqueVariable[i]->getPrettyName(),false);
1423     }
1424
1425     for(i=0;i<obj._mods.size();i++)
1426         _mods.push_back(new Module(*(obj._mods[i])));
1427     for(i=0;i<_mods.size();i++)
1428     {
1429         modsByFileName[_mods[i]->fileName()] = _mods[i];
1430         modsByFullName[_mods[i]->fullName()] = _mods[i];
1431     }
1432     for(i=0;i<modSyms.size();i++)
1433         modSyms.push_back(new Symbol(*(modSyms[i])));
1434     
1435     for(i=0;i<notypeSyms.size();i++)
1436         notypeSyms.push_back(new Symbol(*(obj.notypeSyms[i])));
1437     
1438     for(i=0; i<relocation_table_.size();i++) {
1439         relocation_table_.push_back(relocationEntry(obj.relocation_table_[i]));
1440         undefDynSyms[obj.relocation_table_[i].name()] = relocation_table_[i].getDynSym();
1441     }
1442     
1443     for(i=0;i<excpBlocks.size();i++)
1444         excpBlocks.push_back(new ExceptionBlock(*(obj.excpBlocks[i])));
1445
1446     deps_ = obj.deps_;
1447     setupTypes();
1448 }
1449
1450 bool Symtab::findModule(Module *&ret, const std::string name)
1451 {
1452    dyn_hash_map<std::string, Module *>::iterator loc;
1453    loc = modsByFileName.find(name);
1454    if (loc != modsByFileName.end()) {
1455       ret = loc->second;
1456       return true;
1457    }
1458    loc = modsByFullName.find(name);
1459    if (loc != modsByFullName.end()) {
1460       ret = loc->second;
1461       return true;
1462    }
1463     serr = No_Such_Module;
1464     ret = NULL;
1465     return false;
1466 }
1467
1468 Module *Symtab::findModuleByOffset(Offset off)
1469 {   
1470    Module *ret = NULL;
1471    //  this should be a hash, really
1472    for (unsigned int i = 0; i < _mods.size(); ++i) {
1473       Module *mod = _mods[i];
1474       if (off == mod->addr()) {
1475          ret = mod;
1476          break;
1477       }
1478    } 
1479    return ret;
1480 }
1481
1482 bool Symtab::getAllSymbolsByType(std::vector<Symbol *> &ret, Symbol::SymbolType sType)
1483 {
1484    if(sType == Symbol::ST_FUNCTION)
1485       return getAllFunctions(ret);
1486    else if(sType == Symbol::ST_OBJECT)
1487       return getAllVariables(ret);
1488    else if(sType == Symbol::ST_MODULE)
1489     {
1490         if(modSyms.size()>0)
1491         {
1492             ret =  modSyms;
1493             return true;
1494         }
1495         serr = No_Such_Symbol;
1496         return false;
1497                 
1498     }
1499     else if(sType == Symbol::ST_NOTYPE)
1500     {
1501         if(notypeSyms.size()>0)
1502         {
1503             ret =  notypeSyms;
1504             return true;
1505         }
1506         serr = No_Such_Symbol;
1507         return false;
1508     }
1509     else
1510         return getAllSymbols(ret);
1511 }
1512  
1513  
1514 bool Symtab::getAllFunctions(std::vector<Symbol *> &ret)
1515 {
1516     if(everyUniqueFunction.size() > 0)
1517     {
1518         ret = everyUniqueFunction;
1519         return true;
1520     }   
1521     serr = No_Such_Function;
1522     return false;
1523 }
1524  
1525 bool Symtab::getAllVariables(std::vector<Symbol *> &ret)
1526 {
1527     if(everyUniqueVariable.size() > 0)
1528     {
1529         ret = everyUniqueVariable;
1530         return true;
1531     }   
1532     serr = No_Such_Variable;
1533     return false;
1534 }
1535
1536 bool Symtab::getAllSymbols(std::vector<Symbol *> &ret)
1537 {
1538     std::vector<Symbol *> temp;
1539     getAllFunctions(ret);
1540     getAllVariables(temp);
1541     ret.insert(ret.end(), temp.begin(), temp.end());
1542     temp.clear();
1543     for(unsigned i=0;i<modSyms.size();i++)
1544         ret.push_back(modSyms[i]);
1545     for(unsigned i=0;i<notypeSyms.size();i++)
1546         ret.push_back(notypeSyms[i]);
1547     if(ret.size() > 0)
1548         return true;
1549     serr = No_Such_Symbol;
1550     return false;
1551 }
1552
1553 bool Symtab::getAllUndefinedSymbols(std::vector<Symbol *> &ret){
1554     unsigned size = ret.size();
1555     map<string, Symbol *>::iterator it = undefDynSyms.begin();
1556     for(;it!=undefDynSyms.end();it++)
1557         ret.push_back(it->second);
1558     if(ret.size()>size)
1559         return true;
1560     serr = No_Such_Symbol;
1561     return false;
1562 }
1563
1564 bool Symtab::getAllModules(std::vector<Module *> &ret)
1565 {
1566     if(_mods.size()>0)
1567     {
1568         ret = _mods;
1569         return true;
1570     }   
1571     serr = No_Such_Module;
1572     return false;
1573 }
1574
1575 bool Symtab::getAllRegions(std::vector<Region *>&ret)
1576 {
1577     if(regions_.size() > 0)
1578     {
1579         ret = regions_;
1580         return true;
1581     }
1582     return false;
1583 }
1584
1585 bool Symtab::getCodeRegions(std::vector<Region *>&ret)
1586 {
1587     if(codeRegions_.size() > 0)
1588     {
1589         ret = codeRegions_;
1590         return true;
1591     }
1592     return false;
1593 }
1594
1595 bool Symtab::getDataRegions(std::vector<Region *>&ret)
1596 {
1597     if(dataRegions_.size() > 0)
1598     {
1599         ret = dataRegions_;
1600         return true;
1601     }
1602     return false;
1603 }
1604
1605 bool Symtab::getAllNewRegions(std::vector<Region *>&ret)
1606 {
1607    Annotatable<Region *, user_regions_a, true> &urA = *this;
1608    if (!urA.size())
1609       return false;
1610    ret = urA.getDataStructure();
1611    return true;
1612 }
1613
1614 bool Symtab::getAllExceptions(std::vector<ExceptionBlock *> &exceptions)
1615 {
1616     if(excpBlocks.size()>0)
1617     {
1618         exceptions = excpBlocks;
1619         return true;
1620     }   
1621     return false;
1622 }
1623
1624 bool Symtab::findException(ExceptionBlock &excp, Offset addr)
1625 {
1626     for(unsigned i=0; i<excpBlocks.size(); i++)
1627     {
1628         if(excpBlocks[i]->contains(addr))
1629         {
1630             excp = *(excpBlocks[i]);
1631             return true;
1632         }       
1633     }
1634     return false;
1635 }
1636
1637 /**
1638  * Returns true if the Address range addr -> addr+size contains
1639  * a catch block, with excp pointing to the appropriate block
1640  **/
1641 bool Symtab::findCatchBlock(ExceptionBlock &excp, Offset addr, unsigned size)
1642 {
1643     int min = 0;
1644     int max = excpBlocks.size();
1645     int cur = -1, last_cur;
1646
1647     if (max == 0)
1648         return false;
1649
1650     //Binary search through vector for address
1651     while (true)
1652     {
1653         last_cur = cur;
1654         cur = (min + max) / 2;
1655     
1656         if (last_cur == cur)
1657             return false;
1658
1659         Offset curAddr = excpBlocks[cur]->catchStart();
1660         if ((curAddr <= addr && curAddr+size > addr) ||
1661             (size == 0 && curAddr == addr))
1662         {
1663             //Found it
1664             excp = *(excpBlocks[cur]);
1665             return true;
1666         }
1667         if (addr < curAddr)
1668             max = cur;
1669         else if (addr > curAddr)
1670             min = cur;
1671     }
1672 }
1673  
1674 bool Symtab::findFuncByEntryOffset(std::vector<Symbol *>& ret, const Offset entry)
1675 {
1676     if(funcsByEntryAddr.find(entry)!=funcsByEntryAddr.end()) {
1677         ret = funcsByEntryAddr[entry];
1678         return true;
1679     }
1680     serr = No_Such_Function;
1681     return false;
1682 }
1683  
1684 bool Symtab::findSymbolByType(std::vector<Symbol *> &ret, const std::string name,
1685                                   Symbol::SymbolType sType, bool isMangled,
1686                                   bool isRegex, bool checkCase)
1687 {
1688     if(sType == Symbol::ST_FUNCTION)
1689         return findFunction(ret, name, isMangled, isRegex, checkCase);
1690     else if(sType == Symbol::ST_OBJECT)
1691         return findVariable(ret, name, isMangled, isRegex, checkCase);
1692     else if(sType == Symbol::ST_MODULE)
1693         return findMod(ret, name, isMangled, isRegex, checkCase);
1694     else if(sType == Symbol::ST_NOTYPE)
1695     {
1696         unsigned start = ret.size(),i;
1697         if(!isMangled && !isRegex)
1698         {
1699             for(i=0;i<notypeSyms.size();i++)
1700             {
1701                 if(notypeSyms[i]->getPrettyName() == name)
1702                     ret.push_back(notypeSyms[i]);
1703             }       
1704         }
1705         else if(isMangled&&!isRegex)
1706         {
1707             for(i=0;i<notypeSyms.size();i++)
1708             {
1709                 if(notypeSyms[i]->getName() == name)
1710                     ret.push_back(notypeSyms[i]);
1711             }   
1712         }
1713         else if(!isMangled&&isRegex)
1714         {
1715             for(i=0;i<notypeSyms.size();i++)
1716             {
1717                 if(regexEquiv(name, notypeSyms[i]->getPrettyName(), checkCase))
1718                     ret.push_back(notypeSyms[i]);
1719             }   
1720         }
1721         else
1722         {
1723             for(i=0;i<notypeSyms.size();i++)
1724             {
1725                 if(regexEquiv(name, notypeSyms[i]->getName(), checkCase))
1726                     ret.push_back(notypeSyms[i]);
1727             }   
1728         }
1729         if(ret.size() > start)
1730             return true;
1731         serr = No_Such_Symbol;
1732         return false;
1733     }
1734     else if(sType == Symbol::ST_UNKNOWN)
1735     {
1736         findFunction(ret, name, isMangled, isRegex, checkCase);
1737         std::vector<Symbol *>syms;
1738         findVariable(syms, name, isMangled, isRegex, checkCase);
1739         ret.insert(ret.end(), syms.begin(), syms.end());
1740         syms.clear();
1741         findSymbolByType(syms, name, Symbol::ST_MODULE, isMangled, isRegex, checkCase);
1742         ret.insert(ret.end(), syms.begin(), syms.end());
1743         syms.clear();
1744         findSymbolByType(syms, name, Symbol::ST_NOTYPE, isMangled, isRegex, checkCase);
1745         ret.insert(ret.end(), syms.begin(), syms.end());
1746         syms.clear();
1747         if(ret.size() > 0)
1748             return true;
1749         else
1750         {
1751             serr = No_Such_Symbol;
1752             return false;
1753         }
1754     }
1755     return false;
1756 }
1757                                 
1758 bool Symtab::findFunction(std::vector <Symbol *> &ret,const std::string &name, 
1759                               bool isMangled, bool isRegex, 
1760                               bool checkCase)
1761 {
1762     if(!isMangled&&!isRegex)
1763         return findFuncVectorByPretty(name, ret);
1764     else if(isMangled&&!isRegex)
1765         return findFuncVectorByMangled(name, ret);
1766     else if(!isMangled&&isRegex)
1767         return findFuncVectorByPrettyRegex(name, checkCase, ret);
1768     else
1769         return findFuncVectorByMangledRegex(name, checkCase, ret);
1770 }
1771
1772 bool Symtab::findVariable(std::vector <Symbol *> &ret, const std::string &name,
1773                               bool isMangled, bool isRegex,
1774                               bool checkCase)
1775 {
1776     if(!isMangled&&!isRegex)
1777         return findVarVectorByPretty(name, ret);
1778     else if(isMangled&&!isRegex)
1779         return findVarVectorByMangled(name, ret);
1780     else if(!isMangled&&isRegex)
1781         return findVarVectorByPrettyRegex(name, checkCase, ret);
1782     else
1783         return findVarVectorByMangledRegex(name, checkCase, ret);
1784 }
1785
1786 bool Symtab::findMod(std::vector <Symbol *> &ret, const std::string &name,
1787                             bool /*isMangled*/, bool isRegex,
1788                             bool checkCase)
1789 {
1790     if(!isRegex)
1791     {
1792         if(modsByName.find(name)!=modsByName.end())
1793         {
1794             ret = *(modsByName[name]);
1795             return true;        
1796         }
1797         serr = No_Such_Module;
1798         return false;
1799     }
1800     else
1801         return findModByRegex(name, checkCase, ret);
1802 }
1803
1804 // Return the vector of functions associated with a mangled name
1805 // Very well might be more than one! -- multiple static functions in different .o files
1806 bool Symtab::findFuncVectorByPretty(const std::string &name, std::vector<Symbol *> &ret)
1807 {
1808     if (funcsByPretty.find(name)!=funcsByPretty.end()) 
1809     {
1810         ret = *(funcsByPretty[name]);
1811         return true;    
1812     }
1813     serr = No_Such_Function;
1814     return false;
1815 }
1816  
1817 bool Symtab::findFuncVectorByMangled(const std::string &name, std::vector<Symbol *> &ret)
1818 {
1819     //fprintf(stderr,"findFuncVectorByMangled %s\n",name.c_str());
1820     //#ifdef IBM_BPATCH_COMPAT_STAB_DEBUG
1821     //bperr( "%s[%d]:  inside findFuncVectorByMangled\n", FILE__, __LINE__);
1822     //#endif
1823     if (funcsByMangled.find(name)!=funcsByMangled.end()) 
1824     {
1825         ret = *(funcsByMangled[name]);
1826         return true;    
1827     }
1828     serr = No_Such_Function;
1829     return false;
1830 }
1831  
1832 bool Symtab::findVarVectorByPretty(const std::string &name, std::vector<Symbol *> &ret)
1833 {
1834     //fprintf(stderr,"findVariableVectorByPretty %s\n",name.c_str());
1835     //#ifdef IBM_BPATCH_COMPAT_STAB_DEBUG
1836     //bperr( "%s[%d]:  inside findVariableVectorByPretty\n", FILE__, __LINE__);
1837     //#endif
1838     if (varsByPretty.find(name)!=varsByPretty.end()) 
1839     {
1840         ret = *(varsByPretty[name]);
1841         return true;    
1842     }
1843     serr = No_Such_Variable;
1844     return false;
1845 }
1846
1847 bool Symtab::findVarVectorByMangled(const std::string &name, std::vector<Symbol *> &ret)
1848 {
1849     // fprintf(stderr,"findVariableVectorByPretty %s\n",name.c_str());
1850     //#ifdef IBM_BPATCH_COMPAT_STAB_DEBUG
1851     //bperr( "%s[%d]:  inside findVariableVectorByPretty\n", FILE__, __LINE__);
1852     //#endif
1853     if (varsByMangled.find(name)!=varsByMangled.end()) 
1854     {
1855         ret = *(varsByMangled[name]);
1856         return true;    
1857     }
1858     serr = No_Such_Variable;
1859     return false;
1860 }
1861
1862 bool Symtab::findFuncVectorByMangledRegex(const std::string &rexp, bool checkCase, std::vector<Symbol *>&ret)
1863 {
1864     unsigned start = ret.size();        
1865     dyn_hash_map <std::string, std::vector<Symbol *>*>::iterator iter;
1866     for(iter = funcsByMangled.begin(); iter!=funcsByMangled.end(); iter++)
1867     {
1868         if(regexEquiv(rexp,iter->first,checkCase))
1869         {
1870             std::vector<Symbol *> funcs = *(iter->second);
1871             int size = funcs.size();
1872             for(int index = 0; index < size; index++)
1873                 ret.push_back(funcs[index]);
1874         }
1875     }
1876     if(ret.size() > start)
1877         return true;
1878     serr = No_Such_Function;
1879     return false;
1880 }
1881  
1882 bool Symtab::findFuncVectorByPrettyRegex(const std::string &rexp, bool checkCase, std::vector<Symbol *>&ret)
1883 {
1884     unsigned start = ret.size();
1885     dyn_hash_map <std::string, std::vector<Symbol *>*>::iterator iter;
1886     for(iter = funcsByPretty.begin(); iter!=funcsByPretty.end(); iter++)
1887     {
1888         if(regexEquiv(rexp,iter->first,checkCase))
1889         {
1890             std::vector<Symbol *> funcs = *(iter->second);
1891             int size = funcs.size();
1892             for(int index = 0; index < size; index++)
1893                 ret.push_back(funcs[index]);
1894         }
1895     }
1896     if(ret.size() > start)
1897         return true;
1898     serr = No_Such_Function;
1899     return false;
1900 }
1901
1902 bool Symtab::findVarVectorByMangledRegex(const std::string &rexp, bool checkCase, std::vector<Symbol *>&ret)
1903 {
1904     unsigned start = ret.size();
1905     dyn_hash_map <std::string, std::vector<Symbol *>*>::iterator iter;
1906     for(iter = varsByMangled.begin(); iter!=varsByMangled.end(); iter++)
1907     {
1908         if(regexEquiv(rexp,iter->first,checkCase))
1909         {
1910             std::vector<Symbol *> vars = *(iter->second);
1911             int size = vars.size();
1912             for(int index = 0; index < size; index++)
1913                 ret.push_back(vars[index]);
1914         }
1915     }
1916     if(ret.size() > start)
1917         return true;
1918     serr = No_Such_Variable;
1919     return false;
1920 }
1921
1922 bool Symtab::findVarVectorByPrettyRegex(const std::string &rexp, bool checkCase, std::vector<Symbol *>&ret)
1923 {
1924     unsigned start = ret.size();
1925     dyn_hash_map <std::string, std::vector<Symbol *>*>::iterator iter;
1926     for(iter = varsByPretty.begin(); iter!=varsByPretty.end(); iter++)
1927     {
1928         if(regexEquiv(rexp,iter->first,checkCase))
1929         {
1930             std::vector<Symbol *> vars = *(iter->second);
1931             int size = vars.size();
1932             for(int index = 0; index < size; index++)
1933                 ret.push_back(vars[index]);
1934         }
1935     }
1936     if(ret.size() > start)
1937         return true;
1938     serr = No_Such_Variable;
1939     return false;
1940 }
1941
1942 bool Symtab::findModByRegex(const std::string &rexp, bool checkCase, std::vector<Symbol *>&ret)
1943 {
1944     unsigned start = ret.size();
1945     dyn_hash_map <std::string, std::vector<Symbol *>*>::iterator iter;
1946     for(iter = modsByName.begin(); iter!=modsByName.end(); iter++)
1947     {
1948         if(regexEquiv(rexp,iter->first,checkCase))
1949         {
1950             std::vector<Symbol *> vars = *(iter->second);
1951             int size = vars.size();
1952             for(int index = 0; index < size; index++)
1953                 ret.push_back(vars[index]);
1954         }
1955     }
1956     if(ret.size() > start)
1957         return true;
1958     serr = No_Such_Module;
1959     return false;
1960 }
1961
1962 bool Symtab::findRegionByEntry(Region *&ret, const Offset offset)
1963 {
1964     if(regionsByEntryAddr.find(offset) != regionsByEntryAddr.end())
1965     {
1966         ret = regionsByEntryAddr[offset];
1967         return true;
1968     }
1969     serr = No_Such_Region;
1970     return false;
1971 }
1972
1973 /* Similar to binary search in isCode with the exception that here we
1974  * search to the end of regions without regards to whether they have
1975  * corresponding raw data on disk, and searches all regions.  
1976  */
1977 Region *Symtab::findEnclosingRegion(const Offset where)
1978 {
1979     // search for "where" in regions (regions must not overlap)
1980     int first = 0; 
1981     int last = regions_.size() - 1;
1982     while (last >= first) {
1983         Region *curreg = regions_[(first + last) / 2];
1984         if (where >= curreg->getRegionAddr()
1985             && where < (curreg->getRegionAddr()
1986                         + curreg->getMemSize())) {
1987             return curreg;
1988         }
1989         else if (where < curreg->getRegionAddr()) {
1990             last = ((first + last) / 2) - 1;
1991         }
1992         else {/* where >= (cursec->getSecAddr()
1993                            + cursec->getSecSize()) */
1994             first = ((first + last) / 2) + 1;
1995         }
1996     }
1997     return NULL;
1998 }
1999
2000 bool Symtab::findRegion(Region *&ret, const std::string secName)
2001 {
2002     for(unsigned index=0;index<regions_.size();index++)
2003     {
2004         if(regions_[index]->getRegionName() == secName)
2005         {
2006             ret = regions_[index];
2007             return true;
2008         }
2009     }
2010     serr = No_Such_Region;
2011     return false;
2012 }
2013  
2014 // Address must be in code or data range since some code may end up
2015 // in the data segment
2016 bool Symtab::isValidOffset(const Offset where) const
2017 {
2018     return isCode(where) || isData(where);
2019 }
2020
2021 /* Performs a binary search on the codeRegions_ vector, which must
2022  * always be sorted.  
2023  */
2024 bool Symtab::isCode(const Offset where)  const
2025 {
2026     //    printf("isCode(%x)\n",where);
2027     if(!codeRegions_.size())
2028         return false;
2029     // search for "where" in codeRegions_ (code regions must not overlap)
2030     int first = 0; 
2031     int last = codeRegions_.size() - 1;
2032     while (last >= first) {
2033         Region *curreg = codeRegions_[(first + last) / 2];
2034         //        printf("  reg[%d] [%x %x]\n", (first+last)/2, curreg->getRegionAddr(), curreg->getRegionAddr() + curreg->getRegionSize());
2035         if (where >= curreg->getRegionAddr()
2036             && where < (curreg->getRegionAddr()
2037                         + curreg->getDiskSize())) {
2038             return true;
2039         }
2040         else if (where < curreg->getRegionAddr()) {
2041             last = ((first + last) / 2) - 1;
2042         }
2043         else if (where >= (curreg->getRegionAddr()
2044                            + curreg->getMemSize())) {
2045             first = ((first + last) / 2) + 1;
2046         }
2047         else { // "where" is in the range: 
2048                // [memOffset + diskSize , memOffset + memSize)
2049                // meaning that it's in an uninitialized data region 
2050             return false;
2051         }
2052     }
2053     return false;
2054 }
2055
2056 bool Symtab::isData(const Offset where)  const
2057 {
2058     if(!dataRegions_.size())
2059         return false;
2060     for(unsigned i=0; i< dataRegions_.size(); i++){
2061         if((where>=dataRegions_[i]->getRegionAddr()) && (where <= (dataRegions_[i]->getRegionAddr() + dataRegions_[i]->getDiskSize())))
2062             return true;
2063     }
2064     return false;
2065 //    return (data_ptr_ && 
2066 //            (where >= dataOffset_) && (where < (dataOffset_+dataLen_)));
2067 }
2068
2069 bool Symtab::getFuncBindingTable(std::vector<relocationEntry> &fbt) const
2070 {
2071     fbt = relocation_table_;
2072     return true;
2073 }
2074
2075 DLLEXPORT std::vector<std::string> &Symtab::getDependencies(){
2076     return deps_;
2077 }
2078
2079
2080 Symtab::~Symtab()
2081 {
2082    // Doesn't do anything yet, moved here so we don't mess with symtab.h
2083    // Only called if we fail to create a process.
2084    // Or delete the a.out...
2085         
2086     unsigned i;
2087             
2088     for (i = 0; i < regions_.size(); i++) {
2089         delete regions_[i];
2090     }
2091     regions_.clear();
2092     
2093     Annotatable<Region *, user_regions_a, true> &usA = *this;
2094     for (i = 0; i < usA.size(); ++i) {
2095        Region *s = usA[i];
2096        delete(s);
2097     }
2098     for (i = 0; i < _mods.size(); i++) {
2099         delete _mods[i];
2100     }
2101     _mods.clear();
2102
2103     for(i=0; i< modSyms.size(); i++)
2104         delete modSyms[i];
2105     modSyms.clear();    
2106     modsByFileName.clear();
2107     modsByFullName.clear();
2108
2109     for(i=0; i< notypeSyms.size(); i++)
2110         delete notypeSyms[i];
2111     notypeSyms.clear(); 
2112     
2113     for (i = 0; i < everyUniqueVariable.size(); i++) {
2114         delete everyUniqueVariable[i];
2115     }
2116     everyUniqueVariable.clear();
2117     
2118     for (i = 0; i < everyUniqueFunction.size(); i++) {
2119         delete everyUniqueFunction[i];
2120     }
2121     everyUniqueFunction.clear();
2122     exportedFunctions.clear();
2123     
2124     undefDynSyms.clear();
2125     for (i=0;i<excpBlocks.size();i++)
2126         delete excpBlocks[i];
2127     symtab_printf("%s[%d]: Symtab::~Symtab removing %p from allSymtabs\n", 
2128                   FILE__, __LINE__, this);
2129     
2130     deps_.clear();
2131     
2132     for (i = 0; i < allSymtabs.size(); i++) {
2133         if (allSymtabs[i] == this)
2134             allSymtabs.erase(allSymtabs.begin()+i);
2135     }
2136
2137     //fprintf(stderr, "%s[%d]:  symtab DTOR, mf = %p: %s\n", FILE__, __LINE__, mf, mf->filename().c_str());
2138     if (mf) MappedFile::closeMappedFile(mf);
2139     if (mfForDebugInfo) MappedFile::closeMappedFile(mfForDebugInfo);
2140 }       
2141  
2142 bool Module::findSymbolByType(std::vector<Symbol *> &found, const std::string name,
2143                                   Symbol::SymbolType sType, bool isMangled,
2144                                   bool isRegex, bool checkCase)
2145 {
2146    unsigned orig_size = found.size();
2147    std::vector<Symbol *> obj_syms;
2148
2149    if (!exec()->findSymbolByType(obj_syms, name, sType, isMangled, isRegex, checkCase))
2150       return false;
2151
2152    for (unsigned i = 0; i < obj_syms.size(); i++)  {
2153       if (obj_syms[i]->getModule() == this)
2154          found.push_back(obj_syms[i]);
2155    }
2156
2157    if (found.size() > orig_size) 
2158       return true;
2159
2160    return false;        
2161 }
2162
2163 DLLEXPORT const std::string &Module::fileName() const 
2164 {
2165    return fileName_; 
2166 }
2167
2168 DLLEXPORT const std::string &Module::fullName() const 
2169 {
2170    return fullName_; 
2171 }
2172
2173 DLLEXPORT Symtab *Module::exec() const 
2174 {
2175    return exec_;
2176 }
2177
2178 DLLEXPORT supportedLanguages Module::language() const 
2179 {
2180    return language_;
2181 }
2182
2183 DLLEXPORT  bool Module::hasLineInformation()
2184 {
2185    Annotatable<LineInformation *, module_line_info_a, true> &liA = *this;
2186    return ( 0 != liA.size());
2187 }
2188
2189 DLLEXPORT LineInformation *Module::getLineInformation()
2190 {
2191    if (!exec_->isLineInfoValid_)
2192       exec_->parseLineInformation();
2193
2194    Annotatable<LineInformation *, module_line_info_a, true> &mt = *this;
2195
2196    if (exec_->isLineInfoValid_) {
2197       if (!mt.size()) {
2198           // There is no line info valid for this module
2199          return NULL;
2200       }
2201       if (mt.size() > 1) {
2202         // fprintf(stderr, "%s[%d]:  weird, multiple line info for %s: FIXME\n", 
2203         //       FILE__, __LINE__, fileName_.c_str());
2204       }
2205       if (!mt[0]) {
2206          fprintf(stderr, "%s[%d]:  FIXME:  Line info annotation is NULL!\n", FILE__, __LINE__);
2207       }
2208       return mt[0];
2209    }
2210    
2211    fprintf(stderr, "%s[%d]:  FIXME:  line info not valid after parse\n", 
2212          FILE__, __LINE__);
2213
2214    return NULL;
2215 }
2216
2217 DLLEXPORT bool Module::getAddressRanges(std::vector<pair<Offset, Offset> >&ranges,
2218       std::string lineSource, unsigned int lineNo)
2219 {
2220    unsigned int originalSize = ranges.size();
2221
2222    LineInformation *lineInformation = getLineInformation();
2223    if (lineInformation)
2224       lineInformation->getAddressRanges( lineSource.c_str(), lineNo, ranges );
2225
2226    if ( ranges.size() != originalSize )
2227       return true;
2228
2229    return false;
2230 }
2231
2232 DLLEXPORT bool Module::getSourceLines(std::vector<LineNoTuple> &lines, Offset addressInRange)
2233 {
2234    unsigned int originalSize = lines.size();
2235
2236    LineInformation *lineInformation = getLineInformation();
2237    if (lineInformation)
2238       lineInformation->getSourceLines( addressInRange, lines );
2239
2240    if ( lines.size() != originalSize )
2241       return true;
2242
2243    return false;
2244 }
2245
2246 DLLEXPORT vector<Type *> *Module::getAllTypes()
2247 {
2248    Annotatable<typeCollection *, module_type_info_a, true> &mtA = *this;
2249    if (!mtA.size()) return NULL;
2250
2251    typeCollection *mt = mtA[0]; 
2252    if (!mt) {
2253       fprintf(stderr, "%s[%d]:  FIXME:  NULL type collection\n", FILE__, __LINE__);
2254       return NULL;
2255    }
2256
2257    return mt->getAllTypes();
2258 }
2259
2260 DLLEXPORT vector<pair<string, Type *> > *Module::getAllGlobalVars()
2261 {
2262    Annotatable<typeCollection *, module_type_info_a, true> &mtA = *this;
2263    if (!mtA.size()) return NULL;
2264
2265    typeCollection *mt = mtA[0]; 
2266    if (!mt) {
2267       fprintf(stderr, "%s[%d]:  FIXME:  NULL type collection\n", FILE__, __LINE__);
2268       return NULL;
2269    }
2270
2271    return mt->getAllGlobalVariables();
2272 }
2273
2274 DLLEXPORT typeCollection *Module::getModuleTypes()
2275 {
2276    Annotatable<typeCollection *, module_type_info_a, true> &mtA = *this;
2277    typeCollection *mt;
2278
2279    if(mtA.size()){
2280        mt = mtA[0]; 
2281        if (!mt) {
2282            fprintf(stderr, "%s[%d]:  FIXME:  NULL type collection\n", FILE__, __LINE__);
2283            return NULL;
2284        }
2285    }
2286    else{
2287        mt = typeCollection::getModTypeCollection(this); 
2288        mtA.addAnnotation(mt);
2289    }
2290    return mt;
2291 }
2292
2293 DLLEXPORT bool Module::findType(Type *&type, std::string name)
2294 {
2295    exec_->parseTypesNow();
2296    type = getModuleTypes()->findType(name);
2297
2298    if (type == NULL)
2299       return false;
2300
2301    return true; 
2302 }
2303
2304 DLLEXPORT bool Module::findVariableType(Type *&type, std::string name)
2305 {
2306    exec_->parseTypesNow();
2307    type = getModuleTypes()->findVariableType(name);
2308
2309    if (type == NULL)
2310       return false;
2311    return true; 
2312 }
2313
2314 void Symtab::parseTypesNow()
2315 {
2316    if (isTypeInfoValid_)
2317       return;
2318    parseTypes();
2319 }
2320
2321 DLLEXPORT bool Module::setLineInfo(LineInformation *lineInfo) 
2322 {
2323    Annotatable<LineInformation *, module_line_info_a, true> &mt = *this;
2324    if (mt.size()) {
2325       // We need to remove the existing annotation and make sure there is only one annotation.
2326       mt.clearAnnotations();
2327       //fprintf(stderr, "%s[%d]:  WARNING, already have lineInfo set for module %s\n", FILE__, __LINE__, fileName_.c_str());
2328    }
2329    mt.addAnnotation(lineInfo);
2330    return true;
2331 }
2332
2333 DLLEXPORT bool Module::findLocalVariable(std::vector<localVar *>&vars, std::string name)
2334 {
2335    exec_->parseTypesNow();
2336    std::vector<Symbol *>mod_funcs;
2337
2338    if (!getAllSymbolsByType(mod_funcs, Symbol::ST_FUNCTION))
2339       return false;
2340
2341    unsigned origSize = vars.size();
2342    for (unsigned int i=0;i<mod_funcs.size();i++)
2343       mod_funcs[i]->findLocalVariable(vars, name);
2344
2345    if (vars.size()>origSize)
2346       return true;
2347
2348    return false;        
2349 }
2350
2351 DLLEXPORT Module::Module(supportedLanguages lang, Offset adr, 
2352       std::string fullNm, Symtab *img) :
2353    fullName_(fullNm), 
2354    language_(lang), 
2355    addr_(adr), 
2356    exec_(img)
2357 {
2358    fileName_ = extract_pathname_tail(fullNm);
2359 }
2360
2361 DLLEXPORT Module::Module() :
2362    fileName_(""), 
2363    fullName_(""),
2364    language_(lang_Unknown), 
2365    addr_(0), 
2366    exec_(NULL) 
2367 {
2368 }
2369
2370 DLLEXPORT Module::Module(const Module &mod) :
2371    LookupInterface(), 
2372    Annotatable<LineInformation *, module_line_info_a, true>(),
2373    Annotatable<typeCollection *, module_type_info_a, true>(),
2374    fileName_(mod.fileName_),
2375    fullName_(mod.fullName_), 
2376    language_(mod.language_),
2377    addr_(mod.addr_), 
2378    exec_(mod.exec_)
2379 {
2380    Annotatable<LineInformation *, module_line_info_a, true> &liA = *this;
2381    const Annotatable<LineInformation *, module_line_info_a, true> &liA_src = mod;
2382
2383    if (liA_src.size()) {
2384       LineInformation *li_src = liA_src[0];
2385       assert(li_src);
2386       liA.addAnnotation(li_src);
2387    }
2388 }
2389
2390 DLLEXPORT Module::~Module()
2391 {
2392    Annotatable<LineInformation *, module_line_info_a, true> &liA = *this;
2393    if (liA.size()){
2394        delete liA[0];
2395        liA.clearAnnotations();
2396    }
2397 }
2398
2399 bool Module::isShared() const 
2400
2401    return !exec_->isExec();
2402 }
2403
2404 bool Module::getAllSymbolsByType(std::vector<Symbol *> &found, Symbol::SymbolType sType)
2405 {
2406    unsigned orig_size = found.size();
2407    std::vector<Symbol *> obj_syms;
2408    if (!exec()->getAllSymbolsByType(obj_syms, sType))
2409       return false;
2410
2411    for (unsigned i = 0; i < obj_syms.size(); i++) {
2412       if (obj_syms[i]->getModule() == this)
2413          found.push_back(obj_syms[i]);
2414    }
2415
2416    if (found.size() > orig_size) 
2417       return true;
2418
2419    serr = No_Such_Symbol;       
2420    return false;
2421 }
2422
2423 DLLEXPORT bool Module::operator==(const Module &mod) const 
2424 {
2425    const Annotatable<LineInformation *, module_line_info_a, true> *liA = this;
2426    const Annotatable<LineInformation *, module_line_info_a, true> *liA_src = &mod;
2427    if (liA->size() != liA_src->size()) return false;
2428    if (liA->size()) {
2429       LineInformation *li = liA->getAnnotation(0);
2430       LineInformation *li_src = liA_src->getAnnotation(0);
2431       if ((li != li_src)) return false;
2432    }
2433
2434    return ( 
2435          (language_==mod.language_)
2436          && (addr_==mod.addr_) 
2437          && (fullName_==mod.fullName_) 
2438          && (exec_==mod.exec_) 
2439          );
2440 }
2441
2442 DLLEXPORT bool Module::setName(std::string newName) 
2443 {
2444    fullName_ = newName;
2445    fileName_ = extract_pathname_tail(fullName_);
2446    return true;
2447 }
2448
2449 DLLEXPORT void Module::setLanguage(supportedLanguages lang) 
2450 {
2451    language_ = lang;
2452 }
2453
2454 DLLEXPORT Offset Module::addr() const 
2455 {
2456    return addr_; 
2457 }
2458
2459 DLLEXPORT bool Module::setDefaultNamespacePrefix(string str){
2460     return exec_->setDefaultNamespacePrefix(str);
2461 }
2462
2463 // Use POSIX regular expression pattern matching to check if std::string s matches
2464 // the pattern in this std::string
2465 bool regexEquiv( const std::string &str,const std::string &them, bool checkCase ) 
2466 {
2467    const char *str_ = str.c_str();
2468    const char *s = them.c_str();
2469    // Would this work under NT?  I don't know.
2470    //#if !defined(os_windows)
2471     return pattern_match(str_, s, checkCase);
2472
2473 }
2474
2475 // This function will match string s against pattern p.
2476 // Asterisks match 0 or more wild characters, and a question
2477 // mark matches exactly one wild character.  In other words,
2478 // the asterisk is the equivalent of the regex ".*" and the
2479 // question mark is the equivalent of "."
2480
2481 bool
2482 pattern_match( const char *p, const char *s, bool checkCase ) {
2483    //const char *p = ptrn;
2484    //char *s = str;
2485
2486     while ( true ) {
2487         // If at the end of the pattern, it matches if also at the end of the string
2488         if( *p == '\0' )
2489             return ( *s == '\0' );
2490
2491         // Process a '*'
2492         if( *p == MULTIPLE_WILDCARD_CHARACTER ) {
2493             ++p;
2494
2495             // If at the end of the pattern, it matches
2496             if( *p == '\0' )
2497                 return true;
2498
2499             // Try to match the remaining pattern for each remaining substring of s
2500             for(; *s != '\0'; ++s )
2501                 if( pattern_match( p, s, checkCase ) )
2502                     return true;
2503             // Failed
2504             return false;
2505         }
2506
2507         // If at the end of the string (and at this point, not of the pattern), it fails
2508         if( *s == '\0' )
2509             return false;
2510
2511         // Check if this character matches
2512         bool matchChar = false;
2513         if( *p == WILDCARD_CHARACTER || *p == *s )
2514             matchChar = true;
2515         else if( !checkCase ) {
2516             if( *p >= 'A' && *p <= 'Z' && *s == ( *p + ( 'a' - 'A' ) ) )
2517                 matchChar = true;
2518             else if( *p >= 'a' && *p <= 'z' && *s == ( *p - ( 'a' - 'A' ) ) )
2519                 matchChar = true;
2520         }
2521
2522         if( matchChar ) {
2523             ++p;
2524             ++s;
2525             continue;
2526         }
2527
2528         // Did not match
2529         return false;
2530     }
2531 }
2532
2533 #if defined (cap_serialization)
2534 bool Symtab::exportXML(string file)
2535 {
2536    try {
2537       SymtabTranslatorXML trans(this, file);
2538       if ( serialize(*this, trans))
2539          return true;
2540    } catch (const SerializerError &err) {
2541       fprintf(stderr, "%s[%d]: error serializing xml: %s\n", FILE__, __LINE__, err.what());
2542       return false;
2543    }
2544
2545    return false;
2546 }
2547 #else
2548 bool Symtab::exportXML(string) {
2549    fprintf(stderr, "%s[%d]:  WARNING:  serialization not available\n", FILE__, __LINE__);
2550    return false;
2551 }
2552 #endif
2553
2554 #if defined (cap_serialization)
2555 bool Symtab::exportBin(string file)
2556 {
2557    try
2558    {
2559       bool verbose = false;
2560       if (strstr(file.c_str(), "cache_ld")) verbose = true;
2561       SymtabTranslatorBin trans(this, file, sd_serialize, verbose);
2562       if (serialize(*this, trans))
2563          return true;
2564    }
2565    catch (const SerializerError &err)
2566    {
2567       fprintf(stderr, "%s[%d]: %s\n\tfrom %s[%d]\n", FILE__, __LINE__,
2568             err.what(), err.file().c_str(), err.line());
2569    }
2570
2571
2572    fprintf(stderr, "%s[%d]:  error doing binary serialization\n", __FILE__, __LINE__);
2573    return false;
2574 }
2575 #else
2576 bool Symtab::exportBin(string) {
2577    fprintf(stderr, "%s[%d]:  WARNING:  serialization not available\n", FILE__, __LINE__);
2578    return false;
2579 }
2580 #endif
2581
2582 #if defined (cap_serialization)
2583 Symtab *Symtab::importBin(std::string file)
2584 {
2585    MappedFile *mf= MappedFile::createMappedFile(file);
2586    if (!mf) {
2587       fprintf(stderr, "%s[%d]:  failed to map file %s\n", FILE__, __LINE__, file.c_str());
2588       return NULL;
2589    }
2590
2591    Symtab *st = new Symtab(mf);
2592
2593    try
2594    {
2595       bool verbose = false;
2596       if (strstr(file.c_str(), "ld-")) verbose = true;
2597       SymtabTranslatorBin trans(st, file, sd_deserialize, verbose);
2598       if (deserialize(*st, trans)) {
2599          fprintf(stderr, "%s[%d]:  deserialized '%s' from cache\n", FILE__, __LINE__, file.c_str());
2600          if (!st) fprintf(stderr, "%s[%d]:  FIXME:  no symtab\n", FILE__, __LINE__);
2601          return st;
2602       }
2603    }
2604
2605    catch (const SerializerError &err)
2606    {
2607       fprintf(stderr, "%s[%d]: %s\n\tfrom: %s[%d]\n", FILE__, __LINE__,
2608             err.what(), err.file().c_str(), err.line());
2609    }
2610
2611
2612    fprintf(stderr, "%s[%d]:  error doing binary deserialization\n", __FILE__, __LINE__);
2613    delete st;
2614    return NULL;
2615 }
2616 #else
2617 Symtab *Symtab::importBin(std::string) {
2618    fprintf(stderr, "%s[%d]:  WARNING:  serialization not available\n", FILE__, __LINE__);
2619    return NULL;
2620 }
2621 #endif
2622
2623 bool Symtab::openFile(Symtab *&obj, std::string filename)
2624 {
2625    bool err = false;
2626 #if defined(TIMED_PARSE)
2627    struct timeval starttime;
2628    gettimeofday(&starttime, NULL);
2629 #endif
2630    unsigned numSymtabs = allSymtabs.size();
2631
2632    // AIX: it's possible that we're reparsing a file with better information
2633    // about it. If so, yank the old one out of the allSymtabs std::vector -- replace
2634    // it, basically.
2635    if(filename.find("/proc") == std::string::npos)
2636    {
2637       for (unsigned u=0; u<numSymtabs; u++) {
2638          assert(allSymtabs[u]);
2639             if (filename == allSymtabs[u]->file()) {
2640                 // return it
2641                 obj = allSymtabs[u];
2642                 return true;
2643             }
2644         }   
2645     }
2646 #if defined (cap_serialization)
2647     obj = importBin(filename);
2648     if (!obj) { 
2649        fprintf(stderr, "%s[%d]:  importBin failed\n", FILE__, __LINE__);
2650     }
2651     else {
2652        return true;
2653     }
2654 #endif
2655
2656     obj = new Symtab(filename, err);
2657 #if defined(TIMED_PARSE)
2658     struct timeval endtime;
2659     gettimeofday(&endtime, NULL);
2660     unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
2661     unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
2662     unsigned long difftime = lendtime - lstarttime;
2663     double dursecs = difftime/(1000 );
2664     cout << __FILE__ << ":" << __LINE__ <<": openFile "<< filename<< " took "<<dursecs <<" msecs" << endl;
2665 #endif
2666     if(!err)
2667     {
2668         if(filename.find("/proc") == std::string::npos)
2669             allSymtabs.push_back(obj);
2670         obj->setupTypes();      
2671 #if defined (cap_serialization)
2672         fprintf(stderr, "%s[%d]:  doing bin-serialize for %s\n", FILE__, __LINE__, filename.c_str());
2673         if (!obj->exportBin(filename))
2674         {
2675            fprintf(stderr, "%s[%d]:  failed to export symtab\n", FILE__, __LINE__);
2676         }
2677 #endif
2678
2679     }
2680     else
2681     {
2682       symtab_printf("%s[%d]: WARNING: failed to open symtab for %s\n", FILE__, __LINE__, filename.c_str());
2683       delete obj;
2684         obj = NULL;
2685     }
2686     // returns true on success (not an error)
2687     return !err;
2688 }
2689         
2690 bool Symtab::changeType(Symbol *sym, Symbol::SymbolType oldType)
2691 {
2692     std::vector<std::string>names;
2693     if(oldType == Symbol::ST_FUNCTION)
2694     {
2695         unsigned i;
2696         std::vector<Symbol *> *funcs;
2697         std::vector<Symbol *>::iterator iter;
2698         names = sym->getAllMangledNames();
2699         for(i=0;i<names.size();i++)
2700         {
2701             funcs = funcsByMangled[names[i]];
2702             iter = find(funcs->begin(), funcs->end(), sym);
2703             funcs->erase(iter);
2704         }
2705         names.clear();
2706         names = sym->getAllPrettyNames();
2707         for(i=0;i<names.size();i++)
2708         {
2709             funcs = funcsByPretty[names[i]];
2710             iter = find(funcs->begin(), funcs->end(), sym);
2711             funcs->erase(iter);
2712         }
2713         names.clear();
2714         names = sym->getAllTypedNames();
2715         for(i=0;i<names.size();i++)
2716         {
2717             funcs = funcsByPretty[names[i]];
2718             iter = find(funcs->begin(), funcs->end(), sym);
2719             funcs->erase(iter);
2720         }
2721         names.clear();
2722         iter = find(everyUniqueFunction.begin(), everyUniqueFunction.end(), sym);
2723         everyUniqueFunction.erase(iter);
2724     }
2725     else if(oldType == Symbol::ST_OBJECT)
2726     {
2727         unsigned i;
2728         std::vector<Symbol *> *vars;
2729         std::vector<Symbol *>::iterator iter;
2730         names = sym->getAllMangledNames();
2731         for(i=0;i<names.size();i++)
2732         {
2733             vars = varsByMangled[names[i]];
2734             iter = find(vars->begin(), vars->end(), sym);
2735             vars->erase(iter);
2736         }
2737         names.clear();
2738         names = sym->getAllPrettyNames();
2739         for(i=0;i<names.size();i++)
2740         {
2741             vars = varsByPretty[names[i]];
2742             iter = find(vars->begin(), vars->end(), sym);
2743             vars->erase(iter);
2744         }
2745         names.clear();
2746         names = sym->getAllTypedNames();
2747         for(i=0;i<names.size();i++)
2748         {
2749             vars= varsByPretty[names[i]];
2750             iter = find(vars->begin(), vars->end(), sym);
2751             vars->erase(iter);
2752         }
2753         iter = find(everyUniqueVariable.begin(), everyUniqueVariable.end(), sym);
2754         everyUniqueVariable.erase(iter);
2755     }
2756     else if(oldType == Symbol::ST_MODULE)
2757     {
2758         unsigned i;
2759         std::vector<Symbol *> *mods;
2760         std::vector<Symbol *>::iterator iter;
2761         names = sym->getAllMangledNames();
2762         for(i=0;i<names.size();i++)
2763         {
2764             mods = modsByName[names[i]];
2765             iter = find(mods->begin(), mods->end(), sym);
2766             mods->erase(iter);
2767         }
2768         names.clear();
2769         iter = find(modSyms.begin(),modSyms.end(),sym);
2770         modSyms.erase(iter);
2771     }
2772     else if(oldType == Symbol::ST_NOTYPE)
2773     {
2774         std::vector<Symbol *>::iterator iter;
2775         iter = find(notypeSyms.begin(),notypeSyms.end(),sym);
2776         notypeSyms.erase(iter);
2777     }
2778     addSymbolInt(sym, false);
2779     return true;
2780 }
2781
2782 bool Symtab::delSymbol(Symbol *sym)
2783 {
2784     std::vector<std::string>names;
2785     if(sym->getType() == Symbol::ST_FUNCTION)
2786     {
2787         unsigned i;
2788         std::vector<Symbol *> *funcs;
2789         std::vector<Symbol *>::iterator iter;
2790         names = sym->getAllMangledNames();
2791         for(i=0;i<names.size();i++)
2792         {
2793             funcs = funcsByMangled[names[i]];
2794             iter = find(funcs->begin(), funcs->end(), sym);
2795             funcs->erase(iter);
2796         }
2797         names.clear();
2798         names = sym->getAllPrettyNames();
2799         for(i=0;i<names.size();i++)
2800         {
2801             funcs = funcsByPretty[names[i]];
2802             iter = find(funcs->begin(), funcs->end(), sym);
2803             funcs->erase(iter);
2804         }
2805         names.clear();
2806         names = sym->getAllTypedNames();
2807         for(i=0;i<names.size();i++)
2808         {
2809             funcs = funcsByPretty[names[i]];
2810             iter = find(funcs->begin(), funcs->end(), sym);
2811             funcs->erase(iter);
2812         }
2813         names.clear();
2814         iter = find(everyUniqueFunction.begin(), everyUniqueFunction.end(), sym);
2815         everyUniqueFunction.erase(iter);
2816     }
2817     else if(sym->getType() == Symbol::ST_OBJECT)
2818     {
2819         unsigned i;
2820         std::vector<Symbol *> *vars;
2821         std::vector<Symbol *>::iterator iter;
2822         names = sym->getAllMangledNames();
2823         for(i=0;i<names.size();i++)
2824         {
2825             vars = varsByMangled[names[i]];
2826             iter = find(vars->begin(), vars->end(), sym);
2827             vars->erase(iter);
2828         }
2829         names.clear();
2830         names = sym->getAllPrettyNames();
2831         for(i=0;i<names.size();i++)
2832         {
2833             vars = varsByPretty[names[i]];
2834             iter = find(vars->begin(), vars->end(), sym);
2835             vars->erase(iter);
2836         }
2837         names.clear();
2838         names = sym->getAllTypedNames();
2839         for(i=0;i<names.size();i++)
2840         {
2841             vars= varsByPretty[names[i]];
2842             iter = find(vars->begin(), vars->end(), sym);
2843             vars->erase(iter);
2844         }
2845         iter = find(everyUniqueVariable.begin(), everyUniqueVariable.end(), sym);
2846         everyUniqueVariable.erase(iter);
2847     }
2848     else if(sym->getType() == Symbol::ST_MODULE)
2849     {
2850         std::vector<Symbol *>::iterator iter;
2851         iter = find(modSyms.begin(),modSyms.end(),sym);
2852         modSyms.erase(iter);
2853     }
2854     else if(sym->getType() == Symbol::ST_NOTYPE)
2855     {
2856         std::vector<Symbol *>::iterator iter;
2857         iter = find(notypeSyms.begin(),notypeSyms.end(),sym);
2858         notypeSyms.erase(iter);
2859     }
2860     delete(sym);
2861     return true;
2862 }
2863
2864 bool Symtab::addRegion(Offset vaddr, void *data, unsigned int dataSize, std::string name, Region::region_t rType_, bool loadable)
2865 {
2866     Region *sec;
2867     unsigned i;
2868     if(loadable)
2869     {
2870         sec = new Region(newSectionInsertPoint, name, vaddr, dataSize, vaddr, dataSize, (char *)data, Region::RP_R, rType_, true);
2871         regions_.insert(regions_.begin()+newSectionInsertPoint, sec);
2872         for(i = newSectionInsertPoint+1; i < regions_.size(); i++)
2873             regions_[i]->setRegionNumber(regions_[i]->getRegionNumber() + 1);
2874     }
2875     else
2876     {
2877         sec = new Region(regions_.size()+1, name, vaddr, dataSize, 0, 0, (char *)data, Region::RP_R, rType_);
2878         regions_.push_back(sec);
2879     }   
2880     if((sec->getRegionType() == Region::RT_TEXT) || (sec->getRegionType() == Region::RT_TEXTDATA)){
2881         codeRegions_.push_back(sec);
2882         std::sort(codeRegions_.begin(), codeRegions_.end(), sort_reg_by_addr);
2883     }
2884     if((sec->getRegionType() == Region::RT_DATA) || (sec->getRegionType() == Region::RT_TEXTDATA)){
2885         dataRegions_.push_back(sec);
2886         std::sort(dataRegions_.begin(), dataRegions_.end(), sort_reg_by_addr);
2887     }
2888
2889     Annotatable<Region *, user_regions_a, true> &urA = *this;
2890     urA.addAnnotation(sec);
2891     std::sort(regions_.begin(), regions_.end(), sort_reg_by_addr);
2892     return true;
2893 }
2894
2895 bool Symtab::addRegion(Region *sec)
2896 {
2897     regions_.push_back(sec);
2898     std::sort(regions_.begin(), regions_.end(), sort_reg_by_addr);
2899     Annotatable<Region *, user_regions_a, true> &urA = *this;
2900     urA.addAnnotation(sec);
2901     return true;
2902 }
2903
2904 void Symtab::parseLineInformation()
2905 {
2906    dyn_hash_map<std::string, LineInformation> *lineInfo = new dyn_hash_map <std::string, LineInformation>;
2907
2908    Object *linkedFile = getObject();
2909    linkedFile->parseFileLineInfo(*lineInfo);
2910
2911    isLineInfoValid_ = true;     
2912    dyn_hash_map <std::string, LineInformation>::iterator iter;
2913
2914    //fprintf(stderr, "%s[%d]:  after parse of line information, found info for mods:\n", FILE__, __LINE__);
2915    for (iter = lineInfo->begin(); iter!=lineInfo->end(); iter++)
2916    {
2917       Module *mod = NULL;
2918       if (findModule(mod, iter->first))
2919          mod->setLineInfo(&(iter->second));
2920       else if (findModule(mod, mf->filename()))
2921       {
2922          LineInformation *lineInformation = mod->getLineInformation();
2923          if (!lineInformation) {
2924             mod->setLineInfo(&(iter->second));
2925          } else {
2926             lineInformation->addLineInfo(&(iter->second));
2927             mod->setLineInfo(lineInformation);
2928          }      
2929       }
2930    }
2931 }
2932
2933 DLLEXPORT bool Symtab::getAddressRanges(std::vector<pair<Offset, Offset> >&ranges,
2934       std::string lineSource, unsigned int lineNo)
2935 {
2936    unsigned int originalSize = ranges.size();
2937
2938     /* Iteratate over the modules, looking for ranges in each. */
2939     for( unsigned int i = 0; i < _mods.size(); i++ ) {
2940         LineInformation *lineInformation = _mods[i]->getLineInformation();
2941         if(lineInformation)
2942              lineInformation->getAddressRanges( lineSource.c_str(), lineNo, ranges );
2943      } /* end iteration over modules */
2944      if( ranges.size() != originalSize )
2945         return true;
2946      return false;
2947 }
2948
2949 DLLEXPORT bool Symtab::getSourceLines(std::vector<LineNoTuple> &lines, Offset addressInRange)
2950 {
2951     unsigned int originalSize = lines.size();
2952
2953     /* Iteratate over the modules, looking for ranges in each. */
2954     for( unsigned int i = 0; i < _mods.size(); i++ ) {
2955         LineInformation *lineInformation = _mods[i]->getLineInformation();
2956         if(lineInformation)
2957             lineInformation->getSourceLines( addressInRange, lines );
2958      } /* end iteration over modules */
2959      if( lines.size() != originalSize )
2960         return true;
2961      return false;
2962             
2963 }
2964
2965 DLLEXPORT bool Symtab::addLine(std::string lineSource, unsigned int lineNo,
2966       unsigned int lineOffset, Offset lowInclAddr,
2967       Offset highExclAddr)
2968 {
2969    Module *mod;
2970    if(!findModule(mod, lineSource))
2971    {
2972       std::string fileNm = extract_pathname_tail(lineSource);
2973       if(!findModule(mod, fileNm))
2974       {
2975          if(!findModule(mod, mf->pathname()))
2976             return false;
2977       }    
2978    }
2979    LineInformation *lineInfo = mod->getLineInformation();
2980    if(!lineInfo)
2981       return false;
2982    return(lineInfo->addLine(lineSource.c_str(), lineNo, lineOffset, lowInclAddr, highExclAddr));
2983 }
2984
2985 DLLEXPORT bool Symtab::addAddressRange( Offset lowInclusiveAddr, Offset highExclusiveAddr,
2986       std::string lineSource, unsigned int lineNo,
2987       unsigned int lineOffset)
2988 {
2989    Module *mod;
2990    if(!findModule(mod, lineSource))
2991    {
2992       std::string fileNm = extract_pathname_tail(lineSource);
2993       if(!findModule(mod, fileNm))
2994          return false;
2995    }
2996    LineInformation *lineInfo = mod->getLineInformation();
2997    if(!lineInfo)
2998       return false;
2999    return(lineInfo->addAddressRange(lowInclusiveAddr, highExclusiveAddr, lineSource.c_str(), lineNo, lineOffset));
3000 }
3001
3002
3003 void Symtab::parseTypes()
3004 {
3005    Object *linkedFile = getObject();
3006    linkedFile->parseTypeInfo(this);
3007    isTypeInfoValid_ = true;
3008 }
3009
3010 bool Symtab::addType(Type *type)
3011 {
3012    Annotatable<Type *, user_types_a, true> &utA = *this;
3013    utA.addAnnotation(type);
3014    typeCollection *globaltypes = typeCollection::getGlobalTypeCollection();
3015    globaltypes->addType(type);
3016    return true;
3017 }
3018
3019 DLLEXPORT vector<Type *> *Symtab::getAllstdTypes()
3020 {
3021     setupStdTypes();
3022     return stdTypes->getAllTypes();     
3023 }
3024
3025 DLLEXPORT vector<Type *> *Symtab::getAllbuiltInTypes()
3026 {
3027     setupStdTypes();
3028     return builtInTypes->getAllBuiltInTypes();
3029 }
3030
3031 DLLEXPORT bool Symtab::findType(Type *&type, std::string name)
3032 {
3033     parseTypesNow();
3034     if(!_mods.size())
3035         return false;
3036     type = _mods[0]->getModuleTypes()->findType(name);
3037     if(type == NULL)
3038         return false;
3039     return true;        
3040 }
3041
3042 DLLEXPORT bool Symtab::findVariableType(Type *&type, std::string name)
3043 {
3044         parseTypesNow();
3045     if(!_mods.size())
3046         return false;
3047     type = _mods[0]->getModuleTypes()->findVariableType(name);
3048     if(type == NULL)
3049         return false;
3050     return true;        
3051 }
3052
3053 DLLEXPORT bool Symtab::findLocalVariable(std::vector<localVar *>&vars, std::string name)
3054 {
3055    parseTypesNow();
3056    unsigned i, origSize = vars.size();
3057    for(i=0;i<everyUniqueFunction.size();i++)
3058         everyUniqueFunction[i]->findLocalVariable(vars, name);
3059    if(vars.size()>origSize)
3060         return true;
3061    return false;        
3062 }
3063
3064 bool Symtab::setDefaultNamespacePrefix(string &str){
3065     defaultNamespacePrefix = str;
3066     return true;
3067 }
3068
3069 DLLEXPORT bool Symtab::emitSymbols(Object *linkedFile,std::string filename, unsigned flag)
3070 {
3071     // Add the undefined dynamic symbols so that they are added when emitting the binary
3072     map<string, Symbol *>::iterator iter = undefDynSyms.begin();
3073     while(iter!=undefDynSyms.end()){
3074         notypeSyms.push_back(iter->second);
3075         iter++;
3076     }
3077     return linkedFile->emitDriver(this, filename, everyUniqueFunction, everyUniqueVariable, modSyms, notypeSyms, flag);
3078 }
3079
3080 DLLEXPORT bool Symtab::emit(std::string filename, unsigned flag)
3081 {
3082     map<string, Symbol *>::iterator iter = undefDynSyms.begin();
3083     while(iter!=undefDynSyms.end()){
3084         notypeSyms.push_back(iter->second);
3085         iter++;
3086     }
3087     
3088    Object *linkedFile = getObject();
3089    assert(linkedFile);
3090    bool ret = linkedFile->emitDriver(this, filename, everyUniqueFunction, everyUniqueVariable, modSyms, notypeSyms, flag);
3091    return ret;
3092 }
3093
3094 DLLEXPORT bool Symtab::getSegments(vector<Segment> &segs) const
3095 {
3096    segs = segments_;
3097    if (!segments_.size()) return false;
3098    return true;
3099 }
3100
3101 DLLEXPORT bool Symtab::getMappedRegions(std::vector<Region *> &mappedRegs) const
3102 {
3103     unsigned origSize = mappedRegs.size();
3104         for(unsigned i = 0; i < regions_.size(); i++){
3105                 if(regions_[i]->isLoadable())
3106                         mappedRegs.push_back(regions_[i]);
3107         }
3108         if(mappedRegs.size() > origSize)
3109                 return true;
3110         return false;
3111 }
3112
3113 DLLEXPORT bool Symtab::updateCode(void *buffer, unsigned size)
3114 {
3115     Region *sec;
3116     if(!findRegion(sec, ".text"))
3117         return false;
3118     sec->setPtrToRawData(buffer, size);
3119     return true;
3120 }
3121
3122 DLLEXPORT bool Symtab::updateData(void *buffer, unsigned size)
3123 {
3124     Region *sec;
3125     if(!findRegion(sec, ".data"))
3126         return false;
3127     sec->setPtrToRawData(buffer, size);
3128     return true;
3129 }
3130
3131 DLLEXPORT Offset Symtab::getFreeOffset(unsigned size) 
3132 {
3133     // Look through sections until we find a gap with
3134     // sufficient space.
3135     Offset highWaterMark = 0;
3136     Offset secoffset = 0;
3137     Offset prevSecoffset = 0;
3138
3139     Object *linkedFile = getObject();
3140     assert(linkedFile);
3141
3142     for (unsigned i = 0; i < regions_.size(); i++) {
3143         Offset end = regions_[i]->getRegionAddr() + regions_[i]->getDiskSize();
3144         if (regions_[i]->getRegionAddr() == 0) continue;
3145         prevSecoffset = secoffset;
3146         if ((unsigned)((char *)(regions_[i]->getPtrToRawData()) - linkedFile->mem_image()) < (unsigned)prevSecoffset)
3147             secoffset += regions_[i]->getDiskSize();
3148         else {
3149             secoffset = (char *)(regions_[i]->getPtrToRawData()) - linkedFile->mem_image();
3150             secoffset += regions_[i]->getDiskSize();
3151         }
3152         /*fprintf(stderr, "%d: secAddr 0x%lx, size %d, end 0x%lx, looking for %d\n",
3153                         i, regions_[i]->getSecAddr(), regions_[i]->getSecSize(),
3154                         end,size);*/
3155         if (end > highWaterMark) {
3156             //fprintf(stderr, "Increasing highWaterMark...\n");
3157             newSectionInsertPoint = i+1;
3158             highWaterMark = end;
3159         }
3160         if ((i < (regions_.size()-2)) &&
3161                ((end + size) < regions_[i+1]->getRegionAddr())) {
3162             /*      fprintf(stderr, "Found a hole between sections %d and %d\n",
3163                     i, i+1);
3164                     fprintf(stderr, "End at 0x%lx, next one at 0x%lx\n",
3165                     end, regions_[i+1]->getSecAddr());
3166                     */   
3167             newSectionInsertPoint = i+1;
3168             highWaterMark = end;
3169             break;
3170         }
3171     }
3172
3173     //   return highWaterMark;
3174     unsigned pgSize = P_getpagesize();
3175     Offset newaddr = highWaterMark  - (highWaterMark & (pgSize-1)) + (secoffset & (pgSize-1));
3176     if(newaddr < highWaterMark)
3177         newaddr += pgSize;
3178     return newaddr;
3179 }
3180
3181 DLLEXPORT ObjectType Symtab::getObjectType() const 
3182 {
3183    return object_type_;
3184 }
3185
3186 DLLEXPORT char *Symtab::mem_image() const 
3187 {
3188    return (char *)mf->base_addr();
3189 }
3190
3191 DLLEXPORT std::string Symtab::file() const 
3192 {
3193   assert(mf);
3194    return mf->pathname();
3195 }
3196
3197 DLLEXPORT std::string Symtab::name() const 
3198 {
3199    return mf->filename();
3200 }
3201
3202 DLLEXPORT unsigned Symtab::getNumberofRegions() const 
3203 {
3204     return no_of_sections; 
3205 }
3206
3207 DLLEXPORT unsigned Symtab::getNumberofSymbols() const 
3208 {
3209     return no_of_symbols; 
3210 }
3211
3212 DLLEXPORT LookupInterface::LookupInterface() 
3213 {
3214 }
3215
3216 DLLEXPORT LookupInterface::~LookupInterface()
3217 {
3218 }
3219
3220
3221 DLLEXPORT ExceptionBlock::ExceptionBlock(Offset tStart, 
3222                                                  unsigned tSize, 
3223                                                  Offset cStart) 
3224    : tryStart_(tStart), trySize_(tSize), catchStart_(cStart), hasTry_(true) 
3225 {
3226 }
3227
3228 DLLEXPORT ExceptionBlock::ExceptionBlock(Offset cStart) 
3229    : tryStart_(0), trySize_(0), catchStart_(cStart), hasTry_(false) 
3230 {
3231 }
3232
3233 DLLEXPORT ExceptionBlock::ExceptionBlock(const ExceptionBlock &eb) 
3234    : tryStart_(eb.tryStart_), trySize_(eb.trySize_), 
3235      catchStart_(eb.catchStart_), hasTry_(eb.hasTry_) 
3236 {
3237 }
3238  
3239 DLLEXPORT bool ExceptionBlock::hasTry() const
3240
3241     return hasTry_; 
3242 }
3243
3244 DLLEXPORT Offset ExceptionBlock::tryStart() const
3245
3246     return tryStart_; 
3247 }
3248
3249 DLLEXPORT Offset ExceptionBlock::tryEnd() const
3250
3251     return tryStart_ + trySize_; 
3252 }
3253
3254 DLLEXPORT Offset ExceptionBlock::trySize() const
3255 {
3256     return trySize_; 
3257 }
3258
3259 DLLEXPORT bool ExceptionBlock::contains(Offset a) const
3260
3261     return (a >= tryStart_ && a < tryStart_ + trySize_); 
3262 }
3263
3264 DLLEXPORT Region::Region(): rawDataPtr_(NULL), buffer_(NULL)
3265 {
3266 }
3267
3268 DLLEXPORT Region::Region(unsigned regnum, std::string name, Offset diskOff,
3269                     unsigned long diskSize, Offset memOff, unsigned long memSize,
3270                     char *rawDataPtr, perm_t perms, region_t regType, bool isLoadable):
3271     regNum_(regnum), name_(name), diskOff_(diskOff), diskSize_(diskSize), memOff_(memOff),
3272     memSize_(memSize), rawDataPtr_(rawDataPtr), permissions_(perms), rType_(regType), 
3273     isDirty_(false), buffer_(NULL), isLoadable_(isLoadable)
3274 {
3275      if(memOff)
3276         isLoadable_ = true;
3277 }
3278
3279 DLLEXPORT Region::Region(const Region &reg) : regNum_(reg.regNum_), name_(reg.name_),
3280                     diskOff_(reg.diskOff_), diskSize_(reg.diskSize_), memOff_(reg.memOff_),
3281                     memSize_(reg.memSize_), rawDataPtr_(reg.rawDataPtr_), permissions_(reg.permissions_),
3282                     rType_(reg.rType_), isDirty_(reg.isDirty_), rels_(reg.rels_), buffer_(reg.buffer_)
3283 {
3284 }
3285
3286 DLLEXPORT Region& Region::operator=(const Region &reg){
3287     regNum_ = reg.regNum_;
3288     name_ = reg.name_;
3289     diskOff_ = reg.diskOff_;
3290     diskSize_ = reg.diskSize_;
3291     memOff_ = reg.memOff_;
3292     memSize_ = reg.memSize_;
3293     rawDataPtr_ = reg.rawDataPtr_;
3294     permissions_ = reg.permissions_;
3295     rType_ = reg.rType_;
3296     isDirty_ = reg.isDirty_;
3297     rels_ = reg.rels_;
3298     buffer_ = reg.buffer_;
3299
3300     return *this;
3301 }
3302
3303 DLLEXPORT bool Region::operator==(const Region &reg){
3304     return ((regNum_== reg.regNum_) &&
3305             (name_ == reg.name_) &&
3306             (diskOff_ == reg.diskOff_) &&
3307             (diskSize_ == reg.diskSize_) &&
3308             (memOff_ == reg.memOff_) &&
3309             (memSize_ == reg.memSize_) &&
3310             (rawDataPtr_ == reg.rawDataPtr_) &&
3311             (permissions_ == reg.permissions_) &&
3312             (rType_ == reg.rType_) &&
3313             (isDirty_ == reg.isDirty_) &&
3314             (buffer_ == reg.buffer_));
3315 }
3316
3317 DLLEXPORT ostream& Region::operator<< (ostream &os) 
3318 {
3319     return os   << "{"
3320                 << " Region Number="      << regNum_
3321                 << " name="    << name_
3322                 << " disk offset="    << diskOff_
3323                 << " disk size="    << diskSize_
3324                 << " memory offset="    << memOff_
3325                 << " memory size="    << memSize_
3326                 << " Permissions=" << permissions_
3327                         << " region type " << rType_
3328                 << " }" << endl;
3329 }
3330
3331 DLLEXPORT Region::~Region() 
3332 {
3333     if(buffer_)
3334         free(buffer_);
3335 }
3336
3337 DLLEXPORT unsigned Region::getRegionNumber() const
3338 {
3339     return regNum_;
3340 }
3341
3342 DLLEXPORT bool Region::setRegionNumber(unsigned regnumber){
3343     regNum_ = regnumber;
3344     return true;
3345 }
3346
3347 DLLEXPORT std::string Region::getRegionName() const{
3348     return name_;
3349 }
3350
3351 DLLEXPORT Offset Region::getRegionAddr() const{
3352 #if defined(_MSC_VER)
3353         return memOff_;
3354 #else
3355         return diskOff_;
3356 #endif
3357 }
3358
3359 DLLEXPORT Offset Region::getRegionSize() const{
3360 #if defined(_MSC_VER)
3361         return memSize_;
3362 #else
3363         return diskSize_;
3364 #endif
3365 }
3366
3367 DLLEXPORT Offset Region::getDiskOffset() const{
3368     return diskOff_;
3369 }
3370
3371 DLLEXPORT unsigned long Region::getDiskSize() const{
3372     return diskSize_;
3373 }
3374
3375 DLLEXPORT Offset Region::getMemOffset() const{
3376     return memOff_;
3377 }
3378
3379 DLLEXPORT unsigned long Region::getMemSize() const{
3380     return memSize_;
3381 }
3382
3383 DLLEXPORT void *Region::getPtrToRawData() const{
3384     return rawDataPtr_;
3385 }
3386  
3387 DLLEXPORT bool Region::setPtrToRawData(void *buf, unsigned long newsize){
3388     rawDataPtr_ = buf;
3389     diskSize_ = newsize;
3390     isDirty_ = true;
3391     return true;
3392 }
3393     
3394 DLLEXPORT bool Region::isBSS() const {
3395     return rType_==RT_BSS;
3396 }
3397     
3398 DLLEXPORT bool Region::isText() const{
3399     return rType_==RT_TEXT;
3400 }
3401
3402 DLLEXPORT bool Region::isData() const{
3403     return rType_ == RT_DATA;
3404 }
3405
3406 DLLEXPORT bool Region::isOffsetInRegion(const Offset &offset) const {
3407     return (offset >= diskOff_ && offset<=(diskOff_+diskSize_));
3408 }
3409
3410 DLLEXPORT bool Region::isLoadable() const{
3411     if(isLoadable_)
3412         return true;
3413     return (memOff_ != 0);
3414 }
3415
3416 DLLEXPORT bool Region::isDirty() const{
3417     return isDirty_;
3418 }
3419
3420 DLLEXPORT std::vector<relocationEntry> &Region::getRelocations(){
3421     return rels_;
3422 }
3423
3424 DLLEXPORT bool Region::patchData(Offset off, void *buf, unsigned size){
3425     if(off+size > diskSize_)
3426         return false;
3427     if(!buffer_)
3428         memcpy(buffer_, rawDataPtr_, diskSize_);
3429     memcpy((char *)buffer_+off, buf, size);
3430     return setPtrToRawData(buffer_, diskSize_);
3431 }
3432
3433 DLLEXPORT bool Region::addRelocationEntry(Offset ra, Symbol *dynref, unsigned long relType){
3434     rels_.push_back(relocationEntry(ra, dynref->getPrettyName(), dynref, relType));
3435     return true;
3436 }
3437
3438 DLLEXPORT Region::perm_t Region::getRegionPermissions() const {
3439     return permissions_;
3440 }
3441
3442 DLLEXPORT bool Region::setRegionPermissions(Region::perm_t newPerms){
3443     permissions_ = newPerms;
3444     return true;
3445 }
3446
3447 DLLEXPORT Region::region_t Region::getRegionType() const {
3448     return rType_;
3449 }
3450
3451 DLLEXPORT relocationEntry::relocationEntry()
3452    :target_addr_(0),rel_addr_(0), name_(""), dynref_(NULL), relType_(0)
3453 {
3454 }   
3455
3456 DLLEXPORT relocationEntry::relocationEntry(Offset ta,Offset ra, std::string n, Symbol *dynref, unsigned long relType)
3457    : target_addr_(ta), rel_addr_(ra),name_(n), dynref_(dynref), relType_(relType)
3458 {
3459 }   
3460
3461 DLLEXPORT relocationEntry::relocationEntry(Offset ra, std::string n, Symbol *dynref, unsigned long relType)
3462    : target_addr_(0), rel_addr_(ra),name_(n), dynref_(dynref), relType_(relType)
3463 {
3464 }   
3465
3466 DLLEXPORT const relocationEntry& relocationEntry::operator=(const relocationEntry &ra) 
3467 {
3468     target_addr_ = ra.target_addr_; rel_addr_ = ra.rel_addr_; 
3469     name_ = ra.name_; 
3470     dynref_ = ra.dynref_;
3471     relType_ = ra.relType_;
3472     return *this;
3473 }
3474
3475
3476 int symtab_printf(const char *format, ...)
3477 {
3478    static int dyn_debug_symtab = 0;
3479
3480    if (dyn_debug_symtab == -1) {
3481       return 0;
3482    }
3483    if (!dyn_debug_symtab) {
3484       char *p = getenv("DYNINST_DEBUG_SYMTAB");
3485       if (!p)
3486          p = getenv("SYMTAB_DEBUG_SYMTAB");
3487       if (p) {
3488          fprintf(stderr, "Enabling SymtabAPI debug logging\n");
3489          dyn_debug_symtab = 1;
3490       }
3491       else {
3492          dyn_debug_symtab = -1;
3493          return 0;
3494       }
3495    }
3496
3497    if (!format)
3498       return -1;
3499    
3500    va_list va;
3501    va_start(va, format);
3502    int ret = vfprintf(stderr, format, va);
3503    va_end(va);
3504    
3505    return ret;
3506 }
3507
3508 const char *Symbol::symbolType2Str(SymbolType t) {
3509    switch(t) {
3510       CASE_RETURN_STR(ST_UNKNOWN);
3511       CASE_RETURN_STR(ST_FUNCTION);
3512       CASE_RETURN_STR(ST_OBJECT);
3513       CASE_RETURN_STR(ST_MODULE);
3514       CASE_RETURN_STR(ST_NOTYPE);
3515    }
3516    return "invalid symbol type";
3517 }
3518
3519 const char *Symbol::symbolLinkage2Str(SymbolLinkage t) {
3520    switch(t) {
3521       CASE_RETURN_STR(SL_UNKNOWN);
3522       CASE_RETURN_STR(SL_GLOBAL);
3523       CASE_RETURN_STR(SL_LOCAL);
3524       CASE_RETURN_STR(SL_WEAK);
3525    }
3526    return "invalid symbol linkage";
3527 }
3528
3529 const char *Symbol::symbolTag2Str(SymbolTag t) {
3530    switch(t) {
3531       CASE_RETURN_STR(TAG_UNKNOWN);
3532       CASE_RETURN_STR(TAG_USER);
3533       CASE_RETURN_STR(TAG_LIBRARY);
3534       CASE_RETURN_STR(TAG_INTERNAL);
3535    }
3536    return "invalid symbol tag";
3537 }
3538
3539 Object *Symtab::getObject()
3540 {
3541    if (obj_private)
3542       return obj_private;
3543
3544    //TODO: This likely triggered because we serialized in an object
3545    // from cache, but now the user is requesting more information from
3546    // the on disk object.  We should create a new 'Object' from data
3547    // (likely a file path) serialized in.
3548    
3549    assert(0);
3550    //obj_private = new Object();
3551    return obj_private;
3552 }