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