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