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