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