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