Merge branch 'master' of legendre@git.dyninst.org:/pub/dyninst
[dyninst.git] / symtabAPI / src / Symtab.C
1 /*
2  * Copyright (c) 1996-2008 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_TLS:
775     case Symbol::ST_OBJECT: {
776         // The same as the above, but with variables.
777         Variable *var = NULL;
778         findVariableByOffset(var, sym->getAddr());
779         if (!var) {
780             // Create a new function
781             // Also, update the symbol to point to this function.
782             var = new Variable(sym);
783             
784             everyVariable.push_back(var);
785             varsByOffset[sym->getAddr()] = var;
786         }
787         else {
788             var->addSymbol(sym);
789         }
790         sym->setVariable(var);
791         break;
792     }
793     default: {
794         break;
795     }
796     }
797     return true;
798 }
799
800 /* Add the new name to the appropriate symbol index */
801
802 bool Symtab::updateIndices(Symbol *sym, std::string newName, NameType nameType) {
803     if (nameType & mangledName) {
804         // Add this symbol under the given name (as mangled)
805         symsByMangledName[newName].push_back(sym);
806     }
807     if (nameType & prettyName) {
808         // Add this symbol under the given name (as pretty)
809         symsByPrettyName[newName].push_back(sym);
810     }
811     if (nameType & typedName) {
812         // Add this symbol under the given name (as typed)
813         symsByTypedName[newName].push_back(sym);
814     }
815     return true;
816 }
817
818 #if 0
819 /* checkPPC64DescriptorSymbols() is no longer needed.  3-word descriptor
820  * symbols are properly taken care of during symbol parsing.  See
821  * parse_symbols() in Object-elf.C for details.
822  */
823
824 #if defined(ppc64_linux)
825 /* Special case for ppc64 ELF binaries. Sometimes a function has a 3-byte descriptor symbol
826  * along with it in the symbol table and "." preceding its original pretty name for the correct
827  * function symbol. This checks to see if we have a corresponding 3-byte descriptor symbol existing
828  * and if it does we remove the preceding "." from the name of the symbol
829  */
830
831 void Symtab::checkPPC64DescriptorSymbols(Object *linkedFile)
832 {
833    // find the real functions -- those with the correct type in the symbol table
834    for(SymbolIter symIter(*linkedFile); symIter;symIter++)
835    {
836       Symbol *lookUp = symIter.currval();
837       const char *np = lookUp->getMangledName().c_str();
838       if(!np)
839          continue;
840
841       if(np[0] == '.' && (lookUp->getType() == Symbol::ST_FUNCTION))
842       {
843          std::vector<Symbol *>syms;
844          std::string newName = np+1;
845          if(linkedFile->get_symbols(newName, syms) && (syms[0]->getSize() == 24 || syms[0]->getSize() == 0))
846          {
847             //Remove the "." from the name
848             lookUp->mangledNames[0] = newName;
849
850             //Change the type of the descriptor symbol
851             syms[0]->type_ = Symbol::ST_NOTYPE;
852          }
853       }
854    }
855
856 }
857
858 #endif
859 #endif
860
861 //  setModuleLanguages is only called after modules have been defined.
862 //  it attempts to set each module's language, information which is needed
863 //  before names can be demangled.
864 void Symtab::setModuleLanguages(dyn_hash_map<std::string, supportedLanguages> *mod_langs)
865 {
866    if (!mod_langs->size())
867       return;  // cannot do anything here
868    //  this case will arise on non-stabs platforms until language parsing can be introduced at this level
869    std::vector<Module *> *modlist;
870    Module *currmod = NULL;
871    modlist = &_mods;
872    //int dump = 0;
873
874    for (unsigned int i = 0;  i < modlist->size(); ++i)
875    {
876       currmod = (*modlist)[i];
877       supportedLanguages currLang;
878       if (currmod->isShared()) {
879          continue;  // need to find some way to get shared object languages?
880       }
881
882       const std::string fn = currmod->fileName();
883       if (mod_langs->find(currmod->fileName()) != mod_langs->end())
884       {
885          currLang = (*mod_langs)[fn];
886       }
887       else if (fn.rfind(".s") != std::string::npos ||
888             fn.rfind(".asm") != std::string::npos)
889       {
890          currLang = lang_Assembly;
891       }
892       else if (fn.rfind(".c") != std::string::npos)
893       {
894          currLang = lang_C;
895       }
896       else if (fn.rfind(".cpp") != std::string::npos ||
897             fn.rfind(".cc") != std::string::npos ||
898             fn.rfind(".C") != std::string::npos)
899       {
900          currLang = lang_CPlusPlus;
901       }
902       else
903       {
904          continue;
905       }
906       currmod->setLanguage(currLang);
907    }
908 }
909
910 void Symtab::createDefaultModule() {
911     Module *mod = NULL;
912     if (getObjectType() == obj_SharedLib) {
913         mod = new Module(lang_Unknown, 
914                          imageOffset_,
915                          name(),
916                          this);
917     }
918     else {
919         mod = new Module(lang_Unknown, 
920                          imageOffset_,
921                          "DEFAULT_MODULE",
922                          this);
923     }
924     modsByFileName[mod->fileName()] = mod;
925     modsByFullName[mod->fullName()] = mod;
926     _mods.push_back(mod);
927 }
928
929
930
931 Module *Symtab::getOrCreateModule(const std::string &modName, 
932                                   const Offset modAddr)
933 {
934    std::string nameToUse;
935    if (modName.length() > 0)
936       nameToUse = modName;
937    else
938       nameToUse = "DEFAULT_MODULE";
939
940    Module *fm = NULL;
941    if (findModuleByName(fm, nameToUse)) 
942    {
943       return fm;
944    }
945
946     const char *str = nameToUse.c_str();
947     int len = nameToUse.length();
948     assert(len>0);
949
950     // TODO ignore directory definitions for now
951     if (str[len-1] == '/') 
952         return NULL;
953
954     return (newModule(nameToUse, modAddr, lang_Unknown));
955 }
956  
957 Module *Symtab::newModule(const std::string &name, const Offset addr, supportedLanguages lang)
958 {
959     Module *ret = NULL;
960     // modules can be defined several times in C++ due to templates and
961     //   in-line member functions.
962
963     if (findModuleByName(ret, name)) 
964     {
965         return(ret);
966     }
967
968     //parsing_printf("=== image, creating new pdmodule %s, addr 0x%x\n",
969     //                          name.c_str(), addr);
970     
971     std::string fileNm, fullNm;
972     fullNm = name;
973     fileNm = extract_pathname_tail(name);
974
975     // /* DEBUG */ fprintf( stderr, "%s[%d]: In %p: Creating new pdmodule '%s'/'%s'\n", FILE__, __LINE__, this, fileNm.c_str(), fullNm.c_str() );
976
977     ret = new Module(lang, addr, fullNm, this);
978     assert(ret);
979
980     if (modsByFileName.end() != modsByFileName.find(ret->fileName()))
981     {
982        fprintf(stderr, "%s[%d]:  WARN:  LEAK?  already have module with name %s\n", 
983              FILE__, __LINE__, ret->fileName().c_str());
984     }
985
986     if (modsByFullName.end() != modsByFullName.find(ret->fullName()))
987     {
988        fprintf(stderr, "%s[%d]:  WARN:  LEAK?  already have module with name %s\n", 
989              FILE__, __LINE__, ret->fullName().c_str());
990     }
991
992     modsByFileName[ret->fileName()] = ret;
993     modsByFullName[ret->fullName()] = ret;
994     _mods.push_back(ret);
995     
996     return (ret);
997 }
998
999 Symtab::Symtab(std::string filename,bool &err) :
1000    is_a_out(false), 
1001    main_call_addr_(0),
1002    nativeCompiler(false), 
1003    isLineInfoValid_(false), 
1004    isTypeInfoValid_(false),
1005    obj_private(NULL)
1006 {
1007     init_debug_symtabAPI();
1008    // Initialize error parameter
1009    err = false;
1010    
1011    create_printf("%s[%d]: created symtab for %s\n", FILE__, __LINE__, filename.c_str());
1012
1013 #if defined (os_windows)
1014    extern void fixup_filename(std::string &);
1015    fixup_filename(filename);
1016 #endif
1017
1018    //  createMappedFile handles reference counting
1019    mf = MappedFile::createMappedFile(filename);
1020    if (!mf) {
1021       create_printf("%s[%d]: WARNING: creating symtab for %s, " 
1022                     "createMappedFile() failed\n", FILE__, __LINE__, 
1023                     filename.c_str());
1024       err = true;
1025       return;
1026    }
1027
1028    obj_private = new Object(mf, mfForDebugInfo, symtab_log_perror, true);
1029
1030    if (!extractInfo(obj_private))
1031    {
1032       create_printf("%s[%d]: WARNING: creating symtab for %s, extractInfo() " 
1033                     "failed\n", FILE__, __LINE__, filename.c_str());
1034       err = true;
1035    }
1036
1037    defaultNamespacePrefix = "";
1038 }
1039
1040 Symtab::Symtab(char *mem_image, size_t image_size, bool &err) :
1041    is_a_out(false), 
1042    main_call_addr_(0),
1043    nativeCompiler(false),
1044    isLineInfoValid_(false),
1045    isTypeInfoValid_(false),
1046    obj_private(NULL)
1047 {
1048    // Initialize error parameter
1049    err = false;
1050   
1051    create_printf("%s[%d]: created symtab for memory image at addr %u\n", 
1052                  FILE__, __LINE__, mem_image);
1053
1054    //  createMappedFile handles reference counting
1055    mf = MappedFile::createMappedFile(mem_image, image_size);
1056    if (!mf) {
1057       create_printf("%s[%d]: WARNING: creating symtab for memory image at " 
1058                     "addr %u, createMappedFile() failed\n", FILE__, __LINE__, 
1059                     mem_image);
1060       err = true;
1061       return;
1062    }
1063
1064    obj_private = new Object(mf, mfForDebugInfo, symtab_log_perror, true);
1065
1066    if (!extractInfo(obj_private))
1067    {
1068       create_printf("%s[%d]: WARNING: creating symtab for memory image at addr" 
1069                     "%u, extractInfo() failed\n", FILE__, __LINE__, mem_image);
1070       err = true;
1071    }
1072
1073    defaultNamespacePrefix = "";
1074 }
1075
1076 // Symtab constructor for archive members
1077 #if defined(os_aix) || defined(os_linux) || defined(os_solaris)
1078 Symtab::Symtab(std::string filename, std::string member_name, Offset offset, 
1079                bool &err, void *base) :
1080    member_name_(member_name), 
1081    member_offset_(offset),
1082    is_a_out(false),
1083    main_call_addr_(0), 
1084    nativeCompiler(false), 
1085    isLineInfoValid_(false),
1086    isTypeInfoValid_(false), 
1087    obj_private(NULL)
1088 {
1089    mf = MappedFile::createMappedFile(filename);
1090    assert(mf);
1091    obj_private = new Object(mf, mfForDebugInfo, member_name, offset, symtab_log_perror, base);
1092    err = extractInfo(obj_private);
1093    defaultNamespacePrefix = "";
1094 }
1095 #else
1096 Symtab::Symtab(std::string, std::string, Offset, bool &, void *)
1097 {
1098     assert(0);
1099 }
1100 #endif
1101
1102 #if defined(os_aix) || defined(os_linux) || defined(os_solaris)
1103 Symtab::Symtab(char *mem_image, size_t image_size, std::string member_name,
1104                        Offset offset, bool &err, void *base) :
1105    member_name_(member_name), 
1106    is_a_out(false), 
1107    main_call_addr_(0),
1108    nativeCompiler(false), 
1109    isLineInfoValid_(false), 
1110    isTypeInfoValid_(false)
1111 {
1112    mf = MappedFile::createMappedFile(mem_image, image_size);
1113    assert(mf);
1114    obj_private = new Object(mf, mf, member_name, offset, symtab_log_perror, base);
1115    err = extractInfo(obj_private);
1116    defaultNamespacePrefix = "";
1117 }
1118 #else 
1119 Symtab::Symtab(char *, size_t, std::string , Offset, bool &, void *)
1120 {
1121     assert(0);
1122 }
1123 #endif
1124
1125 bool sort_reg_by_addr(const Region* a, const Region* b)
1126 {
1127   if (a->getRegionAddr() == b->getRegionAddr())
1128     return a->getMemSize() < b->getMemSize();
1129   return a->getRegionAddr() < b->getRegionAddr();
1130 }
1131
1132 extern void print_symbols( std::vector< Symbol *>& allsymbols );
1133 extern void print_symbol_map( dyn_hash_map< std::string, std::vector< Symbol *> > *symbols);
1134
1135 bool Symtab::extractInfo(Object *linkedFile)
1136 {
1137 #if defined(TIMED_PARSE)
1138     struct timeval starttime;
1139     gettimeofday(&starttime, NULL);
1140 #endif
1141     mfForDebugInfo = linkedFile->getMappedFileForDebugInfo();
1142
1143     bool err = true;
1144     imageOffset_ = linkedFile->code_off();
1145     dataOffset_ = linkedFile->data_off();
1146
1147     imageLen_ = linkedFile->code_len();
1148     dataLen_ = linkedFile->data_len();
1149     
1150     if (0 == imageLen_ || 0 == linkedFile->code_ptr()) 
1151     {
1152         // for AIX, code_ptr()==NULL is normal behavior
1153 #if !defined(os_aix)
1154        if (0 == linkedFile->code_ptr()) {
1155           //fprintf(stderr, "[%s][%d]WARNING: null code pointer in Symtab for"
1156           //" file %s, possibly due to a missing .text section.\n",
1157           //__FILE__,__LINE__, file().c_str());
1158           linkedFile->code_ptr_ = (char *) linkedFile->code_off();
1159        }
1160        else 
1161 #endif
1162        {
1163           serr = Obj_Parsing;
1164           return false;
1165        }
1166    }
1167         
1168   //  if (!imageLen_ || !linkedFile->code_ptr()) {
1169   //      serr = Obj_Parsing; 
1170   //      return false; 
1171    // }
1172
1173     no_of_sections = linkedFile->no_of_sections();
1174     newSectionInsertPoint = no_of_sections;
1175     no_of_symbols = linkedFile->no_of_symbols();
1176     
1177     isStaticBinary_ = linkedFile->isStaticBinary();
1178
1179     hasRel_ = false;
1180     hasRela_ = false;
1181     hasReldyn_ = false;
1182     hasReladyn_ = false;
1183     hasRelplt_ = false;
1184     hasRelaplt_ = false;
1185     regions_ = linkedFile->getAllRegions();
1186
1187     for (unsigned index=0;index<regions_.size();index++)
1188     {
1189         if ( regions_[index]->isLoadable() ) 
1190         {
1191            if (     (regions_[index]->getRegionPermissions() == Region::RP_RX) 
1192                  || (regions_[index]->getRegionPermissions() == Region::RP_RWX)) 
1193            {
1194               codeRegions_.push_back(regions_[index]);
1195            }
1196            else 
1197            {
1198                 dataRegions_.push_back(regions_[index]);
1199             }
1200         }
1201
1202         regionsByEntryAddr[regions_[index]->getRegionAddr()] = regions_[index];
1203
1204         if (regions_[index]->getRegionType() == Region::RT_REL) 
1205         {
1206             hasRel_ = true;
1207         }
1208
1209         if (regions_[index]->getRegionType() == Region::RT_RELA) 
1210         {
1211             hasRela_ = true;
1212         }
1213
1214 #if defined(os_linux) || defined(os_solaris)
1215         hasReldyn_ = linkedFile->hasReldyn();
1216         hasReladyn_ = linkedFile->hasReladyn();
1217         hasRelplt_ = linkedFile->hasRelplt();
1218         hasRelaplt_ = linkedFile->hasRelaplt();
1219 #endif  
1220
1221     }
1222     // sort regions_ & codeRegions_ vectors
1223
1224     std::sort(codeRegions_.begin(), codeRegions_.end(), sort_reg_by_addr);
1225     std::sort(dataRegions_.begin(), dataRegions_.end(), sort_reg_by_addr);
1226     std::sort(regions_.begin(), regions_.end(), sort_reg_by_addr);
1227
1228     /* insert error check here. check if parsed */
1229     address_width_ = linkedFile->getAddressWidth();
1230     is_a_out = linkedFile->is_aout();
1231     code_ptr_ = linkedFile->code_ptr();
1232     data_ptr_ = linkedFile->data_ptr();
1233
1234     if (linkedFile->interpreter_name())
1235        interpreter_name_ = std::string(linkedFile->interpreter_name());
1236
1237     entry_address_ = linkedFile->getEntryAddress();
1238     base_address_ = linkedFile->getBaseAddress();
1239     load_address_ = linkedFile->getLoadAddress();
1240     toc_offset_ = linkedFile->getTOCoffset();
1241     object_type_  = linkedFile->objType();
1242     is_eel_ = linkedFile->isEEL();
1243     linkedFile->getSegments(segments_);
1244
1245 #if !defined(os_aix) && !defined(os_windows)
1246     linkedFile->getDependencies(deps_);
1247 #endif
1248
1249 #if defined (os_aix)
1250     //  These should go away
1251     linkedFile->get_stab_info(stabstr_, nstabs_, stabs_, stringpool_);
1252     linkedFile->get_line_info(nlines_, lines_, fdptr_);
1253 #endif
1254
1255 #if defined(os_solaris) || defined(os_aix) || defined(os_linux)
1256     // make sure we're using the right demangler
1257     
1258     nativeCompiler = parseCompilerType(linkedFile);
1259     //parsing_printf("isNativeCompiler: %d\n", nativeCompiler);
1260 #endif
1261     
1262     // define all of the functions
1263     //statusLine("winnowing functions");
1264
1265 #if defined(ppc64_linux)
1266     //checkPPC64DescriptorSymbols(linkedFile);
1267 #endif
1268
1269     // a vector to hold all created symbols until they are properly classified
1270     std::vector<Symbol *> raw_syms;
1271
1272 #ifdef BINEDIT_DEBUG
1273     printf("== from linkedFile...\n");
1274     print_symbol_map(linkedFile->getAllSymbols());
1275 #endif
1276
1277     if (!extractSymbolsFromFile(linkedFile, raw_syms)) 
1278     {
1279         err = false;
1280         serr = Syms_To_Functions;
1281         return false;
1282     }
1283
1284 #ifdef BINEDIT_DEBUG
1285     printf("== in Symtab now...\n");
1286     //print_symbols(raw_syms);
1287     std::vector<Symbol *> undefsyms;
1288     std::map<std::string, std::vector<Symbol *> >::iterator iter;
1289     std::vector<Symbol *>::iterator siter;
1290     for (iter = undefDynSyms.begin(); iter != undefDynSyms.end(); iter++)
1291         for (siter = iter->second.begin(); siter != iter->second.end(); siter++)
1292             undefsyms.push_back(*siter);
1293     //print_symbols(undefsyms);
1294     printf("%d total symbol(s)\n", raw_syms.size() + undefsyms.size());
1295 #endif
1296
1297     // don't sort the symbols--preserve the original ordering
1298     //sort(raw_syms.begin(),raw_syms.end(),symbol_compare);
1299
1300     createDefaultModule();
1301
1302     if (!fixSymModules(raw_syms)) 
1303     {
1304         err = false;
1305         serr = Syms_To_Functions;
1306         return false;
1307     }
1308         Object *obj = getObject();
1309         if (!obj)
1310         {
1311                 fprintf(stderr, "%s[%d]:  getObject failed here\n", FILE__, __LINE__);
1312                 return false;
1313         }
1314     obj->clearSymsToMods();
1315
1316     // wait until all modules are defined before applying languages to
1317     // them we want to do it this way so that module information comes
1318     // from the function symbols, first and foremost, to avoid any
1319     // internal module-function mismatching.
1320             
1321     // get Information on the language each modules is written in
1322     // (prior to making modules)
1323
1324     dyn_hash_map<std::string, supportedLanguages> mod_langs;
1325     linkedFile->getModuleLanguageInfo(&mod_langs);
1326     setModuleLanguages(&mod_langs);
1327         
1328     // Be sure that module languages are set before demangling, or
1329     // we won't get very far.
1330
1331     if (!demangleSymbols(raw_syms)) 
1332     {
1333         err = false;
1334         serr = Syms_To_Functions;
1335         return false;
1336     }
1337
1338     if (!createIndices(raw_syms)) 
1339     {
1340         err = false;
1341         serr = Syms_To_Functions;
1342         return false;
1343     }
1344
1345     if (!createAggregates()) 
1346     {
1347         err = false;
1348         serr = Syms_To_Functions;
1349         return false;
1350     }
1351         
1352     // Once languages are assigned, we can build demangled names (in
1353     // the wider sense of demangling which includes stripping _'s from
1354     // fortran names -- this is why language information must be
1355     // determined before this step).
1356     
1357     // Also identifies aliases (multiple names with equal addresses)
1358     
1359     //addSymtabVariables();
1360     linkedFile->getAllExceptions(excpBlocks);
1361
1362     vector<relocationEntry >fbt;
1363     linkedFile->get_func_binding_table(fbt);
1364     for(unsigned i=0; i<fbt.size();i++)
1365         relocation_table_.push_back(fbt[i]);
1366     return true;
1367 }
1368
1369 Symtab::Symtab(const Symtab& obj) :
1370    LookupInterface(),
1371    Serializable(),
1372    AnnotatableSparse()
1373 {
1374     create_printf("%s[%d]: Creating symtab 0x%p from symtab 0x%p\n", FILE__, __LINE__, this, &obj);
1375   
1376     member_name_ = obj.member_name_;
1377     imageOffset_ = obj.imageOffset_;
1378     imageLen_ = obj.imageLen_;
1379     dataOffset_ = obj.dataOffset_;
1380     dataLen_ = obj.dataLen_;
1381
1382    isLineInfoValid_ = obj.isLineInfoValid_;
1383    isTypeInfoValid_ = obj.isTypeInfoValid_;
1384
1385    is_a_out = obj.is_a_out;
1386    main_call_addr_ = obj.main_call_addr_; // address of call to main()
1387
1388    nativeCompiler = obj.nativeCompiler;
1389    defaultNamespacePrefix = obj.defaultNamespacePrefix;
1390
1391    //sections
1392    no_of_sections = obj.no_of_sections;
1393    unsigned i;
1394
1395    for (i=0;i<obj.regions_.size();i++)
1396       regions_.push_back(new Region(*(obj.regions_[i])));
1397
1398    for (i=0;i<regions_.size();i++)
1399       regionsByEntryAddr[regions_[i]->getRegionAddr()] = regions_[i];
1400
1401    // TODO FIXME: copying symbols/Functions/Variables
1402
1403    for (i=0;i<obj._mods.size();i++)
1404    {
1405       Module *m = new Module(*(obj._mods[i]));
1406       _mods.push_back(m);
1407       modsByFileName[m->fileName()] = m;
1408       modsByFullName[m->fullName()] = m;
1409       fprintf(stderr, "%s[%d]:  copy ctor creating new module %s\n", 
1410             FILE__, __LINE__, m->fileName().c_str());
1411    }
1412
1413    for (i=0; i<relocation_table_.size();i++) 
1414    {
1415       relocation_table_.push_back(relocationEntry(obj.relocation_table_[i]));
1416       //undefDynSyms[obj.relocation_table_[i].name()] = relocation_table_[i].getDynSym();
1417       undefDynSyms[obj.relocation_table_[i].name()].push_back(relocation_table_[i].getDynSym());
1418
1419    }
1420
1421    for (i=0;i<excpBlocks.size();i++)
1422    {
1423       excpBlocks.push_back(new ExceptionBlock(*(obj.excpBlocks[i])));
1424    }
1425
1426    deps_ = obj.deps_;
1427    setupTypes();
1428 }
1429
1430 // Address must be in code or data range since some code may end up
1431 // in the data segment
1432 bool Symtab::isValidOffset(const Offset where) const
1433 {
1434    return isCode(where) || isData(where);
1435 }
1436
1437 /* Performs a binary search on the codeRegions_ vector, which must
1438  * be kept in sorted order
1439  */
1440 bool Symtab::isCode(const Offset where)  const
1441 {
1442    if (!codeRegions_.size()) 
1443    {
1444       fprintf(stderr, "%s[%d] No code regions in %s \n",
1445             __FILE__, __LINE__, mf->filename().c_str());
1446       return false;
1447    }
1448
1449    // search for "where" in codeRegions_ (code regions must not overlap)
1450    int first = 0; 
1451    int last = codeRegions_.size() - 1;
1452
1453    while (last >= first) 
1454    {
1455       Region *curreg = codeRegions_[(first + last) / 2];
1456       if (where >= curreg->getRegionAddr()
1457             && where < (curreg->getRegionAddr()
1458                + curreg->getDiskSize())) 
1459       {
1460          if (curreg->getRegionType() == Region::RT_BSS)
1461             return false;
1462          return true;
1463       }
1464       else if (where < curreg->getRegionAddr()) 
1465       {
1466          last = ((first + last) / 2) - 1;
1467       }
1468       else if (where >= (curreg->getRegionAddr() + curreg->getMemSize()))
1469       {
1470          first = ((first + last) / 2) + 1;
1471       }
1472       else 
1473       {  // "where" is in the range: 
1474          // [memOffset + diskSize , memOffset + memSize)
1475          // meaning that it's in an uninitialized data region 
1476          return false;
1477       }
1478    }
1479
1480    return false;
1481 }
1482
1483 /* Performs a binary search on the dataRegions_ vector, which must
1484  * be kept in sorted order */
1485 bool Symtab::isData(const Offset where)  const
1486 {
1487    if (!dataRegions_.size()) 
1488    {
1489       fprintf(stderr, "%s[%d] No data regions in %s \n",
1490             __FILE__,__LINE__,mf->filename().c_str());
1491       return false;
1492    }
1493
1494    int first = 0; 
1495    int last = dataRegions_.size() - 1;
1496
1497    while (last >= first) 
1498    {
1499       Region *curreg = dataRegions_[(first + last) / 2];
1500
1501       if (     (where >= curreg->getRegionAddr())
1502             && (where < (curreg->getRegionAddr() + curreg->getRegionSize())))
1503       {
1504          return true;
1505       }
1506       else if (where < curreg->getRegionAddr()) 
1507       {
1508          last = ((first + last) / 2) - 1;
1509       }
1510       else 
1511       {
1512          first = ((first + last) / 2) + 1;
1513       }
1514    }
1515
1516    return false;
1517 }
1518
1519 SYMTAB_EXPORT bool Symtab::getFuncBindingTable(std::vector<relocationEntry> &fbt) const
1520 {
1521    fbt = relocation_table_;
1522    return true;
1523 }
1524
1525 SYMTAB_EXPORT bool Symtab::updateFuncBindingTable(Offset stub_addr, Offset plt_addr)
1526 {
1527     int stub_idx = -1, plt_idx = -1;
1528
1529     for (int i = 0; i < relocation_table_.size(); ++i) {
1530         if (stub_addr == relocation_table_[i].target_addr())
1531             stub_idx = i;
1532         if (plt_addr  == relocation_table_[i].target_addr())
1533             plt_idx = i;
1534         if (stub_addr >= 0 && plt_addr >= 0)
1535             break;
1536     }
1537     if (stub_idx >= 0 && plt_idx >= 0) {
1538         relocation_table_[stub_idx] = relocation_table_[plt_idx];
1539         relocation_table_[stub_idx].setTargetAddr(stub_addr);
1540         return true;
1541     }
1542     return false;
1543 }
1544
1545 SYMTAB_EXPORT std::vector<std::string> &Symtab::getDependencies(){
1546     return deps_;
1547 }
1548
1549
1550 Symtab::~Symtab()
1551 {
1552    // Doesn't do anything yet, moved here so we don't mess with symtab.h
1553    // Only called if we fail to create a process.
1554    // Or delete the a.out...
1555
1556 #if 1 
1557
1558    for (unsigned i = 0; i < regions_.size(); i++) 
1559    {
1560       delete regions_[i];
1561    }
1562
1563    regions_.clear();
1564    codeRegions_.clear();
1565    dataRegions_.clear();
1566    regionsByEntryAddr.clear();
1567
1568    std::vector<Region *> *user_regions = NULL;
1569    getAnnotation(user_regions, UserRegionsAnno);
1570
1571    if (user_regions)
1572    {
1573       for (unsigned i = 0; i < user_regions->size(); ++i) 
1574          delete (*user_regions)[i];
1575       user_regions->clear();
1576    }
1577
1578    // Symbols are copied from linkedFile, and NOT deleted
1579    everyDefinedSymbol.clear();
1580    undefDynSyms.clear();
1581
1582    // TODO make annotation
1583    userAddedSymbols.clear();
1584    symsByOffset.clear();
1585    symsByMangledName.clear();
1586    symsByPrettyName.clear();
1587    symsByTypedName.clear();
1588
1589    for (unsigned i = 0; i < everyFunction.size(); i++) 
1590    {
1591       delete everyFunction[i];
1592    }
1593
1594    everyFunction.clear();
1595    funcsByOffset.clear();
1596
1597    for (unsigned i = 0; i < everyVariable.size(); i++) 
1598    {
1599       delete everyVariable[i];
1600    }
1601
1602    everyVariable.clear();
1603    varsByOffset.clear();
1604
1605    for (unsigned i = 0; i < _mods.size(); i++) 
1606    {
1607       delete _mods[i];
1608    }
1609    _mods.clear();
1610    modsByFileName.clear();
1611    modsByFullName.clear();
1612
1613    for (unsigned i=0;i<excpBlocks.size();i++)
1614       delete excpBlocks[i];
1615
1616    create_printf("%s[%d]: Symtab::~Symtab removing %p from allSymtabs\n", 
1617          FILE__, __LINE__, this);
1618
1619    deps_.clear();
1620
1621    for (unsigned i = 0; i < allSymtabs.size(); i++) 
1622    {
1623       if (allSymtabs[i] == this)
1624          allSymtabs.erase(allSymtabs.begin()+i);
1625    }
1626
1627    //fprintf(stderr, "%s[%d]:  symtab DTOR, mf = %p: %s\n", FILE__, __LINE__, mf, mf->filename().c_str());
1628    if (mf) MappedFile::closeMappedFile(mf);
1629    //if (mfForDebugInfo) MappedFile::closeMappedFile(mfForDebugInfo);
1630 #endif
1631 }       
1632
1633 bool Symtab::exportXML(string file)
1634 {
1635 #if defined (cap_serialization)
1636    try 
1637    {
1638            SerContext<Symtab> *scs = new SerContext<Symtab>(this, file);
1639            serialize(file, scs, ser_xml);
1640 #if 0
1641            SerContext<Symtab> *scs = new SerContext<Symtab>(this);
1642            SerializerXML *ser = new SerializerXML(scs, "XMLTranslator", file, sd_serialize, true);
1643            serialize(ser, "Symtab");
1644 #endif
1645 #if 0
1646       SerializerXML sb("XMLTranslator", file, sd_serialize, true);
1647       serialize(&sb, "Symtab");
1648 #endif
1649    } 
1650    catch (const SerializerError &err) 
1651    {
1652       fprintf(stderr, "%s[%d]: error serializing xml: %s\n", FILE__, __LINE__, err.what());
1653       return false;
1654    }
1655
1656    return false;
1657 #else
1658    fprintf(stderr, "%s[%d]:  WARNING:  cannot produce %s, serialization not available\n", FILE__, __LINE__, file.c_str());
1659    return false;
1660 #endif
1661 }
1662
1663 #if defined (cap_serialization)
1664 bool Symtab::exportBin(string file)
1665 {
1666    try
1667    {
1668            SerContext<Symtab> *scs = new SerContext<Symtab>(this, file);
1669            serialize(file, scs, ser_bin);
1670            //fprintf(stderr, "%s[%d]:  did serialize\n", FILE__, __LINE__);
1671            return true;
1672    }
1673
1674    catch (const SerializerError &err)
1675    {
1676       if (err.code() == SerializerError::ser_err_disabled) 
1677       {
1678          fprintf(stderr, "%s[%d]:  WARN:  serialization is disabled for file %s\n",
1679                FILE__, __LINE__, file.c_str());
1680          return false;
1681       }
1682
1683       fprintf(stderr, "%s[%d]: %s\n\tfrom: %s[%d]\n", FILE__, __LINE__,
1684             err.what(), err.file().c_str(), err.line());
1685    }
1686
1687    fprintf(stderr, "%s[%d]:  error doing binary serialization\n", __FILE__, __LINE__);
1688    return false;
1689 }
1690 #else
1691 bool Symtab::exportBin(string) 
1692 {
1693    fprintf(stderr, "%s[%d]:  WARNING:  serialization not available\n", FILE__, __LINE__);
1694    return false;
1695 }
1696 #endif
1697
1698 Symtab *Symtab::importBin(std::string file)
1699 {
1700 #if defined (cap_serialization)
1701    MappedFile *mf= MappedFile::createMappedFile(file);
1702    if (!mf) 
1703    {
1704       fprintf(stderr, "%s[%d]:  failed to map file %s\n", FILE__, __LINE__, file.c_str());
1705       return NULL;
1706    }
1707
1708    Symtab *st = new Symtab(mf);
1709
1710    try
1711    {
1712            SerContext<Symtab> *scs = new SerContext<Symtab>(st, file);
1713            if (!st->deserialize(file, scs))
1714            {
1715                    delete st;
1716                    return NULL;
1717            }
1718
1719            return st;
1720    }
1721
1722    catch (const SerializerError &err)
1723    {
1724       if (err.code() == SerializerError::ser_err_disabled) 
1725       {
1726          serialize_printf("%s[%d]:  WARN:  serialization is disabled for file %s\n",
1727                FILE__, __LINE__, file.c_str());
1728          fprintf(stderr, "%s[%d]:  WARN:  serialization is disabled for file %s\n",
1729                FILE__, __LINE__, file.c_str());
1730          return NULL;
1731       }
1732
1733       serialize_printf("%s[%d]: %s\n\tfrom: %s[%d]\n", FILE__, __LINE__,
1734             err.what(), err.file().c_str(), err.line());
1735       fprintf(stderr, "%s[%d]: %s\n\tfrom: %s[%d]\n", FILE__, __LINE__,
1736             err.what(), err.file().c_str(), err.line());
1737    }
1738
1739
1740    serialize_printf("%s[%d]:  error doing binary deserialization\n", __FILE__, __LINE__);
1741    delete st;
1742    return NULL;
1743 #else
1744    serialize_printf("%s[%d]:  WARNING:  cannot produce %s, serialization not available\n", FILE__, __LINE__, file.c_str());
1745    return NULL;
1746 #endif
1747 }
1748
1749
1750 bool Symtab::openFile(Symtab *&obj, char *mem_image, size_t size)
1751 {
1752    bool err = false;
1753 #if defined(TIMED_PARSE)
1754    struct timeval starttime;
1755    gettimeofday(&starttime, NULL);
1756 #endif
1757
1758    obj = new Symtab(mem_image, size, err);
1759
1760 #if defined(TIMED_PARSE)
1761     struct timeval endtime;
1762     gettimeofday(&endtime, NULL);
1763     unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
1764     unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
1765     unsigned long difftime = lendtime - lstarttime;
1766     double dursecs = difftime/(1000 );
1767     cout << __FILE__ << ":" << __LINE__ <<": openFile "<< filename<< " took "<<dursecs <<" msecs" << endl;
1768 #endif
1769     if(!err)
1770     {
1771        allSymtabs.push_back(obj);
1772        obj->setupTypes();       
1773     }
1774     else
1775     {
1776         delete obj;
1777        obj = NULL;
1778     }
1779     // returns true on success (not an error)
1780     return !err;
1781 }
1782
1783 bool Symtab::closeSymtab(Symtab *st)
1784 {
1785         bool found = false;
1786         if (!st) return false;
1787
1788         std::vector<Symtab *>::reverse_iterator iter;
1789         for (iter = allSymtabs.rbegin(); iter != allSymtabs.rend() ; iter++)
1790         {
1791                 if (*iter == st)
1792                 {
1793                         allSymtabs.erase(iter.base() -1);
1794                         found = true;
1795                 }
1796         }
1797         delete(st);
1798         return found;
1799 }
1800
1801 Symtab *Symtab::findOpenSymtab(std::string filename)
1802 {
1803    unsigned numSymtabs = allSymtabs.size();
1804         for (unsigned u=0; u<numSymtabs; u++) 
1805         {
1806                 assert(allSymtabs[u]);
1807                 if (filename == allSymtabs[u]->file() && 
1808           allSymtabs[u]->mf->canBeShared()) 
1809                 {
1810                         // return it
1811                         return allSymtabs[u];
1812                 }
1813         }   
1814         return NULL;
1815 }
1816
1817 bool Symtab::openFile(Symtab *&obj, std::string filename)
1818 {
1819    bool err = false;
1820 #if defined(TIMED_PARSE)
1821    struct timeval starttime;
1822    gettimeofday(&starttime, NULL);
1823 #endif
1824
1825    // AIX: it's possible that we're reparsing a file with better information
1826    // about it. If so, yank the old one out of the allSymtabs std::vector -- replace
1827    // it, basically.
1828    if ( filename.find("/proc") == std::string::npos)
1829    {
1830            obj = findOpenSymtab(filename);
1831            if (obj)
1832            {
1833                    //fprintf(stderr, "%s[%d]:  have existing symtab obj for %s\n", FILE__, __LINE__, filename.c_str());
1834                    return true;
1835    }
1836    }
1837
1838
1839 #if defined (cap_serialization)
1840    obj = importBin(filename);
1841
1842    if (NULL == obj) 
1843    {
1844            if (deserializeEnforced<Symtab>(filename))
1845           {
1846                           serialize_printf("%s[%d]: aborting new symtab, expected deserialize failed\n",
1847                                           FILE__, __LINE__);
1848                           fprintf(stderr, "%s[%d]: aborting new symtab, expected deserialize failed\n",
1849                                           FILE__, __LINE__);
1850                           return false;
1851           }
1852            //fprintf(stderr, "%s[%d]:  deserialize failed, but not enforced for %s\n", FILE__, __LINE__, filename.c_str());
1853    }
1854    else 
1855    {
1856           //fprintf(stderr, "%s[%d]:  deserialize success\n", FILE__, __LINE__);
1857       return true;
1858    }
1859 #endif
1860
1861    obj = new Symtab(filename, err);
1862 #if defined(TIMED_PARSE)
1863    struct timeval endtime;
1864    gettimeofday(&endtime, NULL);
1865    unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
1866    unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
1867    unsigned long difftime = lendtime - lstarttime;
1868    double dursecs = difftime/(1000 );
1869    cout << __FILE__ << ":" << __LINE__ <<": openFile "<< filename<< " took "<<dursecs <<" msecs" << endl;
1870 #endif
1871
1872    if (!err)
1873    {
1874       if (filename.find("/proc") == std::string::npos)
1875          allSymtabs.push_back(obj);
1876
1877       obj->setupTypes();        
1878
1879 #if defined (cap_serialization)
1880       serialize_printf("%s[%d]:  doing bin-serialize for %s\n", 
1881             FILE__, __LINE__, filename.c_str());
1882
1883       if (!obj->exportBin(filename))
1884       {
1885          serialize_printf("%s[%d]:  failed to export symtab\n", FILE__, __LINE__);
1886       }
1887       else
1888          serialize_printf("%s[%d]:  did bin-serialize for %s\n", 
1889                FILE__, __LINE__, filename.c_str());
1890 #endif
1891
1892     }
1893     else
1894     {
1895        create_printf("%s[%d]: WARNING: failed to open symtab for %s\n", 
1896              FILE__, __LINE__, filename.c_str());
1897        delete obj;
1898        obj = NULL;
1899     }
1900
1901    // returns true on success (not an error)
1902    return !err;
1903 }
1904
1905 bool Symtab::addRegion(Offset vaddr, void *data, unsigned int dataSize, std::string name, Region::RegionType rType_, bool loadable)
1906 {
1907    Region *sec;
1908    unsigned i;
1909    if (loadable)
1910    {
1911       sec = new Region(newSectionInsertPoint, name, vaddr, dataSize, vaddr, 
1912             dataSize, (char *)data, Region::RP_R, rType_, true);
1913
1914       regions_.insert(regions_.begin()+newSectionInsertPoint, sec);
1915
1916       for (i = newSectionInsertPoint+1; i < regions_.size(); i++)
1917       {
1918          regions_[i]->setRegionNumber(regions_[i]->getRegionNumber() + 1);
1919       }
1920
1921       if (    (sec->getRegionType() == Region::RT_TEXT) 
1922             || (sec->getRegionType() == Region::RT_TEXTDATA))
1923       {
1924          codeRegions_.push_back(sec);
1925          std::sort(codeRegions_.begin(), codeRegions_.end(), sort_reg_by_addr);
1926       }
1927
1928       if (    (sec->getRegionType() == Region::RT_DATA) 
1929             || (sec->getRegionType() == Region::RT_TEXTDATA))
1930       {
1931          dataRegions_.push_back(sec);
1932          std::sort(dataRegions_.begin(), dataRegions_.end(), sort_reg_by_addr);
1933       }
1934    }
1935    else
1936    {
1937       sec = new Region(regions_.size()+1, name, vaddr, dataSize, 0, 0, 
1938             (char *)data, Region::RP_R, rType_);
1939       regions_.push_back(sec);
1940    }
1941
1942    addUserRegion(sec);
1943    std::sort(regions_.begin(), regions_.end(), sort_reg_by_addr);
1944    return true;
1945 }
1946
1947 bool Symtab::addUserRegion(Region *reg)
1948 {
1949    std::vector<Region *> *user_regions = NULL;
1950
1951    if (!getAnnotation(user_regions, UserRegionsAnno))
1952    {
1953       user_regions = new std::vector<Region *>();
1954       if (!addAnnotation(user_regions, UserRegionsAnno))
1955       {
1956          fprintf(stderr, "%s[%d]:  failed to addAnnotation here\n", FILE__, __LINE__);
1957          return false;
1958       }
1959    }
1960
1961    if (!user_regions)
1962    {
1963       fprintf(stderr, "%s[%d]:  failed to addAnnotation here\n", FILE__, __LINE__);
1964       return false;
1965    }
1966
1967    user_regions->push_back(reg);
1968
1969    return true;
1970 }
1971
1972 bool Symtab::addUserType(Type *t)
1973 {
1974    std::vector<Type *> *user_types = NULL;
1975
1976    //  need to change this to something based on AnnotationContainer
1977    //  for it to work with serialization
1978    if (!getAnnotation(user_types, UserTypesAnno))
1979    {
1980       user_types = new std::vector<Type *>();
1981       if (!addAnnotation(user_types, UserTypesAnno))
1982       {
1983          fprintf(stderr, "%s[%d]:  failed to addAnnotation here\n", FILE__, __LINE__);
1984          return false;
1985       }
1986    }
1987    if (!user_types)
1988    {
1989       fprintf(stderr, "%s[%d]:  failed to addAnnotation here\n", FILE__, __LINE__);
1990       return false;
1991    }
1992
1993    user_types->push_back(t);
1994
1995    return true;
1996 }
1997
1998 bool Symtab::addRegion(Region *sec)
1999 {
2000    regions_.push_back(sec);
2001    std::sort(regions_.begin(), regions_.end(), sort_reg_by_addr);
2002    addUserRegion(sec);
2003    return true;
2004 }
2005
2006 void Symtab::parseLineInformation()
2007 {
2008    dyn_hash_map<std::string, LineInformation> *lineInfo = new dyn_hash_map <std::string, LineInformation>;
2009
2010
2011    Object *linkedFile = getObject();
2012         if (!linkedFile)
2013         {
2014                 fprintf(stderr, "%s[%d]:  getObject failed here\n", FILE__, __LINE__);
2015                 return;
2016         }
2017    linkedFile->parseFileLineInfo(this, *lineInfo);
2018
2019    isLineInfoValid_ = true;     
2020    dyn_hash_map <std::string, LineInformation>::iterator iter;
2021
2022    for (iter = lineInfo->begin(); iter!=lineInfo->end(); iter++)
2023    {
2024       Module *mod = NULL;
2025       bool result = findModuleByName(mod, iter->first);
2026       if (!result) {
2027          mod = getDefaultModule();
2028       }
2029
2030          LineInformation *lineInformation = mod->getLineInformation();
2031          if (!lineInformation) 
2032          {
2033             mod->setLineInfo(&(iter->second));
2034          } 
2035          else 
2036          {
2037             lineInformation->addLineInfo(&(iter->second));
2038             mod->setLineInfo(lineInformation);
2039          }
2040       }
2041 }
2042
2043 SYMTAB_EXPORT bool Symtab::getAddressRanges(std::vector<pair<Offset, Offset> >&ranges,
2044       std::string lineSource, unsigned int lineNo)
2045 {
2046    unsigned int originalSize = ranges.size();
2047
2048    /* Iteratate over the modules, looking for ranges in each. */
2049
2050    for ( unsigned int i = 0; i < _mods.size(); i++ ) 
2051    {
2052       LineInformation *lineInformation = _mods[i]->getLineInformation();
2053
2054       if (lineInformation)
2055          lineInformation->getAddressRanges( lineSource.c_str(), lineNo, ranges );
2056
2057    } /* end iteration over modules */
2058
2059    if ( ranges.size() != originalSize )
2060       return true;
2061
2062    fprintf(stderr, "%s[%d]:  failing to getAdressRanges for %s[%d]\n", FILE__, __LINE__, lineSource.c_str(), lineNo);
2063    return false;
2064 }
2065
2066 SYMTAB_EXPORT bool Symtab::getSourceLines(std::vector<Statement *> &lines, Offset addressInRange)
2067 {
2068    unsigned int originalSize = lines.size();
2069
2070    /* Iteratate over the modules, looking for ranges in each. */
2071    for ( unsigned int i = 0; i < _mods.size(); i++ ) 
2072    {
2073       LineInformation *lineInformation = _mods[i]->getLineInformation();
2074
2075       if (lineInformation)
2076          lineInformation->getSourceLines( addressInRange, lines );
2077
2078    } /* end iteration over modules */
2079
2080    if ( lines.size() != originalSize )
2081       return true;
2082
2083    return false;
2084
2085 }
2086
2087 SYMTAB_EXPORT bool Symtab::addLine(std::string lineSource, unsigned int lineNo,
2088       unsigned int lineOffset, Offset lowInclAddr,
2089       Offset highExclAddr)
2090 {
2091    Module *mod;
2092
2093    if (!findModuleByName(mod, lineSource))
2094    {
2095       std::string fileNm = extract_pathname_tail(lineSource);
2096
2097       if (!findModuleByName(mod, fileNm))
2098       {
2099          if (!findModuleByName(mod, mf->pathname()))
2100             return false;
2101       }    
2102    }
2103
2104    LineInformation *lineInfo = mod->getLineInformation();
2105
2106    if (!lineInfo)
2107       return false;
2108
2109    return (lineInfo->addLine(lineSource.c_str(), lineNo, lineOffset, 
2110             lowInclAddr, highExclAddr));
2111 }
2112
2113 SYMTAB_EXPORT bool Symtab::addAddressRange( Offset lowInclusiveAddr, Offset highExclusiveAddr,
2114       std::string lineSource, unsigned int lineNo,
2115       unsigned int lineOffset)
2116 {
2117    Module *mod;
2118
2119    if (!findModuleByName(mod, lineSource))
2120    {
2121       std::string fileNm = extract_pathname_tail(lineSource);
2122
2123       if (!findModuleByName(mod, fileNm))
2124          return false;
2125    }
2126
2127    LineInformation *lineInfo = mod->getLineInformation();
2128
2129    if (!lineInfo)
2130       return false;
2131
2132    return (lineInfo->addAddressRange(lowInclusiveAddr, highExclusiveAddr, 
2133             lineSource.c_str(), lineNo, lineOffset));
2134 }
2135
2136
2137 void Symtab::parseTypes()
2138 {
2139    Object *linkedFile = getObject();
2140         if (!linkedFile)
2141         {
2142                 fprintf(stderr, "%s[%d]:  getObject failed here\n", FILE__, __LINE__);
2143                 return;
2144         }
2145    linkedFile->parseTypeInfo(this);
2146    isTypeInfoValid_ = true;
2147
2148    for (unsigned int i = 0; i < _mods.size(); ++i)
2149    {
2150            typeCollection *tc = typeCollection::getModTypeCollection(_mods[i]);
2151
2152            if (!_mods[i]->addAnnotation(tc, ModuleTypeInfoAnno))
2153            {
2154                    fprintf(stderr, "%s[%d]:  failed to addAnnotation here\n", FILE__, __LINE__);
2155            }
2156    }
2157
2158    //  optionally we might want to clear the static data struct in typeCollection
2159    //  here....  the parsing is over, and we have added all typeCollections as
2160    //  annotations proper.
2161
2162    typeCollection::fileToTypesMap.clear();
2163
2164 }
2165
2166 bool Symtab::addType(Type *type)
2167 {
2168   bool result = addUserType(type);
2169   if (!result)
2170     return false;
2171
2172   return true;
2173 }
2174
2175 SYMTAB_EXPORT vector<Type *> *Symtab::getAllstdTypes()
2176 {
2177    setupStdTypes();
2178    return stdTypes->getAllTypes();      
2179 }
2180
2181 SYMTAB_EXPORT vector<Type *> *Symtab::getAllbuiltInTypes()
2182 {
2183    setupStdTypes();
2184    return builtInTypes->getAllBuiltInTypes();
2185 }
2186
2187 SYMTAB_EXPORT bool Symtab::findType(Type *&type, std::string name)
2188 {
2189    parseTypesNow();
2190
2191    if (!_mods.size())
2192       return false;
2193
2194    for (unsigned int i = 0; i < _mods.size(); ++i)
2195    {
2196            typeCollection *tc = _mods[i]->getModuleTypes();
2197            if (!tc) continue;
2198            type = tc->findType(name);
2199            if (type) return true;
2200    }
2201
2202    if (type == NULL)
2203       return false;
2204
2205    return true; 
2206 }
2207
2208 SYMTAB_EXPORT Type *Symtab::findType(unsigned type_id)
2209 {
2210         Type *t = NULL;
2211    parseTypesNow();
2212
2213    if (!_mods.size())
2214    {
2215            //fprintf(stderr, "%s[%d]:  findType failing due to lack of modules\n", FILE__, __LINE__);
2216       return NULL;
2217    }
2218
2219    for (unsigned int i = 0; i < _mods.size(); ++i)
2220    {
2221            typeCollection *tc = _mods[i]->getModuleTypes();
2222            if (!tc) continue;
2223            t = tc->findType(type_id);
2224            if (t)  break;
2225    }
2226
2227    if (t == NULL)
2228    {
2229            if (builtInTypes)
2230            {
2231                    t = builtInTypes->findBuiltInType(type_id);
2232                    if (t) return t;
2233            }
2234            else
2235            {
2236                    //fprintf(stderr, "%s[%d]:  no built in types!\n", FILE__, __LINE__);
2237            }
2238
2239            if (stdTypes)
2240            {
2241                    t = stdTypes->findType(type_id);
2242                    if (t) return t;
2243            }
2244            else
2245            {
2246                    //fprintf(stderr, "%s[%d]:  no std types!\n", FILE__, __LINE__);
2247            }
2248
2249            return NULL;
2250    }
2251
2252    return t;    
2253 }
2254
2255 SYMTAB_EXPORT bool Symtab::findVariableType(Type *&type, std::string name)
2256 {
2257    parseTypesNow();
2258
2259    if (!_mods.size())
2260       return false;
2261
2262
2263    for (unsigned int i = 0; i < _mods.size(); ++i)
2264    {
2265            typeCollection *tc = _mods[i]->getModuleTypes();
2266            if (!tc) continue;
2267            type = tc->findVariableType(name);
2268            if (type) break;
2269    }
2270
2271    if (type == NULL)
2272       return false;
2273
2274    return true; 
2275 }
2276
2277 SYMTAB_EXPORT bool Symtab::findLocalVariable(std::vector<localVar *>&vars, std::string name)
2278 {
2279    parseTypesNow();
2280    unsigned origSize = vars.size();
2281
2282    for (unsigned i = 0; i < everyFunction.size(); i++)
2283    {
2284       everyFunction[i]->findLocalVariable(vars, name);
2285    }
2286
2287    if (vars.size()>origSize)
2288       return true;
2289
2290    return false;        
2291 }
2292
2293 SYMTAB_EXPORT bool Symtab::hasRel() const
2294 {
2295    return hasRel_;
2296 }
2297
2298 SYMTAB_EXPORT bool Symtab::hasRela() const
2299 {
2300    return hasRela_;
2301 }
2302
2303 SYMTAB_EXPORT bool Symtab::hasReldyn() const
2304 {
2305    return hasReldyn_;
2306 }
2307
2308 SYMTAB_EXPORT bool Symtab::hasReladyn() const
2309 {
2310    return hasReladyn_;
2311 }
2312
2313 SYMTAB_EXPORT bool Symtab::hasRelplt() const
2314 {
2315    return hasRelplt_;
2316 }
2317
2318 SYMTAB_EXPORT bool Symtab::hasRelaplt() const
2319 {
2320    return hasRelaplt_;
2321 }
2322
2323 SYMTAB_EXPORT bool Symtab::isStaticBinary() const
2324 {
2325    return isStaticBinary_;
2326 }
2327
2328 bool Symtab::setDefaultNamespacePrefix(string &str)
2329 {
2330    defaultNamespacePrefix = str;
2331    return true;
2332 }
2333
2334 SYMTAB_EXPORT bool Symtab::emitSymbols(Object *linkedFile,std::string filename, unsigned flag)
2335 {
2336     // Start with all the defined symbols
2337     std::vector<Symbol *> allSyms;
2338     for (unsigned i = 0; i < everyDefinedSymbol.size(); i++) {
2339         allSyms.push_back(everyDefinedSymbol[i]);
2340     }
2341
2342     // Add the undefined dynamic symbols
2343     map<string, std::vector<Symbol *> >::iterator iter;
2344     std::vector<Symbol *>::iterator siter;
2345
2346     for (iter = undefDynSyms.begin(); iter != undefDynSyms.end(); iter++)
2347         for (siter=iter->second.begin(); siter != iter->second.end(); siter++)
2348             allSyms.push_back(*siter);
2349
2350     // Write the new file
2351     return linkedFile->emitDriver(this, filename, allSyms, flag);
2352 }
2353
2354 SYMTAB_EXPORT bool Symtab::emit(std::string filename, unsigned flag)
2355 {
2356         Object *obj = getObject();
2357         if (!obj)
2358         {
2359                 fprintf(stderr, "%s[%d]:  getObject failed here\n", FILE__, __LINE__);
2360                 return false;
2361         }
2362    obj->mf->setSharing(false);
2363    return emitSymbols(obj, filename, flag);
2364 }
2365
2366 SYMTAB_EXPORT void Symtab::addDynLibSubstitution(std::string oldName, std::string newName)
2367 {
2368    dynLibSubs[oldName] = newName;
2369 }
2370
2371 SYMTAB_EXPORT std::string Symtab::getDynLibSubstitution(std::string name)
2372 {
2373 #ifdef BINEDIT_DEBUG
2374    map<std::string, std::string>::iterator iter = dynLibSubs.begin();
2375
2376    printf ("substitutions for %s:\n", mf->filename().c_str());
2377
2378    while (iter != dynLibSubs.end()) 
2379    {
2380       printf("  \"%s\" => \"%s\"\n", iter->first.c_str(), iter->second.c_str());
2381       iter++;
2382    }
2383 #endif
2384
2385    map<std::string, std::string>::iterator loc = dynLibSubs.find(name);
2386
2387    if (loc == dynLibSubs.end())
2388       return name;
2389    else
2390       return loc->second;
2391 }
2392
2393 SYMTAB_EXPORT bool Symtab::getSegments(vector<Segment> &segs) const
2394 {
2395    segs = segments_;
2396
2397    if (!segments_.size()) 
2398       return false;
2399
2400    return true;
2401 }
2402
2403 SYMTAB_EXPORT bool Symtab::getMappedRegions(std::vector<Region *> &mappedRegs) const
2404 {
2405    unsigned origSize = mappedRegs.size();
2406
2407    for (unsigned i = 0; i < regions_.size(); i++)
2408    {
2409       if (regions_[i]->isLoadable())
2410          mappedRegs.push_back(regions_[i]);
2411    }
2412
2413    if (mappedRegs.size() > origSize)
2414       return true;
2415
2416    return false;
2417 }
2418
2419 SYMTAB_EXPORT bool Symtab::updateRegion(const char* name, void *buffer, unsigned size)
2420 {
2421    Region *sec;
2422
2423    if (!findRegion(sec, name))
2424       return false;
2425
2426    sec->setPtrToRawData(buffer, size);
2427
2428    return true;
2429 }
2430
2431 SYMTAB_EXPORT bool Symtab::updateCode(void *buffer, unsigned size)
2432 {
2433   return updateRegion(".text", buffer, size);
2434 }
2435
2436 SYMTAB_EXPORT bool Symtab::updateData(void *buffer, unsigned size)
2437 {
2438   return updateRegion(".data", buffer, size);
2439 }
2440
2441 SYMTAB_EXPORT Offset Symtab::getFreeOffset(unsigned size) 
2442 {
2443    // Look through sections until we find a gap with
2444    // sufficient space.
2445    Offset highWaterMark = 0;
2446    Offset secoffset = 0;
2447    Offset prevSecoffset = 0;
2448
2449    Object *linkedFile = getObject();
2450         if (!linkedFile)
2451         {
2452                 fprintf(stderr, "%s[%d]:  getObject failed here\n", FILE__, __LINE__);
2453                 return 0;
2454         }
2455
2456    for (unsigned i = 0; i < regions_.size(); i++) 
2457    {
2458       //Offset end = regions_[i]->getRegionAddr() + regions_[i]->getDiskSize();
2459       Offset end = regions_[i]->getRegionAddr() + regions_[i]->getRegionSize();
2460       if (regions_[i]->getRegionAddr() == 0) 
2461          continue;
2462
2463       prevSecoffset = secoffset;
2464
2465       unsigned region_offset = (unsigned)((char *)(regions_[i]->getPtrToRawData())
2466                                           - linkedFile->mem_image());
2467
2468       if (region_offset < (unsigned)prevSecoffset)
2469       {
2470          //secoffset += regions_[i]->getDiskSize();
2471          secoffset += regions_[i]->getRegionSize();
2472       }
2473       else 
2474       {
2475          secoffset = (char *)(regions_[i]->getPtrToRawData()) - linkedFile->mem_image();
2476          //secoffset += regions_[i]->getDiskSize();
2477          secoffset += regions_[i]->getRegionSize();
2478       }
2479
2480       /*fprintf(stderr, "%d: secAddr 0x%lx, size %d, end 0x%lx, looking for %d\n",
2481         i, regions_[i]->getSecAddr(), regions_[i]->getSecSize(),
2482         end,size);*/
2483
2484       if (end > highWaterMark) 
2485       {
2486          //fprintf(stderr, "Increasing highWaterMark...\n");
2487          newSectionInsertPoint = i+1;
2488          highWaterMark = end;
2489       }
2490
2491       if (     (i < (regions_.size()-2)) 
2492                && ((end + size) < regions_[i+1]->getRegionAddr())) 
2493       {
2494          /*      fprintf(stderr, "Found a hole between sections %d and %d\n",
2495                  i, i+1);
2496                  fprintf(stderr, "End at 0x%lx, next one at 0x%lx\n",
2497                  end, regions_[i+1]->getSecAddr());
2498          */   
2499          newSectionInsertPoint = i+1;
2500          highWaterMark = end;
2501          break;
2502       }
2503    }
2504
2505    //   return highWaterMark;
2506 #if defined (os_windows)
2507         Object *obj = getObject();
2508         if (!obj)
2509         {
2510                 fprintf(stderr, "%s[%d]:  getObject failed here\n", FILE__, __LINE__);
2511                 return 0;
2512         }
2513         unsigned pgSize = obj->getSecAlign();
2514         //printf("pgSize:0x%x\n", pgSize);
2515         Offset newaddr = highWaterMark  - (highWaterMark & (pgSize-1));
2516         while(newaddr < highWaterMark)
2517       newaddr += pgSize;
2518         //printf("getfreeoffset:%lu\n", newaddr);
2519         return newaddr;
2520
2521 #else
2522         unsigned pgSize = P_getpagesize();
2523         Offset newaddr = highWaterMark  - (highWaterMark & (pgSize-1));
2524         if(newaddr < highWaterMark)
2525                 newaddr += pgSize;
2526
2527    return newaddr;
2528 #endif  
2529 }
2530
2531 SYMTAB_EXPORT ObjectType Symtab::getObjectType() const 
2532 {
2533    return object_type_;
2534 }
2535
2536 SYMTAB_EXPORT char *Symtab::mem_image() const 
2537 {
2538    return (char *)mf->base_addr();
2539 }
2540
2541 SYMTAB_EXPORT std::string Symtab::file() const 
2542 {
2543    assert(mf);
2544    return mf->pathname();
2545 }
2546
2547 SYMTAB_EXPORT std::string Symtab::name() const 
2548 {
2549    return mf->filename();
2550 }
2551
2552 SYMTAB_EXPORT unsigned Symtab::getNumberofRegions() const 
2553 {
2554    return no_of_sections; 
2555 }
2556
2557 SYMTAB_EXPORT unsigned Symtab::getNumberofSymbols() const 
2558 {
2559    return no_of_symbols; 
2560 }
2561
2562 bool Symtab::setup_module_up_ptrs(SerializerBase *, Symtab *st)
2563 {
2564    std::vector<Module *> &mods = st->_mods;
2565
2566    for (unsigned int i = 0; i < mods.size(); ++i) 
2567    {
2568       Module *m = mods[i];
2569       m->exec_ = st;
2570    }
2571
2572    return true;
2573 }
2574
2575 bool Symtab::fixup_relocation_symbols(SerializerBase *, Symtab *st)
2576 {
2577    std::vector<Module *> &mods = st->_mods;
2578
2579    for (unsigned int i = 0; i < mods.size(); ++i) 
2580    {
2581       Module *m = mods[i];
2582       m->exec_ = st;
2583    }
2584
2585    return true;
2586 }
2587
2588 void Symtab::rebuild_symbol_hashes(SerializerBase *sb)
2589 {
2590         if (!is_input(sb))
2591                 return;
2592
2593         for (unsigned long i = 0; i < everyDefinedSymbol.size(); ++i)
2594         {
2595                 Symbol *s = everyDefinedSymbol[i];
2596                 assert(s);
2597                 const std::string &pn = s->getPrettyName();
2598                 const std::string &mn = s->getMangledName();
2599                 const std::string tn = s->getTypedName();
2600
2601                 symsByPrettyName[pn].push_back(s);
2602                 symsByMangledName[mn].push_back(s);
2603                 symsByTypedName[tn].push_back(s);
2604                 symsByOffset[s->getOffset()].push_back(s);
2605         }
2606 }
2607
2608 void Symtab::rebuild_funcvar_hashes(SerializerBase *sb)
2609 {
2610         if (!is_input(sb))
2611                 return;
2612         for (unsigned int i = 0; i < everyFunction.size(); ++i)
2613         {
2614                 Function *f = everyFunction[i];
2615                 funcsByOffset[f->getOffset()] = f;
2616         }
2617         for (unsigned int i = 0; i < everyVariable.size(); ++i)
2618         {
2619                 Variable *v = everyVariable[i];
2620                 varsByOffset[v->getOffset()] = v;
2621         }
2622 }
2623 void Symtab::rebuild_module_hashes(SerializerBase *sb)
2624 {
2625         if (!is_input(sb))
2626                 return;
2627         for (unsigned int i = 0; i < _mods.size(); ++i)
2628         {
2629                 Module *m = _mods[i];
2630                 modsByFileName[m->fileName()] = m;
2631                 modsByFullName[m->fullName()] = m;
2632         }
2633 }
2634 void Symtab::rebuild_region_indexes(SerializerBase *sb) THROW_SPEC (SerializerError)
2635 {
2636         if (!is_input(sb))
2637                 return;
2638
2639         for (unsigned int i = 0; i < regions_.size(); ++i)
2640         {
2641                 Region *r = regions_[i];
2642
2643                 if (!r) SER_ERR("FIXME:  NULL REGION");
2644
2645                 if ( r->isLoadable() )
2646                 {
2647                         if ((r->getRegionPermissions() == Region::RP_RX)
2648                                         || (r->getRegionPermissions() == Region::RP_RWX))
2649                                 codeRegions_.push_back(r);
2650                         else
2651                                 dataRegions_.push_back(r);
2652                 }
2653
2654                 //  entry addr might require some special attn on windows, since it
2655                 //  is not the disk offset but the actual mem addr, which is going to be
2656                 //  different after deserialize.  Probably have to look it up again.
2657                 regionsByEntryAddr[r->getRegionAddr()] = r;
2658         }
2659
2660         std::sort(codeRegions_.begin(), codeRegions_.end(), sort_reg_by_addr);
2661         std::sort(dataRegions_.begin(), dataRegions_.end(), sort_reg_by_addr);
2662
2663
2664 }
2665
2666 Serializable *Symtab::serialize_impl(SerializerBase *sb, 
2667                 const char *tag) THROW_SPEC (SerializerError)
2668 {
2669         serialize_printf("%s[%d]:  welcome to Symtab::serialize_impl\n", 
2670                         FILE__, __LINE__);
2671         if (is_input(sb))
2672         {
2673                 //  don't bother with serializing standard and builtin types.
2674                 setupTypes();
2675         }
2676
2677         ifxml_start_element(sb, tag);
2678         gtranslate(sb, imageOffset_, "imageOffset");
2679         gtranslate(sb, imageLen_, "imageLen");
2680         gtranslate(sb, dataOffset_, "dataOff");
2681         gtranslate(sb, dataLen_, "dataLen");
2682         gtranslate(sb, is_a_out, "isExec");
2683         gtranslate(sb, _mods, "Modules", "Module");
2684         rebuild_module_hashes(sb);
2685         if (is_input(sb))
2686         {
2687                 //  problem:  if isTypeInfoValid_ is not true, we can trigger type parsing
2688                 //  for an object class that does not exist.  Need to introduce logic to 
2689                 //  recreate the object in this case
2690                 isTypeInfoValid_ = true;
2691                 isLineInfoValid_ = true; //  NOTE:  set this to true after deserializing at least one lineInformaton object
2692         }
2693         gtranslate(sb, regions_, "Regions", "Region");
2694         rebuild_region_indexes(sb);
2695         gtranslate(sb, everyDefinedSymbol, "EveryDefinedSymbol", "Symbol");
2696         rebuild_symbol_hashes(sb);
2697         gtranslate(sb, relocation_table_, "RelocationTable", "RelocationTableEntry");
2698         gtranslate(sb, everyFunction, "EveryFunction", "Function");
2699         gtranslate(sb, everyVariable, "EveryVariable", "Variable");
2700         rebuild_funcvar_hashes(sb);
2701
2702         //gtranslate(sb, everyUniqueVariable, "EveryUniqueVariable", "UniqueVariable");
2703         //gtranslate(sb, modSyms, "ModuleSymbols", "ModuleSymbol");
2704
2705         gtranslate(sb, excpBlocks, "ExceptionBlocks", "ExceptionBlock");
2706         ifxml_end_element(sb, tag);
2707
2708         sb->magic_check(FILE__, __LINE__);
2709 #if 0
2710         ifinput(Symtab::setup_module_up_ptrs, sb, this);
2711         ifinput(fixup_relocation_symbols, sb, this);
2712 #endif
2713
2714         if (is_input(sb))
2715         {
2716                 dyn_hash_map<Address, Symbol *> *map_p = NULL;
2717                 if (getAnnotation(map_p, IdToSymAnno) && (NULL != map_p))
2718                 {
2719                         if (!removeAnnotation(IdToSymAnno))
2720                         {
2721                                 fprintf(stderr, "%s[%d]:  failed to remove id-to-sym map\n", 
2722                                                 FILE__, __LINE__);
2723                         }
2724                         delete map_p;
2725                 }
2726         }
2727         serialize_printf("%s[%d]:  leaving Symtab::serialize_impl\n", FILE__, __LINE__);
2728         return NULL;
2729 }
2730
2731 SYMTAB_EXPORT LookupInterface::LookupInterface() 
2732 {
2733 }
2734
2735 SYMTAB_EXPORT LookupInterface::~LookupInterface()
2736 {
2737 }
2738
2739
2740 SYMTAB_EXPORT ExceptionBlock::ExceptionBlock(Offset tStart, 
2741       unsigned tSize, 
2742       Offset cStart) 
2743 : tryStart_(tStart), trySize_(tSize), catchStart_(cStart), hasTry_(true) 
2744 {
2745 }
2746
2747    SYMTAB_EXPORT ExceptionBlock::ExceptionBlock(Offset cStart) 
2748 : tryStart_(0), trySize_(0), catchStart_(cStart), hasTry_(false) 
2749 {
2750 }
2751
2752 SYMTAB_EXPORT ExceptionBlock::ExceptionBlock(const ExceptionBlock &eb) :
2753    Serializable(),
2754    tryStart_(eb.tryStart_), trySize_(eb.trySize_), 
2755    catchStart_(eb.catchStart_), hasTry_(eb.hasTry_) 
2756 {
2757 }
2758 SYMTAB_EXPORT bool ExceptionBlock::hasTry() const
2759
2760    return hasTry_; 
2761 }
2762
2763 SYMTAB_EXPORT Offset ExceptionBlock::tryStart() const
2764
2765    return tryStart_; 
2766 }
2767
2768 SYMTAB_EXPORT Offset ExceptionBlock::tryEnd() const
2769
2770    return tryStart_ + trySize_; 
2771 }
2772
2773 SYMTAB_EXPORT Offset ExceptionBlock::trySize() const
2774 {
2775    return trySize_; 
2776 }
2777
2778 SYMTAB_EXPORT bool ExceptionBlock::contains(Offset a) const
2779
2780    return (a >= tryStart_ && a < tryStart_ + trySize_); 
2781 }
2782
2783 Serializable * ExceptionBlock::serialize_impl(SerializerBase *sb, const char *tag) THROW_SPEC (SerializerError)
2784 {
2785         ifxml_start_element(sb, tag);
2786         gtranslate(sb, tryStart_, "tryStart");
2787         gtranslate(sb, trySize_, "trySize");
2788         gtranslate(sb, catchStart_, "catchStart");
2789         gtranslate(sb, hasTry_, "hasTry");
2790         ifxml_end_element(sb, tag);
2791         return NULL;
2792 }
2793
2794
2795 SYMTAB_EXPORT relocationEntry::relocationEntry() :
2796    target_addr_(0), 
2797    rel_addr_(0), 
2798    addend_(0), 
2799    rtype_(Region::RT_REL), 
2800    name_(""), 
2801    dynref_(NULL), 
2802    relType_(0)
2803 {
2804 }   
2805
2806 SYMTAB_EXPORT relocationEntry::relocationEntry(Offset ta, Offset ra, std::string n, 
2807       Symbol *dynref, unsigned long relType) :
2808    target_addr_(ta), 
2809    rel_addr_(ra), 
2810    addend_(0), 
2811    rtype_(Region::RT_REL), 
2812    name_(n), 
2813    dynref_(dynref), 
2814    relType_(relType)
2815 {
2816 }   
2817
2818 SYMTAB_EXPORT relocationEntry::relocationEntry(Offset ta, Offset ra, Offset add, 
2819       std::string n, Symbol *dynref, unsigned long relType) :
2820    target_addr_(ta), 
2821    rel_addr_(ra), 
2822    addend_(add), 
2823    rtype_(Region::RT_REL), 
2824    name_(n), 
2825    dynref_(dynref), 
2826    relType_(relType)
2827 {
2828 }
2829
2830 SYMTAB_EXPORT relocationEntry::relocationEntry(Offset ra, std::string n, 
2831       Symbol *dynref, unsigned long relType, Region::RegionType rtype) :
2832    target_addr_(0), 
2833    rel_addr_(ra), 
2834    addend_(0), 
2835    rtype_(rtype), 
2836    name_(n), 
2837    dynref_(dynref), 
2838    relType_(relType)
2839 {
2840 }   
2841
2842 SYMTAB_EXPORT const relocationEntry& relocationEntry::operator=(const relocationEntry &ra) 
2843 {
2844    target_addr_ = ra.target_addr_;
2845    rel_addr_ = ra.rel_addr_;
2846    addend_ = ra.addend_;
2847    rtype_ = ra.rtype_;
2848    name_ = ra.name_; 
2849    dynref_ = ra.dynref_;
2850    relType_ = ra.relType_;
2851    return *this;
2852 }
2853
2854 SYMTAB_EXPORT Offset relocationEntry::target_addr() const 
2855 {
2856     return target_addr_;
2857 }
2858
2859 SYMTAB_EXPORT void relocationEntry::setTargetAddr(const Offset off)
2860 {
2861     target_addr_ = off;
2862 }
2863
2864 SYMTAB_EXPORT Offset relocationEntry::rel_addr() const 
2865 {
2866     return rel_addr_;
2867 }
2868
2869 SYMTAB_EXPORT void relocationEntry::setRelAddr(const Offset value)
2870 {
2871     rel_addr_ = value;
2872 }
2873
2874 SYMTAB_EXPORT const string &relocationEntry::name() const 
2875 {
2876     return name_;
2877 }
2878
2879 SYMTAB_EXPORT Symbol *relocationEntry::getDynSym() const 
2880 {
2881     return dynref_;
2882 }
2883
2884 SYMTAB_EXPORT bool relocationEntry::addDynSym(Symbol *dynref) 
2885 {
2886     dynref_ = dynref;
2887     return true;
2888 }
2889
2890 SYMTAB_EXPORT Region::RegionType relocationEntry::regionType() const
2891 {
2892         return rtype_;
2893 }
2894
2895 SYMTAB_EXPORT unsigned long relocationEntry::getRelType() const 
2896 {
2897     return relType_;
2898 }
2899
2900 SYMTAB_EXPORT Offset relocationEntry::addend() const
2901 {
2902     return addend_;
2903 }
2904
2905 SYMTAB_EXPORT void relocationEntry::setAddend(const Offset value)
2906 {
2907     addend_ = value;
2908 }
2909
2910 SYMTAB_EXPORT void relocationEntry::setRegionType(const Region::RegionType value)
2911 {
2912     rtype_ = value;
2913 }
2914
2915 bool relocationEntry::operator==(const relocationEntry &r) const
2916 {
2917         if (target_addr_ != r.target_addr_) return false;
2918         if (rel_addr_ != r.rel_addr_) return false;
2919         if (addend_ != r.addend_) return false;
2920         if (rtype_ != r.rtype_) return false;
2921         if (name_ != r.name_) return false;
2922         if (relType_ != r.relType_) return false;
2923         if (dynref_ && !r.dynref_) return false;
2924         if (!dynref_ && r.dynref_) return false;
2925         if (dynref_)
2926         {
2927                 if (dynref_->getName() != r.dynref_->getName()) return false;
2928                 if (dynref_->getOffset() != r.dynref_->getOffset()) return false;
2929         }
2930
2931         return true;
2932 }
2933
2934 Serializable *relocationEntry::serialize_impl(SerializerBase *sb, const char *tag) THROW_SPEC (SerializerError)
2935 {
2936         //  on deserialize need to rebuild symtab::undefDynSyms before deserializing relocations
2937
2938         std::string symname = dynref_ ? dynref_->getName() : std::string("");
2939         Offset symoff = dynref_ ? dynref_->getOffset() : (Offset) -1;
2940
2941       ifxml_start_element(sb, tag);
2942       gtranslate(sb, target_addr_, "targetAddress");
2943       gtranslate(sb, rel_addr_, "relocationAddress");
2944       gtranslate(sb, addend_, "Addend");
2945       gtranslate(sb, name_, "relocationName");
2946       gtranslate(sb,  rtype_, Region::regionType2Str, "regionType");
2947       gtranslate(sb, relType_, "relocationType");
2948       gtranslate(sb, symname, "SymbolName");
2949       gtranslate(sb, symoff, "SymbolOffset");
2950       ifxml_end_element(sb, tag);
2951
2952           if (sb->isInput())
2953           {
2954                   dynref_ = NULL;
2955                   if (symname != std::string(""))
2956                   {
2957                           //  if we have a name for this symbol, the offset should not be -1;
2958                           if (symoff == (Offset) -1)
2959                           {
2960                                   fprintf(stderr, "%s[%d]:  inconsistent symname and offset combo!\n", 
2961                                                   FILE__, __LINE__);
2962                           }
2963
2964                           SerContextBase *scb = sb->getContext();
2965                           if (!scb)
2966                           {
2967                                   fprintf(stderr, "%s[%d]:  SERIOUS:  FIXME\n", FILE__, __LINE__);
2968                                   SER_ERR("FIXME");
2969                           }
2970
2971                           SerContext<Symtab> *scs = dynamic_cast<SerContext<Symtab> *>(scb);
2972
2973                           if (!scs)
2974                           {
2975                                   fprintf(stderr, "%s[%d]:  SERIOUS:  FIXME\n", FILE__, __LINE__);
2976                                   SER_ERR("FIXME");
2977                           }
2978
2979                           Symtab *st = scs->getScope();
2980
2981                           if (!st)
2982                           {
2983                                   fprintf(stderr, "%s[%d]:  SERIOUS:  FIXME\n", FILE__, __LINE__);
2984                                   SER_ERR("FIXME");
2985                           }
2986
2987                           std::vector<Symbol *> *syms = st->findSymbolByOffset(symoff);
2988                           if (!syms || !syms->size())
2989                           {
2990                                   serialize_printf("%s[%d]:  cannot find symbol by offset %p\n", 
2991                                                   FILE__, __LINE__, (void *)symoff);
2992                                   return NULL;
2993                           }
2994
2995                           //  Might want to try to select the "best" symbol here if there is
2996                           //  more than one.  Or Maybe just returning the first is sufficient.
2997
2998                           dynref_ = (*syms)[0];
2999                   }
3000           }
3001           return NULL;
3002 }
3003
3004
3005 const char *Symbol::symbolType2Str(SymbolType t) 
3006 {
3007    switch (t) 
3008    {
3009       CASE_RETURN_STR(ST_UNKNOWN);
3010       CASE_RETURN_STR(ST_FUNCTION);
3011       CASE_RETURN_STR(ST_OBJECT);
3012       CASE_RETURN_STR(ST_MODULE);
3013       CASE_RETURN_STR(ST_SECTION);
3014       CASE_RETURN_STR(ST_TLS);
3015       CASE_RETURN_STR(ST_DELETED);
3016       CASE_RETURN_STR(ST_NOTYPE);
3017    };
3018
3019    return "invalid symbol type";
3020 }
3021
3022 const char *Symbol::symbolLinkage2Str(SymbolLinkage t) 
3023 {
3024    switch (t) 
3025    {
3026       CASE_RETURN_STR(SL_UNKNOWN);
3027       CASE_RETURN_STR(SL_GLOBAL);
3028       CASE_RETURN_STR(SL_LOCAL);
3029       CASE_RETURN_STR(SL_WEAK);
3030    };
3031
3032    return "invalid symbol linkage";
3033 }
3034
3035 const char *Symbol::symbolTag2Str(SymbolTag t) 
3036 {
3037    switch (t) 
3038    {
3039       CASE_RETURN_STR(TAG_UNKNOWN);
3040       CASE_RETURN_STR(TAG_USER);
3041       CASE_RETURN_STR(TAG_LIBRARY);
3042       CASE_RETURN_STR(TAG_INTERNAL);
3043    };
3044
3045    return "invalid symbol tag";
3046 }
3047
3048 const char *Symbol::symbolVisibility2Str(SymbolVisibility t) 
3049 {
3050    switch(t) {
3051       CASE_RETURN_STR(SV_UNKNOWN);
3052       CASE_RETURN_STR(SV_DEFAULT);
3053       CASE_RETURN_STR(SV_INTERNAL);
3054       CASE_RETURN_STR(SV_HIDDEN);
3055       CASE_RETURN_STR(SV_PROTECTED);
3056    }
3057    return "invalid symbol visibility";
3058 }
3059
3060 bool Symtab::hasStackwalkDebugInfo()
3061 {
3062
3063         Object *obj = getObject();
3064         if (!obj)
3065         {
3066                 fprintf(stderr, "%s[%d]:  getObject failed here\n", FILE__, __LINE__);
3067                 return false;
3068         }
3069    return obj->hasFrameDebugInfo();
3070 }
3071
3072 bool Symtab::getRegValueAtFrame(Address pc, 
3073                                 Dyninst::MachRegister reg, 
3074                                 Dyninst::MachRegisterVal &reg_result,
3075                                 MemRegReader *reader)
3076 {
3077         Object *obj = getObject();
3078         if (!obj)
3079         {
3080                 fprintf(stderr, "%s[%d]:  getObject failed here\n", FILE__, __LINE__);
3081                 return false;
3082         }
3083    return obj->getRegValueAtFrame(pc, reg, reg_result, reader);
3084 }
3085
3086 Object *Symtab::getObject()
3087 {
3088    if (obj_private)
3089       return obj_private;
3090
3091    //TODO: This likely triggered because we serialized in an object
3092    // from cache, but now the user is requesting more information from
3093    // the on disk object.  We should create a new 'Object' from data
3094    // (likely a file path) serialized in.
3095    
3096    fprintf(stderr, "%s[%d]:  FIXME:  request for object that does not exist!\n", FILE__, __LINE__);
3097    return NULL;
3098    //obj_private = new Object();
3099    //return obj_private;
3100 }
3101
3102 void Symtab::parseTypesNow()
3103 {
3104    if (isTypeInfoValid_)
3105       return;
3106
3107    parseTypes();
3108 }
3109
3110 MemRegReader::~MemRegReader()
3111 {
3112 }
3113
3114 #if defined (cap_serialization)
3115 //  Not sure this is strictly necessary, problems only seem to exist with Module 
3116 // annotations when the file was split off, so there's probably something else that
3117 //  can be done to instantiate the relevant functions.
3118
3119 bool dummy_for_ser_instance(std::string file, SerializerBase *sb)
3120 {
3121    if (file == std::string("no_such_file")) 
3122    {
3123       if (!sb) 
3124       {
3125          fprintf(stderr, "%s[%d]:  really should not happen\n", FILE__, __LINE__);
3126          return false;
3127       }
3128       fprintf(stderr, "%s[%d]:  WARN:  disabled serializer init here\n", FILE__, __LINE__);
3129    }
3130    return true;
3131 }
3132
3133 #endif
3134
3135 namespace Dyninst {
3136         namespace SymtabAPI {
3137
3138
3139 #if 1
3140 SYMTAB_EXPORT SerializerBase *nonpublic_make_bin_symtab_serializer(Symtab *t, std::string file)
3141 {
3142         SerializerBin *ser;
3143         SerContext<Symtab> *scs = new SerContext<Symtab>(t, file);
3144         ser = new SerializerBin(scs, "SerializerBin", file, sd_serialize, false);
3145         return ser;
3146 }
3147
3148 SYMTAB_EXPORT SerializerBase *nonpublic_make_bin_symtab_deserializer(Symtab *t, std::string file)
3149 {
3150         SerializerBin *ser;
3151         SerContext<Symtab> *scs = new SerContext<Symtab>(t, file);
3152         ser = new SerializerBin(scs, "DeserializerBin", file, sd_deserialize, false);
3153         return ser;
3154 }
3155
3156 SYMTAB_EXPORT void nonpublic_free_bin_symtab_serializer(SerializerBase *sb)
3157 {
3158         SerializerBin *sbin = dynamic_cast<SerializerBin *>(sb);
3159         if (sbin)
3160         {
3161                 delete(sbin);
3162         }
3163         else
3164                 fprintf(stderr, "%s[%d]:  FIXME\n", FILE__, __LINE__);
3165
3166 }
3167 #endif
3168
3169 SYMTAB_EXPORT Offset Symtab::getElfDynamicOffset()
3170 {
3171 #if defined(os_linux)
3172         Object *obj = getObject();
3173         if (!obj)
3174         {
3175                 fprintf(stderr, "%s[%d]:  getObject failed here\n", FILE__, __LINE__);
3176                 return 0;
3177         }
3178    return obj->getDynamicAddr();
3179 #else
3180    return 0;
3181 #endif
3182 }
3183
3184 SYMTAB_EXPORT bool Symtab::addLibraryPrereq(std::string name)
3185 {
3186 #if defined(os_linux)
3187         Object *obj = getObject();
3188         if (!obj)
3189         {
3190                 fprintf(stderr, "%s[%d]:  getObject failed here\n", FILE__, __LINE__);
3191                 return false;
3192         }
3193    obj->insertPrereqLibrary(name);
3194    return true;
3195 #else
3196    return false;
3197 #endif
3198 }
3199
3200 SYMTAB_EXPORT bool Symtab::addSysVDynamic(long name, long value)
3201 {
3202 #if defined(os_linux)
3203         Object *obj = getObject();
3204         if (!obj)
3205         {
3206                 fprintf(stderr, "%s[%d]:  getObject failed here\n", FILE__, __LINE__);
3207                 return false;
3208         }
3209   obj->insertDynamicEntry(name, value);
3210    return true;
3211 #else
3212    return false;
3213 #endif
3214 }
3215
3216 SYMTAB_EXPORT Address Symtab::getLoadAddress()
3217 {
3218 #if defined(os_linux) || defined(os_aix)
3219    return getObject()->getLoadAddress();
3220 #else
3221    return 0x0;
3222 #endif
3223 }
3224
3225 SYMTAB_EXPORT bool Symtab::canBeShared()
3226 {
3227    return mf->canBeShared();
3228 }
3229
3230 SYMTAB_EXPORT Offset Symtab::getInitOffset()
3231 {
3232 #if defined(os_linux) || defined(os_solaris)
3233    return getObject()->getInitAddr();
3234 #else
3235    return 0x0;
3236 #endif
3237
3238 }
3239
3240 SYMTAB_EXPORT Offset Symtab::getFiniOffset()
3241 {
3242 #if defined(os_linux) || defined(os_solaris)
3243    return getObject()->getFiniAddr();
3244 #else
3245    return 0x0;
3246 #endif
3247
3248 }
3249
3250
3251 } // namespace SymtabAPI
3252 } // namespace Dyninst
3253