Windows test suite & build fixes. VC2003 and VC2008 should both now build. Known...
[dyninst.git] / symtabAPI / src / Symtab.C
1 /*
2  * Copyright (c) 1996-2007 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
38 #include "common/h/Timer.h"
39 #include "common/h/debugOstream.h"
40 #include "common/h/serialize.h"
41 #include "common/h/pathName.h"
42
43 #include "Serialization.h"
44 #include "Symtab.h"
45 #include "Module.h"
46 #include "Collections.h"
47 #include "Function.h"
48 #include "Variable.h"
49
50 #include "annotations.h"
51
52 #include "debug.h"
53
54 #include "symtabAPI/src/Object.h"
55
56 #if !defined(os_windows)
57 #include <dlfcn.h>
58 #else
59 #include <windows.h>
60 #endif
61
62 #include <iomanip>
63 #include <stdarg.h>
64
65 using namespace Dyninst;
66 using namespace Dyninst::SymtabAPI;
67 using namespace std;
68
69 static std::string errMsg;
70 extern bool parseCompilerType(Object *);
71
72 void pd_log_perror(const char *msg)
73 {
74    errMsg = std::string(msg);
75 };
76
77
78 SymtabError serr;
79
80 std::vector<Symtab *> Symtab::allSymtabs;
81 builtInTypeCollection *Symtab::builtInTypes = NULL;
82 typeCollection *Symtab::stdTypes = NULL;
83  
84 SymtabError Symtab::getLastSymtabError()
85 {
86     return serr;
87 }
88
89 std::string Symtab::printError(SymtabError serr)
90 {
91     switch (serr)
92     {
93         case Obj_Parsing:
94             return "Failed to parse the Object"+errMsg;
95         case Syms_To_Functions:
96             return "Failed to convert Symbols to Functions";
97         case No_Such_Function:
98             return "Function does not exist";
99         case No_Such_Variable:
100             return "Variable does not exist";
101        case No_Such_Module:
102             return "Module does not exist";
103         case No_Such_Region:
104             return "Region does not exist";
105         case No_Such_Symbol:
106             return "Symbol does not exist";
107         case Not_A_File:
108             return "Not a File. Call openArchive()";
109         case Not_An_Archive:
110             return "Not an Archive. Call openFile()";
111         case Export_Error:
112             return "Error Constructing XML"+errMsg;
113         case Invalid_Flags:
114             return "Flags passed are invalid.";
115         case No_Error:
116             return "No previous Error.";
117         default:
118             return "Unknown Error";
119     }           
120 }
121
122 void Symtab::setupTypes()
123 {
124     /*
125      * Create the "error" and "untyped" types.
126      */
127     std::string name = "<error>";
128     type_Error   = Type::createFake(name);
129     name = "<no type>";
130     type_Untyped = Type::createFake(name);
131     setupStdTypes();
132 }    
133
134 void Symtab::setupStdTypes() 
135 {
136    if (builtInTypes)
137         return;
138
139    builtInTypes = new builtInTypeCollection;
140    typeScalar *newType;
141
142    // NOTE: integral type  mean twos-complement
143    // -1  int, 32 bit signed integral type
144    // in stab document, size specified in bits, system size is in bytes
145    builtInTypes->addBuiltInType(newType = new typeScalar(-1, 4, "int", true));
146    newType->decrRefCount();
147    // -2  char, 8 bit type holding a character. GDB & dbx(AIX) treat as signed
148    builtInTypes->addBuiltInType(newType = new typeScalar(-2, 1, "char", true));
149    newType->decrRefCount();
150    // -3  short, 16 bit signed integral type
151    builtInTypes->addBuiltInType(newType = new typeScalar(-3, 2, "short", true));
152    newType->decrRefCount();
153    // -4  long, 32/64 bit signed integral type
154    builtInTypes->addBuiltInType(newType = new typeScalar(-4, sizeof(long), "long", true));
155    newType->decrRefCount();
156    // -5  unsigned char, 8 bit unsigned integral type
157    builtInTypes->addBuiltInType(newType = new typeScalar(-5, 1, "unsigned char"));
158    newType->decrRefCount();
159    // -6  signed char, 8 bit signed integral type
160    builtInTypes->addBuiltInType(newType = new typeScalar(-6, 1, "signed char", true));
161    newType->decrRefCount();
162    // -7  unsigned short, 16 bit unsigned integral type
163    builtInTypes->addBuiltInType(newType = new typeScalar(-7, 2, "unsigned short"));
164    newType->decrRefCount();
165    // -8  unsigned int, 32 bit unsigned integral type
166    builtInTypes->addBuiltInType(newType = new typeScalar(-8, 4, "unsigned int"));
167    newType->decrRefCount();
168    // -9  unsigned, 32 bit unsigned integral type
169    builtInTypes->addBuiltInType(newType = new typeScalar(-9, 4, "unsigned"));
170    newType->decrRefCount();
171    // -10 unsigned long, 32 bit unsigned integral type
172    builtInTypes->addBuiltInType(newType = new typeScalar(-10, sizeof(unsigned long), "unsigned long"));
173    newType->decrRefCount();
174    // -11 void, type indicating the lack of a value
175    //  XXX-size may not be correct jdd 4/22/99
176    builtInTypes->addBuiltInType(newType = new typeScalar(-11, 0, "void", false));
177    newType->decrRefCount();
178    // -12 float, IEEE single precision
179    builtInTypes->addBuiltInType(newType = new typeScalar(-12, sizeof(float), "float", true));
180    newType->decrRefCount();
181    // -13 double, IEEE double precision
182    builtInTypes->addBuiltInType(newType = new typeScalar(-13, sizeof(double), "double", true));
183    newType->decrRefCount();
184    // -14 long double, IEEE double precision, size may increase in future
185    builtInTypes->addBuiltInType(newType = new typeScalar(-14, sizeof(long double), "long double", true));
186    newType->decrRefCount();
187    // -15 integer, 32 bit signed integral type
188    builtInTypes->addBuiltInType(newType = new typeScalar(-15, 4, "integer", true));
189    newType->decrRefCount();
190    // -16 boolean, 32 bit type. GDB/GCC 0=False, 1=True, all other values
191    //  have unspecified meaning
192    builtInTypes->addBuiltInType(newType = new typeScalar(-16, sizeof(bool), "boolean"));
193    newType->decrRefCount();
194    // -17 short real, IEEE single precision
195    //  XXX-size may not be correct jdd 4/22/99
196    builtInTypes->addBuiltInType(newType = new typeScalar(-17, sizeof(float), "short real", true));
197    newType->decrRefCount();
198    // -18 real, IEEE double precision XXX-size may not be correct jdd 4/22/99
199    builtInTypes->addBuiltInType(newType = new typeScalar(-18, sizeof(double), "real", true));
200    newType->decrRefCount();
201    // -19 stringptr XXX- size of void * -- jdd 4/22/99
202    builtInTypes->addBuiltInType(newType = new typeScalar(-19, sizeof(void *), "stringptr"));
203    newType->decrRefCount();
204    // -20 character, 8 bit unsigned character type
205    builtInTypes->addBuiltInType(newType = new typeScalar(-20, 1, "character"));
206    newType->decrRefCount();
207    // -21 logical*1, 8 bit type (Fortran, used for boolean or unsigned int)
208    builtInTypes->addBuiltInType(newType = new typeScalar(-21, 1, "logical*1"));
209    newType->decrRefCount();
210    // -22 logical*2, 16 bit type (Fortran, some for boolean or unsigned int)
211    builtInTypes->addBuiltInType(newType = new typeScalar(-22, 2, "logical*2"));
212    newType->decrRefCount();
213    // -23 logical*4, 32 bit type (Fortran, some for boolean or unsigned int)
214    builtInTypes->addBuiltInType(newType = new typeScalar(-23, 4, "logical*4"));
215    newType->decrRefCount();
216    // -24 logical, 32 bit type (Fortran, some for boolean or unsigned int)
217    builtInTypes->addBuiltInType(newType = new typeScalar(-24, 4, "logical"));
218    newType->decrRefCount();
219    // -25 complex, consists of 2 IEEE single-precision floating point values
220    builtInTypes->addBuiltInType(newType = new typeScalar(-25, sizeof(float)*2, "complex", true));
221    newType->decrRefCount();
222    // -26 complex, consists of 2 IEEE double-precision floating point values
223    builtInTypes->addBuiltInType(newType = new typeScalar(-26, sizeof(double)*2, "complex*16", true));
224    newType->decrRefCount();
225    // -27 integer*1, 8 bit signed integral type
226    builtInTypes->addBuiltInType(newType = new typeScalar(-27, 1, "integer*1", true));
227    newType->decrRefCount();
228    // -28 integer*2, 16 bit signed integral type
229    builtInTypes->addBuiltInType(newType = new typeScalar(-28, 2, "integer*2", true));
230    newType->decrRefCount();
231
232    /* Quick hack to make integer*4 compatible with int for Fortran
233       jnb 6/20/01 */
234    // This seems questionable - let's try removing that hack - jmo 05/21/04
235    /*
236      builtInTypes->addBuiltInType(newType = new type("int",-29,
237      built_inType, 4));
238      newType->decrRefCount();
239    */
240    // -29 integer*4, 32 bit signed integral type
241    builtInTypes->addBuiltInType(newType = new typeScalar(-29, 4, "integer*4", true));
242    newType->decrRefCount();
243    // -30 wchar, Wide character, 16 bits wide, unsigned (unknown format)
244    builtInTypes->addBuiltInType(newType = new typeScalar(-30, 2, "wchar"));
245    newType->decrRefCount();
246 #if defined(os_windows)
247    // -31 long long, 64 bit signed integral type
248    builtInTypes->addBuiltInType(newType = new typeScalar(-31, sizeof(LONGLONG), "long long", true));
249    newType->decrRefCount();
250    // -32 unsigned long long, 64 bit unsigned integral type
251    builtInTypes->addBuiltInType(newType = new typeScalar(-32, sizeof(ULONGLONG), "unsigned long long"));
252    newType->decrRefCount();
253 #else
254    // -31 long long, 64 bit signed integral type
255    builtInTypes->addBuiltInType(newType = new typeScalar(-31, sizeof(long long), "long long", true));
256    newType->decrRefCount();
257    // -32 unsigned long long, 64 bit unsigned integral type
258    builtInTypes->addBuiltInType(newType = new typeScalar(-32, sizeof(unsigned long long), "unsigned long long"));
259    newType->decrRefCount();
260 #endif
261    // -33 logical*8, 64 bit unsigned integral type
262    builtInTypes->addBuiltInType(newType = new typeScalar(-33, 8, "logical*8"));
263    newType->decrRefCount();
264    // -34 integer*8, 64 bit signed integral type
265    builtInTypes->addBuiltInType(newType = new typeScalar(-34, 8, "integer*8", true));
266    newType->decrRefCount();
267
268         /*
269     * Initialize hash table of standard types.
270     */
271         if (stdTypes)
272         return;
273
274    stdTypes = typeCollection::getGlobalTypeCollection();
275    stdTypes->addType(newType = new typeScalar(-1, sizeof(int), "int"));
276    newType->decrRefCount();
277
278    Type *charType = new typeScalar(-2, sizeof(char), "char");
279    stdTypes->addType(charType);
280
281         std::string tName = "char *";
282         typePointer *newPtrType;
283    stdTypes->addType(newPtrType = new typePointer(-3, charType, tName));
284    charType->decrRefCount();
285    newPtrType->decrRefCount();
286
287    Type *voidType = new typeScalar(-11, 0, "void", false);
288    stdTypes->addType(voidType);
289
290         tName = "void *";
291    stdTypes->addType(newPtrType = new typePointer(-4, voidType, tName));
292    voidType->decrRefCount();
293    newPtrType->decrRefCount();
294
295    stdTypes->addType(newType = new typeScalar(-12, sizeof(float), "float"));
296    newType->decrRefCount();
297
298 #if defined(i386_unknown_nt4_0)
299    stdTypes->addType(newType = new typeScalar(-31, sizeof(LONGLONG), "long long"));    
300 #else
301    stdTypes->addType(newType = new typeScalar(-31, sizeof(long long), "long long"));
302 #endif
303
304         newType->decrRefCount();
305
306    return;
307 }
308
309 SYMTAB_EXPORT unsigned Symtab::getAddressWidth() const 
310 {
311    return address_width_;
312 }
313  
314 SYMTAB_EXPORT bool Symtab::isNativeCompiler() const 
315 {
316     return nativeCompiler; 
317 }
318  
319
320 SYMTAB_EXPORT Symtab::Symtab(MappedFile *mf_) :
321    AnnotatableSparse(),
322    mf(mf_), 
323    mfForDebugInfo(mf_),
324    obj_private(NULL)
325 {   
326     init_debug_symtabAPI();
327 }   
328
329
330 SYMTAB_EXPORT Symtab::Symtab() :
331    obj_private(NULL)
332 {
333     init_debug_symtabAPI();
334     create_printf("%s[%d]: Created symtab via default constructor\n", FILE__, __LINE__);
335     defaultNamespacePrefix = "";
336 }
337
338 SYMTAB_EXPORT bool Symtab::isExec() const 
339 {
340     return is_a_out; 
341 }
342
343 SYMTAB_EXPORT bool Symtab::isStripped() 
344 {
345 #if defined(os_linux) || defined(os_solaris)
346     Region *sec;
347     return findRegion(sec,".symtab");
348 #else
349     return (no_of_symbols==0);
350 #endif
351 }
352
353 SYMTAB_EXPORT Offset Symtab::imageOffset() const 
354 {
355     return imageOffset_;
356 }
357
358 SYMTAB_EXPORT Offset Symtab::dataOffset() const 
359
360     return dataOffset_;
361 }
362
363 SYMTAB_EXPORT Offset Symtab::dataLength() const 
364 {
365     return dataLen_;
366
367
368 SYMTAB_EXPORT Offset Symtab::imageLength() const 
369 {
370     return imageLen_;
371 }
372 /*
373 SYMTAB_EXPORT char* Symtab::image_ptr ()  const 
374 {
375    return code_ptr_;
376 }
377
378 SYMTAB_EXPORT char* Symtab::data_ptr ()  const 
379
380    return data_ptr_;
381 }
382 */
383 SYMTAB_EXPORT const char*  Symtab::getInterpreterName() const 
384 {
385    if (interpreter_name_.length())
386       return interpreter_name_.c_str();
387    return NULL;
388 }
389  
390 SYMTAB_EXPORT Offset Symtab::getEntryOffset() const 
391
392    return entry_address_;
393 }
394
395 SYMTAB_EXPORT Offset Symtab::getBaseOffset() const 
396 {
397    return base_address_;
398 }
399
400 SYMTAB_EXPORT Offset Symtab::getLoadOffset() const 
401
402    return load_address_;
403 }
404
405 SYMTAB_EXPORT Offset Symtab::getTOCoffset() const 
406 {
407    return toc_offset_;
408 }
409
410 SYMTAB_EXPORT string Symtab::getDefaultNamespacePrefix() const
411 {
412     return defaultNamespacePrefix;
413 }
414         
415         
416 // TODO -- is this g++ specific
417 bool Symtab::buildDemangledName( const std::string &mangled, 
418       std::string &pretty,
419       std::string &typed,
420       bool nativeCompiler, 
421       supportedLanguages lang )
422 {
423    /* The C++ demangling function demangles MPI__Allgather (and other MPI__
424     * functions with start with A) into the MPI constructor.  In order to
425     * prevent this a hack needed to be made, and this seemed the cleanest
426     * approach.
427     */
428
429    if ((mangled.length()>5) && (mangled.substr(0,5)==std::string("MPI__"))) 
430    {
431       return false;
432    }      
433
434    /* If it's Fortran, eliminate the trailing underscores, if any. */
435    if (lang == lang_Fortran 
436          || lang == lang_CMFortran 
437          || lang == lang_Fortran_with_pretty_debug )
438    {
439       if ( mangled[ mangled.length() - 1 ] == '_' ) 
440       {
441          char * demangled = P_strdup( mangled.c_str() );
442          demangled[ mangled.length() - 1 ] = '\0';
443          pretty = std::string( demangled );
444
445          free ( demangled );
446          return true;
447       }
448       else 
449       {
450          /* No trailing underscores, do nothing */
451          return false;
452       }
453    } /* end if it's Fortran. */
454
455    //  Check to see if we have a gnu versioned symbol on our hands.
456    //  These are of the form <symbol>@<version> or <symbol>@@<version>
457    //
458    //  If we do, we want to create a "demangled" name for the one that
459    //  is of the form <symbol>@@<version> since this is, by definition,
460    //  the default.  The "demangled" name will just be <symbol>
461
462    //  NOTE:  this is just a 0th order approach to dealing with versioned
463    //         symbols.  We may need to do something more sophisticated
464    //         in the future.  JAW 10/03
465
466 #if !defined(os_windows)
467
468    char *atat;
469
470    if (NULL != (atat = strstr(mangled.c_str(), "@@"))) 
471    {
472         pretty = mangled.substr(0 /*start pos*/, 
473                         (int)(atat - mangled.c_str())/*len*/);
474         //char msg[256];
475         //sprintf(msg, "%s[%d]: 'demangling' versioned symbol: %s, to %s",
476         //          __FILE__, __LINE__, mangled.c_str(), pretty.c_str());
477
478         //cerr << msg << endl;
479         //logLine(msg);
480       
481         return true;
482     }
483
484 #endif
485
486     bool retval = false;
487   
488     /* Try demangling it. */
489     char * demangled = P_cplus_demangle( mangled.c_str(), nativeCompiler, false);
490     if (demangled) 
491     {
492         pretty = std::string( demangled );
493         retval = true;
494     }
495   
496     char *t_demangled = P_cplus_demangle(mangled.c_str(), nativeCompiler, true);
497     if (t_demangled && (strcmp(t_demangled, demangled) != 0)) 
498     {
499         typed = std::string(t_demangled);
500         retval = true;
501     }
502
503     if (demangled)
504         free(demangled);
505     if (t_demangled)
506         free(t_demangled);
507
508     return retval;
509 } /* end buildDemangledName() */
510
511
512 /*
513  * extractSymbolsFromFile
514  *
515  * Create a Symtab-level list of symbols by pulling out data
516  * from the low-level parse (linkedFile).
517  * Technically this causes a duplication of symbols; however,
518  * we will be rewriting these symbols and so we need our own
519  * copy. 
520  *
521  * TODO: delete the linkedFile once we're done?
522  */
523
524 bool Symtab::extractSymbolsFromFile(Object *linkedFile, std::vector<Symbol *> &raw_syms) 
525 {
526     for (SymbolIter symIter(*linkedFile); symIter; symIter++) {
527         Symbol *sym = symIter.currval();
528
529         // If a symbol starts with "." we want to skip it. These indicate labels in the
530         // code. 
531         
532         // removed 1/09: this should be done in Dyninst, not Symtab
533 #if 0
534         if (sym->getMangledName()[0] == '.') 
535             continue;
536 #endif
537
538         // check for undefined dynamic symbols. Used when rewriting relocation section.
539         // relocation entries have references to these undefined dynamic symbols.
540         // We also have undefined symbols for the static binary case.
541         
542         if (sym->getSec() == NULL && !sym->isAbsolute()) {
543             undefDynSyms[sym->getMangledName()].push_back(sym);
544             continue;
545         }
546
547         // Check whether this symbol has a valid offset. If they do not we have a
548         // consistency issue. This should be a null check.
549
550         // Symbols can have an offset of 0 if they don't refer to things within a file.
551 #if 0
552         if (!isValidOffset(sym->getAddr())) {
553             fprintf(stderr, "Symbol %s has invalid offset 0x%lx\n", sym->getName().c_str(), sym->getAddr());
554             fprintf(stderr, "... in file %s\n", name().c_str());
555             return false;
556         }
557 #endif
558
559         raw_syms.push_back(sym);
560     }
561
562     return true;
563 }
564
565 /*
566  * fixSymModules
567  * 
568  * Add Module information to all symbols. 
569  */
570
571 bool Symtab::fixSymModules(std::vector<Symbol *> &raw_syms) 
572 {
573     for (unsigned i = 0; i < raw_syms.size(); i++) {
574         fixSymModule(raw_syms[i]);
575     }
576     return true;
577 }
578
579 /*
580  * demangleSymbols
581  *
582  * Perform name demangling on all symbols.
583  */
584
585 bool Symtab::demangleSymbols(std::vector<Symbol *> &raw_syms) 
586 {
587     for (unsigned i = 0; i < raw_syms.size(); i++) {
588         demangleSymbol(raw_syms[i]);
589     }
590     return true;
591 }
592
593 /*
594  * createIndices
595  *
596  * We index symbols by various attributes for quick lookup. Build those
597  * indices here. 
598  */
599
600 bool Symtab::createIndices(std::vector<Symbol *> &raw_syms) {
601     for (unsigned i = 0; i < raw_syms.size(); i++) {
602         addSymbolToIndices(raw_syms[i]);
603     }
604     return true;
605 }
606
607 /*
608  * createAggregates
609  *
610  * Frequently there will be multiple Symbols that refer to a single 
611  * code object (e.g., function or variable). We use separate objects
612  * to refer to these aggregates, and build those objects here. 
613  */
614
615 bool Symtab::createAggregates() {
616     for (unsigned i = 0; i < everyDefinedSymbol.size(); i++) {
617         addSymbolToAggregates(everyDefinedSymbol[i]);
618     }
619     return true;
620 }
621  
622 bool Symtab::fixSymModule(Symbol *&sym) {
623 #if !defined(os_windows)
624     // Occasionally get symbols with no module.
625     // Variables on Windows platform
626     if (sym->getModuleName().length() == 0) return false;
627 #endif    
628
629     Module *newMod = getOrCreateModule(sym->getModuleName(), sym->getAddr());
630     assert(newMod);
631     sym->setModule(newMod);
632     return true;
633 }
634
635 bool Symtab::demangleSymbol(Symbol *&sym) {
636     switch (sym->getType()) {
637     case Symbol::ST_FUNCTION: {
638         Module *rawmod = getOrCreateModule(sym->getModuleName(),sym->getAddr());
639         
640         assert(rawmod);
641         
642         // At this point we need to generate the following information:
643         // A symtab name.
644         // A pretty (demangled) name.
645         // The symtab name goes in the global list as well as the module list.
646         // Same for the pretty name.
647         // Finally, check addresses to find aliases.
648         
649         std::string mangled_name = sym->getMangledName();
650         std::string working_name = mangled_name;
651         
652 #if !defined(os_windows)        
653         //Remove extra stabs information
654         const char *p = strchr(working_name.c_str(), ':');
655         if( p ) {
656             unsigned nchars = p - mangled_name.c_str();
657             working_name = std::string(mangled_name.c_str(), nchars);
658         }
659 #endif        
660         
661         std::string pretty_name = working_name;
662         std::string typed_name = working_name;
663         
664         if (!buildDemangledName(working_name, pretty_name, typed_name,
665                                 nativeCompiler, rawmod->language())) {
666             pretty_name = working_name;
667         }
668
669         sym->setPrettyName(pretty_name);
670         sym->setTypedName(typed_name);
671         
672         break;
673     }
674     default: {
675         // All cases where there really shouldn't be a mangled
676         // name, since mangling is for functions.
677         
678         char *prettyName = P_cplus_demangle(sym->getMangledName().c_str(), nativeCompiler, false);
679         if (prettyName) {
680             sym->setPrettyName(prettyName);
681         }
682         else {
683             sym->setPrettyName(sym->getMangledName().c_str());
684         }
685         break;
686     }
687     }
688     return true;
689 }
690
691 bool Symtab::addSymbolToIndices(Symbol *&sym) {
692     everyDefinedSymbol.push_back(sym);
693     
694     symsByOffset[sym->getAddr()].push_back(sym);
695     
696     symsByMangledName[sym->getMangledName()].push_back(sym);
697
698     symsByPrettyName[sym->getPrettyName()].push_back(sym);
699
700     symsByTypedName[sym->getTypedName()].push_back(sym);
701
702     return true;
703 }
704
705 bool Symtab::addSymbolToAggregates(Symbol *&sym) {
706     switch(sym->getType()) {
707     case Symbol::ST_FUNCTION: {
708         // We want to do the following:
709         // If no function exists, create and add. 
710         // Combine this information
711         //   Add this symbol's names to the function.
712         //   Keep module information 
713
714         Function *func = NULL;
715         findFuncByEntryOffset(func, sym->getAddr());
716         if (!func) {
717             // Create a new function
718             // Also, update the symbol to point to this function.
719
720             func = Function::createFunction(sym);
721
722             everyFunction.push_back(func);
723             funcsByOffset[sym->getAddr()] = func;
724         }
725         else {
726             func->addSymbol(sym);
727         }
728         sym->setFunction(func);
729
730         break;
731     }
732     case Symbol::ST_OBJECT: {
733         // The same as the above, but with variables.
734         Variable *var = NULL;
735         findVariableByOffset(var, sym->getAddr());
736         if (!var) {
737             // Create a new function
738             // Also, update the symbol to point to this function.
739             var = Variable::createVariable(sym);
740             
741             everyVariable.push_back(var);
742             varsByOffset[sym->getAddr()] = var;
743         }
744         else {
745             var->addSymbol(sym);
746         }
747         sym->setVariable(var);
748         break;
749     }
750     default: {
751         break;
752     }
753     }
754     return true;
755 }
756
757 /* Add the new name to the appropriate symbol index */
758
759 bool Symtab::updateIndices(Symbol *sym, std::string newName, nameType_t nameType) {
760     if (nameType & mangledName) {
761         // Add this symbol under the given name (as mangled)
762         symsByMangledName[newName].push_back(sym);
763     }
764     if (nameType & prettyName) {
765         // Add this symbol under the given name (as pretty)
766         symsByPrettyName[newName].push_back(sym);
767     }
768     if (nameType & typedName) {
769         // Add this symbol under the given name (as typed)
770         symsByTypedName[newName].push_back(sym);
771     }
772     return true;
773 }
774
775 #if defined(ppc64_linux)
776 /* Special case for ppc64 ELF binaries. Sometimes a function has a 3-byte descriptor symbol
777  * along with it in the symbol table and "." preceding its original pretty name for the correct
778  * function symbol. This checks to see if we have a corresponding 3-byte descriptor symbol existing
779  * and if it does we remove the preceding "." from the name of the symbol
780  */
781
782 void Symtab::checkPPC64DescriptorSymbols(Object *linkedFile)
783 {
784    // find the real functions -- those with the correct type in the symbol table
785    for(SymbolIter symIter(*linkedFile); symIter;symIter++)
786    {
787       Symbol *lookUp = symIter.currval();
788       const char *np = lookUp->getMangledName().c_str();
789       if(!np)
790          continue;
791
792       if(np[0] == '.' && (lookUp->getType() == Symbol::ST_FUNCTION))
793       {
794          std::vector<Symbol *>syms;
795          std::string newName = np+1;
796          if(linkedFile->get_symbols(newName, syms) && (syms[0]->getSize() == 24 || syms[0]->getSize() == 0))
797          {
798             //Remove the "." from the name
799             lookUp->mangledNames[0] = newName;
800
801             //Change the type of the descriptor symbol
802             syms[0]->type_ = Symbol::ST_NOTYPE;
803          }
804       }
805    }
806
807 }
808
809 #endif
810
811 //  setModuleLanguages is only called after modules have been defined.
812 //  it attempts to set each module's language, information which is needed
813 //  before names can be demangled.
814 void Symtab::setModuleLanguages(dyn_hash_map<std::string, supportedLanguages> *mod_langs)
815 {
816    if (!mod_langs->size())
817       return;  // cannot do anything here
818    //  this case will arise on non-stabs platforms until language parsing can be introduced at this level
819    std::vector<Module *> *modlist;
820    Module *currmod = NULL;
821    modlist = &_mods;
822    //int dump = 0;
823
824    for (unsigned int i = 0;  i < modlist->size(); ++i)
825    {
826       currmod = (*modlist)[i];
827       supportedLanguages currLang;
828       if (currmod->isShared()) {
829          continue;  // need to find some way to get shared object languages?
830       }
831
832       const std::string fn = currmod->fileName();
833       if (mod_langs->find(currmod->fileName()) != mod_langs->end())
834       {
835          currLang = (*mod_langs)[fn];
836       }
837       else if (fn.rfind(".s") != std::string::npos ||
838             fn.rfind(".asm") != std::string::npos)
839       {
840          currLang = lang_Assembly;
841       }
842       else if (fn.rfind(".c") != std::string::npos)
843       {
844          currLang = lang_C;
845       }
846       else if (fn.rfind(".cpp") != std::string::npos ||
847             fn.rfind(".cc") != std::string::npos ||
848             fn.rfind(".C") != std::string::npos)
849       {
850          currLang = lang_CPlusPlus;
851       }
852       else
853       {
854          continue;
855       }
856       currmod->setLanguage(currLang);
857    }
858 }
859
860 Module *Symtab::getOrCreateModule(const std::string &modName, 
861       const Offset modAddr)
862 {
863    std::string nameToUse;
864    if (modName.length() > 0)
865       nameToUse = modName;
866    else
867       nameToUse = "DEFAULT_MODULE";
868
869    Module *fm = NULL;
870    if (findModuleByName(fm, nameToUse)) 
871    {
872       return fm;
873    }
874
875     const char *str = nameToUse.c_str();
876     int len = nameToUse.length();
877     assert(len>0);
878
879     // TODO ignore directory definitions for now
880     if (str[len-1] == '/') 
881         return NULL;
882
883     return (newModule(nameToUse, modAddr, lang_Unknown));
884 }
885  
886 Module *Symtab::newModule(const std::string &name, const Offset addr, supportedLanguages lang)
887 {
888     Module *ret = new Module();
889     // modules can be defined several times in C++ due to templates and
890     //   in-line member functions.
891
892     if (findModuleByName(ret, name)) 
893     {
894         return(ret);
895     }
896
897     delete ret;
898
899     //parsing_printf("=== image, creating new pdmodule %s, addr 0x%x\n",
900     //                          name.c_str(), addr);
901     
902     std::string fileNm, fullNm;
903     fullNm = name;
904     fileNm = extract_pathname_tail(name);
905
906      // /* DEBUG */ fprintf( stderr, "%s[%d]: In %p: Creating new pdmodule '%s'/'%s'\n", FILE__, __LINE__, this, fileNm.c_str(), fullNm.c_str() );
907
908     ret = new Module(lang, addr, fullNm, this);
909     assert(ret);
910
911     if (modsByFileName.end() != modsByFileName.find(ret->fileName()))
912     {
913        fprintf(stderr, "%s[%d]:  WARN:  LEAK?  already have module with name %s\n", 
914              FILE__, __LINE__, ret->fileName().c_str());
915     }
916
917     if (modsByFullName.end() != modsByFullName.find(ret->fullName()))
918     {
919        fprintf(stderr, "%s[%d]:  WARN:  LEAK?  already have module with name %s\n", 
920              FILE__, __LINE__, ret->fullName().c_str());
921     }
922
923     modsByFileName[ret->fileName()] = ret;
924     modsByFullName[ret->fullName()] = ret;
925     _mods.push_back(ret);
926     
927     return (ret);
928 }
929
930 Symtab::Symtab(std::string filename,bool &err) :
931    is_a_out(false), 
932    main_call_addr_(0),
933    nativeCompiler(false), 
934    isLineInfoValid_(false), 
935    isTypeInfoValid_(false),
936    obj_private(NULL),
937    type_Error(NULL), 
938    type_Untyped(NULL)
939 {
940     init_debug_symtabAPI();
941    // Initialize error parameter
942    err = false;
943    
944    create_printf("%s[%d]: created symtab for %s\n", FILE__, __LINE__, filename.c_str());
945
946 #if defined (os_windows)
947    extern void fixup_filename(std::string &);
948    fixup_filename(filename);
949 #endif
950
951    //  createMappedFile handles reference counting
952    mf = MappedFile::createMappedFile(filename);
953    if (!mf) {
954       create_printf("%s[%d]: WARNING: creating symtab for %s, " 
955                     "createMappedFile() failed\n", FILE__, __LINE__, 
956                     filename.c_str());
957       err = true;
958       return;
959    }
960
961    obj_private = new Object(mf, mfForDebugInfo, pd_log_perror, true);
962
963    if (!extractInfo(obj_private))
964    {
965       create_printf("%s[%d]: WARNING: creating symtab for %s, extractInfo() " 
966                     "failed\n", FILE__, __LINE__, filename.c_str());
967       err = true;
968    }
969
970    defaultNamespacePrefix = "";
971 }
972
973
974 Symtab::Symtab(char *mem_image, size_t image_size, bool &err) :
975    is_a_out(false), 
976    main_call_addr_(0),
977    nativeCompiler(false),
978    isLineInfoValid_(false),
979    isTypeInfoValid_(false),
980    obj_private(NULL),
981    type_Error(NULL), 
982    type_Untyped(NULL)
983 {
984    // Initialize error parameter
985    err = false;
986   
987    create_printf("%s[%d]: created symtab for memory image at addr %u\n", 
988                  FILE__, __LINE__, mem_image);
989
990    //  createMappedFile handles reference counting
991    mf = MappedFile::createMappedFile(mem_image, image_size);
992    if (!mf) {
993       create_printf("%s[%d]: WARNING: creating symtab for memory image at " 
994                     "addr %u, createMappedFile() failed\n", FILE__, __LINE__, 
995                     mem_image);
996       err = true;
997       return;
998    }
999
1000    obj_private = new Object(mf, mfForDebugInfo, pd_log_perror, true);
1001
1002    if (!extractInfo(obj_private))
1003    {
1004       create_printf("%s[%d]: WARNING: creating symtab for memory image at addr" 
1005                     "%u, extractInfo() failed\n", FILE__, __LINE__, mem_image);
1006       err = true;
1007    }
1008
1009    defaultNamespacePrefix = "";
1010 }
1011
1012 // Symtab constructor for archive members
1013 #if defined(os_aix) || defined(os_linux) || defined(os_solaris)
1014 Symtab::Symtab(std::string filename, std::string member_name, Offset offset, 
1015                bool &err, void *base) :
1016    member_name_(member_name), 
1017    member_offset_(offset),
1018    is_a_out(false),
1019    main_call_addr_(0), 
1020    nativeCompiler(false), 
1021    isLineInfoValid_(false),
1022    isTypeInfoValid_(false), 
1023    obj_private(NULL),
1024    type_Error(NULL), 
1025    type_Untyped(NULL)
1026 {
1027    mf = MappedFile::createMappedFile(filename);
1028    assert(mf);
1029    obj_private = new Object(mf, mfForDebugInfo, member_name, offset, pd_log_perror, base);
1030    err = extractInfo(obj_private);
1031    defaultNamespacePrefix = "";
1032 }
1033 #else
1034 Symtab::Symtab(std::string, std::string, Offset, bool &, void *base)
1035 {
1036     assert(0);
1037 }
1038 #endif
1039
1040 #if defined(os_aix) || defined(os_linux) || defined(os_solaris)
1041 Symtab::Symtab(char *mem_image, size_t image_size, std::string member_name,
1042                        Offset offset, bool &err, void *base) :
1043    member_name_(member_name), 
1044    is_a_out(false), 
1045    main_call_addr_(0),
1046    nativeCompiler(false), 
1047    isLineInfoValid_(false), 
1048    isTypeInfoValid_(false), 
1049    type_Error(NULL), 
1050    type_Untyped(NULL)
1051 {
1052    mf = MappedFile::createMappedFile(mem_image, image_size);
1053    assert(mf);
1054    obj_private = new Object(mf, mf, member_name, offset, pd_log_perror, base);
1055    err = extractInfo(obj_private);
1056    defaultNamespacePrefix = "";
1057 }
1058 #else 
1059 Symtab::Symtab(char *, size_t, std::string , Offset, bool &, void *)
1060 {
1061     assert(0);
1062 }
1063 #endif
1064
1065 bool sort_reg_by_addr(const Region* a, const Region* b)
1066 {
1067    return a->getRegionAddr() < b->getRegionAddr();
1068 }
1069
1070
1071 extern void print_symbols( std::vector< Symbol *>& allsymbols );
1072 extern void print_symbol_map( dyn_hash_map< std::string, std::vector< Symbol *> > *symbols);
1073
1074 bool Symtab::extractInfo(Object *linkedFile)
1075 {
1076 #if defined(TIMED_PARSE)
1077     struct timeval starttime;
1078     gettimeofday(&starttime, NULL);
1079 #endif
1080     mfForDebugInfo = linkedFile->getMappedFileForDebugInfo();
1081
1082     bool err = true;
1083     imageOffset_ = linkedFile->code_off();
1084     dataOffset_ = linkedFile->data_off();
1085
1086     imageLen_ = linkedFile->code_len();
1087     dataLen_ = linkedFile->data_len();
1088     
1089     if (0 == imageLen_ || 0 == linkedFile->code_ptr()) 
1090     {
1091         // for AIX, code_ptr()==NULL is normal behavior
1092 #if !defined(os_aix)
1093        if (0 == linkedFile->code_ptr()) {
1094           //fprintf(stderr, "[%s][%d]WARNING: null code pointer in Symtab for"
1095           //" file %s, possibly due to a missing .text section.\n",
1096           //__FILE__,__LINE__, file().c_str());
1097           linkedFile->code_ptr_ = (char *) linkedFile->code_off();
1098        }
1099        else 
1100 #endif
1101        {
1102           serr = Obj_Parsing;
1103           return false;
1104        }
1105    }
1106         
1107   //  if (!imageLen_ || !linkedFile->code_ptr()) {
1108   //      serr = Obj_Parsing; 
1109   //      return false; 
1110    // }
1111
1112     no_of_sections = linkedFile->no_of_sections();
1113     newSectionInsertPoint = no_of_sections;
1114     no_of_symbols = linkedFile->no_of_symbols();
1115
1116     hasRel_ = false;
1117     hasRela_ = false;
1118     regions_ = linkedFile->getAllRegions();
1119
1120     for (unsigned index=0;index<regions_.size();index++)
1121     {
1122         if ( regions_[index]->isLoadable() ) 
1123         {
1124            if (     (regions_[index]->getRegionPermissions() == Region::RP_RX) 
1125                  || (regions_[index]->getRegionPermissions() == Region::RP_RWX)) 
1126            {
1127               codeRegions_.push_back(regions_[index]);
1128            }
1129            else 
1130            {
1131                 dataRegions_.push_back(regions_[index]);
1132             }
1133         }
1134
1135         regionsByEntryAddr[regions_[index]->getRegionAddr()] = regions_[index];
1136
1137         if (regions_[index]->getRegionType() == Region::RT_REL) 
1138         {
1139             hasRel_ = true;
1140         }
1141
1142         if (regions_[index]->getRegionType() == Region::RT_RELA) 
1143         {
1144             hasRela_ = true;
1145         }
1146     }
1147     // sort regions_ & codeRegions_ vectors
1148
1149     std::sort(codeRegions_.begin(), codeRegions_.end(), sort_reg_by_addr);
1150     std::sort(dataRegions_.begin(), dataRegions_.end(), sort_reg_by_addr);
1151     std::sort(regions_.begin(), regions_.end(), sort_reg_by_addr);
1152
1153     /* insert error check here. check if parsed */
1154     address_width_ = linkedFile->getAddressWidth();
1155     is_a_out = linkedFile->is_aout();
1156     code_ptr_ = linkedFile->code_ptr();
1157     data_ptr_ = linkedFile->data_ptr();
1158
1159     if (linkedFile->interpreter_name())
1160        interpreter_name_ = std::string(linkedFile->interpreter_name());
1161
1162     entry_address_ = linkedFile->getEntryAddress();
1163     base_address_ = linkedFile->getBaseAddress();
1164     load_address_ = linkedFile->getLoadAddress();
1165     toc_offset_ = linkedFile->getTOCoffset();
1166     object_type_  = linkedFile->objType();
1167     is_eel_ = linkedFile->isEEL();
1168     linkedFile->getSegments(segments_);
1169
1170 #if !defined(os_aix) && !defined(os_windows)
1171     linkedFile->getDependencies(deps_);
1172 #endif
1173
1174 #if defined (os_aix)
1175     //  These should go away
1176     linkedFile->get_stab_info(stabstr_, nstabs_, stabs_, stringpool_);
1177     linkedFile->get_line_info(nlines_, lines_, fdptr_);
1178 #endif
1179
1180 #if defined(os_solaris) || defined(os_aix) || defined(os_linux)
1181     // make sure we're using the right demangler
1182     
1183     nativeCompiler = parseCompilerType(linkedFile);
1184     //parsing_printf("isNativeCompiler: %d\n", nativeCompiler);
1185 #endif
1186     
1187     // define all of the functions
1188     //statusLine("winnowing functions");
1189
1190 #if defined(ppc64_linux)
1191     checkPPC64DescriptorSymbols(linkedFile);
1192 #endif
1193
1194     // a vector to hold all created symbols until they are properly classified
1195     std::vector<Symbol *> raw_syms;
1196
1197 #ifdef BINEDIT_DEBUG
1198     printf("== from linkedFile...\n");
1199     print_symbol_map(linkedFile->getAllSymbols());
1200 #endif
1201
1202     if (!extractSymbolsFromFile(linkedFile, raw_syms)) 
1203     {
1204         err = false;
1205         serr = Syms_To_Functions;
1206         return false;
1207     }
1208
1209 #ifdef BINEDIT_DEBUG
1210     printf("== in Symtab now...\n");
1211     //print_symbols(raw_syms);
1212     std::vector<Symbol *> undefsyms;
1213     std::map<std::string, std::vector<Symbol *> >::iterator iter;
1214     std::vector<Symbol *>::iterator siter;
1215     for (iter = undefDynSyms.begin(); iter != undefDynSyms.end(); iter++)
1216         for (siter = iter->second.begin(); siter != iter->second.end(); siter++)
1217             undefsyms.push_back(*siter);
1218     //print_symbols(undefsyms);
1219     printf("%d total symbol(s)\n", raw_syms.size() + undefsyms.size());
1220 #endif
1221
1222     // don't sort the symbols--preserve the original ordering
1223     //sort(raw_syms.begin(),raw_syms.end(),symbol_compare);
1224
1225     if (!fixSymModules(raw_syms)) 
1226     {
1227         err = false;
1228         serr = Syms_To_Functions;
1229         return false;
1230     }
1231
1232     // wait until all modules are defined before applying languages to
1233     // them we want to do it this way so that module information comes
1234     // from the function symbols, first and foremost, to avoid any
1235     // internal module-function mismatching.
1236             
1237     // get Information on the language each modules is written in
1238     // (prior to making modules)
1239
1240     dyn_hash_map<std::string, supportedLanguages> mod_langs;
1241     linkedFile->getModuleLanguageInfo(&mod_langs);
1242     setModuleLanguages(&mod_langs);
1243         
1244     // Be sure that module languages are set before demangling, or
1245     // we won't get very far.
1246
1247     if (!demangleSymbols(raw_syms)) 
1248     {
1249         err = false;
1250         serr = Syms_To_Functions;
1251         return false;
1252     }
1253
1254     if (!createIndices(raw_syms)) 
1255     {
1256         err = false;
1257         serr = Syms_To_Functions;
1258         return false;
1259     }
1260
1261     if (!createAggregates()) 
1262     {
1263         err = false;
1264         serr = Syms_To_Functions;
1265         return false;
1266     }
1267         
1268 #if 0
1269     // define all of the functions, this also defines all of the modules
1270     if (!symbolsToFunctions(linkedFile, &raw_syms))
1271     {
1272         fprintf(stderr, "%s[%d] Error converting symbols to functions in file %s\n", 
1273                 __FILE__, __LINE__, mf->filename().c_str());
1274         err = false;
1275         serr = Syms_To_Functions;
1276         return false;
1277     }
1278 #endif
1279         
1280     // Once languages are assigned, we can build demangled names (in
1281     // the wider sense of demangling which includes stripping _'s from
1282     // fortran names -- this is why language information must be
1283     // determined before this step).
1284     
1285     // Also identifies aliases (multiple names with equal addresses)
1286     
1287     //addSymtabVariables();
1288     linkedFile->getAllExceptions(excpBlocks);
1289
1290     vector<relocationEntry >fbt;
1291     linkedFile->get_func_binding_table(fbt);
1292     for(unsigned i=0; i<fbt.size();i++)
1293         relocation_table_.push_back(fbt[i]);
1294     return true;
1295 }
1296
1297 Symtab::Symtab(const Symtab& obj) :
1298    LookupInterface(),
1299    Serializable(),
1300    AnnotatableSparse()
1301 {
1302     create_printf("%s[%d]: Creating symtab 0x%p from symtab 0x%p\n", FILE__, __LINE__, this, &obj);
1303   
1304     member_name_ = obj.member_name_;
1305     imageOffset_ = obj.imageOffset_;
1306     imageLen_ = obj.imageLen_;
1307     dataOffset_ = obj.dataOffset_;
1308     dataLen_ = obj.dataLen_;
1309
1310    isLineInfoValid_ = obj.isLineInfoValid_;
1311    isTypeInfoValid_ = obj.isTypeInfoValid_;
1312
1313    is_a_out = obj.is_a_out;
1314    main_call_addr_ = obj.main_call_addr_; // address of call to main()
1315
1316    nativeCompiler = obj.nativeCompiler;
1317    defaultNamespacePrefix = obj.defaultNamespacePrefix;
1318
1319    //sections
1320    no_of_sections = obj.no_of_sections;
1321    unsigned i;
1322
1323    for (i=0;i<obj.regions_.size();i++)
1324       regions_.push_back(new Region(*(obj.regions_[i])));
1325
1326    for (i=0;i<regions_.size();i++)
1327       regionsByEntryAddr[regions_[i]->getRegionAddr()] = regions_[i];
1328
1329    // TODO FIXME: copying symbols/Functions/Variables
1330
1331    for (i=0;i<obj._mods.size();i++)
1332    {
1333       Module *m = new Module(*(obj._mods[i]));
1334       _mods.push_back(m);
1335       modsByFileName[m->fileName()] = m;
1336       modsByFullName[m->fullName()] = m;
1337       fprintf(stderr, "%s[%d]:  copy ctor creating new module %s\n", 
1338             FILE__, __LINE__, m->fileName().c_str());
1339    }
1340
1341    for (i=0; i<relocation_table_.size();i++) 
1342    {
1343       relocation_table_.push_back(relocationEntry(obj.relocation_table_[i]));
1344       //undefDynSyms[obj.relocation_table_[i].name()] = relocation_table_[i].getDynSym();
1345       undefDynSyms[obj.relocation_table_[i].name()].push_back(relocation_table_[i].getDynSym());
1346
1347    }
1348
1349
1350
1351 #if 0
1352     is_a_out = obj.is_a_out;
1353     main_call_addr_ = obj.main_call_addr_; // address of call to main()
1354     
1355     nativeCompiler = obj.nativeCompiler;
1356     defaultNamespacePrefix = obj.defaultNamespacePrefix;
1357     
1358     //sections
1359     no_of_sections = obj.no_of_sections;
1360     unsigned i;
1361     for(i=0;i<obj.regions_.size();i++)
1362         regions_.push_back(new Region(*(obj.regions_[i])));
1363     for(i=0;i<regions_.size();i++)
1364         regionsByEntryAddr[regions_[i]->getRegionAddr()] = regions_[i];
1365
1366     // TODO FIXME: copying symbols/Functions/Variables
1367     
1368     for(i=0;i<obj._mods.size();i++)
1369         _mods.push_back(new Module(*(obj._mods[i])));
1370     for(i=0;i<_mods.size();i++)
1371     {
1372         modsByFileName[_mods[i]->fileName()] = _mods[i];
1373         modsByFullName[_mods[i]->fullName()] = _mods[i];
1374     }
1375     
1376     for(i=0; i<relocation_table_.size();i++) {
1377         relocation_table_.push_back(relocationEntry(obj.relocation_table_[i]));
1378         //undefDynSyms[obj.relocation_table_[i].name()] = relocation_table_[i].getDynSym();
1379         undefDynSyms[obj.relocation_table_[i].name()].push_back(relocation_table_[i].getDynSym());
1380     }
1381     
1382     for(i=0;i<excpBlocks.size();i++)
1383         excpBlocks.push_back(new ExceptionBlock(*(obj.excpBlocks[i])));
1384 #endif
1385
1386    for (i=0;i<excpBlocks.size();i++)
1387    {
1388       excpBlocks.push_back(new ExceptionBlock(*(obj.excpBlocks[i])));
1389    }
1390
1391    deps_ = obj.deps_;
1392    setupTypes();
1393 }
1394
1395 // Address must be in code or data range since some code may end up
1396 // in the data segment
1397 bool Symtab::isValidOffset(const Offset where) const
1398 {
1399    return isCode(where) || isData(where);
1400 }
1401
1402 /* Performs a binary search on the codeRegions_ vector, which must
1403  * be kept in sorted order
1404  */
1405 bool Symtab::isCode(const Offset where)  const
1406 {
1407    if (!codeRegions_.size()) 
1408    {
1409       fprintf(stderr, "%s[%d] No code regions in %s \n",
1410             __FILE__, __LINE__, mf->filename().c_str());
1411       return false;
1412    }
1413
1414    // search for "where" in codeRegions_ (code regions must not overlap)
1415    int first = 0; 
1416    int last = codeRegions_.size() - 1;
1417
1418    while (last >= first) 
1419    {
1420       Region *curreg = codeRegions_[(first + last) / 2];
1421       if (where >= curreg->getRegionAddr()
1422             && where < (curreg->getRegionAddr()
1423                + curreg->getDiskSize())) 
1424       {
1425          return true;
1426       }
1427       else if (where < curreg->getRegionAddr()) 
1428       {
1429          last = ((first + last) / 2) - 1;
1430       }
1431       else if (where >= (curreg->getRegionAddr() + curreg->getMemSize()))
1432       {
1433          first = ((first + last) / 2) + 1;
1434       }
1435       else 
1436       {  // "where" is in the range: 
1437          // [memOffset + diskSize , memOffset + memSize)
1438          // meaning that it's in an uninitialized data region 
1439          return false;
1440       }
1441    }
1442
1443    return false;
1444 }
1445
1446 /* Performs a binary search on the dataRegions_ vector, which must
1447  * be kept in sorted order */
1448 bool Symtab::isData(const Offset where)  const
1449 {
1450    if (!dataRegions_.size()) 
1451    {
1452       fprintf(stderr, "%s[%d] No data regions in %s \n",
1453             __FILE__,__LINE__,mf->filename().c_str());
1454       return false;
1455    }
1456
1457    int first = 0; 
1458    int last = dataRegions_.size() - 1;
1459
1460    while (last >= first) 
1461    {
1462       Region *curreg = dataRegions_[(first + last) / 2];
1463
1464       if (     (where >= curreg->getRegionAddr())
1465             && (where < (curreg->getRegionAddr() + curreg->getRegionSize())))
1466       {
1467          return true;
1468       }
1469       else if (where < curreg->getRegionAddr()) 
1470       {
1471          last = ((first + last) / 2) - 1;
1472       }
1473       else 
1474       {
1475          first = ((first + last) / 2) + 1;
1476       }
1477    }
1478
1479    return false;
1480 }
1481
1482 bool Symtab::getFuncBindingTable(std::vector<relocationEntry> &fbt) const
1483 {
1484    fbt = relocation_table_;
1485    return true;
1486 }
1487
1488 SYMTAB_EXPORT std::vector<std::string> &Symtab::getDependencies(){
1489     return deps_;
1490 }
1491
1492
1493 Symtab::~Symtab()
1494 {
1495    // Doesn't do anything yet, moved here so we don't mess with symtab.h
1496    // Only called if we fail to create a process.
1497    // Or delete the a.out...
1498
1499
1500    for (unsigned i = 0; i < regions_.size(); i++) 
1501    {
1502       delete regions_[i];
1503    }
1504
1505    regions_.clear();
1506    codeRegions_.clear();
1507    dataRegions_.clear();
1508    regionsByEntryAddr.clear();
1509
1510    std::vector<Region *> *user_regions = NULL;
1511    getAnnotation(user_regions, UserRegionsAnno);
1512
1513    if (user_regions)
1514    {
1515       for (unsigned i = 0; i < user_regions->size(); ++i) 
1516          delete (*user_regions)[i];
1517       user_regions->clear();
1518    }
1519
1520    // Symbols are copied from linkedFile, and NOT deleted
1521    everyDefinedSymbol.clear();
1522    undefDynSyms.clear();
1523
1524    // TODO make annotation
1525    userAddedSymbols.clear();
1526    symsByOffset.clear();
1527    symsByMangledName.clear();
1528    symsByPrettyName.clear();
1529    symsByTypedName.clear();
1530
1531    for (unsigned i = 0; i < everyFunction.size(); i++) 
1532    {
1533       delete everyFunction[i];
1534    }
1535
1536    everyFunction.clear();
1537    funcsByOffset.clear();
1538
1539    for (unsigned i = 0; i < everyVariable.size(); i++) 
1540    {
1541       delete everyVariable[i];
1542    }
1543
1544    everyVariable.clear();
1545    varsByOffset.clear();
1546
1547    for (unsigned i = 0; i < _mods.size(); i++) 
1548    {
1549       delete _mods[i];
1550    }
1551    _mods.clear();
1552    modsByFileName.clear();
1553    modsByFullName.clear();
1554
1555    for (unsigned i=0;i<excpBlocks.size();i++)
1556       delete excpBlocks[i];
1557
1558    create_printf("%s[%d]: Symtab::~Symtab removing %p from allSymtabs\n", 
1559          FILE__, __LINE__, this);
1560
1561    deps_.clear();
1562
1563    for (unsigned i = 0; i < allSymtabs.size(); i++) 
1564    {
1565       if (allSymtabs[i] == this)
1566          allSymtabs.erase(allSymtabs.begin()+i);
1567    }
1568
1569    //fprintf(stderr, "%s[%d]:  symtab DTOR, mf = %p: %s\n", FILE__, __LINE__, mf, mf->filename().c_str());
1570    //if (mf) MappedFile::closeMappedFile(mf);
1571    //if (mfForDebugInfo) MappedFile::closeMappedFile(mfForDebugInfo);
1572 }       
1573
1574 bool Symtab::exportXML(string file)
1575 {
1576 #if defined (cap_serialization)
1577    try 
1578    {
1579       SerializerXML sb("XMLTranslator", file, sd_serialize, true);
1580       serialize(&sb, "Symtab");
1581 #if 0
1582       SymtabTranslatorXML trans(this, file);
1583       if ( serialize(*this, trans))
1584          return true;
1585 #endif
1586    } 
1587    catch (const SerializerError &err) 
1588    {
1589       fprintf(stderr, "%s[%d]: error serializing xml: %s\n", FILE__, __LINE__, err.what());
1590       return false;
1591    }
1592
1593    return false;
1594 #else
1595    fprintf(stderr, "%s[%d]:  WARNING:  cannot produce %s, serialization not available\n", FILE__, __LINE__, file.c_str());
1596    return false;
1597 #endif
1598 }
1599
1600 #if defined (cap_serialization)
1601 bool Symtab::exportBin(string file)
1602 {
1603    try
1604    {
1605       //  This needs some work (probably want to do object cacheing and retrieval)
1606       SerializerBin sb("BinSerializer", file, sd_serialize, true);
1607       serialize(&sb, "Symtab");
1608
1609 #if 0 
1610       bool verbose = false;
1611       if (strstr(file.c_str(), "cache_ld")) verbose = true;
1612       SymtabTranslatorBin *transptr = SymtabTranslatorBin::getTranslator(this, file, sd_serialize, verbose);
1613       assert(transptr);
1614       SymtabTranslatorBin &trans = *transptr;
1615       if (serialize(*this, trans))
1616          return true;
1617 #endif
1618       fprintf(stderr, "%s[%d]:  binary serialization ok\n", __FILE__, __LINE__);
1619       return true;
1620    }
1621    catch (const SerializerError &err)
1622    {
1623       if (err.code() == SerializerError::ser_err_disabled) 
1624       {
1625          fprintf(stderr, "%s[%d]:  WARN:  serialization is disabled for file %s\n",
1626                FILE__, __LINE__, file.c_str());
1627          return true;
1628       }
1629       else 
1630       {
1631          fprintf(stderr, "%s[%d]: %s\n\tfrom %s[%d], code %d\n", FILE__, __LINE__,
1632                err.what(), err.file().c_str(), err.line(), err.code());
1633       }
1634    }
1635
1636    fprintf(stderr, "%s[%d]:  error doing binary serialization\n", __FILE__, __LINE__);
1637    return false;
1638 }
1639 #else
1640 bool Symtab::exportBin(string) 
1641 {
1642    fprintf(stderr, "%s[%d]:  WARNING:  serialization not available\n", FILE__, __LINE__);
1643    return false;
1644 }
1645 #endif
1646
1647 Symtab *Symtab::importBin(std::string file)
1648 {
1649 #if defined (cap_serialization)
1650    MappedFile *mf= MappedFile::createMappedFile(file);
1651    if (!mf) 
1652    {
1653       fprintf(stderr, "%s[%d]:  failed to map file %s\n", FILE__, __LINE__, file.c_str());
1654       return NULL;
1655    }
1656
1657    Symtab *st = new Symtab(mf);
1658
1659    try
1660    {
1661       bool verbose = false;
1662       if (strstr(file.c_str(), "ld-")) verbose = true;
1663       SerializerBin sb("BinTranslator", file, sd_deserialize, true);
1664       st->serialize(&sb);
1665 #if 0
1666       SymtabTranslatorBin *transptr = SymtabTranslatorBin::getTranslator(st, file, sd_deserialize, verbose);
1667       assert(transptr);
1668       SymtabTranslatorBin &trans = *transptr;
1669       if (deserialize(*st, trans)) {
1670          fprintf(stderr, "%s[%d]:  deserialized '%s' from cache\n", FILE__, __LINE__, file.c_str());
1671          if (!st) fprintf(stderr, "%s[%d]:  FIXME:  no symtab\n", FILE__, __LINE__);
1672          return st;
1673       }
1674 #endif
1675    }
1676
1677    catch (const SerializerError &err)
1678    {
1679       if (err.code() == SerializerError::ser_err_disabled) 
1680       {
1681          fprintf(stderr, "%s[%d]:  WARN:  serialization is disabled for file %s\n",
1682                FILE__, __LINE__, file.c_str());
1683          return NULL;
1684       }
1685
1686       fprintf(stderr, "%s[%d]: %s\n\tfrom: %s[%d]\n", FILE__, __LINE__,
1687             err.what(), err.file().c_str(), err.line());
1688    }
1689
1690
1691    fprintf(stderr, "%s[%d]:  error doing binary deserialization\n", __FILE__, __LINE__);
1692    delete st;
1693    return NULL;
1694 #else
1695    fprintf(stderr, "%s[%d]:  WARNING:  cannot produce %s, serialization not available\n", FILE__, __LINE__, file.c_str());
1696    return NULL;
1697 #endif
1698 }
1699
1700 bool Symtab::openFile(Symtab *&obj, std::string filename)
1701 {
1702    bool err = false;
1703 #if defined(TIMED_PARSE)
1704    struct timeval starttime;
1705    gettimeofday(&starttime, NULL);
1706 #endif
1707    unsigned numSymtabs = allSymtabs.size();
1708
1709    // AIX: it's possible that we're reparsing a file with better information
1710    // about it. If so, yank the old one out of the allSymtabs std::vector -- replace
1711    // it, basically.
1712    if ( filename.find("/proc") == std::string::npos)
1713    {
1714       for (unsigned u=0; u<numSymtabs; u++) 
1715       {
1716          assert(allSymtabs[u]);
1717          if (filename == allSymtabs[u]->file()) 
1718          {
1719             // return it
1720             obj = allSymtabs[u];
1721             return true;
1722          }
1723       }   
1724    }
1725
1726 #if defined (cap_serialization)
1727    obj = importBin(filename);
1728
1729    if (!obj) 
1730    {
1731       fprintf(stderr, "%s[%d]:  importBin failed\n", FILE__, __LINE__);
1732    }
1733    else 
1734    {
1735       return true;
1736    }
1737 #endif
1738
1739    obj = new Symtab(filename, err);
1740 #if defined(TIMED_PARSE)
1741    struct timeval endtime;
1742    gettimeofday(&endtime, NULL);
1743    unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
1744    unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
1745    unsigned long difftime = lendtime - lstarttime;
1746    double dursecs = difftime/(1000 );
1747    cout << __FILE__ << ":" << __LINE__ <<": openFile "<< filename<< " took "<<dursecs <<" msecs" << endl;
1748 #endif
1749
1750    if (!err)
1751    {
1752       if (filename.find("/proc") == std::string::npos)
1753          allSymtabs.push_back(obj);
1754
1755       obj->setupTypes();        
1756
1757 #if defined (cap_serialization)
1758       fprintf(stderr, "%s[%d]:  doing bin-serialize for %s\n", 
1759             FILE__, __LINE__, filename.c_str());
1760
1761       if (!obj->exportBin(filename))
1762       {
1763          fprintf(stderr, "%s[%d]:  failed to export symtab\n", FILE__, __LINE__);
1764       }
1765       else
1766          fprintf(stderr, "%s[%d]:  did bin-serialize for %s\n", 
1767                FILE__, __LINE__, filename.c_str());
1768 #endif
1769
1770     }
1771     else
1772     {
1773        create_printf("%s[%d]: WARNING: failed to open symtab for %s\n", 
1774              FILE__, __LINE__, filename.c_str());
1775        delete obj;
1776        obj = NULL;
1777     }
1778
1779    // returns true on success (not an error)
1780    return !err;
1781 }
1782
1783 bool Symtab::addRegion(Offset vaddr, void *data, unsigned int dataSize, std::string name, Region::RegionType rType_, bool loadable)
1784 {
1785    Region *sec;
1786    unsigned i;
1787    if (loadable)
1788    {
1789       sec = new Region(newSectionInsertPoint, name, vaddr, dataSize, vaddr, 
1790             dataSize, (char *)data, Region::RP_R, rType_, true);
1791
1792       regions_.insert(regions_.begin()+newSectionInsertPoint, sec);
1793
1794       for (i = newSectionInsertPoint+1; i < regions_.size(); i++)
1795       {
1796          regions_[i]->setRegionNumber(regions_[i]->getRegionNumber() + 1);
1797       }
1798
1799       if (    (sec->getRegionType() == Region::RT_TEXT) 
1800             || (sec->getRegionType() == Region::RT_TEXTDATA))
1801       {
1802          codeRegions_.push_back(sec);
1803          std::sort(codeRegions_.begin(), codeRegions_.end(), sort_reg_by_addr);
1804       }
1805
1806       if (    (sec->getRegionType() == Region::RT_DATA) 
1807             || (sec->getRegionType() == Region::RT_TEXTDATA))
1808       {
1809          dataRegions_.push_back(sec);
1810          std::sort(dataRegions_.begin(), dataRegions_.end(), sort_reg_by_addr);
1811       }
1812    }
1813    else
1814    {
1815       sec = new Region(regions_.size()+1, name, vaddr, dataSize, 0, 0, 
1816             (char *)data, Region::RP_R, rType_);
1817       regions_.push_back(sec);
1818    }
1819
1820    addUserRegion(sec);
1821    std::sort(regions_.begin(), regions_.end(), sort_reg_by_addr);
1822    return true;
1823 }
1824
1825 bool Symtab::addUserRegion(Region *reg)
1826 {
1827    std::vector<Region *> *user_regions = NULL;
1828
1829    if (!getAnnotation(user_regions, UserRegionsAnno))
1830    {
1831       user_regions = new std::vector<Region *>();
1832       if (!addAnnotation(user_regions, UserRegionsAnno))
1833       {
1834          fprintf(stderr, "%s[%d]:  failed to addAnnotation here\n", FILE__, __LINE__);
1835          return false;
1836       }
1837    }
1838
1839    if (!user_regions)
1840    {
1841       fprintf(stderr, "%s[%d]:  failed to addAnnotation here\n", FILE__, __LINE__);
1842       return false;
1843    }
1844
1845    user_regions->push_back(reg);
1846
1847    return true;
1848 }
1849
1850 bool Symtab::addUserType(Type *t)
1851 {
1852    std::vector<Type *> *user_types = NULL;
1853
1854    if (!getAnnotation(user_types, UserTypesAnno))
1855    {
1856       user_types = new std::vector<Type *>();
1857       if (!addAnnotation(user_types, UserTypesAnno))
1858       {
1859          fprintf(stderr, "%s[%d]:  failed to addAnnotation here\n", FILE__, __LINE__);
1860          return false;
1861       }
1862    }
1863    if (!user_types)
1864    {
1865       fprintf(stderr, "%s[%d]:  failed to addAnnotation here\n", FILE__, __LINE__);
1866       return false;
1867    }
1868
1869    user_types->push_back(t);
1870
1871    return true;
1872 }
1873
1874 bool Symtab::addRegion(Region *sec)
1875 {
1876    regions_.push_back(sec);
1877    std::sort(regions_.begin(), regions_.end(), sort_reg_by_addr);
1878    addUserRegion(sec);
1879    return true;
1880 }
1881
1882 void Symtab::parseLineInformation()
1883 {
1884    dyn_hash_map<std::string, LineInformation> *lineInfo = new dyn_hash_map <std::string, LineInformation>;
1885
1886    Object *linkedFile = getObject();
1887    linkedFile->parseFileLineInfo(*lineInfo);
1888
1889    isLineInfoValid_ = true;     
1890    dyn_hash_map <std::string, LineInformation>::iterator iter;
1891
1892    for (iter = lineInfo->begin(); iter!=lineInfo->end(); iter++)
1893    {
1894       Module *mod = NULL;
1895       if (findModuleByName(mod, iter->first))
1896       {
1897          mod->setLineInfo(&(iter->second));
1898       }
1899       else if (findModuleByName(mod, mf->filename()))
1900       {
1901          LineInformation *lineInformation = mod->getLineInformation();
1902          if (!lineInformation) 
1903          {
1904             mod->setLineInfo(&(iter->second));
1905          } 
1906          else 
1907          {
1908             lineInformation->addLineInfo(&(iter->second));
1909             mod->setLineInfo(lineInformation);
1910          }
1911       }
1912       else {
1913         object_printf("[%s:%u] - Couldn't find module %s to go with line info\n",
1914                      __FILE__, __LINE__, iter->first.c_str()); 
1915       }
1916    }
1917 }
1918
1919 SYMTAB_EXPORT bool Symtab::getAddressRanges(std::vector<pair<Offset, Offset> >&ranges,
1920       std::string lineSource, unsigned int lineNo)
1921 {
1922    unsigned int originalSize = ranges.size();
1923
1924    /* Iteratate over the modules, looking for ranges in each. */
1925
1926    for ( unsigned int i = 0; i < _mods.size(); i++ ) 
1927    {
1928       LineInformation *lineInformation = _mods[i]->getLineInformation();
1929
1930       if (lineInformation)
1931          lineInformation->getAddressRanges( lineSource.c_str(), lineNo, ranges );
1932
1933    } /* end iteration over modules */
1934
1935    if ( ranges.size() != originalSize )
1936       return true;
1937
1938    return false;
1939 }
1940
1941 SYMTAB_EXPORT bool Symtab::getSourceLines(std::vector<LineNoTuple> &lines, Offset addressInRange)
1942 {
1943    unsigned int originalSize = lines.size();
1944
1945    /* Iteratate over the modules, looking for ranges in each. */
1946    for ( unsigned int i = 0; i < _mods.size(); i++ ) 
1947    {
1948       LineInformation *lineInformation = _mods[i]->getLineInformation();
1949
1950       if (lineInformation)
1951          lineInformation->getSourceLines( addressInRange, lines );
1952
1953    } /* end iteration over modules */
1954
1955    if ( lines.size() != originalSize )
1956       return true;
1957
1958    return false;
1959
1960 }
1961
1962 SYMTAB_EXPORT bool Symtab::addLine(std::string lineSource, unsigned int lineNo,
1963       unsigned int lineOffset, Offset lowInclAddr,
1964       Offset highExclAddr)
1965 {
1966    Module *mod;
1967
1968    if (!findModuleByName(mod, lineSource))
1969    {
1970       std::string fileNm = extract_pathname_tail(lineSource);
1971
1972       if (!findModuleByName(mod, fileNm))
1973       {
1974          if (!findModuleByName(mod, mf->pathname()))
1975             return false;
1976       }    
1977    }
1978
1979    LineInformation *lineInfo = mod->getLineInformation();
1980
1981    if (!lineInfo)
1982       return false;
1983
1984    return (lineInfo->addLine(lineSource.c_str(), lineNo, lineOffset, 
1985             lowInclAddr, highExclAddr));
1986 }
1987
1988 SYMTAB_EXPORT bool Symtab::addAddressRange( Offset lowInclusiveAddr, Offset highExclusiveAddr,
1989       std::string lineSource, unsigned int lineNo,
1990       unsigned int lineOffset)
1991 {
1992    Module *mod;
1993
1994    if (!findModuleByName(mod, lineSource))
1995    {
1996       std::string fileNm = extract_pathname_tail(lineSource);
1997
1998       if (!findModuleByName(mod, fileNm))
1999          return false;
2000    }
2001
2002    LineInformation *lineInfo = mod->getLineInformation();
2003
2004    if (!lineInfo)
2005       return false;
2006
2007    return (lineInfo->addAddressRange(lowInclusiveAddr, highExclusiveAddr, 
2008             lineSource.c_str(), lineNo, lineOffset));
2009 }
2010
2011
2012 void Symtab::parseTypes()
2013 {
2014    Object *linkedFile = getObject();
2015    linkedFile->parseTypeInfo(this);
2016    isTypeInfoValid_ = true;
2017 }
2018
2019 bool Symtab::addType(Type *type)
2020 {
2021    if (!addUserType(type))
2022    {
2023       fprintf(stderr, "%s[%d]:  failed to addUserType\n", FILE__, __LINE__);
2024    }
2025
2026    typeCollection *globaltypes = typeCollection::getGlobalTypeCollection();
2027    globaltypes->addType(type);
2028
2029    return true;
2030 }
2031
2032 SYMTAB_EXPORT vector<Type *> *Symtab::getAllstdTypes()
2033 {
2034    setupStdTypes();
2035    return stdTypes->getAllTypes();      
2036 }
2037
2038 SYMTAB_EXPORT vector<Type *> *Symtab::getAllbuiltInTypes()
2039 {
2040    setupStdTypes();
2041    return builtInTypes->getAllBuiltInTypes();
2042 }
2043
2044 SYMTAB_EXPORT bool Symtab::findType(Type *&type, std::string name)
2045 {
2046    parseTypesNow();
2047
2048    if (!_mods.size())
2049       return false;
2050
2051    type = _mods[0]->getModuleTypes()->findType(name);
2052
2053    if (type == NULL)
2054       return false;
2055
2056    return true; 
2057 }
2058
2059 SYMTAB_EXPORT bool Symtab::findVariableType(Type *&type, std::string name)
2060 {
2061    parseTypesNow();
2062
2063    if (!_mods.size())
2064       return false;
2065
2066    type = _mods[0]->getModuleTypes()->findVariableType(name);
2067
2068    if (type == NULL)
2069       return false;
2070
2071    return true; 
2072 }
2073
2074 SYMTAB_EXPORT bool Symtab::findLocalVariable(std::vector<localVar *>&vars, std::string name)
2075 {
2076    parseTypesNow();
2077    unsigned origSize = vars.size();
2078
2079    for (unsigned i = 0; i < everyFunction.size(); i++)
2080    {
2081       everyFunction[i]->findLocalVariable(vars, name);
2082    }
2083
2084    if (vars.size()>origSize)
2085       return true;
2086
2087    return false;        
2088 }
2089
2090 SYMTAB_EXPORT bool Symtab::hasRel() const
2091 {
2092    return hasRel_;
2093 }
2094
2095 SYMTAB_EXPORT bool Symtab::hasRela() const
2096 {
2097    return hasRela_;
2098 }
2099
2100 bool Symtab::setDefaultNamespacePrefix(string &str)
2101 {
2102    defaultNamespacePrefix = str;
2103    return true;
2104 }
2105
2106 SYMTAB_EXPORT bool Symtab::emitSymbols(Object *linkedFile,std::string filename, unsigned flag)
2107 {
2108     // Start with all the defined symbols
2109     std::vector<Symbol *> allSyms;
2110     for (unsigned i = 0; i < everyDefinedSymbol.size(); i++) {
2111         allSyms.push_back(everyDefinedSymbol[i]);
2112     }
2113
2114     // Add the undefined dynamic symbols
2115     map<string, std::vector<Symbol *> >::iterator iter;
2116     std::vector<Symbol *>::iterator siter;
2117
2118     for (iter = undefDynSyms.begin(); iter != undefDynSyms.end(); iter++)
2119         for (siter=iter->second.begin(); siter != iter->second.end(); siter++)
2120             allSyms.push_back(*siter);
2121
2122     // Write the new file
2123     return linkedFile->emitDriver(this, filename, allSyms, flag);
2124 }
2125
2126 SYMTAB_EXPORT bool Symtab::emit(std::string filename, unsigned flag)
2127 {
2128     return emitSymbols(getObject(), filename, flag);
2129 }
2130
2131 SYMTAB_EXPORT void Symtab::addDynLibSubstitution(std::string oldName, std::string newName)
2132 {
2133    dynLibSubs[oldName] = newName;
2134 }
2135
2136 SYMTAB_EXPORT std::string Symtab::getDynLibSubstitution(std::string name)
2137 {
2138 #ifdef BINEDIT_DEBUG
2139    map<std::string, std::string>::iterator iter = dynLibSubs.begin();
2140
2141    printf ("substitutions for %s:\n", mf->filename().c_str());
2142
2143    while (iter != dynLibSubs.end()) 
2144    {
2145       printf("  \"%s\" => \"%s\"\n", iter->first.c_str(), iter->second.c_str());
2146       iter++;
2147    }
2148 #endif
2149
2150    map<std::string, std::string>::iterator loc = dynLibSubs.find(name);
2151
2152    if (loc == dynLibSubs.end())
2153       return name;
2154    else
2155       return loc->second;
2156 }
2157
2158 SYMTAB_EXPORT bool Symtab::getSegments(vector<Segment> &segs) const
2159 {
2160    segs = segments_;
2161
2162    if (!segments_.size()) 
2163       return false;
2164
2165    return true;
2166 }
2167
2168 SYMTAB_EXPORT bool Symtab::getMappedRegions(std::vector<Region *> &mappedRegs) const
2169 {
2170    unsigned origSize = mappedRegs.size();
2171
2172    for (unsigned i = 0; i < regions_.size(); i++)
2173    {
2174       if (regions_[i]->isLoadable())
2175          mappedRegs.push_back(regions_[i]);
2176    }
2177
2178    if (mappedRegs.size() > origSize)
2179       return true;
2180
2181    return false;
2182 }
2183
2184 SYMTAB_EXPORT bool Symtab::updateCode(void *buffer, unsigned size)
2185 {
2186    Region *sec;
2187
2188    if (!findRegion(sec, ".text"))
2189       return false;
2190
2191    sec->setPtrToRawData(buffer, size);
2192
2193    return true;
2194 }
2195
2196 SYMTAB_EXPORT bool Symtab::updateData(void *buffer, unsigned size)
2197 {
2198    Region *sec;
2199
2200    if (!findRegion(sec, ".data"))
2201       return false;
2202
2203    sec->setPtrToRawData(buffer, size);
2204
2205    return true;
2206 }
2207
2208 SYMTAB_EXPORT Offset Symtab::getFreeOffset(unsigned size) 
2209 {
2210    // Look through sections until we find a gap with
2211    // sufficient space.
2212    Offset highWaterMark = 0;
2213    Offset secoffset = 0;
2214    Offset prevSecoffset = 0;
2215
2216    Object *linkedFile = getObject();
2217    assert(linkedFile);
2218
2219    for (unsigned i = 0; i < regions_.size(); i++) 
2220    {
2221       Offset end = regions_[i]->getRegionAddr() + regions_[i]->getDiskSize();
2222
2223       if (regions_[i]->getRegionAddr() == 0) 
2224          continue;
2225
2226       prevSecoffset = secoffset;
2227
2228       unsigned region_offset = (unsigned)((char *)(regions_[i]->getPtrToRawData())
2229             - linkedFile->mem_image());
2230
2231       if (region_offset < (unsigned)prevSecoffset)
2232       {
2233          secoffset += regions_[i]->getDiskSize();
2234       }
2235       else 
2236       {
2237          secoffset = (char *)(regions_[i]->getPtrToRawData()) - linkedFile->mem_image();
2238          secoffset += regions_[i]->getDiskSize();
2239       }
2240
2241       /*fprintf(stderr, "%d: secAddr 0x%lx, size %d, end 0x%lx, looking for %d\n",
2242         i, regions_[i]->getSecAddr(), regions_[i]->getSecSize(),
2243         end,size);*/
2244
2245       if (end > highWaterMark) 
2246       {
2247          //fprintf(stderr, "Increasing highWaterMark...\n");
2248          newSectionInsertPoint = i+1;
2249          highWaterMark = end;
2250       }
2251
2252       if (     (i < (regions_.size()-2)) 
2253             && ((end + size) < regions_[i+1]->getRegionAddr())) 
2254       {
2255          /*      fprintf(stderr, "Found a hole between sections %d and %d\n",
2256                  i, i+1);
2257                  fprintf(stderr, "End at 0x%lx, next one at 0x%lx\n",
2258                  end, regions_[i+1]->getSecAddr());
2259           */   
2260          newSectionInsertPoint = i+1;
2261          highWaterMark = end;
2262          break;
2263       }
2264    }
2265
2266    //   return highWaterMark;
2267
2268    unsigned pgSize = P_getpagesize();
2269    Offset newaddr = highWaterMark - (highWaterMark & (pgSize-1)) + (secoffset & (pgSize-1));
2270
2271    if (newaddr < highWaterMark)
2272       newaddr += pgSize;
2273
2274    return newaddr;
2275 }
2276
2277 SYMTAB_EXPORT ObjectType Symtab::getObjectType() const 
2278 {
2279    return object_type_;
2280 }
2281
2282 SYMTAB_EXPORT char *Symtab::mem_image() const 
2283 {
2284    return (char *)mf->base_addr();
2285 }
2286
2287 SYMTAB_EXPORT std::string Symtab::file() const 
2288 {
2289    assert(mf);
2290    return mf->pathname();
2291 }
2292
2293 SYMTAB_EXPORT std::string Symtab::name() const 
2294 {
2295    return mf->filename();
2296 }
2297
2298 SYMTAB_EXPORT unsigned Symtab::getNumberofRegions() const 
2299 {
2300    return no_of_sections; 
2301 }
2302
2303 SYMTAB_EXPORT unsigned Symtab::getNumberofSymbols() const 
2304 {
2305    return no_of_symbols; 
2306 }
2307
2308 bool Symtab::setup_module_up_ptrs(SerializerBase *, Symtab *st)
2309 {
2310    std::vector<Module *> &mods = st->_mods;
2311
2312    for (unsigned int i = 0; i < mods.size(); ++i) 
2313    {
2314       Module *m = mods[i];
2315       m->exec_ = st;
2316    }
2317
2318    return true;
2319 }
2320
2321 bool Symtab::fixup_relocation_symbols(SerializerBase *, Symtab *st)
2322 {
2323    std::vector<Module *> &mods = st->_mods;
2324
2325    for (unsigned int i = 0; i < mods.size(); ++i) 
2326    {
2327       Module *m = mods[i];
2328       m->exec_ = st;
2329    }
2330
2331    return true;
2332 }
2333
2334 void Symtab::serialize(SerializerBase *sb, const char *tag)
2335 {
2336    try 
2337    {
2338       ifxml_start_element(sb, tag);
2339       gtranslate(sb, imageOffset_, "imageOffset");
2340       gtranslate(sb, imageLen_, "imageLen");
2341       gtranslate(sb, dataOffset_, "dataOff");
2342       gtranslate(sb, dataLen_, "dataLen");
2343       gtranslate(sb, is_a_out, "isExec");
2344       gtranslate(sb, _mods, "Modules", "Module");
2345       //gtranslate(sb, everyUniqueFunction, "EveryUniqueFunction", "UniqueFunction");
2346       //gtranslate(sb, everyUniqueVariable, "EveryUniqueVariable", "UniqueVariable");
2347       //gtranslate(sb, modSyms, "ModuleSymbols", "ModuleSymbol");
2348       gtranslate(sb, excpBlocks, "ExceptionBlocks", "ExceptionBlock");
2349       ifxml_end_element(sb, tag);
2350
2351
2352       ifinput(Symtab::setup_module_up_ptrs, sb, this);
2353       ifinput(fixup_relocation_symbols, sb, this);
2354
2355       //  Patch up module's exec_ (pointer to Symtab) at a higher level??
2356       //if (getSD().iomode() == sd_deserialize)
2357       //   param.exec_ = parent_symtab;
2358    } SER_CATCH("Symtab");
2359 }
2360
2361 SYMTAB_EXPORT LookupInterface::LookupInterface() 
2362 {
2363 }
2364
2365 SYMTAB_EXPORT LookupInterface::~LookupInterface()
2366 {
2367 }
2368
2369
2370 SYMTAB_EXPORT ExceptionBlock::ExceptionBlock(Offset tStart, 
2371       unsigned tSize, 
2372       Offset cStart) 
2373 : tryStart_(tStart), trySize_(tSize), catchStart_(cStart), hasTry_(true) 
2374 {
2375 }
2376
2377    SYMTAB_EXPORT ExceptionBlock::ExceptionBlock(Offset cStart) 
2378 : tryStart_(0), trySize_(0), catchStart_(cStart), hasTry_(false) 
2379 {
2380 }
2381
2382 SYMTAB_EXPORT ExceptionBlock::ExceptionBlock(const ExceptionBlock &eb) :
2383    Serializable(),
2384    tryStart_(eb.tryStart_), trySize_(eb.trySize_), 
2385    catchStart_(eb.catchStart_), hasTry_(eb.hasTry_) 
2386 {
2387 }
2388 SYMTAB_EXPORT bool ExceptionBlock::hasTry() const
2389
2390    return hasTry_; 
2391 }
2392
2393 SYMTAB_EXPORT Offset ExceptionBlock::tryStart() const
2394
2395    return tryStart_; 
2396 }
2397
2398 SYMTAB_EXPORT Offset ExceptionBlock::tryEnd() const
2399
2400    return tryStart_ + trySize_; 
2401 }
2402
2403 SYMTAB_EXPORT Offset ExceptionBlock::trySize() const
2404 {
2405    return trySize_; 
2406 }
2407
2408 SYMTAB_EXPORT bool ExceptionBlock::contains(Offset a) const
2409
2410    return (a >= tryStart_ && a < tryStart_ + trySize_); 
2411 }
2412
2413 void ExceptionBlock::serialize(SerializerBase *sb, const char *tag)
2414 {
2415    try 
2416    {
2417       ifxml_start_element(sb, tag);
2418       gtranslate(sb, tryStart_, "tryStart");
2419       gtranslate(sb, trySize_, "trySize");
2420       gtranslate(sb, catchStart_, "catchStart");
2421       gtranslate(sb, hasTry_, "hasTry");
2422       ifxml_end_element(sb, tag);
2423    } SER_CATCH("Symtab");
2424 }
2425
2426
2427 SYMTAB_EXPORT relocationEntry::relocationEntry() :
2428    target_addr_(0), 
2429    rel_addr_(0), 
2430    addend_(0), 
2431    rtype_(Region::RT_REL), 
2432    name_(""), 
2433    dynref_(NULL), 
2434    relType_(0)
2435 {
2436 }   
2437
2438 SYMTAB_EXPORT relocationEntry::relocationEntry(Offset ta, Offset ra, std::string n, 
2439       Symbol *dynref, unsigned long relType) :
2440    target_addr_(ta), 
2441    rel_addr_(ra), 
2442    addend_(0), 
2443    rtype_(Region::RT_REL), 
2444    name_(n), 
2445    dynref_(dynref), 
2446    relType_(relType)
2447 {
2448 }   
2449
2450 SYMTAB_EXPORT relocationEntry::relocationEntry(Offset ta, Offset ra, Offset add, 
2451       std::string n, Symbol *dynref, unsigned long relType) :
2452    target_addr_(ta), 
2453    rel_addr_(ra), 
2454    addend_(add), 
2455    rtype_(Region::RT_REL), 
2456    name_(n), 
2457    dynref_(dynref), 
2458    relType_(relType)
2459 {
2460 }
2461
2462 SYMTAB_EXPORT relocationEntry::relocationEntry(Offset ra, std::string n, 
2463       Symbol *dynref, unsigned long relType, Region::RegionType rtype) :
2464    target_addr_(0), 
2465    rel_addr_(ra), 
2466    addend_(0), 
2467    rtype_(rtype), 
2468    name_(n), 
2469    dynref_(dynref), 
2470    relType_(relType)
2471 {
2472 }   
2473
2474 SYMTAB_EXPORT const relocationEntry& relocationEntry::operator=(const relocationEntry &ra) 
2475 {
2476    target_addr_ = ra.target_addr_;
2477    rel_addr_ = ra.rel_addr_;
2478    addend_ = ra.addend_;
2479    rtype_ = ra.rtype_;
2480    name_ = ra.name_; 
2481    dynref_ = ra.dynref_;
2482    relType_ = ra.relType_;
2483    return *this;
2484 }
2485
2486 SYMTAB_EXPORT void relocationEntry::setAddend(const Offset value) {
2487     addend_ = value;
2488 }
2489
2490 SYMTAB_EXPORT Offset relocationEntry::addend() const {
2491     return addend_;
2492 }
2493
2494 SYMTAB_EXPORT void relocationEntry::setRegionType(const Region::RegionType value) {
2495     rtype_ = value;
2496 }
2497
2498 SYMTAB_EXPORT Region::RegionType relocationEntry::regionType() const {
2499         return rtype_;
2500 }
2501
2502 void relocationEntry::serialize(SerializerBase *sb, const char *tag)
2503 {
2504    try 
2505    {
2506       ifxml_start_element(sb, tag);
2507       gtranslate(sb, target_addr_, "targetAddress");
2508       gtranslate(sb, rel_addr_, "relocationAddress");
2509       gtranslate(sb, name_, "relocationName");
2510       gtranslate(sb, relType_, "relocationType");
2511       //  deserialize: Re-assign dynref_ symbol elsewhere (in Symtab class)
2512       ifxml_end_element(sb, tag);
2513    } SER_CATCH("relocationEntry");
2514 }
2515
2516
2517 const char *Symbol::symbolType2Str(SymbolType t) 
2518 {
2519    switch (t) 
2520    {
2521       CASE_RETURN_STR(ST_UNKNOWN);
2522       CASE_RETURN_STR(ST_FUNCTION);
2523       CASE_RETURN_STR(ST_OBJECT);
2524       CASE_RETURN_STR(ST_MODULE);
2525       CASE_RETURN_STR(ST_SECTION);
2526       CASE_RETURN_STR(ST_NOTYPE);
2527    };
2528
2529    return "invalid symbol type";
2530 }
2531
2532 const char *Symbol::symbolLinkage2Str(SymbolLinkage t) 
2533 {
2534    switch (t) 
2535    {
2536       CASE_RETURN_STR(SL_UNKNOWN);
2537       CASE_RETURN_STR(SL_GLOBAL);
2538       CASE_RETURN_STR(SL_LOCAL);
2539       CASE_RETURN_STR(SL_WEAK);
2540    };
2541
2542    return "invalid symbol linkage";
2543 }
2544
2545 const char *Symbol::symbolTag2Str(SymbolTag t) 
2546 {
2547    switch (t) 
2548    {
2549       CASE_RETURN_STR(TAG_UNKNOWN);
2550       CASE_RETURN_STR(TAG_USER);
2551       CASE_RETURN_STR(TAG_LIBRARY);
2552       CASE_RETURN_STR(TAG_INTERNAL);
2553    };
2554
2555    return "invalid symbol tag";
2556 }
2557
2558 const char *Symbol::symbolVisibility2Str(SymbolVisibility t) 
2559 {
2560    switch(t) {
2561       CASE_RETURN_STR(SV_UNKNOWN);
2562       CASE_RETURN_STR(SV_DEFAULT);
2563       CASE_RETURN_STR(SV_INTERNAL);
2564       CASE_RETURN_STR(SV_HIDDEN);
2565       CASE_RETURN_STR(SV_PROTECTED);
2566    }
2567    return "invalid symbol visibility";
2568 }
2569
2570
2571 Object *Symtab::getObject()
2572 {
2573    if (obj_private)
2574       return obj_private;
2575
2576    //TODO: This likely triggered because we serialized in an object
2577    // from cache, but now the user is requesting more information from
2578    // the on disk object.  We should create a new 'Object' from data
2579    // (likely a file path) serialized in.
2580    
2581    assert(0);
2582    //obj_private = new Object();
2583    return obj_private;
2584 }
2585
2586 #if defined (cap_serialization)
2587 //  Not sure this is strictly necessary, problems only seem to exist with Module 
2588 // annotations when the file was split off, so there's probably something else that
2589 //  can be done to instantiate the relevant functions.
2590
2591 bool dummy_for_ser_instance(std::string file, SerializerBase *sb)
2592 {
2593    if (file == std::string("no_such_file")) 
2594    {
2595       if (!sb) 
2596       {
2597          fprintf(stderr, "%s[%d]:  really should not happen\n", FILE__, __LINE__);
2598          return false;
2599       }
2600 #if 0
2601       bool r = false;
2602       const char *sbb = "no_name_dummy";
2603       r = init_anno_serialization<Dyninst::SymtabAPI::localVarCollection, symbol_parameters_a >(sbb);
2604       if (!r) {fprintf(stderr, "%s[%d]:  failed to init anno serialize for symbol_params\n", FILE__, __LINE__);}
2605       r = false;
2606       r = init_anno_serialization<Dyninst::SymtabAPI::localVarCollection, symbol_variables_a>(sbb);
2607       if (!r) {fprintf(stderr, "%s[%d]:  failed to init anno serialize for symbol_vars\n", FILE__, __LINE__);}
2608       r = false;
2609       r = init_anno_serialization<Dyninst::SymtabAPI::LineInformation *, module_line_info_a>(sbb);
2610       if (!r) {fprintf(stderr, "%s[%d]:  failed to init anno serialize for module_line_info\n", FILE__, __LINE__);}
2611       r = false;
2612       r = init_anno_serialization<Dyninst::SymtabAPI::typeCollection *, module_type_info_a>(sbb);
2613       if (!r) {fprintf(stderr, "%s[%d]:  failed to init anno serialize for module_type_info\n", FILE__, __LINE__);}
2614       r = false;
2615 #else
2616       fprintf(stderr, "%s[%d]:  WARN:  disabled serializer init here\n", FILE__, __LINE__);
2617 #endif
2618    }
2619    return true;
2620 }
2621 #endif
2622