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