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