Update copyright to LGPL on all files
[dyninst.git] / symtabAPI / src / Symtab.C
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <assert.h>
35 #include <string.h>
36 #include <algorithm>
37
38 #include "common/h/Timer.h"
39 #include "common/h/debugOstream.h"
40 #include "common/h/serialize.h"
41 #include "common/h/pathName.h"
42
43 #include "Serialization.h"
44 #include "Symtab.h"
45 #include "Module.h"
46 #include "Collections.h"
47 #include "Function.h"
48 #include "Variable.h"
49
50 #include "annotations.h"
51
52 #include "debug.h"
53
54 #include "symtabAPI/src/Object.h"
55
56 #if !defined(os_windows)
57 #include <dlfcn.h>
58 #else
59 #include <windows.h>
60 #endif
61
62 #include <iomanip>
63 #include <stdarg.h>
64
65 using namespace Dyninst;
66 using namespace Dyninst::SymtabAPI;
67 using namespace std;
68
69 static std::string errMsg;
70 extern bool parseCompilerType(Object *);
71
72 void symtab_log_perror(const char *msg)
73 {
74    errMsg = std::string(msg);
75 };
76
77
78 SymtabError serr;
79
80 std::vector<Symtab *> Symtab::allSymtabs;
81 builtInTypeCollection *Symtab::builtInTypes = NULL;
82 typeCollection *Symtab::stdTypes = NULL;
83  
84 SymtabError Symtab::getLastSymtabError()
85 {
86     return serr;
87 }
88
89 void setSymtabError(SymtabError new_err)
90 {
91    serr = new_err;
92 }
93
94 std::string Symtab::printError(SymtabError serr)
95 {
96     switch (serr)
97     {
98        case Obj_Parsing:
99            return "Failed to parse the Object"+errMsg;
100        case Syms_To_Functions:
101            return "Failed to convert Symbols to Functions";
102        case No_Such_Function:
103            return "Function does not exist";
104        case No_Such_Variable:
105            return "Variable does not exist";
106        case No_Such_Module:
107           return "Module does not exist";
108        case No_Such_Region:
109            return "Region does not exist";
110        case No_Such_Symbol:
111            return "Symbol does not exist";
112        case Not_A_File:
113            return "Not a File. Call openArchive()";
114        case Not_An_Archive:
115            return "Not an Archive. Call openFile()";
116        case Export_Error:
117            return "Error Constructing XML"+errMsg;
118        case Invalid_Flags:
119           return "Flags passed are invalid.";
120        case No_Error:
121           return "No previous Error.";
122        default:
123           return "Unknown Error";
124     }           
125 }
126
127 Type *Symtab::type_Error = NULL;
128 Type *Symtab::type_Untyped = NULL;
129
130 void Symtab::setupTypes()
131 {
132     /*
133      * Create the "error" and "untyped" types.
134      */
135     std::string name = "<error>";
136     if (NULL == type_Error) type_Error  = new Type(name, 0, dataUnknownType);
137     name = std::string("<no type>");
138     if (NULL == type_Untyped) type_Untyped = new Type(name, 0, dataUnknownType);
139     setupStdTypes();
140 }    
141
142 void Symtab::setupStdTypes() 
143 {
144    if (builtInTypes)
145         return;
146
147    builtInTypes = new builtInTypeCollection;
148    typeScalar *newType;
149
150    // NOTE: integral type  mean twos-complement
151    // -1  int, 32 bit signed integral type
152    // in stab document, size specified in bits, system size is in bytes
153    builtInTypes->addBuiltInType(newType = new typeScalar(-1, 4, "int", true));
154    newType->decrRefCount();
155    // -2  char, 8 bit type holding a character. GDB & dbx(AIX) treat as signed
156    builtInTypes->addBuiltInType(newType = new typeScalar(-2, 1, "char", true));
157    newType->decrRefCount();
158    // -3  short, 16 bit signed integral type
159    builtInTypes->addBuiltInType(newType = new typeScalar(-3, 2, "short", true));
160    newType->decrRefCount();
161    // -4  long, 32/64 bit signed integral type
162    builtInTypes->addBuiltInType(newType = new typeScalar(-4, sizeof(long), "long", true));
163    newType->decrRefCount();
164    // -5  unsigned char, 8 bit unsigned integral type
165    builtInTypes->addBuiltInType(newType = new typeScalar(-5, 1, "unsigned char"));
166    newType->decrRefCount();
167    // -6  signed char, 8 bit signed integral type
168    builtInTypes->addBuiltInType(newType = new typeScalar(-6, 1, "signed char", true));
169    newType->decrRefCount();
170    // -7  unsigned short, 16 bit unsigned integral type
171    builtInTypes->addBuiltInType(newType = new typeScalar(-7, 2, "unsigned short"));
172    newType->decrRefCount();
173    // -8  unsigned int, 32 bit unsigned integral type
174    builtInTypes->addBuiltInType(newType = new typeScalar(-8, 4, "unsigned int"));
175    newType->decrRefCount();
176    // -9  unsigned, 32 bit unsigned integral type
177    builtInTypes->addBuiltInType(newType = new typeScalar(-9, 4, "unsigned"));
178    newType->decrRefCount();
179    // -10 unsigned long, 32 bit unsigned integral type
180    builtInTypes->addBuiltInType(newType = new typeScalar(-10, sizeof(unsigned long), "unsigned long"));
181    newType->decrRefCount();
182    // -11 void, type indicating the lack of a value
183    //  XXX-size may not be correct jdd 4/22/99
184    builtInTypes->addBuiltInType(newType = new typeScalar(-11, 0, "void", false));
185    newType->decrRefCount();
186    // -12 float, IEEE single precision
187    builtInTypes->addBuiltInType(newType = new typeScalar(-12, sizeof(float), "float", true));
188    newType->decrRefCount();
189    // -13 double, IEEE double precision
190    builtInTypes->addBuiltInType(newType = new typeScalar(-13, sizeof(double), "double", true));
191    newType->decrRefCount();
192    // -14 long double, IEEE double precision, size may increase in future
193    builtInTypes->addBuiltInType(newType = new typeScalar(-14, sizeof(long double), "long double", true));
194    newType->decrRefCount();
195    // -15 integer, 32 bit signed integral type
196    builtInTypes->addBuiltInType(newType = new typeScalar(-15, 4, "integer", true));
197    newType->decrRefCount();
198    // -16 boolean, 32 bit type. GDB/GCC 0=False, 1=True, all other values
199    //  have unspecified meaning
200    builtInTypes->addBuiltInType(newType = new typeScalar(-16, sizeof(bool), "boolean"));
201    newType->decrRefCount();
202    // -17 short real, IEEE single precision
203    //  XXX-size may not be correct jdd 4/22/99
204    builtInTypes->addBuiltInType(newType = new typeScalar(-17, sizeof(float), "short real", true));
205    newType->decrRefCount();
206    // -18 real, IEEE double precision XXX-size may not be correct jdd 4/22/99
207    builtInTypes->addBuiltInType(newType = new typeScalar(-18, sizeof(double), "real", true));
208    newType->decrRefCount();
209    // -19 stringptr XXX- size of void * -- jdd 4/22/99
210    builtInTypes->addBuiltInType(newType = new typeScalar(-19, sizeof(void *), "stringptr"));
211    newType->decrRefCount();
212    // -20 character, 8 bit unsigned character type
213    builtInTypes->addBuiltInType(newType = new typeScalar(-20, 1, "character"));
214    newType->decrRefCount();
215    // -21 logical*1, 8 bit type (Fortran, used for boolean or unsigned int)
216    builtInTypes->addBuiltInType(newType = new typeScalar(-21, 1, "logical*1"));
217    newType->decrRefCount();
218    // -22 logical*2, 16 bit type (Fortran, some for boolean or unsigned int)
219    builtInTypes->addBuiltInType(newType = new typeScalar(-22, 2, "logical*2"));
220    newType->decrRefCount();
221    // -23 logical*4, 32 bit type (Fortran, some for boolean or unsigned int)
222    builtInTypes->addBuiltInType(newType = new typeScalar(-23, 4, "logical*4"));
223    newType->decrRefCount();
224    // -24 logical, 32 bit type (Fortran, some for boolean or unsigned int)
225    builtInTypes->addBuiltInType(newType = new typeScalar(-24, 4, "logical"));
226    newType->decrRefCount();
227    // -25 complex, consists of 2 IEEE single-precision floating point values
228    builtInTypes->addBuiltInType(newType = new typeScalar(-25, sizeof(float)*2, "complex", true));
229    newType->decrRefCount();
230    // -26 complex, consists of 2 IEEE double-precision floating point values
231    builtInTypes->addBuiltInType(newType = new typeScalar(-26, sizeof(double)*2, "complex*16", true));
232    newType->decrRefCount();
233    // -27 integer*1, 8 bit signed integral type
234    builtInTypes->addBuiltInType(newType = new typeScalar(-27, 1, "integer*1", true));
235    newType->decrRefCount();
236    // -28 integer*2, 16 bit signed integral type
237    builtInTypes->addBuiltInType(newType = new typeScalar(-28, 2, "integer*2", true));
238    newType->decrRefCount();
239
240    /* Quick hack to make integer*4 compatible with int for Fortran
241       jnb 6/20/01 */
242    // This seems questionable - let's try removing that hack - jmo 05/21/04
243    /*
244      builtInTypes->addBuiltInType(newType = new type("int",-29,
245      built_inType, 4));
246      newType->decrRefCount();
247    */
248    // -29 integer*4, 32 bit signed integral type
249    builtInTypes->addBuiltInType(newType = new typeScalar(-29, 4, "integer*4", true));
250    newType->decrRefCount();
251    // -30 wchar, Wide character, 16 bits wide, unsigned (unknown format)
252    builtInTypes->addBuiltInType(newType = new typeScalar(-30, 2, "wchar"));
253    newType->decrRefCount();
254 #if defined(os_windows)
255    // -31 long long, 64 bit signed integral type
256    builtInTypes->addBuiltInType(newType = new typeScalar(-31, sizeof(LONGLONG), "long long", true));
257    newType->decrRefCount();
258    // -32 unsigned long long, 64 bit unsigned integral type
259    builtInTypes->addBuiltInType(newType = new typeScalar(-32, sizeof(ULONGLONG), "unsigned long long"));
260    newType->decrRefCount();
261 #else
262    // -31 long long, 64 bit signed integral type
263    builtInTypes->addBuiltInType(newType = new typeScalar(-31, sizeof(long long), "long long", true));
264    newType->decrRefCount();
265    // -32 unsigned long long, 64 bit unsigned integral type
266    builtInTypes->addBuiltInType(newType = new typeScalar(-32, sizeof(unsigned long long), "unsigned long long"));
267    newType->decrRefCount();
268 #endif
269    // -33 logical*8, 64 bit unsigned integral type
270    builtInTypes->addBuiltInType(newType = new typeScalar(-33, 8, "logical*8"));
271    newType->decrRefCount();
272    // -34 integer*8, 64 bit signed integral type
273    builtInTypes->addBuiltInType(newType = new typeScalar(-34, 8, "integer*8", true));
274    newType->decrRefCount();
275
276         /*
277     * Initialize hash table of standard types.
278     */
279         if (stdTypes)
280         return;
281
282    stdTypes = new typeCollection();
283    stdTypes->addType(newType = new typeScalar(-1, sizeof(int), "int"));
284    newType->decrRefCount();
285
286    Type *charType = new typeScalar(-2, sizeof(char), "char");
287    stdTypes->addType(charType);
288
289         std::string tName = "char *";
290         typePointer *newPtrType;
291    stdTypes->addType(newPtrType = new typePointer(-3, charType, tName));
292    charType->decrRefCount();
293    newPtrType->decrRefCount();
294
295    Type *voidType = new typeScalar(-11, 0, "void", false);
296    stdTypes->addType(voidType);
297
298         tName = "void *";
299    stdTypes->addType(newPtrType = new typePointer(-4, voidType, tName));
300    voidType->decrRefCount();
301    newPtrType->decrRefCount();
302
303    stdTypes->addType(newType = new typeScalar(-12, sizeof(float), "float"));
304    newType->decrRefCount();
305
306 #if defined(i386_unknown_nt4_0)
307    stdTypes->addType(newType = new typeScalar(-31, sizeof(LONGLONG), "long long"));    
308 #else
309    stdTypes->addType(newType = new typeScalar(-31, sizeof(long long), "long long"));
310 #endif
311
312         newType->decrRefCount();
313
314    return;
315 }
316
317 SYMTAB_EXPORT unsigned Symtab::getAddressWidth() const 
318 {
319    return address_width_;
320 }
321  
322 SYMTAB_EXPORT bool Symtab::isNativeCompiler() const 
323 {
324     return nativeCompiler; 
325 }
326  
327
328 SYMTAB_EXPORT Symtab::Symtab(MappedFile *mf_) :
329    AnnotatableSparse(),
330    mf(mf_), 
331    mfForDebugInfo(mf_),
332    obj_private(NULL)
333 {   
334     init_debug_symtabAPI();
335 }   
336
337
338 SYMTAB_EXPORT Symtab::Symtab() :
339    obj_private(NULL)
340 {
341     init_debug_symtabAPI();
342     create_printf("%s[%d]: Created symtab via default constructor\n", FILE__, __LINE__);
343     defaultNamespacePrefix = "";
344 }
345
346 SYMTAB_EXPORT bool Symtab::isExec() const 
347 {
348     return is_a_out; 
349 }
350
351 SYMTAB_EXPORT bool Symtab::isStripped() 
352 {
353 #if defined(os_linux) || defined(os_solaris)
354     Region *sec;
355     return findRegion(sec,".symtab");
356 #else
357     return (no_of_symbols==0);
358 #endif
359 }
360
361 SYMTAB_EXPORT Offset Symtab::imageOffset() const 
362 {
363     return imageOffset_;
364 }
365
366 SYMTAB_EXPORT Offset Symtab::dataOffset() const 
367
368     return dataOffset_;
369 }
370
371 SYMTAB_EXPORT Offset Symtab::dataLength() const 
372 {
373     return dataLen_;
374
375
376 SYMTAB_EXPORT Offset Symtab::imageLength() const 
377 {
378     return imageLen_;
379 }
380 /*
381 SYMTAB_EXPORT char* Symtab::image_ptr ()  const 
382 {
383    return code_ptr_;
384 }
385
386 SYMTAB_EXPORT char* Symtab::data_ptr ()  const 
387
388    return data_ptr_;
389 }
390 */
391 SYMTAB_EXPORT const char*  Symtab::getInterpreterName() const 
392 {
393    if (interpreter_name_.length())
394       return interpreter_name_.c_str();
395    return NULL;
396 }
397  
398 SYMTAB_EXPORT Offset Symtab::getEntryOffset() const 
399
400    return entry_address_;
401 }
402
403 SYMTAB_EXPORT Offset Symtab::getBaseOffset() const 
404 {
405    return base_address_;
406 }
407
408 SYMTAB_EXPORT Offset Symtab::getLoadOffset() const 
409
410    return load_address_;
411 }
412
413 SYMTAB_EXPORT Offset Symtab::getTOCoffset() const 
414 {
415    return toc_offset_;
416 }
417
418 SYMTAB_EXPORT string Symtab::getDefaultNamespacePrefix() const
419 {
420     return defaultNamespacePrefix;
421 }
422         
423         
424 // TODO -- is this g++ specific
425 bool Symtab::buildDemangledName( const std::string &mangled, 
426       std::string &pretty,
427       std::string &typed,
428       bool nativeCompiler, 
429       supportedLanguages lang )
430 {
431    /* The C++ demangling function demangles MPI__Allgather (and other MPI__
432     * functions with start with A) into the MPI constructor.  In order to
433     * prevent this a hack needed to be made, and this seemed the cleanest
434     * approach.
435     */
436
437    if ((mangled.length()>5) && (mangled.substr(0,5)==std::string("MPI__"))) 
438    {
439       return false;
440    }      
441
442    /* If it's Fortran, eliminate the trailing underscores, if any. */
443    if (lang == lang_Fortran 
444          || lang == lang_CMFortran 
445          || lang == lang_Fortran_with_pretty_debug )
446    {
447       if ( mangled[ mangled.length() - 1 ] == '_' ) 
448       {
449          char * demangled = P_strdup( mangled.c_str() );
450          demangled[ mangled.length() - 1 ] = '\0';
451          pretty = std::string( demangled );
452
453          free ( demangled );
454          return true;
455       }
456       else 
457       {
458          /* No trailing underscores, do nothing */
459          return false;
460       }
461    } /* end if it's Fortran. */
462
463    //  Check to see if we have a gnu versioned symbol on our hands.
464    //  These are of the form <symbol>@<version> or <symbol>@@<version>
465    //
466    //  If we do, we want to create a "demangled" name for the one that
467    //  is of the form <symbol>@@<version> since this is, by definition,
468    //  the default.  The "demangled" name will just be <symbol>
469
470    //  NOTE:  this is just a 0th order approach to dealing with versioned
471    //         symbols.  We may need to do something more sophisticated
472    //         in the future.  JAW 10/03
473
474 #if !defined(os_windows)
475
476    const char *atat;
477
478    if (NULL != (atat = strstr(mangled.c_str(), "@@"))) 
479    {
480         pretty = mangled.substr(0 /*start pos*/, 
481                         (int)(atat - mangled.c_str())/*len*/);
482         //char msg[256];
483         //sprintf(msg, "%s[%d]: 'demangling' versioned symbol: %s, to %s",
484         //          __FILE__, __LINE__, mangled.c_str(), pretty.c_str());
485
486         //cerr << msg << endl;
487         //logLine(msg);
488       
489         return true;
490     }
491
492 #endif
493
494     bool retval = false;
495   
496     /* Try demangling it. */
497     char * demangled = P_cplus_demangle( mangled.c_str(), nativeCompiler, false);
498     if (demangled) 
499     {
500         pretty = std::string( demangled );
501         retval = true;
502     }
503   
504     char *t_demangled = P_cplus_demangle(mangled.c_str(), nativeCompiler, true);
505     if (t_demangled && (strcmp(t_demangled, demangled) != 0)) 
506     {
507         typed = std::string(t_demangled);
508         retval = true;
509     }
510
511     if (demangled)
512         free(demangled);
513     if (t_demangled)
514         free(t_demangled);
515
516     return retval;
517 } /* end buildDemangledName() */
518
519
520 /*
521  * extractSymbolsFromFile
522  *
523  * Create a Symtab-level list of symbols by pulling out data
524  * from the low-level parse (linkedFile).
525  * Technically this causes a duplication of symbols; however,
526  * we will be rewriting these symbols and so we need our own
527  * copy. 
528  *
529  * TODO: delete the linkedFile once we're done?
530  */
531
532 bool Symtab::extractSymbolsFromFile(Object *linkedFile, std::vector<Symbol *> &raw_syms) 
533 {
534     for (SymbolIter symIter(*linkedFile); symIter; symIter++) 
535         {
536         Symbol *sym = symIter.currval();
537                 if (!sym) 
538                 {
539                         fprintf(stderr, "%s[%d]:  range error, stopping now\n", FILE__, __LINE__);
540                         return true;
541                 }
542
543         // If a symbol starts with "." we want to skip it. These indicate labels in the
544         // code. 
545         
546         // removed 1/09: this should be done in Dyninst, not Symtab
547
548         // check for undefined dynamic symbols. Used when rewriting relocation section.
549         // relocation entries have references to these undefined dynamic symbols.
550         // We also have undefined symbols for the static binary case.
551         
552         if (sym->getSec() == NULL && !sym->isAbsolute()) {
553             undefDynSyms[sym->getMangledName()].push_back(sym);
554             continue;
555         }
556
557         // Check whether this symbol has a valid offset. If they do not we have a
558         // consistency issue. This should be a null check.
559
560         // Symbols can have an offset of 0 if they don't refer to things within a file.
561
562         raw_syms.push_back(sym);
563     }
564
565     return true;
566 }
567
568 /*
569  * fixSymModules
570  * 
571  * Add Module information to all symbols. 
572  */
573
574 bool Symtab::fixSymModules(std::vector<Symbol *> &raw_syms) 
575 {
576     for (unsigned i = 0; i < raw_syms.size(); i++) {
577         fixSymModule(raw_syms[i]);
578     }
579         Object *obj = getObject();
580         if (!obj)
581         {
582                 fprintf(stderr, "%s[%d]:  getObject failed here\n", FILE__, __LINE__);
583                 return false;
584         }
585     const std::vector<std::pair<std::string, Offset> > &mods = obj->modules_;
586     for (unsigned i=0; i< mods.size(); i++) {
587        getOrCreateModule(mods[i].first, mods[i].second);
588     }
589        
590     return true;
591 }
592
593 /*
594  * demangleSymbols
595  *
596  * Perform name demangling on all symbols.
597  */
598
599 bool Symtab::demangleSymbols(std::vector<Symbol *> &raw_syms) 
600 {
601     for (unsigned i = 0; i < raw_syms.size(); i++) {
602         demangleSymbol(raw_syms[i]);
603     }
604     return true;
605 }
606
607 /*
608  * createIndices
609  *
610  * We index symbols by various attributes for quick lookup. Build those
611  * indices here. 
612  */
613
614 bool Symtab::createIndices(std::vector<Symbol *> &raw_syms) {
615     for (unsigned i = 0; i < raw_syms.size(); i++) {
616         addSymbolToIndices(raw_syms[i]);
617     }
618     return true;
619 }
620
621 /*
622  * createAggregates
623  *
624  * Frequently there will be multiple Symbols that refer to a single 
625  * code object (e.g., function or variable). We use separate objects
626  * to refer to these aggregates, and build those objects here. 
627  */
628
629 bool Symtab::createAggregates() 
630 {
631     for (unsigned i = 0; i < everyDefinedSymbol.size(); i++) 
632         {
633         addSymbolToAggregates(everyDefinedSymbol[i]);
634     }
635     return true;
636 }
637  
638 bool Symtab::fixSymModule(Symbol *&sym) 
639 {
640     //////////
641     //////////
642     //////////
643     //
644     // It has been decided that all libraries shall have only one
645     // module named after the library. The a.out has one module
646     // per (reported) source file, plus DEFAULT_MODULE for everything
647     // else. This is enforced here, although the Object-* files might
648     // do it as well.
649     Module *mod = NULL;
650     if (getObjectType() == obj_SharedLib) {
651         mod = getDefaultModule();
652     }
653     else {
654                 Object *obj = getObject();
655                 if (!obj)
656                 {
657                         fprintf(stderr, "%s[%d]:  getObject failed here\n", FILE__, __LINE__);
658                         return false;
659                 }
660         std::string modName = obj->findModuleForSym(sym);
661         if (modName.length() == 0) {
662             mod = getDefaultModule();
663         }
664         else {
665             mod = getOrCreateModule(modName, sym->getOffset());
666         }
667     }
668     if (!mod)
669         return false;
670
671     sym->setModule(mod);
672     return true;
673 }
674
675 bool Symtab::demangleSymbol(Symbol *&sym) {
676     switch (sym->getType()) {
677     case Symbol::ST_FUNCTION: {
678         Module *rawmod = sym->getModule();
679         assert(rawmod);
680         
681         // At this point we need to generate the following information:
682         // A symtab name.
683         // A pretty (demangled) name.
684         // The symtab name goes in the global list as well as the module list.
685         // Same for the pretty name.
686         // Finally, check addresses to find aliases.
687         
688         std::string mangled_name = sym->getMangledName();
689         std::string working_name = mangled_name;
690         
691 #if !defined(os_windows)        
692         //Remove extra stabs information
693         const char *p = strchr(working_name.c_str(), ':');
694         if( p ) {
695             unsigned nchars = p - mangled_name.c_str();
696             working_name = std::string(mangled_name.c_str(), nchars);
697         }
698 #endif        
699         
700         std::string pretty_name = working_name;
701         std::string typed_name = working_name;
702         
703         if (!buildDemangledName(working_name, pretty_name, typed_name,
704                                 nativeCompiler, rawmod->language())) {
705             pretty_name = working_name;
706         }
707
708         sym->prettyName_ = pretty_name;
709         sym->typedName_ = typed_name;
710         
711         break;
712     }
713     default: {
714         // All cases where there really shouldn't be a mangled
715         // name, since mangling is for functions.
716         
717         char *prettyName = P_cplus_demangle(sym->getMangledName().c_str(), nativeCompiler, false);
718         if (prettyName) {
719             sym->prettyName_ = prettyName;
720         }
721         break;
722     }
723     }
724     return true;
725 }
726
727 bool Symtab::addSymbolToIndices(Symbol *&sym) 
728 {
729         assert(sym);
730 //      sym->index_ = everyDefinedSymbol.size();
731
732     everyDefinedSymbol.push_back(sym);
733     
734     symsByOffset[sym->getAddr()].push_back(sym);
735     
736     symsByMangledName[sym->getMangledName()].push_back(sym);
737
738     symsByPrettyName[sym->getPrettyName()].push_back(sym);
739
740     symsByTypedName[sym->getTypedName()].push_back(sym);
741
742     return true;
743 }
744
745 bool Symtab::addSymbolToAggregates(Symbol *&sym) 
746 {
747     switch(sym->getType()) {
748     case Symbol::ST_FUNCTION: {
749         // We want to do the following:
750         // If no function exists, create and add. 
751         // Combine this information
752         //   Add this symbol's names to the function.
753         //   Keep module information 
754
755         Function *func = NULL;
756         findFuncByEntryOffset(func, sym->getAddr());
757         if (!func) {
758             // Create a new function
759             // Also, update the symbol to point to this function.
760
761             func = new Function(sym);
762
763             everyFunction.push_back(func);
764             sorted_everyFunction = false;
765             funcsByOffset[sym->getAddr()] = func;
766         }
767         else {
768             func->addSymbol(sym);
769         }
770         sym->setFunction(func);
771
772         break;
773     }
774     case Symbol::ST_OBJECT: {
775         // The same as the above, but with variables.
776         Variable *var = NULL;
777         findVariableByOffset(var, sym->getAddr());
778         if (!var) {
779             // Create a new function
780             // Also, update the symbol to point to this function.
781             var = new Variable(sym);
782             
783             everyVariable.push_back(var);
784             varsByOffset[sym->getAddr()] = var;
785         }
786         else {
787             var->addSymbol(sym);
788         }
789         sym->setVariable(var);
790         break;
791     }
792     default: {
793         break;
794     }
795     }
796     return true;
797 }
798
799 /* Add the new name to the appropriate symbol index */
800
801 bool Symtab::updateIndices(Symbol *sym, std::string newName, NameType nameType) {
802     if (nameType & mangledName) {
803         // Add this symbol under the given name (as mangled)
804         symsByMangledName[newName].push_back(sym);
805     }
806     if (nameType & prettyName) {
807         // Add this symbol under the given name (as pretty)
808         symsByPrettyName[newName].push_back(sym);
809     }
810     if (nameType & typedName) {
811         // Add this symbol under the given name (as typed)
812         symsByTypedName[newName].push_back(sym);
813     }
814     return true;
815 }
816
817 #if 0
818 /* checkPPC64DescriptorSymbols() is no longer needed.  3-word descriptor
819  * symbols are properly taken care of during symbol parsing.  See
820  * parse_symbols() in Object-elf.C for details.
821  */
822
823 #if defined(ppc64_linux)
824 /* Special case for ppc64 ELF binaries. Sometimes a function has a 3-byte descriptor symbol
825  * along with it in the symbol table and "." preceding its original pretty name for the correct
826  * function symbol. This checks to see if we have a corresponding 3-byte descriptor symbol existing
827  * and if it does we remove the preceding "." from the name of the symbol
828  */
829
830 void Symtab::checkPPC64DescriptorSymbols(Object *linkedFile)
831 {
832    // find the real functions -- those with the correct type in the symbol table
833    for(SymbolIter symIter(*linkedFile); symIter;symIter++)
834    {
835       Symbol *lookUp = symIter.currval();
836       const char *np = lookUp->getMangledName().c_str();
837       if(!np)
838          continue;
839
840       if(np[0] == '.' && (lookUp->getType() == Symbol::ST_FUNCTION))
841       {
842          std::vector<Symbol *>syms;
843          std::string newName = np+1;
844          if(linkedFile->get_symbols(newName, syms) && (syms[0]->getSize() == 24 || syms[0]->getSize() == 0))
845          {
846             //Remove the "." from the name
847             lookUp->mangledNames[0] = newName;
848
849             //Change the type of the descriptor symbol
850             syms[0]->type_ = Symbol::ST_NOTYPE;
851          }
852       }
853    }
854
855 }
856
857 #endif
858 #endif
859
860 //  setModuleLanguages is only called after modules have been defined.
861 //  it attempts to set each module's language, information which is needed
862 //  before names can be demangled.
863 void Symtab::setModuleLanguages(dyn_hash_map<std::string, supportedLanguages> *mod_langs)
864 {
865    if (!mod_langs->size())
866       return;  // cannot do anything here
867    //  this case will arise on non-stabs platforms until language parsing can be introduced at this level
868    std::vector<Module *> *modlist;
869    Module *currmod = NULL;
870    modlist = &_mods;
871    //int dump = 0;
872
873    for (unsigned int i = 0;  i < modlist->size(); ++i)
874    {
875       currmod = (*modlist)[i];
876       supportedLanguages currLang;
877       if (currmod->isShared()) {
878          continue;  // need to find some way to get shared object languages?
879       }
880
881       const std::string fn = currmod->fileName();
882       if (mod_langs->find(currmod->fileName()) != mod_langs->end())
883       {
884          currLang = (*mod_langs)[fn];
885       }
886       else if (fn.rfind(".s") != std::string::npos ||
887             fn.rfind(".asm") != std::string::npos)
888       {
889          currLang = lang_Assembly;
890       }
891       else if (fn.rfind(".c") != std::string::npos)
892       {
893          currLang = lang_C;
894       }
895       else if (fn.rfind(".cpp") != std::string::npos ||
896             fn.rfind(".cc") != std::string::npos ||
897             fn.rfind(".C") != std::string::npos)
898       {
899          currLang = lang_CPlusPlus;
900       }
901       else
902       {
903          continue;
904       }
905       currmod->setLanguage(currLang);
906    }
907 }
908
909 void Symtab::createDefaultModule() {
910     Module *mod = NULL;
911     if (getObjectType() == obj_SharedLib) {
912         mod = new Module(lang_Unknown, 
913                          imageOffset_,
914                          name(),
915                          this);
916     }
917     else {
918         mod = new Module(lang_Unknown, 
919                          imageOffset_,
920                          "DEFAULT_MODULE",
921                          this);
922     }
923     modsByFileName[mod->fileName()] = mod;
924     modsByFullName[mod->fullName()] = mod;
925     _mods.push_back(mod);
926 }
927
928
929
930 Module *Symtab::getOrCreateModule(const std::string &modName, 
931                                   const Offset modAddr)
932 {
933    std::string nameToUse;
934    if (modName.length() > 0)
935       nameToUse = modName;
936    else
937       nameToUse = "DEFAULT_MODULE";
938
939    Module *fm = NULL;
940    if (findModuleByName(fm, nameToUse)) 
941    {
942       return fm;
943    }
944
945     const char *str = nameToUse.c_str();
946     int len = nameToUse.length();
947     assert(len>0);
948
949     // TODO ignore directory definitions for now
950     if (str[len-1] == '/') 
951         return NULL;
952
953     return (newModule(nameToUse, modAddr, lang_Unknown));
954 }
955  
956 Module *Symtab::newModule(const std::string &name, const Offset addr, supportedLanguages lang)
957 {
958     Module *ret = NULL;
959     // modules can be defined several times in C++ due to templates and
960     //   in-line member functions.
961
962     if (findModuleByName(ret, name)) 
963     {
964         return(ret);
965     }
966
967     //parsing_printf("=== image, creating new pdmodule %s, addr 0x%x\n",
968     //                          name.c_str(), addr);
969     
970     std::string fileNm, fullNm;
971     fullNm = name;
972     fileNm = extract_pathname_tail(name);
973
974     // /* DEBUG */ fprintf( stderr, "%s[%d]: In %p: Creating new pdmodule '%s'/'%s'\n", FILE__, __LINE__, this, fileNm.c_str(), fullNm.c_str() );
975
976     ret = new Module(lang, addr, fullNm, this);
977     assert(ret);
978
979     if (modsByFileName.end() != modsByFileName.find(ret->fileName()))
980     {
981        fprintf(stderr, "%s[%d]:  WARN:  LEAK?  already have module with name %s\n", 
982              FILE__, __LINE__, ret->fileName().c_str());
983     }
984
985     if (modsByFullName.end() != modsByFullName.find(ret->fullName()))
986     {
987        fprintf(stderr, "%s[%d]:  WARN:  LEAK?  already have module with name %s\n", 
988              FILE__, __LINE__, ret->fullName().c_str());
989     }
990
991     modsByFileName[ret->fileName()] = ret;
992     modsByFullName[ret->fullName()] = ret;
993     _mods.push_back(ret);
994     
995     return (ret);
996 }
997
998 Symtab::Symtab(std::string filename,bool &err) :
999    is_a_out(false), 
1000    main_call_addr_(0),
1001    nativeCompiler(false), 
1002    isLineInfoValid_(false), 
1003    isTypeInfoValid_(false),
1004    obj_private(NULL)
1005 {
1006     init_debug_symtabAPI();
1007    // Initialize error parameter
1008    err = false;
1009    
1010    create_printf("%s[%d]: created symtab for %s\n", FILE__, __LINE__, filename.c_str());
1011
1012 #if defined (os_windows)
1013    extern void fixup_filename(std::string &);
1014    fixup_filename(filename);
1015 #endif
1016
1017    //  createMappedFile handles reference counting
1018    mf = MappedFile::createMappedFile(filename);
1019    if (!mf) {
1020       create_printf("%s[%d]: WARNING: creating symtab for %s, " 
1021                     "createMappedFile() failed\n", FILE__, __LINE__, 
1022                     filename.c_str());
1023       err = true;
1024       return;
1025    }
1026
1027    obj_private = new Object(mf, mfForDebugInfo, symtab_log_perror, true);
1028
1029    if (!extractInfo(obj_private))
1030    {
1031       create_printf("%s[%d]: WARNING: creating symtab for %s, extractInfo() " 
1032                     "failed\n", FILE__, __LINE__, filename.c_str());
1033       err = true;
1034    }
1035
1036    defaultNamespacePrefix = "";
1037 }
1038
1039 Symtab::Symtab(char *mem_image, size_t image_size, bool &err) :
1040    is_a_out(false), 
1041    main_call_addr_(0),
1042    nativeCompiler(false),
1043    isLineInfoValid_(false),
1044    isTypeInfoValid_(false),
1045    obj_private(NULL)
1046 {
1047    // Initialize error parameter
1048    err = false;
1049   
1050    create_printf("%s[%d]: created symtab for memory image at addr %u\n", 
1051                  FILE__, __LINE__, mem_image);
1052
1053    //  createMappedFile handles reference counting
1054    mf = MappedFile::createMappedFile(mem_image, image_size);
1055    if (!mf) {
1056       create_printf("%s[%d]: WARNING: creating symtab for memory image at " 
1057                     "addr %u, createMappedFile() failed\n", FILE__, __LINE__, 
1058                     mem_image);
1059       err = true;
1060       return;
1061    }
1062
1063    obj_private = new Object(mf, mfForDebugInfo, symtab_log_perror, true);
1064
1065    if (!extractInfo(obj_private))
1066    {
1067       create_printf("%s[%d]: WARNING: creating symtab for memory image at addr" 
1068                     "%u, extractInfo() failed\n", FILE__, __LINE__, mem_image);
1069       err = true;
1070    }
1071
1072    defaultNamespacePrefix = "";
1073 }
1074
1075 // Symtab constructor for archive members
1076 #if defined(os_aix) || defined(os_linux) || defined(os_solaris)
1077 Symtab::Symtab(std::string filename, std::string member_name, Offset offset, 
1078                bool &err, void *base) :
1079    member_name_(member_name), 
1080    member_offset_(offset),
1081    is_a_out(false),
1082    main_call_addr_(0), 
1083    nativeCompiler(false), 
1084    isLineInfoValid_(false),
1085    isTypeInfoValid_(false), 
1086    obj_private(NULL)
1087 {
1088    mf = MappedFile::createMappedFile(filename);
1089    assert(mf);
1090    obj_private = new Object(mf, mfForDebugInfo, member_name, offset, symtab_log_perror, base);
1091    err = extractInfo(obj_private);
1092    defaultNamespacePrefix = "";
1093 }
1094 #else
1095 Symtab::Symtab(std::string, std::string, Offset, bool &, void *)
1096 {
1097     assert(0);
1098 }
1099 #endif
1100
1101 #if defined(os_aix) || defined(os_linux) || defined(os_solaris)
1102 Symtab::Symtab(char *mem_image, size_t image_size, std::string member_name,
1103                        Offset offset, bool &err, void *base) :
1104    member_name_(member_name), 
1105    is_a_out(false), 
1106    main_call_addr_(0),
1107    nativeCompiler(false), 
1108    isLineInfoValid_(false), 
1109    isTypeInfoValid_(false)
1110 {
1111    mf = MappedFile::createMappedFile(mem_image, image_size);
1112    assert(mf);
1113    obj_private = new Object(mf, mf, member_name, offset, symtab_log_perror, base);
1114    err = extractInfo(obj_private);
1115    defaultNamespacePrefix = "";
1116 }
1117 #else 
1118 Symtab::Symtab(char *, size_t, std::string , Offset, bool &, void *)
1119 {
1120     assert(0);
1121 }
1122 #endif
1123
1124 bool sort_reg_by_addr(const Region* a, const Region* b)
1125 {
1126   if (a->getRegionAddr() == b->getRegionAddr())
1127     return a->getMemSize() < b->getMemSize();
1128   return a->getRegionAddr() < b->getRegionAddr();
1129 }
1130
1131 extern void print_symbols( std::vector< Symbol *>& allsymbols );
1132 extern void print_symbol_map( dyn_hash_map< std::string, std::vector< Symbol *> > *symbols);
1133
1134 bool Symtab::extractInfo(Object *linkedFile)
1135 {
1136 #if defined(TIMED_PARSE)
1137     struct timeval starttime;
1138     gettimeofday(&starttime, NULL);
1139 #endif
1140     mfForDebugInfo = linkedFile->getMappedFileForDebugInfo();
1141
1142     bool err = true;
1143     imageOffset_ = linkedFile->code_off();
1144     dataOffset_ = linkedFile->data_off();
1145
1146     imageLen_ = linkedFile->code_len();
1147     dataLen_ = linkedFile->data_len();
1148     
1149     if (0 == imageLen_ || 0 == linkedFile->code_ptr()) 
1150     {
1151         // for AIX, code_ptr()==NULL is normal behavior
1152 #if !defined(os_aix)
1153        if (0 == linkedFile->code_ptr()) {
1154           //fprintf(stderr, "[%s][%d]WARNING: null code pointer in Symtab for"
1155           //" file %s, possibly due to a missing .text section.\n",
1156           //__FILE__,__LINE__, file().c_str());
1157           linkedFile->code_ptr_ = (char *) linkedFile->code_off();
1158        }
1159        else 
1160 #endif
1161        {
1162           serr = Obj_Parsing;
1163           return false;
1164        }
1165    }
1166         
1167   //  if (!imageLen_ || !linkedFile->code_ptr()) {
1168   //      serr = Obj_Parsing; 
1169   //      return false; 
1170    // }
1171
1172     no_of_sections = linkedFile->no_of_sections();
1173     newSectionInsertPoint = no_of_sections;
1174     no_of_symbols = linkedFile->no_of_symbols();
1175     
1176     isStaticBinary_ = linkedFile->isStaticBinary();
1177
1178     hasRel_ = false;
1179     hasRela_ = false;
1180     hasReldyn_ = false;
1181     hasReladyn_ = false;
1182     hasRelplt_ = false;
1183     hasRelaplt_ = false;
1184     regions_ = linkedFile->getAllRegions();
1185
1186     for (unsigned index=0;index<regions_.size();index++)
1187     {
1188         if ( regions_[index]->isLoadable() ) 
1189         {
1190            if (     (regions_[index]->getRegionPermissions() == Region::RP_RX) 
1191                  || (regions_[index]->getRegionPermissions() == Region::RP_RWX)) 
1192            {
1193               codeRegions_.push_back(regions_[index]);
1194            }
1195            else 
1196            {
1197                 dataRegions_.push_back(regions_[index]);
1198             }
1199         }
1200
1201         regionsByEntryAddr[regions_[index]->getRegionAddr()] = regions_[index];
1202
1203         if (regions_[index]->getRegionType() == Region::RT_REL) 
1204         {
1205             hasRel_ = true;
1206         }
1207
1208         if (regions_[index]->getRegionType() == Region::RT_RELA) 
1209         {
1210             hasRela_ = true;
1211         }
1212
1213 #if defined(os_linux) || defined(os_solaris)
1214         hasReldyn_ = linkedFile->hasReldyn();
1215         hasReladyn_ = linkedFile->hasReladyn();
1216         hasRelplt_ = linkedFile->hasRelplt();
1217         hasRelaplt_ = linkedFile->hasRelaplt();
1218 #endif  
1219
1220     }
1221     // sort regions_ & codeRegions_ vectors
1222
1223     std::sort(codeRegions_.begin(), codeRegions_.end(), sort_reg_by_addr);
1224     std::sort(dataRegions_.begin(), dataRegions_.end(), sort_reg_by_addr);
1225     std::sort(regions_.begin(), regions_.end(), sort_reg_by_addr);
1226
1227     /* insert error check here. check if parsed */
1228     address_width_ = linkedFile->getAddressWidth();
1229     is_a_out = linkedFile->is_aout();
1230     code_ptr_ = linkedFile->code_ptr();
1231     data_ptr_ = linkedFile->data_ptr();
1232
1233     if (linkedFile->interpreter_name())
1234        interpreter_name_ = std::string(linkedFile->interpreter_name());
1235
1236     entry_address_ = linkedFile->getEntryAddress();
1237     base_address_ = linkedFile->getBaseAddress();
1238     load_address_ = linkedFile->getLoadAddress();
1239     toc_offset_ = linkedFile->getTOCoffset();
1240     object_type_  = linkedFile->objType();
1241     is_eel_ = linkedFile->isEEL();
1242     linkedFile->getSegments(segments_);
1243
1244 #if !defined(os_aix) && !defined(os_windows)
1245     linkedFile->getDependencies(deps_);
1246 #endif
1247
1248 #if defined (os_aix)
1249     //  These should go away
1250     linkedFile->get_stab_info(stabstr_, nstabs_, stabs_, stringpool_);
1251     linkedFile->get_line_info(nlines_, lines_, fdptr_);
1252 #endif
1253
1254 #if defined(os_solaris) || defined(os_aix) || defined(os_linux)
1255     // make sure we're using the right demangler
1256     
1257     nativeCompiler = parseCompilerType(linkedFile);
1258     //parsing_printf("isNativeCompiler: %d\n", nativeCompiler);
1259 #endif
1260     
1261     // define all of the functions
1262     //statusLine("winnowing functions");
1263
1264 #if defined(ppc64_linux)
1265     //checkPPC64DescriptorSymbols(linkedFile);
1266 #endif
1267
1268     // a vector to hold all created symbols until they are properly classified
1269     std::vector<Symbol *> raw_syms;
1270
1271 #ifdef BINEDIT_DEBUG
1272     printf("== from linkedFile...\n");
1273     print_symbol_map(linkedFile->getAllSymbols());
1274 #endif
1275
1276     if (!extractSymbolsFromFile(linkedFile, raw_syms)) 
1277     {
1278         err = false;
1279         serr = Syms_To_Functions;
1280         return false;
1281     }
1282
1283 #ifdef BINEDIT_DEBUG
1284     printf("== in Symtab now...\n");
1285     //print_symbols(raw_syms);
1286     std::vector<Symbol *> undefsyms;
1287     std::map<std::string, std::vector<Symbol *> >::iterator iter;
1288     std::vector<Symbol *>::iterator siter;
1289     for (iter = undefDynSyms.begin(); iter != undefDynSyms.end(); iter++)
1290         for (siter = iter->second.begin(); siter != iter->second.end(); siter++)
1291             undefsyms.push_back(*siter);
1292     //print_symbols(undefsyms);
1293     printf("%d total symbol(s)\n", raw_syms.size() + undefsyms.size());
1294 #endif
1295
1296     // don't sort the symbols--preserve the original ordering
1297     //sort(raw_syms.begin(),raw_syms.end(),symbol_compare);
1298
1299     createDefaultModule();
1300
1301     if (!fixSymModules(raw_syms)) 
1302     {
1303         err = false;
1304         serr = Syms_To_Functions;
1305         return false;
1306     }
1307         Object *obj = getObject();
1308         if (!obj)
1309         {
1310                 fprintf(stderr, "%s[%d]:  getObject failed here\n", FILE__, __LINE__);
1311                 return false;
1312         }
1313     obj->clearSymsToMods();
1314
1315     // wait until all modules are defined before applying languages to
1316     // them we want to do it this way so that module information comes
1317     // from the function symbols, first and foremost, to avoid any
1318     // internal module-function mismatching.
1319             
1320     // get Information on the language each modules is written in
1321     // (prior to making modules)
1322
1323     dyn_hash_map<std::string, supportedLanguages> mod_langs;
1324     linkedFile->getModuleLanguageInfo(&mod_langs);
1325     setModuleLanguages(&mod_langs);
1326         
1327     // Be sure that module languages are set before demangling, or
1328     // we won't get very far.
1329
1330     if (!demangleSymbols(raw_syms)) 
1331     {
1332         err = false;
1333         serr = Syms_To_Functions;
1334         return false;
1335     }
1336
1337     if (!createIndices(raw_syms)) 
1338     {
1339         err = false;
1340         serr = Syms_To_Functions;
1341         return false;
1342     }
1343
1344     if (!createAggregates()) 
1345     {
1346         err = false;
1347         serr = Syms_To_Functions;
1348         return false;
1349     }
1350         
1351     // Once languages are assigned, we can build demangled names (in
1352     // the wider sense of demangling which includes stripping _'s from
1353     // fortran names -- this is why language information must be
1354     // determined before this step).
1355     
1356     // Also identifies aliases (multiple names with equal addresses)
1357     
1358     //addSymtabVariables();
1359     linkedFile->getAllExceptions(excpBlocks);
1360
1361     vector<relocationEntry >fbt;
1362     linkedFile->get_func_binding_table(fbt);
1363     for(unsigned i=0; i<fbt.size();i++)
1364         relocation_table_.push_back(fbt[i]);
1365     return true;
1366 }
1367
1368 Symtab::Symtab(const Symtab& obj) :
1369    LookupInterface(),
1370    Serializable(),
1371    AnnotatableSparse()
1372 {
1373     create_printf("%s[%d]: Creating symtab 0x%p from symtab 0x%p\n", FILE__, __LINE__, this, &obj);
1374   
1375     member_name_ = obj.member_name_;
1376     imageOffset_ = obj.imageOffset_;
1377     imageLen_ = obj.imageLen_;
1378     dataOffset_ = obj.dataOffset_;
1379     dataLen_ = obj.dataLen_;
1380
1381    isLineInfoValid_ = obj.isLineInfoValid_;
1382    isTypeInfoValid_ = obj.isTypeInfoValid_;
1383
1384    is_a_out = obj.is_a_out;
1385    main_call_addr_ = obj.main_call_addr_; // address of call to main()
1386
1387    nativeCompiler = obj.nativeCompiler;
1388    defaultNamespacePrefix = obj.defaultNamespacePrefix;
1389
1390    //sections
1391    no_of_sections = obj.no_of_sections;
1392    unsigned i;
1393
1394    for (i=0;i<obj.regions_.size();i++)
1395       regions_.push_back(new Region(*(obj.regions_[i])));
1396
1397    for (i=0;i<regions_.size();i++)
1398       regionsByEntryAddr[regions_[i]->getRegionAddr()] = regions_[i];
1399
1400    // TODO FIXME: copying symbols/Functions/Variables
1401
1402    for (i=0;i<obj._mods.size();i++)
1403    {
1404       Module *m = new Module(*(obj._mods[i]));
1405       _mods.push_back(m);
1406       modsByFileName[m->fileName()] = m;
1407       modsByFullName[m->fullName()] = m;
1408       fprintf(stderr, "%s[%d]:  copy ctor creating new module %s\n", 
1409             FILE__, __LINE__, m->fileName().c_str());
1410    }
1411
1412    for (i=0; i<relocation_table_.size();i++) 
1413    {
1414       relocation_table_.push_back(relocationEntry(obj.relocation_table_[i]));
1415       //undefDynSyms[obj.relocation_table_[i].name()] = relocation_table_[i].getDynSym();
1416       undefDynSyms[obj.relocation_table_[i].name()].push_back(relocation_table_[i].getDynSym());
1417
1418    }
1419
1420    for (i=0;i<excpBlocks.size();i++)
1421    {
1422       excpBlocks.push_back(new ExceptionBlock(*(obj.excpBlocks[i])));
1423    }
1424
1425    deps_ = obj.deps_;
1426    setupTypes();
1427 }
1428
1429 // Address must be in code or data range since some code may end up
1430 // in the data segment
1431 bool Symtab::isValidOffset(const Offset where) const
1432 {
1433    return isCode(where) || isData(where);
1434 }
1435
1436 /* Performs a binary search on the codeRegions_ vector, which must
1437  * be kept in sorted order
1438  */
1439 bool Symtab::isCode(const Offset where)  const
1440 {
1441    if (!codeRegions_.size()) 
1442    {
1443       fprintf(stderr, "%s[%d] No code regions in %s \n",
1444             __FILE__, __LINE__, mf->filename().c_str());
1445       return false;
1446    }
1447
1448    // search for "where" in codeRegions_ (code regions must not overlap)
1449    int first = 0; 
1450    int last = codeRegions_.size() - 1;
1451
1452    while (last >= first) 
1453    {
1454       Region *curreg = codeRegions_[(first + last) / 2];
1455       if (where >= curreg->getRegionAddr()
1456             && where < (curreg->getRegionAddr()
1457                + curreg->getDiskSize())) 
1458       {
1459          if (curreg->getRegionType() == Region::RT_BSS)
1460             return false;
1461          return true;
1462       }
1463       else if (where < curreg->getRegionAddr()) 
1464       {
1465          last = ((first + last) / 2) - 1;
1466       }
1467       else if (where >= (curreg->getRegionAddr() + curreg->getMemSize()))
1468       {
1469          first = ((first + last) / 2) + 1;
1470       }
1471       else 
1472       {  // "where" is in the range: 
1473          // [memOffset + diskSize , memOffset + memSize)
1474          // meaning that it's in an uninitialized data region 
1475          return false;
1476       }
1477    }
1478
1479    return false;
1480 }
1481
1482 /* Performs a binary search on the dataRegions_ vector, which must
1483  * be kept in sorted order */
1484 bool Symtab::isData(const Offset where)  const
1485 {
1486    if (!dataRegions_.size()) 
1487    {
1488       fprintf(stderr, "%s[%d] No data regions in %s \n",
1489             __FILE__,__LINE__,mf->filename().c_str());
1490       return false;
1491    }
1492
1493    int first = 0; 
1494    int last = dataRegions_.size() - 1;
1495
1496    while (last >= first) 
1497    {
1498       Region *curreg = dataRegions_[(first + last) / 2];
1499
1500       if (     (where >= curreg->getRegionAddr())
1501             && (where < (curreg->getRegionAddr() + curreg->getRegionSize())))
1502       {
1503          return true;
1504       }
1505       else if (where < curreg->getRegionAddr()) 
1506       {
1507          last = ((first + last) / 2) - 1;
1508       }
1509       else 
1510       {
1511          first = ((first + last) / 2) + 1;
1512       }
1513    }
1514
1515    return false;
1516 }
1517
1518 SYMTAB_EXPORT bool Symtab::getFuncBindingTable(std::vector<relocationEntry> &fbt) const
1519 {
1520    fbt = relocation_table_;
1521    return true;
1522 }
1523
1524 SYMTAB_EXPORT bool Symtab::updateFuncBindingTable(Offset stub_addr, Offset plt_addr)
1525 {
1526     int stub_idx = -1, plt_idx = -1;
1527
1528     for (int i = 0; i < relocation_table_.size(); ++i) {
1529         if (stub_addr == relocation_table_[i].target_addr())
1530             stub_idx = i;
1531         if (plt_addr  == relocation_table_[i].target_addr())
1532             plt_idx = i;
1533         if (stub_addr >= 0 && plt_addr >= 0)
1534             break;
1535     }
1536     if (stub_idx >= 0 && plt_idx >= 0) {
1537         relocation_table_[stub_idx] = relocation_table_[plt_idx];
1538         relocation_table_[stub_idx].setTargetAddr(stub_addr);
1539         return true;
1540     }
1541     return false;
1542 }
1543
1544 SYMTAB_EXPORT std::vector<std::string> &Symtab::getDependencies(){
1545     return deps_;
1546 }
1547
1548
1549 Symtab::~Symtab()
1550 {
1551    // Doesn't do anything yet, moved here so we don't mess with symtab.h
1552    // Only called if we fail to create a process.
1553    // Or delete the a.out...
1554
1555 #if 1 
1556
1557    for (unsigned i = 0; i < regions_.size(); i++) 
1558    {
1559       delete regions_[i];
1560    }
1561
1562    regions_.clear();
1563    codeRegions_.clear();
1564    dataRegions_.clear();
1565    regionsByEntryAddr.clear();
1566
1567    std::vector<Region *> *user_regions = NULL;
1568    getAnnotation(user_regions, UserRegionsAnno);
1569
1570    if (user_regions)
1571    {
1572       for (unsigned i = 0; i < user_regions->size(); ++i) 
1573          delete (*user_regions)[i];
1574       user_regions->clear();
1575    }
1576
1577    // Symbols are copied from linkedFile, and NOT deleted
1578    everyDefinedSymbol.clear();
1579    undefDynSyms.clear();
1580
1581    // TODO make annotation
1582    userAddedSymbols.clear();
1583    symsByOffset.clear();
1584    symsByMangledName.clear();
1585    symsByPrettyName.clear();
1586    symsByTypedName.clear();
1587
1588    for (unsigned i = 0; i < everyFunction.size(); i++) 
1589    {
1590       delete everyFunction[i];
1591    }
1592
1593    everyFunction.clear();
1594    funcsByOffset.clear();
1595
1596    for (unsigned i = 0; i < everyVariable.size(); i++) 
1597    {
1598       delete everyVariable[i];
1599    }
1600
1601    everyVariable.clear();
1602    varsByOffset.clear();
1603
1604    for (unsigned i = 0; i < _mods.size(); i++) 
1605    {
1606       delete _mods[i];
1607    }
1608    _mods.clear();
1609    modsByFileName.clear();
1610    modsByFullName.clear();
1611
1612    for (unsigned i=0;i<excpBlocks.size();i++)
1613       delete excpBlocks[i];
1614
1615    create_printf("%s[%d]: Symtab::~Symtab removing %p from allSymtabs\n", 
1616          FILE__, __LINE__, this);
1617
1618    deps_.clear();
1619
1620    for (unsigned i = 0; i < allSymtabs.size(); i++) 
1621    {
1622       if (allSymtabs[i] == this)
1623          allSymtabs.erase(allSymtabs.begin()+i);
1624    }
1625
1626    //fprintf(stderr, "%s[%d]:  symtab DTOR, mf = %p: %s\n", FILE__, __LINE__, mf, mf->filename().c_str());
1627    if (mf) MappedFile::closeMappedFile(mf);
1628    //if (mfForDebugInfo) MappedFile::closeMappedFile(mfForDebugInfo);
1629 #endif
1630 }       
1631
1632 bool Symtab::exportXML(string file)
1633 {
1634 #if defined (cap_serialization)
1635    try 
1636    {
1637            SerContext<Symtab> *scs = new SerContext<Symtab>(this, file);
1638            serialize(file, scs, ser_xml);
1639 #if 0
1640            SerContext<Symtab> *scs = new SerContext<Symtab>(this);
1641            SerializerXML *ser = new SerializerXML(scs, "XMLTranslator", file, sd_serialize, true);
1642            serialize(ser, "Symtab");
1643 #endif
1644 #if 0
1645       SerializerXML sb("XMLTranslator", file, sd_serialize, true);
1646       serialize(&sb, "Symtab");
1647 #endif
1648    } 
1649    catch (const SerializerError &err) 
1650    {
1651       fprintf(stderr, "%s[%d]: error serializing xml: %s\n", FILE__, __LINE__, err.what());
1652       return false;
1653    }
1654
1655    return false;
1656 #else
1657    fprintf(stderr, "%s[%d]:  WARNING:  cannot produce %s, serialization not available\n", FILE__, __LINE__, file.c_str());
1658    return false;
1659 #endif
1660 }
1661
1662 #if defined (cap_serialization)
1663 bool Symtab::exportBin(string file)
1664 {
1665    try
1666    {
1667            SerContext<Symtab> *scs = new SerContext<Symtab>(this, file);
1668            serialize(file, scs, ser_bin);
1669            //fprintf(stderr, "%s[%d]:  did serialize\n", FILE__, __LINE__);
1670            return true;
1671    }
1672
1673    catch (const SerializerError &err)
1674    {
1675       if (err.code() == SerializerError::ser_err_disabled) 
1676       {
1677          fprintf(stderr, "%s[%d]:  WARN:  serialization is disabled for file %s\n",
1678                FILE__, __LINE__, file.c_str());
1679          return false;
1680       }
1681
1682       fprintf(stderr, "%s[%d]: %s\n\tfrom: %s[%d]\n", FILE__, __LINE__,
1683             err.what(), err.file().c_str(), err.line());
1684    }
1685
1686    fprintf(stderr, "%s[%d]:  error doing binary serialization\n", __FILE__, __LINE__);
1687    return false;
1688 }
1689 #else
1690 bool Symtab::exportBin(string) 
1691 {
1692    fprintf(stderr, "%s[%d]:  WARNING:  serialization not available\n", FILE__, __LINE__);
1693    return false;
1694 }
1695 #endif
1696
1697 Symtab *Symtab::importBin(std::string file)
1698 {
1699 #if defined (cap_serialization)
1700    MappedFile *mf= MappedFile::createMappedFile(file);
1701    if (!mf) 
1702    {
1703       fprintf(stderr, "%s[%d]:  failed to map file %s\n", FILE__, __LINE__, file.c_str());
1704       return NULL;
1705    }
1706
1707    Symtab *st = new Symtab(mf);
1708
1709    try
1710    {
1711            SerContext<Symtab> *scs = new SerContext<Symtab>(st, file);
1712            if (!st->deserialize(file, scs))
1713            {
1714                    delete st;
1715                    return NULL;
1716            }
1717
1718            return st;
1719    }
1720
1721    catch (const SerializerError &err)
1722    {
1723       if (err.code() == SerializerError::ser_err_disabled) 
1724       {
1725          serialize_printf("%s[%d]:  WARN:  serialization is disabled for file %s\n",
1726                FILE__, __LINE__, file.c_str());
1727          fprintf(stderr, "%s[%d]:  WARN:  serialization is disabled for file %s\n",
1728                FILE__, __LINE__, file.c_str());
1729          return NULL;
1730       }
1731
1732       serialize_printf("%s[%d]: %s\n\tfrom: %s[%d]\n", FILE__, __LINE__,
1733             err.what(), err.file().c_str(), err.line());
1734       fprintf(stderr, "%s[%d]: %s\n\tfrom: %s[%d]\n", FILE__, __LINE__,
1735             err.what(), err.file().c_str(), err.line());
1736    }
1737
1738
1739    serialize_printf("%s[%d]:  error doing binary deserialization\n", __FILE__, __LINE__);
1740    delete st;
1741    return NULL;
1742 #else
1743    serialize_printf("%s[%d]:  WARNING:  cannot produce %s, serialization not available\n", FILE__, __LINE__, file.c_str());
1744    return NULL;
1745 #endif
1746 }
1747
1748
1749 bool Symtab::openFile(Symtab *&obj, char *mem_image, size_t size)
1750 {
1751    bool err = false;
1752 #if defined(TIMED_PARSE)
1753    struct timeval starttime;
1754    gettimeofday(&starttime, NULL);
1755 #endif
1756
1757    obj = new Symtab(mem_image, size, err);
1758
1759 #if defined(TIMED_PARSE)
1760     struct timeval endtime;
1761     gettimeofday(&endtime, NULL);
1762     unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
1763     unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
1764     unsigned long difftime = lendtime - lstarttime;
1765     double dursecs = difftime/(1000 );
1766     cout << __FILE__ << ":" << __LINE__ <<": openFile "<< filename<< " took "<<dursecs <<" msecs" << endl;
1767 #endif
1768     if(!err)
1769     {
1770        allSymtabs.push_back(obj);
1771        obj->setupTypes();       
1772     }
1773     else
1774     {
1775         delete obj;
1776        obj = NULL;
1777     }
1778     // returns true on success (not an error)
1779     return !err;
1780 }
1781
1782 bool Symtab::closeSymtab(Symtab *st)
1783 {
1784         bool found = false;
1785         if (!st) return false;
1786
1787         std::vector<Symtab *>::reverse_iterator iter;
1788         for (iter = allSymtabs.rbegin(); iter != allSymtabs.rend() ; iter++)
1789         {
1790                 if (*iter == st)
1791                 {
1792                         allSymtabs.erase(iter.base() -1);
1793                         found = true;
1794                 }
1795         }
1796         delete(st);
1797         return found;
1798 }
1799
1800 Symtab *Symtab::findOpenSymtab(std::string filename)
1801 {
1802    unsigned numSymtabs = allSymtabs.size();
1803         for (unsigned u=0; u<numSymtabs; u++) 
1804         {
1805                 assert(allSymtabs[u]);
1806                 if (filename == allSymtabs[u]->file() && 
1807           allSymtabs[u]->mf->canBeShared()) 
1808                 {
1809                         // return it
1810                         return allSymtabs[u];
1811                 }
1812         }   
1813         return NULL;
1814 }
1815
1816 bool Symtab::openFile(Symtab *&obj, std::string filename)
1817 {
1818    bool err = false;
1819 #if defined(TIMED_PARSE)
1820    struct timeval starttime;
1821    gettimeofday(&starttime, NULL);
1822 #endif
1823
1824    // AIX: it's possible that we're reparsing a file with better information
1825    // about it. If so, yank the old one out of the allSymtabs std::vector -- replace
1826    // it, basically.
1827    if ( filename.find("/proc") == std::string::npos)
1828    {
1829            obj = findOpenSymtab(filename);
1830            if (obj)
1831            {
1832                    //fprintf(stderr, "%s[%d]:  have existing symtab obj for %s\n", FILE__, __LINE__, filename.c_str());
1833                    return true;
1834    }
1835    }
1836
1837
1838 #if defined (cap_serialization)
1839    obj = importBin(filename);
1840
1841    if (NULL == obj) 
1842    {
1843            if (deserializeEnforced<Symtab>(filename))
1844           {
1845                           serialize_printf("%s[%d]: aborting new symtab, expected deserialize failed\n",
1846                                           FILE__, __LINE__);
1847                           fprintf(stderr, "%s[%d]: aborting new symtab, expected deserialize failed\n",
1848                                           FILE__, __LINE__);
1849                           return false;
1850           }
1851            //fprintf(stderr, "%s[%d]:  deserialize failed, but not enforced for %s\n", FILE__, __LINE__, filename.c_str());
1852    }
1853    else 
1854    {
1855           //fprintf(stderr, "%s[%d]:  deserialize success\n", FILE__, __LINE__);
1856       return true;
1857    }
1858 #endif
1859
1860    obj = new Symtab(filename, err);
1861 #if defined(TIMED_PARSE)
1862    struct timeval endtime;
1863    gettimeofday(&endtime, NULL);
1864    unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
1865    unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
1866    unsigned long difftime = lendtime - lstarttime;
1867    double dursecs = difftime/(1000 );
1868    cout << __FILE__ << ":" << __LINE__ <<": openFile "<< filename<< " took "<<dursecs <<" msecs" << endl;
1869 #endif
1870
1871    if (!err)
1872    {
1873       if (filename.find("/proc") == std::string::npos)
1874          allSymtabs.push_back(obj);
1875
1876       obj->setupTypes();        
1877
1878 #if defined (cap_serialization)
1879       serialize_printf("%s[%d]:  doing bin-serialize for %s\n", 
1880             FILE__, __LINE__, filename.c_str());
1881
1882       if (!obj->exportBin(filename))
1883       {
1884          serialize_printf("%s[%d]:  failed to export symtab\n", FILE__, __LINE__);
1885       }
1886       else
1887          serialize_printf("%s[%d]:  did bin-serialize for %s\n", 
1888                FILE__, __LINE__, filename.c_str());
1889 #endif
1890
1891     }
1892     else
1893     {
1894        create_printf("%s[%d]: WARNING: failed to open symtab for %s\n", 
1895              FILE__, __LINE__, filename.c_str());
1896        delete obj;
1897        obj = NULL;
1898     }
1899
1900    // returns true on success (not an error)
1901    return !err;
1902 }
1903
1904 bool Symtab::addRegion(Offset vaddr, void *data, unsigned int dataSize, std::string name, Region::RegionType rType_, bool loadable)
1905 {
1906    Region *sec;
1907    unsigned i;
1908    if (loadable)
1909    {
1910       sec = new Region(newSectionInsertPoint, name, vaddr, dataSize, vaddr, 
1911             dataSize, (char *)data, Region::RP_R, rType_, true);
1912
1913       regions_.insert(regions_.begin()+newSectionInsertPoint, sec);
1914
1915       for (i = newSectionInsertPoint+1; i < regions_.size(); i++)
1916       {
1917          regions_[i]->setRegionNumber(regions_[i]->getRegionNumber() + 1);
1918       }
1919
1920       if (    (sec->getRegionType() == Region::RT_TEXT) 
1921             || (sec->getRegionType() == Region::RT_TEXTDATA))
1922       {
1923          codeRegions_.push_back(sec);
1924          std::sort(codeRegions_.begin(), codeRegions_.end(), sort_reg_by_addr);
1925       }
1926
1927       if (    (sec->getRegionType() == Region::RT_DATA) 
1928             || (sec->getRegionType() == Region::RT_TEXTDATA))
1929       {
1930          dataRegions_.push_back(sec);
1931          std::sort(dataRegions_.begin(), dataRegions_.end(), sort_reg_by_addr);
1932       }
1933    }
1934    else
1935    {
1936       sec = new Region(regions_.size()+1, name, vaddr, dataSize, 0, 0, 
1937             (char *)data, Region::RP_R, rType_);
1938       regions_.push_back(sec);
1939    }
1940
1941    addUserRegion(sec);
1942    std::sort(regions_.begin(), regions_.end(), sort_reg_by_addr);
1943    return true;
1944 }
1945
1946 bool Symtab::addUserRegion(Region *reg)
1947 {
1948    std::vector<Region *> *user_regions = NULL;
1949
1950    if (!getAnnotation(user_regions, UserRegionsAnno))
1951    {
1952       user_regions = new std::vector<Region *>();
1953       if (!addAnnotation(user_regions, UserRegionsAnno))
1954       {
1955          fprintf(stderr, "%s[%d]:  failed to addAnnotation here\n", FILE__, __LINE__);
1956          return false;
1957       }
1958    }
1959
1960    if (!user_regions)
1961    {
1962       fprintf(stderr, "%s[%d]:  failed to addAnnotation here\n", FILE__, __LINE__);
1963       return false;
1964    }
1965
1966    user_regions->push_back(reg);
1967
1968    return true;
1969 }
1970
1971 bool Symtab::addUserType(Type *t)
1972 {
1973    std::vector<Type *> *user_types = NULL;
1974
1975    //  need to change this to something based on AnnotationContainer
1976    //  for it to work with serialization
1977    if (!getAnnotation(user_types, UserTypesAnno))
1978    {
1979       user_types = new std::vector<Type *>();
1980       if (!addAnnotation(user_types, UserTypesAnno))
1981       {
1982          fprintf(stderr, "%s[%d]:  failed to addAnnotation here\n", FILE__, __LINE__);
1983          return false;
1984       }
1985    }
1986    if (!user_types)
1987    {
1988       fprintf(stderr, "%s[%d]:  failed to addAnnotation here\n", FILE__, __LINE__);
1989       return false;
1990    }
1991
1992    user_types->push_back(t);
1993
1994    return true;
1995 }
1996
1997 bool Symtab::addRegion(Region *sec)
1998 {
1999    regions_.push_back(sec);
2000    std::sort(regions_.begin(), regions_.end(), sort_reg_by_addr);
2001    addUserRegion(sec);
2002    return true;
2003 }
2004
2005 void Symtab::parseLineInformation()
2006 {
2007    dyn_hash_map<std::string, LineInformation> *lineInfo = new dyn_hash_map <std::string, LineInformation>;
2008
2009
2010    Object *linkedFile = getObject();
2011         if (!linkedFile)
2012         {
2013                 fprintf(stderr, "%s[%d]:  getObject failed here\n", FILE__, __LINE__);
2014                 return;
2015         }
2016    linkedFile->parseFileLineInfo(this, *lineInfo);
2017
2018    isLineInfoValid_ = true;     
2019    dyn_hash_map <std::string, LineInformation>::iterator iter;
2020
2021    for (iter = lineInfo->begin(); iter!=lineInfo->end(); iter++)
2022    {
2023       Module *mod = NULL;
2024       bool result = findModuleByName(mod, iter->first);
2025       if (!result) {
2026          mod = getDefaultModule();
2027       }
2028
2029          LineInformation *lineInformation = mod->getLineInformation();
2030          if (!lineInformation) 
2031          {
2032             mod->setLineInfo(&(iter->second));
2033          } 
2034          else 
2035          {
2036             lineInformation->addLineInfo(&(iter->second));
2037             mod->setLineInfo(lineInformation);
2038          }
2039       }
2040 }
2041
2042 SYMTAB_EXPORT bool Symtab::getAddressRanges(std::vector<pair<Offset, Offset> >&ranges,
2043       std::string lineSource, unsigned int lineNo)
2044 {
2045    unsigned int originalSize = ranges.size();
2046
2047    /* Iteratate over the modules, looking for ranges in each. */
2048
2049    for ( unsigned int i = 0; i < _mods.size(); i++ ) 
2050    {
2051       LineInformation *lineInformation = _mods[i]->getLineInformation();
2052
2053       if (lineInformation)
2054          lineInformation->getAddressRanges( lineSource.c_str(), lineNo, ranges );
2055
2056    } /* end iteration over modules */
2057
2058    if ( ranges.size() != originalSize )
2059       return true;
2060
2061    fprintf(stderr, "%s[%d]:  failing to getAdressRanges for %s[%d]\n", FILE__, __LINE__, lineSource.c_str(), lineNo);
2062    return false;
2063 }
2064
2065 SYMTAB_EXPORT bool Symtab::getSourceLines(std::vector<Statement *> &lines, Offset addressInRange)
2066 {
2067    unsigned int originalSize = lines.size();
2068
2069    /* Iteratate over the modules, looking for ranges in each. */
2070    for ( unsigned int i = 0; i < _mods.size(); i++ ) 
2071    {
2072       LineInformation *lineInformation = _mods[i]->getLineInformation();
2073
2074       if (lineInformation)
2075          lineInformation->getSourceLines( addressInRange, lines );
2076
2077    } /* end iteration over modules */
2078
2079    if ( lines.size() != originalSize )
2080       return true;
2081
2082    return false;
2083
2084 }
2085
2086 SYMTAB_EXPORT bool Symtab::addLine(std::string lineSource, unsigned int lineNo,
2087       unsigned int lineOffset, Offset lowInclAddr,
2088       Offset highExclAddr)
2089 {
2090    Module *mod;
2091
2092    if (!findModuleByName(mod, lineSource))
2093    {
2094       std::string fileNm = extract_pathname_tail(lineSource);
2095
2096       if (!findModuleByName(mod, fileNm))
2097       {
2098          if (!findModuleByName(mod, mf->pathname()))
2099             return false;
2100       }    
2101    }
2102
2103    LineInformation *lineInfo = mod->getLineInformation();
2104
2105    if (!lineInfo)
2106       return false;
2107
2108    return (lineInfo->addLine(lineSource.c_str(), lineNo, lineOffset, 
2109             lowInclAddr, highExclAddr));
2110 }
2111
2112 SYMTAB_EXPORT bool Symtab::addAddressRange( Offset lowInclusiveAddr, Offset highExclusiveAddr,
2113       std::string lineSource, unsigned int lineNo,
2114       unsigned int lineOffset)
2115 {
2116    Module *mod;
2117
2118    if (!findModuleByName(mod, lineSource))
2119    {
2120       std::string fileNm = extract_pathname_tail(lineSource);
2121
2122       if (!findModuleByName(mod, fileNm))
2123          return false;
2124    }
2125
2126    LineInformation *lineInfo = mod->getLineInformation();
2127
2128    if (!lineInfo)
2129       return false;
2130
2131    return (lineInfo->addAddressRange(lowInclusiveAddr, highExclusiveAddr, 
2132             lineSource.c_str(), lineNo, lineOffset));
2133 }
2134
2135
2136 void Symtab::parseTypes()
2137 {
2138    Object *linkedFile = getObject();
2139         if (!linkedFile)
2140         {
2141                 fprintf(stderr, "%s[%d]:  getObject failed here\n", FILE__, __LINE__);
2142                 return;
2143         }
2144    linkedFile->parseTypeInfo(this);
2145    isTypeInfoValid_ = true;
2146
2147    for (unsigned int i = 0; i < _mods.size(); ++i)
2148    {
2149            typeCollection *tc = typeCollection::getModTypeCollection(_mods[i]);
2150
2151            if (!_mods[i]->addAnnotation(tc, ModuleTypeInfoAnno))
2152            {
2153                    fprintf(stderr, "%s[%d]:  failed to addAnnotation here\n", FILE__, __LINE__);
2154            }
2155    }
2156
2157    //  optionally we might want to clear the static data struct in typeCollection
2158    //  here....  the parsing is over, and we have added all typeCollections as
2159    //  annotations proper.
2160
2161    typeCollection::fileToTypesMap.clear();
2162
2163 }
2164
2165 bool Symtab::addType(Type *type)
2166 {
2167   bool result = addUserType(type);
2168   if (!result)
2169     return false;
2170
2171   return true;
2172 }
2173
2174 SYMTAB_EXPORT vector<Type *> *Symtab::getAllstdTypes()
2175 {
2176    setupStdTypes();
2177    return stdTypes->getAllTypes();      
2178 }
2179
2180 SYMTAB_EXPORT vector<Type *> *Symtab::getAllbuiltInTypes()
2181 {
2182    setupStdTypes();
2183    return builtInTypes->getAllBuiltInTypes();
2184 }
2185
2186 SYMTAB_EXPORT bool Symtab::findType(Type *&type, std::string name)
2187 {
2188    parseTypesNow();
2189
2190    if (!_mods.size())
2191       return false;
2192
2193    for (unsigned int i = 0; i < _mods.size(); ++i)
2194    {
2195            typeCollection *tc = _mods[i]->getModuleTypes();
2196            if (!tc) continue;
2197            type = tc->findType(name);
2198            if (type) return true;
2199    }
2200
2201    if (type == NULL)
2202       return false;
2203
2204    return true; 
2205 }
2206
2207 SYMTAB_EXPORT Type *Symtab::findType(unsigned type_id)
2208 {
2209         Type *t = NULL;
2210    parseTypesNow();
2211
2212    if (!_mods.size())
2213    {
2214            //fprintf(stderr, "%s[%d]:  findType failing due to lack of modules\n", FILE__, __LINE__);
2215       return NULL;
2216    }
2217
2218    for (unsigned int i = 0; i < _mods.size(); ++i)
2219    {
2220            typeCollection *tc = _mods[i]->getModuleTypes();
2221            if (!tc) continue;
2222            t = tc->findType(type_id);
2223            if (t)  break;
2224    }
2225
2226    if (t == NULL)
2227    {
2228            if (builtInTypes)
2229            {
2230                    t = builtInTypes->findBuiltInType(type_id);
2231                    if (t) return t;
2232            }
2233            else
2234            {
2235                    //fprintf(stderr, "%s[%d]:  no built in types!\n", FILE__, __LINE__);
2236            }
2237
2238            if (stdTypes)
2239            {
2240                    t = stdTypes->findType(type_id);
2241                    if (t) return t;
2242            }
2243            else
2244            {
2245                    //fprintf(stderr, "%s[%d]:  no std types!\n", FILE__, __LINE__);
2246            }
2247
2248            return NULL;
2249    }
2250
2251    return t;    
2252 }
2253
2254 SYMTAB_EXPORT bool Symtab::findVariableType(Type *&type, std::string name)
2255 {
2256    parseTypesNow();
2257
2258    if (!_mods.size())
2259       return false;
2260
2261
2262    for (unsigned int i = 0; i < _mods.size(); ++i)
2263    {
2264            typeCollection *tc = _mods[i]->getModuleTypes();
2265            if (!tc) continue;
2266            type = tc->findVariableType(name);
2267            if (type) break;
2268    }
2269
2270    if (type == NULL)
2271       return false;
2272
2273    return true; 
2274 }
2275
2276 SYMTAB_EXPORT bool Symtab::findLocalVariable(std::vector<localVar *>&vars, std::string name)
2277 {
2278    parseTypesNow();
2279    unsigned origSize = vars.size();
2280
2281    for (unsigned i = 0; i < everyFunction.size(); i++)
2282    {
2283       everyFunction[i]->findLocalVariable(vars, name);
2284    }
2285
2286    if (vars.size()>origSize)
2287       return true;
2288
2289    return false;        
2290 }
2291
2292 SYMTAB_EXPORT bool Symtab::hasRel() const
2293 {
2294    return hasRel_;
2295 }
2296
2297 SYMTAB_EXPORT bool Symtab::hasRela() const
2298 {
2299    return hasRela_;
2300 }
2301
2302 SYMTAB_EXPORT bool Symtab::hasReldyn() const
2303 {
2304    return hasReldyn_;
2305 }
2306
2307 SYMTAB_EXPORT bool Symtab::hasReladyn() const
2308 {
2309    return hasReladyn_;
2310 }
2311
2312 SYMTAB_EXPORT bool Symtab::hasRelplt() const
2313 {
2314    return hasRelplt_;
2315 }
2316
2317 SYMTAB_EXPORT bool Symtab::hasRelaplt() const
2318 {
2319    return hasRelaplt_;
2320 }
2321
2322 SYMTAB_EXPORT bool Symtab::isStaticBinary() const
2323 {
2324    return isStaticBinary_;
2325 }
2326
2327 bool Symtab::setDefaultNamespacePrefix(string &str)
2328 {
2329    defaultNamespacePrefix = str;
2330    return true;
2331 }
2332
2333 SYMTAB_EXPORT bool Symtab::emitSymbols(Object *linkedFile,std::string filename, unsigned flag)
2334 {
2335     // Start with all the defined symbols
2336     std::vector<Symbol *> allSyms;
2337     for (unsigned i = 0; i < everyDefinedSymbol.size(); i++) {
2338         allSyms.push_back(everyDefinedSymbol[i]);
2339     }
2340
2341     // Add the undefined dynamic symbols
2342     map<string, std::vector<Symbol *> >::iterator iter;
2343     std::vector<Symbol *>::iterator siter;
2344
2345     for (iter = undefDynSyms.begin(); iter != undefDynSyms.end(); iter++)
2346         for (siter=iter->second.begin(); siter != iter->second.end(); siter++)
2347             allSyms.push_back(*siter);
2348
2349     // Write the new file
2350     return linkedFile->emitDriver(this, filename, allSyms, flag);
2351 }
2352
2353 SYMTAB_EXPORT bool Symtab::emit(std::string filename, unsigned flag)
2354 {
2355         Object *obj = getObject();
2356         if (!obj)
2357         {
2358                 fprintf(stderr, "%s[%d]:  getObject failed here\n", FILE__, __LINE__);
2359                 return false;
2360         }
2361    obj->mf->setSharing(false);
2362    return emitSymbols(obj, filename, flag);
2363 }
2364
2365 SYMTAB_EXPORT void Symtab::addDynLibSubstitution(std::string oldName, std::string newName)
2366 {
2367    dynLibSubs[oldName] = newName;
2368 }
2369
2370 SYMTAB_EXPORT std::string Symtab::getDynLibSubstitution(std::string name)
2371 {
2372 #ifdef BINEDIT_DEBUG
2373    map<std::string, std::string>::iterator iter = dynLibSubs.begin();
2374
2375    printf ("substitutions for %s:\n", mf->filename().c_str());
2376
2377    while (iter != dynLibSubs.end()) 
2378    {
2379       printf("  \"%s\" => \"%s\"\n", iter->first.c_str(), iter->second.c_str());
2380       iter++;
2381    }
2382 #endif
2383
2384    map<std::string, std::string>::iterator loc = dynLibSubs.find(name);
2385
2386    if (loc == dynLibSubs.end())
2387       return name;
2388    else
2389       return loc->second;
2390 }
2391
2392 SYMTAB_EXPORT bool Symtab::getSegments(vector<Segment> &segs) const
2393 {
2394    segs = segments_;
2395
2396    if (!segments_.size()) 
2397       return false;
2398
2399    return true;
2400 }
2401
2402 SYMTAB_EXPORT bool Symtab::getMappedRegions(std::vector<Region *> &mappedRegs) const
2403 {
2404    unsigned origSize = mappedRegs.size();
2405
2406    for (unsigned i = 0; i < regions_.size(); i++)
2407    {
2408       if (regions_[i]->isLoadable())
2409          mappedRegs.push_back(regions_[i]);
2410    }
2411
2412    if (mappedRegs.size() > origSize)
2413       return true;
2414
2415    return false;
2416 }
2417
2418 SYMTAB_EXPORT bool Symtab::updateRegion(const char* name, void *buffer, unsigned size)
2419 {
2420    Region *sec;
2421
2422    if (!findRegion(sec, name))
2423       return false;
2424
2425    sec->setPtrToRawData(buffer, size);
2426
2427    return true;
2428 }
2429
2430 SYMTAB_EXPORT bool Symtab::updateCode(void *buffer, unsigned size)
2431 {
2432   return updateRegion(".text", buffer, size);
2433 }
2434
2435 SYMTAB_EXPORT bool Symtab::updateData(void *buffer, unsigned size)
2436 {
2437   return updateRegion(".data", buffer, size);
2438 }
2439
2440 SYMTAB_EXPORT Offset Symtab::getFreeOffset(unsigned size) 
2441 {
2442    // Look through sections until we find a gap with
2443    // sufficient space.
2444    Offset highWaterMark = 0;
2445    Offset secoffset = 0;
2446    Offset prevSecoffset = 0;
2447
2448    Object *linkedFile = getObject();
2449         if (!linkedFile)
2450         {
2451                 fprintf(stderr, "%s[%d]:  getObject failed here\n", FILE__, __LINE__);
2452                 return 0;
2453         }
2454
2455    for (unsigned i = 0; i < regions_.size(); i++) 
2456    {
2457       //Offset end = regions_[i]->getRegionAddr() + regions_[i]->getDiskSize();
2458       Offset end = regions_[i]->getRegionAddr() + regions_[i]->getRegionSize();
2459       if (regions_[i]->getRegionAddr() == 0) 
2460          continue;
2461
2462       prevSecoffset = secoffset;
2463
2464       unsigned region_offset = (unsigned)((char *)(regions_[i]->getPtrToRawData())
2465                                           - linkedFile->mem_image());
2466
2467       if (region_offset < (unsigned)prevSecoffset)
2468       {
2469          //secoffset += regions_[i]->getDiskSize();
2470          secoffset += regions_[i]->getRegionSize();
2471       }
2472       else 
2473       {
2474          secoffset = (char *)(regions_[i]->getPtrToRawData()) - linkedFile->mem_image();
2475          //secoffset += regions_[i]->getDiskSize();
2476          secoffset += regions_[i]->getRegionSize();
2477       }
2478
2479       /*fprintf(stderr, "%d: secAddr 0x%lx, size %d, end 0x%lx, looking for %d\n",
2480         i, regions_[i]->getSecAddr(), regions_[i]->getSecSize(),
2481         end,size);*/
2482
2483       if (end > highWaterMark) 
2484       {
2485          //fprintf(stderr, "Increasing highWaterMark...\n");
2486          newSectionInsertPoint = i+1;
2487          highWaterMark = end;
2488       }
2489
2490       if (     (i < (regions_.size()-2)) 
2491                && ((end + size) < regions_[i+1]->getRegionAddr())) 
2492       {
2493          /*      fprintf(stderr, "Found a hole between sections %d and %d\n",
2494                  i, i+1);
2495                  fprintf(stderr, "End at 0x%lx, next one at 0x%lx\n",
2496                  end, regions_[i+1]->getSecAddr());
2497          */   
2498          newSectionInsertPoint = i+1;
2499          highWaterMark = end;
2500          break;
2501       }
2502    }
2503
2504    //   return highWaterMark;
2505 #if defined (os_windows)
2506         Object *obj = getObject();
2507         if (!obj)
2508         {
2509                 fprintf(stderr, "%s[%d]:  getObject failed here\n", FILE__, __LINE__);
2510                 return 0;
2511         }
2512         unsigned pgSize = obj->getSecAlign();
2513         //printf("pgSize:0x%x\n", pgSize);
2514         Offset newaddr = highWaterMark  - (highWaterMark & (pgSize-1));
2515         while(newaddr < highWaterMark)
2516       newaddr += pgSize;
2517         //printf("getfreeoffset:%lu\n", newaddr);
2518         return newaddr;
2519
2520 #else
2521         unsigned pgSize = P_getpagesize();
2522         Offset newaddr = highWaterMark  - (highWaterMark & (pgSize-1));
2523         if(newaddr < highWaterMark)
2524                 newaddr += pgSize;
2525
2526    return newaddr;
2527 #endif  
2528 }
2529
2530 SYMTAB_EXPORT ObjectType Symtab::getObjectType() const 
2531 {
2532    return object_type_;
2533 }
2534
2535 SYMTAB_EXPORT char *Symtab::mem_image() const 
2536 {
2537    return (char *)mf->base_addr();
2538 }
2539
2540 SYMTAB_EXPORT std::string Symtab::file() const 
2541 {
2542    assert(mf);
2543    return mf->pathname();
2544 }
2545
2546 SYMTAB_EXPORT std::string Symtab::name() const 
2547 {
2548    return mf->filename();
2549 }
2550
2551 SYMTAB_EXPORT unsigned Symtab::getNumberofRegions() const 
2552 {
2553    return no_of_sections; 
2554 }
2555
2556 SYMTAB_EXPORT unsigned Symtab::getNumberofSymbols() const 
2557 {
2558    return no_of_symbols; 
2559 }
2560
2561 bool Symtab::setup_module_up_ptrs(SerializerBase *, Symtab *st)
2562 {
2563    std::vector<Module *> &mods = st->_mods;
2564
2565    for (unsigned int i = 0; i < mods.size(); ++i) 
2566    {
2567       Module *m = mods[i];
2568       m->exec_ = st;
2569    }
2570
2571    return true;
2572 }
2573
2574 bool Symtab::fixup_relocation_symbols(SerializerBase *, Symtab *st)
2575 {
2576    std::vector<Module *> &mods = st->_mods;
2577
2578    for (unsigned int i = 0; i < mods.size(); ++i) 
2579    {
2580       Module *m = mods[i];
2581       m->exec_ = st;
2582    }
2583
2584    return true;
2585 }
2586
2587 void Symtab::rebuild_symbol_hashes(SerializerBase *sb)
2588 {
2589         if (!is_input(sb))
2590                 return;
2591
2592         for (unsigned long i = 0; i < everyDefinedSymbol.size(); ++i)
2593         {
2594                 Symbol *s = everyDefinedSymbol[i];
2595                 assert(s);
2596                 const std::string &pn = s->getPrettyName();
2597                 const std::string &mn = s->getMangledName();
2598                 const std::string tn = s->getTypedName();
2599
2600                 symsByPrettyName[pn].push_back(s);
2601                 symsByMangledName[mn].push_back(s);
2602                 symsByTypedName[tn].push_back(s);
2603                 symsByOffset[s->getOffset()].push_back(s);
2604         }
2605 }
2606
2607 void Symtab::rebuild_funcvar_hashes(SerializerBase *sb)
2608 {
2609         if (!is_input(sb))
2610                 return;
2611         for (unsigned int i = 0; i < everyFunction.size(); ++i)
2612         {
2613                 Function *f = everyFunction[i];
2614                 funcsByOffset[f->getOffset()] = f;
2615         }
2616         for (unsigned int i = 0; i < everyVariable.size(); ++i)
2617         {
2618                 Variable *v = everyVariable[i];
2619                 varsByOffset[v->getOffset()] = v;
2620         }
2621 }
2622 void Symtab::rebuild_module_hashes(SerializerBase *sb)
2623 {
2624         if (!is_input(sb))
2625                 return;
2626         for (unsigned int i = 0; i < _mods.size(); ++i)
2627         {
2628                 Module *m = _mods[i];
2629                 modsByFileName[m->fileName()] = m;
2630                 modsByFullName[m->fullName()] = m;
2631         }
2632 }
2633 void Symtab::rebuild_region_indexes(SerializerBase *sb) THROW_SPEC (SerializerError)
2634 {
2635         if (!is_input(sb))
2636                 return;
2637
2638         for (unsigned int i = 0; i < regions_.size(); ++i)
2639         {
2640                 Region *r = regions_[i];
2641
2642                 if (!r) SER_ERR("FIXME:  NULL REGION");
2643
2644                 if ( r->isLoadable() )
2645                 {
2646                         if ((r->getRegionPermissions() == Region::RP_RX)
2647                                         || (r->getRegionPermissions() == Region::RP_RWX))
2648                                 codeRegions_.push_back(r);
2649                         else
2650                                 dataRegions_.push_back(r);
2651                 }
2652
2653                 //  entry addr might require some special attn on windows, since it
2654                 //  is not the disk offset but the actual mem addr, which is going to be
2655                 //  different after deserialize.  Probably have to look it up again.
2656                 regionsByEntryAddr[r->getRegionAddr()] = r;
2657         }
2658
2659         std::sort(codeRegions_.begin(), codeRegions_.end(), sort_reg_by_addr);
2660         std::sort(dataRegions_.begin(), dataRegions_.end(), sort_reg_by_addr);
2661
2662
2663 }
2664
2665 Serializable *Symtab::serialize_impl(SerializerBase *sb, 
2666                 const char *tag) THROW_SPEC (SerializerError)
2667 {
2668         serialize_printf("%s[%d]:  welcome to Symtab::serialize_impl\n", 
2669                         FILE__, __LINE__);
2670         if (is_input(sb))
2671         {
2672                 //  don't bother with serializing standard and builtin types.
2673                 setupTypes();
2674         }
2675
2676         ifxml_start_element(sb, tag);
2677         gtranslate(sb, imageOffset_, "imageOffset");
2678         gtranslate(sb, imageLen_, "imageLen");
2679         gtranslate(sb, dataOffset_, "dataOff");
2680         gtranslate(sb, dataLen_, "dataLen");
2681         gtranslate(sb, is_a_out, "isExec");
2682         gtranslate(sb, _mods, "Modules", "Module");
2683         rebuild_module_hashes(sb);
2684         if (is_input(sb))
2685         {
2686                 //  problem:  if isTypeInfoValid_ is not true, we can trigger type parsing
2687                 //  for an object class that does not exist.  Need to introduce logic to 
2688                 //  recreate the object in this case
2689                 isTypeInfoValid_ = true;
2690                 isLineInfoValid_ = true; //  NOTE:  set this to true after deserializing at least one lineInformaton object
2691         }
2692         gtranslate(sb, regions_, "Regions", "Region");
2693         rebuild_region_indexes(sb);
2694         gtranslate(sb, everyDefinedSymbol, "EveryDefinedSymbol", "Symbol");
2695         rebuild_symbol_hashes(sb);
2696         gtranslate(sb, relocation_table_, "RelocationTable", "RelocationTableEntry");
2697         gtranslate(sb, everyFunction, "EveryFunction", "Function");
2698         gtranslate(sb, everyVariable, "EveryVariable", "Variable");
2699         rebuild_funcvar_hashes(sb);
2700
2701         //gtranslate(sb, everyUniqueVariable, "EveryUniqueVariable", "UniqueVariable");
2702         //gtranslate(sb, modSyms, "ModuleSymbols", "ModuleSymbol");
2703
2704         gtranslate(sb, excpBlocks, "ExceptionBlocks", "ExceptionBlock");
2705         ifxml_end_element(sb, tag);
2706
2707         sb->magic_check(FILE__, __LINE__);
2708 #if 0
2709         ifinput(Symtab::setup_module_up_ptrs, sb, this);
2710         ifinput(fixup_relocation_symbols, sb, this);
2711 #endif
2712
2713         if (is_input(sb))
2714         {
2715                 dyn_hash_map<Address, Symbol *> *map_p = NULL;
2716                 if (getAnnotation(map_p, IdToSymAnno) && (NULL != map_p))
2717                 {
2718                         if (!removeAnnotation(IdToSymAnno))
2719                         {
2720                                 fprintf(stderr, "%s[%d]:  failed to remove id-to-sym map\n", 
2721                                                 FILE__, __LINE__);
2722                         }
2723                         delete map_p;
2724                 }
2725         }
2726         serialize_printf("%s[%d]:  leaving Symtab::serialize_impl\n", FILE__, __LINE__);
2727         return NULL;
2728 }
2729
2730 SYMTAB_EXPORT LookupInterface::LookupInterface() 
2731 {
2732 }
2733
2734 SYMTAB_EXPORT LookupInterface::~LookupInterface()
2735 {
2736 }
2737
2738
2739 SYMTAB_EXPORT ExceptionBlock::ExceptionBlock(Offset tStart, 
2740       unsigned tSize, 
2741       Offset cStart) 
2742 : tryStart_(tStart), trySize_(tSize), catchStart_(cStart), hasTry_(true) 
2743 {
2744 }
2745
2746    SYMTAB_EXPORT ExceptionBlock::ExceptionBlock(Offset cStart) 
2747 : tryStart_(0), trySize_(0), catchStart_(cStart), hasTry_(false) 
2748 {
2749 }
2750
2751 SYMTAB_EXPORT ExceptionBlock::ExceptionBlock(const ExceptionBlock &eb) :
2752    Serializable(),
2753    tryStart_(eb.tryStart_), trySize_(eb.trySize_), 
2754    catchStart_(eb.catchStart_), hasTry_(eb.hasTry_) 
2755 {
2756 }
2757 SYMTAB_EXPORT bool ExceptionBlock::hasTry() const
2758
2759    return hasTry_; 
2760 }
2761
2762 SYMTAB_EXPORT Offset ExceptionBlock::tryStart() const
2763
2764    return tryStart_; 
2765 }
2766
2767 SYMTAB_EXPORT Offset ExceptionBlock::tryEnd() const
2768
2769    return tryStart_ + trySize_; 
2770 }
2771
2772 SYMTAB_EXPORT Offset ExceptionBlock::trySize() const
2773 {
2774    return trySize_; 
2775 }
2776
2777 SYMTAB_EXPORT bool ExceptionBlock::contains(Offset a) const
2778
2779    return (a >= tryStart_ && a < tryStart_ + trySize_); 
2780 }
2781
2782 Serializable * ExceptionBlock::serialize_impl(SerializerBase *sb, const char *tag) THROW_SPEC (SerializerError)
2783 {
2784         ifxml_start_element(sb, tag);
2785         gtranslate(sb, tryStart_, "tryStart");
2786         gtranslate(sb, trySize_, "trySize");
2787         gtranslate(sb, catchStart_, "catchStart");
2788         gtranslate(sb, hasTry_, "hasTry");
2789         ifxml_end_element(sb, tag);
2790         return NULL;
2791 }
2792
2793
2794 SYMTAB_EXPORT relocationEntry::relocationEntry() :
2795    target_addr_(0), 
2796    rel_addr_(0), 
2797    addend_(0), 
2798    rtype_(Region::RT_REL), 
2799    name_(""), 
2800    dynref_(NULL), 
2801    relType_(0)
2802 {
2803 }   
2804
2805 SYMTAB_EXPORT relocationEntry::relocationEntry(Offset ta, Offset ra, std::string n, 
2806       Symbol *dynref, unsigned long relType) :
2807    target_addr_(ta), 
2808    rel_addr_(ra), 
2809    addend_(0), 
2810    rtype_(Region::RT_REL), 
2811    name_(n), 
2812    dynref_(dynref), 
2813    relType_(relType)
2814 {
2815 }   
2816
2817 SYMTAB_EXPORT relocationEntry::relocationEntry(Offset ta, Offset ra, Offset add, 
2818       std::string n, Symbol *dynref, unsigned long relType) :
2819    target_addr_(ta), 
2820    rel_addr_(ra), 
2821    addend_(add), 
2822    rtype_(Region::RT_REL), 
2823    name_(n), 
2824    dynref_(dynref), 
2825    relType_(relType)
2826 {
2827 }
2828
2829 SYMTAB_EXPORT relocationEntry::relocationEntry(Offset ra, std::string n, 
2830       Symbol *dynref, unsigned long relType, Region::RegionType rtype) :
2831    target_addr_(0), 
2832    rel_addr_(ra), 
2833    addend_(0), 
2834    rtype_(rtype), 
2835    name_(n), 
2836    dynref_(dynref), 
2837    relType_(relType)
2838 {
2839 }   
2840
2841 SYMTAB_EXPORT const relocationEntry& relocationEntry::operator=(const relocationEntry &ra) 
2842 {
2843    target_addr_ = ra.target_addr_;
2844    rel_addr_ = ra.rel_addr_;
2845    addend_ = ra.addend_;
2846    rtype_ = ra.rtype_;
2847    name_ = ra.name_; 
2848    dynref_ = ra.dynref_;
2849    relType_ = ra.relType_;
2850    return *this;
2851 }
2852
2853 SYMTAB_EXPORT Offset relocationEntry::target_addr() const 
2854 {
2855     return target_addr_;
2856 }
2857
2858 SYMTAB_EXPORT void relocationEntry::setTargetAddr(const Offset off)
2859 {
2860     target_addr_ = off;
2861 }
2862
2863 SYMTAB_EXPORT Offset relocationEntry::rel_addr() const 
2864 {
2865     return rel_addr_;
2866 }
2867
2868 SYMTAB_EXPORT void relocationEntry::setRelAddr(const Offset value)
2869 {
2870     rel_addr_ = value;
2871 }
2872
2873 SYMTAB_EXPORT const string &relocationEntry::name() const 
2874 {
2875     return name_;
2876 }
2877
2878 SYMTAB_EXPORT Symbol *relocationEntry::getDynSym() const 
2879 {
2880     return dynref_;
2881 }
2882
2883 SYMTAB_EXPORT bool relocationEntry::addDynSym(Symbol *dynref) 
2884 {
2885     dynref_ = dynref;
2886     return true;
2887 }
2888
2889 SYMTAB_EXPORT Region::RegionType relocationEntry::regionType() const
2890 {
2891         return rtype_;
2892 }
2893
2894 SYMTAB_EXPORT unsigned long relocationEntry::getRelType() const 
2895 {
2896     return relType_;
2897 }
2898
2899 SYMTAB_EXPORT Offset relocationEntry::addend() const
2900 {
2901     return addend_;
2902 }
2903
2904 SYMTAB_EXPORT void relocationEntry::setAddend(const Offset value)
2905 {
2906     addend_ = value;
2907 }
2908
2909 SYMTAB_EXPORT void relocationEntry::setRegionType(const Region::RegionType value)
2910 {
2911     rtype_ = value;
2912 }
2913
2914 bool relocationEntry::operator==(const relocationEntry &r) const
2915 {
2916         if (target_addr_ != r.target_addr_) return false;
2917         if (rel_addr_ != r.rel_addr_) return false;
2918         if (addend_ != r.addend_) return false;
2919         if (rtype_ != r.rtype_) return false;
2920         if (name_ != r.name_) return false;
2921         if (relType_ != r.relType_) return false;
2922         if (dynref_ && !r.dynref_) return false;
2923         if (!dynref_ && r.dynref_) return false;
2924         if (dynref_)
2925         {
2926                 if (dynref_->getName() != r.dynref_->getName()) return false;
2927                 if (dynref_->getOffset() != r.dynref_->getOffset()) return false;
2928         }
2929
2930         return true;
2931 }
2932
2933 Serializable *relocationEntry::serialize_impl(SerializerBase *sb, const char *tag) THROW_SPEC (SerializerError)
2934 {
2935         //  on deserialize need to rebuild symtab::undefDynSyms before deserializing relocations
2936
2937         std::string symname = dynref_ ? dynref_->getName() : std::string("");
2938         Offset symoff = dynref_ ? dynref_->getOffset() : (Offset) -1;
2939
2940       ifxml_start_element(sb, tag);
2941       gtranslate(sb, target_addr_, "targetAddress");
2942       gtranslate(sb, rel_addr_, "relocationAddress");
2943       gtranslate(sb, addend_, "Addend");
2944       gtranslate(sb, name_, "relocationName");
2945       gtranslate(sb,  rtype_, Region::regionType2Str, "regionType");
2946       gtranslate(sb, relType_, "relocationType");
2947       gtranslate(sb, symname, "SymbolName");
2948       gtranslate(sb, symoff, "SymbolOffset");
2949       ifxml_end_element(sb, tag);
2950
2951           if (sb->isInput())
2952           {
2953                   dynref_ = NULL;
2954                   if (symname != std::string(""))
2955                   {
2956                           //  if we have a name for this symbol, the offset should not be -1;
2957                           if (symoff == (Offset) -1)
2958                           {
2959                                   fprintf(stderr, "%s[%d]:  inconsistent symname and offset combo!\n", 
2960                                                   FILE__, __LINE__);
2961                           }
2962
2963                           SerContextBase *scb = sb->getContext();
2964                           if (!scb)
2965                           {
2966                                   fprintf(stderr, "%s[%d]:  SERIOUS:  FIXME\n", FILE__, __LINE__);
2967                                   SER_ERR("FIXME");
2968                           }
2969
2970                           SerContext<Symtab> *scs = dynamic_cast<SerContext<Symtab> *>(scb);
2971
2972                           if (!scs)
2973                           {
2974                                   fprintf(stderr, "%s[%d]:  SERIOUS:  FIXME\n", FILE__, __LINE__);
2975                                   SER_ERR("FIXME");
2976                           }
2977
2978                           Symtab *st = scs->getScope();
2979
2980                           if (!st)
2981                           {
2982                                   fprintf(stderr, "%s[%d]:  SERIOUS:  FIXME\n", FILE__, __LINE__);
2983                                   SER_ERR("FIXME");
2984                           }
2985
2986                           std::vector<Symbol *> *syms = st->findSymbolByOffset(symoff);
2987                           if (!syms || !syms->size())
2988                           {
2989                                   serialize_printf("%s[%d]:  cannot find symbol by offset %p\n", 
2990                                                   FILE__, __LINE__, (void *)symoff);
2991                                   return NULL;
2992                           }
2993
2994                           //  Might want to try to select the "best" symbol here if there is
2995                           //  more than one.  Or Maybe just returning the first is sufficient.
2996
2997                           dynref_ = (*syms)[0];
2998                   }
2999           }
3000           return NULL;
3001 }
3002
3003
3004 const char *Symbol::symbolType2Str(SymbolType t) 
3005 {
3006    switch (t) 
3007    {
3008       CASE_RETURN_STR(ST_UNKNOWN);
3009       CASE_RETURN_STR(ST_FUNCTION);
3010       CASE_RETURN_STR(ST_OBJECT);
3011       CASE_RETURN_STR(ST_MODULE);
3012       CASE_RETURN_STR(ST_SECTION);
3013       CASE_RETURN_STR(ST_DELETED);
3014       CASE_RETURN_STR(ST_NOTYPE);
3015    };
3016
3017    return "invalid symbol type";
3018 }
3019
3020 const char *Symbol::symbolLinkage2Str(SymbolLinkage t) 
3021 {
3022    switch (t) 
3023    {
3024       CASE_RETURN_STR(SL_UNKNOWN);
3025       CASE_RETURN_STR(SL_GLOBAL);
3026       CASE_RETURN_STR(SL_LOCAL);
3027       CASE_RETURN_STR(SL_WEAK);
3028    };
3029
3030    return "invalid symbol linkage";
3031 }
3032
3033 const char *Symbol::symbolTag2Str(SymbolTag t) 
3034 {
3035    switch (t) 
3036    {
3037       CASE_RETURN_STR(TAG_UNKNOWN);
3038       CASE_RETURN_STR(TAG_USER);
3039       CASE_RETURN_STR(TAG_LIBRARY);
3040       CASE_RETURN_STR(TAG_INTERNAL);
3041    };
3042
3043    return "invalid symbol tag";
3044 }
3045
3046 const char *Symbol::symbolVisibility2Str(SymbolVisibility t) 
3047 {
3048    switch(t) {
3049       CASE_RETURN_STR(SV_UNKNOWN);
3050       CASE_RETURN_STR(SV_DEFAULT);
3051       CASE_RETURN_STR(SV_INTERNAL);
3052       CASE_RETURN_STR(SV_HIDDEN);
3053       CASE_RETURN_STR(SV_PROTECTED);
3054    }
3055    return "invalid symbol visibility";
3056 }
3057
3058 bool Symtab::hasStackwalkDebugInfo()
3059 {
3060
3061         Object *obj = getObject();
3062         if (!obj)
3063         {
3064                 fprintf(stderr, "%s[%d]:  getObject failed here\n", FILE__, __LINE__);
3065                 return false;
3066         }
3067    return obj->hasFrameDebugInfo();
3068 }
3069
3070 bool Symtab::getRegValueAtFrame(Address pc, 
3071                                 Dyninst::MachRegister reg, 
3072                                 Dyninst::MachRegisterVal &reg_result,
3073                                 MemRegReader *reader)
3074 {
3075         Object *obj = getObject();
3076         if (!obj)
3077         {
3078                 fprintf(stderr, "%s[%d]:  getObject failed here\n", FILE__, __LINE__);
3079                 return false;
3080         }
3081    return obj->getRegValueAtFrame(pc, reg, reg_result, reader);
3082 }
3083
3084 Object *Symtab::getObject()
3085 {
3086    if (obj_private)
3087       return obj_private;
3088
3089    //TODO: This likely triggered because we serialized in an object
3090    // from cache, but now the user is requesting more information from
3091    // the on disk object.  We should create a new 'Object' from data
3092    // (likely a file path) serialized in.
3093    
3094    fprintf(stderr, "%s[%d]:  FIXME:  request for object that does not exist!\n", FILE__, __LINE__);
3095    return NULL;
3096    //obj_private = new Object();
3097    //return obj_private;
3098 }
3099
3100 void Symtab::parseTypesNow()
3101 {
3102    if (isTypeInfoValid_)
3103       return;
3104
3105    parseTypes();
3106 }
3107
3108 MemRegReader::~MemRegReader()
3109 {
3110 }
3111
3112 #if defined (cap_serialization)
3113 //  Not sure this is strictly necessary, problems only seem to exist with Module 
3114 // annotations when the file was split off, so there's probably something else that
3115 //  can be done to instantiate the relevant functions.
3116
3117 bool dummy_for_ser_instance(std::string file, SerializerBase *sb)
3118 {
3119    if (file == std::string("no_such_file")) 
3120    {
3121       if (!sb) 
3122       {
3123          fprintf(stderr, "%s[%d]:  really should not happen\n", FILE__, __LINE__);
3124          return false;
3125       }
3126       fprintf(stderr, "%s[%d]:  WARN:  disabled serializer init here\n", FILE__, __LINE__);
3127    }
3128    return true;
3129 }
3130
3131 #endif
3132
3133 namespace Dyninst {
3134         namespace SymtabAPI {
3135
3136
3137 #if 1
3138 SYMTAB_EXPORT SerializerBase *nonpublic_make_bin_symtab_serializer(Symtab *t, std::string file)
3139 {
3140         SerializerBin *ser;
3141         SerContext<Symtab> *scs = new SerContext<Symtab>(t, file);
3142         ser = new SerializerBin(scs, "SerializerBin", file, sd_serialize, false);
3143         return ser;
3144 }
3145
3146 SYMTAB_EXPORT SerializerBase *nonpublic_make_bin_symtab_deserializer(Symtab *t, std::string file)
3147 {
3148         SerializerBin *ser;
3149         SerContext<Symtab> *scs = new SerContext<Symtab>(t, file);
3150         ser = new SerializerBin(scs, "DeserializerBin", file, sd_deserialize, false);
3151         return ser;
3152 }
3153
3154 SYMTAB_EXPORT void nonpublic_free_bin_symtab_serializer(SerializerBase *sb)
3155 {
3156         SerializerBin *sbin = dynamic_cast<SerializerBin *>(sb);
3157         if (sbin)
3158         {
3159                 delete(sbin);
3160         }
3161         else
3162                 fprintf(stderr, "%s[%d]:  FIXME\n", FILE__, __LINE__);
3163
3164 }
3165 #endif
3166
3167 SYMTAB_EXPORT Offset Symtab::getElfDynamicOffset()
3168 {
3169 #if defined(os_linux)
3170         Object *obj = getObject();
3171         if (!obj)
3172         {
3173                 fprintf(stderr, "%s[%d]:  getObject failed here\n", FILE__, __LINE__);
3174                 return 0;
3175         }
3176    return obj->getDynamicAddr();
3177 #else
3178    return 0;
3179 #endif
3180 }
3181
3182 SYMTAB_EXPORT bool Symtab::addLibraryPrereq(std::string name)
3183 {
3184 #if defined(os_linux)
3185         Object *obj = getObject();
3186         if (!obj)
3187         {
3188                 fprintf(stderr, "%s[%d]:  getObject failed here\n", FILE__, __LINE__);
3189                 return false;
3190         }
3191    obj->insertPrereqLibrary(name);
3192    return true;
3193 #else
3194    return false;
3195 #endif
3196 }
3197
3198 SYMTAB_EXPORT bool Symtab::addSysVDynamic(long name, long value)
3199 {
3200 #if defined(os_linux)
3201         Object *obj = getObject();
3202         if (!obj)
3203         {
3204                 fprintf(stderr, "%s[%d]:  getObject failed here\n", FILE__, __LINE__);
3205                 return false;
3206         }
3207   obj->insertDynamicEntry(name, value);
3208    return true;
3209 #else
3210    return false;
3211 #endif
3212 }
3213
3214 SYMTAB_EXPORT Address Symtab::getLoadAddress()
3215 {
3216 #if defined(os_linux) || defined(os_aix)
3217    return getObject()->getLoadAddress();
3218 #else
3219    return 0x0;
3220 #endif
3221 }
3222
3223 SYMTAB_EXPORT bool Symtab::canBeShared()
3224 {
3225    return mf->canBeShared();
3226 }
3227
3228 SYMTAB_EXPORT Offset Symtab::getInitOffset()
3229 {
3230 #if defined(os_linux) || defined(os_solaris)
3231    return getObject()->getInitAddr();
3232 #else
3233    return 0x0;
3234 #endif
3235
3236 }
3237
3238 SYMTAB_EXPORT Offset Symtab::getFiniOffset()
3239 {
3240 #if defined(os_linux) || defined(os_solaris)
3241    return getObject()->getFiniAddr();
3242 #else
3243    return 0x0;
3244 #endif
3245
3246 }
3247
3248
3249 } // namespace SymtabAPI
3250 } // namespace Dyninst
3251