00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <assert.h>
00034 #include <string.h>
00035 #include <algorithm>
00036 #include <iostream>
00037 #include <iomanip>
00038 #include <sstream>
00039
00040 #include "common/h/Timer.h"
00041 #include "common/h/debugOstream.h"
00042 #include "common/h/serialize.h"
00043 #include "common/h/pathName.h"
00044
00045 #include "Serialization.h"
00046 #include "Symtab.h"
00047 #include "Module.h"
00048 #include "Collections.h"
00049 #include "Function.h"
00050 #include "Variable.h"
00051
00052 #include "annotations.h"
00053
00054 #include "debug.h"
00055
00056 #include "symtabAPI/src/Object.h"
00057
00058 #if !defined(os_windows)
00059 #include <dlfcn.h>
00060 #else
00061 #include <windows.h>
00062 #endif
00063
00064 #include <iomanip>
00065 #include <stdarg.h>
00066
00067 using namespace Dyninst;
00068 using namespace Dyninst::SymtabAPI;
00069 using namespace std;
00070
00071 static std::string errMsg;
00072 extern bool parseCompilerType(Object *);
00073
00074 static const int Symtab_major_version = 8;
00075 static const int Symtab_minor_version = 1;
00076 static const int Symtab_maintenance_version = 2;
00077
00078
00079 void Symtab::version(int& major, int& minor, int& maintenance)
00080 {
00081 major = Symtab_major_version;
00082 minor = Symtab_minor_version;
00083 maintenance = Symtab_maintenance_version;
00084 }
00085
00086
00087 void symtab_log_perror(const char *msg)
00088 {
00089 errMsg = std::string(msg);
00090 };
00091
00092
00093 SymtabError serr;
00094
00095 std::vector<Symtab *> Symtab::allSymtabs;
00096
00097
00098 SymtabError Symtab::getLastSymtabError()
00099 {
00100 return serr;
00101 }
00102
00103 void setSymtabError(SymtabError new_err)
00104 {
00105 serr = new_err;
00106 }
00107
00108 std::string Symtab::printError(SymtabError serr)
00109 {
00110 switch (serr)
00111 {
00112 case Obj_Parsing:
00113 return "Failed to parse the Object"+errMsg;
00114 case Syms_To_Functions:
00115 return "Failed to convert Symbols to Functions";
00116 case No_Such_Function:
00117 return "Function does not exist";
00118 case No_Such_Variable:
00119 return "Variable does not exist";
00120 case No_Such_Module:
00121 return "Module does not exist";
00122 case No_Such_Region:
00123 return "Region does not exist";
00124 case No_Such_Symbol:
00125 return "Symbol does not exist";
00126 case Not_A_File:
00127 return "Not a File. Call openArchive()";
00128 case Not_An_Archive:
00129 return "Not an Archive. Call openFile()";
00130 case Export_Error:
00131 return "Error Constructing XML"+errMsg;
00132 case Emit_Error:
00133 return "Error rewriting binary: " + errMsg;
00134 case Invalid_Flags:
00135 return "Flags passed are invalid.";
00136 case No_Error:
00137 return "No previous Error.";
00138 default:
00139 return "Unknown Error";
00140 }
00141 }
00142
00143 boost::shared_ptr<Type> Symtab::type_Error()
00144 {
00145 static boost::shared_ptr<Type> store =
00146 boost::shared_ptr<Type>(new Type(std::string("<error>"), 0, dataUnknownType));
00147 return store;
00148 }
00149 boost::shared_ptr<Type> Symtab::type_Untyped()
00150 {
00151 static boost::shared_ptr<Type> store =
00152 boost::shared_ptr<Type>(new Type(std::string("<no type>"), 0, dataUnknownType));
00153 return store;
00154 }
00155
00156 boost::shared_ptr<builtInTypeCollection> Symtab::builtInTypes()
00157 {
00158 static boost::shared_ptr<builtInTypeCollection> store =
00159 setupBuiltinTypes();
00160 return store;
00161 }
00162 boost::shared_ptr<typeCollection> Symtab::stdTypes()
00163 {
00164 static boost::shared_ptr<typeCollection> store =
00165 setupStdTypes();
00166 return store;
00167 }
00168
00169 boost::shared_ptr<builtInTypeCollection> Symtab::setupBuiltinTypes()
00170 {
00171 boost::shared_ptr<builtInTypeCollection> builtInTypes =
00172 boost::shared_ptr<builtInTypeCollection>(new builtInTypeCollection);
00173
00174 typeScalar *newType;
00175
00176
00177
00178
00179 builtInTypes->addBuiltInType(newType = new typeScalar(-1, 4, "int", true));
00180 newType->decrRefCount();
00181
00182 builtInTypes->addBuiltInType(newType = new typeScalar(-2, 1, "char", true));
00183 newType->decrRefCount();
00184
00185 builtInTypes->addBuiltInType(newType = new typeScalar(-3, 2, "short", true));
00186 newType->decrRefCount();
00187
00188 builtInTypes->addBuiltInType(newType = new typeScalar(-4, sizeof(long), "long", true));
00189 newType->decrRefCount();
00190
00191 builtInTypes->addBuiltInType(newType = new typeScalar(-5, 1, "unsigned char"));
00192 newType->decrRefCount();
00193
00194 builtInTypes->addBuiltInType(newType = new typeScalar(-6, 1, "signed char", true));
00195 newType->decrRefCount();
00196
00197 builtInTypes->addBuiltInType(newType = new typeScalar(-7, 2, "unsigned short"));
00198 newType->decrRefCount();
00199
00200 builtInTypes->addBuiltInType(newType = new typeScalar(-8, 4, "unsigned int"));
00201 newType->decrRefCount();
00202
00203 builtInTypes->addBuiltInType(newType = new typeScalar(-9, 4, "unsigned"));
00204 newType->decrRefCount();
00205
00206 builtInTypes->addBuiltInType(newType = new typeScalar(-10, sizeof(unsigned long), "unsigned long"));
00207 newType->decrRefCount();
00208
00209
00210 builtInTypes->addBuiltInType(newType = new typeScalar(-11, 0, "void", false));
00211 newType->decrRefCount();
00212
00213 builtInTypes->addBuiltInType(newType = new typeScalar(-12, sizeof(float), "float", true));
00214 newType->decrRefCount();
00215
00216 builtInTypes->addBuiltInType(newType = new typeScalar(-13, sizeof(double), "double", true));
00217 newType->decrRefCount();
00218
00219 builtInTypes->addBuiltInType(newType = new typeScalar(-14, sizeof(long double), "long double", true));
00220 newType->decrRefCount();
00221
00222 builtInTypes->addBuiltInType(newType = new typeScalar(-15, 4, "integer", true));
00223 newType->decrRefCount();
00224
00225
00226 builtInTypes->addBuiltInType(newType = new typeScalar(-16, sizeof(bool), "boolean"));
00227 newType->decrRefCount();
00228
00229
00230 builtInTypes->addBuiltInType(newType = new typeScalar(-17, sizeof(float), "short real", true));
00231 newType->decrRefCount();
00232
00233 builtInTypes->addBuiltInType(newType = new typeScalar(-18, sizeof(double), "real", true));
00234 newType->decrRefCount();
00235
00236 builtInTypes->addBuiltInType(newType = new typeScalar(-19, sizeof(void *), "stringptr"));
00237 newType->decrRefCount();
00238
00239 builtInTypes->addBuiltInType(newType = new typeScalar(-20, 1, "character"));
00240 newType->decrRefCount();
00241
00242 builtInTypes->addBuiltInType(newType = new typeScalar(-21, 1, "logical*1"));
00243 newType->decrRefCount();
00244
00245 builtInTypes->addBuiltInType(newType = new typeScalar(-22, 2, "logical*2"));
00246 newType->decrRefCount();
00247
00248 builtInTypes->addBuiltInType(newType = new typeScalar(-23, 4, "logical*4"));
00249 newType->decrRefCount();
00250
00251 builtInTypes->addBuiltInType(newType = new typeScalar(-24, 4, "logical"));
00252 newType->decrRefCount();
00253
00254 builtInTypes->addBuiltInType(newType = new typeScalar(-25, sizeof(float)*2, "complex", true));
00255 newType->decrRefCount();
00256
00257 builtInTypes->addBuiltInType(newType = new typeScalar(-26, sizeof(double)*2, "complex*16", true));
00258 newType->decrRefCount();
00259
00260 builtInTypes->addBuiltInType(newType = new typeScalar(-27, 1, "integer*1", true));
00261 newType->decrRefCount();
00262
00263 builtInTypes->addBuiltInType(newType = new typeScalar(-28, 2, "integer*2", true));
00264 newType->decrRefCount();
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 builtInTypes->addBuiltInType(newType = new typeScalar(-29, 4, "integer*4", true));
00276 newType->decrRefCount();
00277
00278 builtInTypes->addBuiltInType(newType = new typeScalar(-30, 2, "wchar"));
00279 newType->decrRefCount();
00280 #if defined(os_windows)
00281
00282 builtInTypes->addBuiltInType(newType = new typeScalar(-31, sizeof(LONGLONG), "long long", true));
00283 newType->decrRefCount();
00284
00285 builtInTypes->addBuiltInType(newType = new typeScalar(-32, sizeof(ULONGLONG), "unsigned long long"));
00286 newType->decrRefCount();
00287 #else
00288
00289 builtInTypes->addBuiltInType(newType = new typeScalar(-31, sizeof(long long), "long long", true));
00290 newType->decrRefCount();
00291
00292 builtInTypes->addBuiltInType(newType = new typeScalar(-32, sizeof(unsigned long long), "unsigned long long"));
00293 newType->decrRefCount();
00294 #endif
00295
00296 builtInTypes->addBuiltInType(newType = new typeScalar(-33, 8, "logical*8"));
00297 newType->decrRefCount();
00298
00299 builtInTypes->addBuiltInType(newType = new typeScalar(-34, 8, "integer*8", true));
00300 newType->decrRefCount();
00301
00302 return builtInTypes;
00303 }
00304
00305
00306 boost::shared_ptr<typeCollection> Symtab::setupStdTypes()
00307 {
00308 boost::shared_ptr<typeCollection> stdTypes =
00309 boost::shared_ptr<typeCollection>(new typeCollection);
00310
00311 typeScalar *newType;
00312
00313 stdTypes->addType(newType = new typeScalar(-1, sizeof(int), "int"));
00314 newType->decrRefCount();
00315
00316 Type *charType = new typeScalar(-2, sizeof(char), "char");
00317 stdTypes->addType(charType);
00318
00319 std::string tName = "char *";
00320 typePointer *newPtrType;
00321 stdTypes->addType(newPtrType = new typePointer(-3, charType, tName));
00322 charType->decrRefCount();
00323 newPtrType->decrRefCount();
00324
00325 Type *voidType = new typeScalar(-11, 0, "void", false);
00326 stdTypes->addType(voidType);
00327
00328 tName = "void *";
00329 stdTypes->addType(newPtrType = new typePointer(-4, voidType, tName));
00330 voidType->decrRefCount();
00331 newPtrType->decrRefCount();
00332
00333 stdTypes->addType(newType = new typeScalar(-12, sizeof(float), "float"));
00334 newType->decrRefCount();
00335
00336 #if defined(i386_unknown_nt4_0)
00337 stdTypes->addType(newType = new typeScalar(-31, sizeof(LONGLONG), "long long"));
00338 #else
00339 stdTypes->addType(newType = new typeScalar(-31, sizeof(long long), "long long"));
00340 #endif
00341
00342 newType->decrRefCount();
00343
00344 return stdTypes;
00345 }
00346
00347 SYMTAB_EXPORT unsigned Symtab::getAddressWidth() const
00348 {
00349 return address_width_;
00350 }
00351
00352 SYMTAB_EXPORT bool Symtab::isNativeCompiler() const
00353 {
00354 return nativeCompiler;
00355 }
00356
00357 SYMTAB_EXPORT Symtab::Symtab(MappedFile *mf_) :
00358 AnnotatableSparse(),
00359 mf(mf_),
00360 imageOffset_(0),
00361 address_width_(sizeof(int)),
00362 object_type_(obj_Unknown),
00363 defaultNamespacePrefix(""),
00364 no_of_sections(0),
00365 newSectionInsertPoint(0),
00366 no_of_symbols(0),
00367 obj_private(NULL),
00368 _ref_cnt(1)
00369 {
00370 init_debug_symtabAPI();
00371
00372 #if defined(os_vxworks)
00373
00374
00375 object_type_ = obj_RelocatableFile;
00376 imageOffset_ = 0;
00377 dataOffset_ = 0;
00378 imageLen_ = 0;
00379 dataLen_ = 0;
00380 isStaticBinary_ = false;
00381 hasRel_ = false;
00382 hasRela_ = false;
00383 hasReldyn_ = false;
00384 hasReladyn_ = false;
00385 hasRelplt_ = false;
00386 hasRelaplt_ = false;
00387 is_a_out = false;
00388 code_ptr_ = NULL;
00389 data_ptr_ = NULL;
00390 entry_address_ = 0;
00391 base_address_ = 0;
00392 load_address_ = 0;
00393 is_eel_ = false;
00394 #endif
00395
00396 createDefaultModule();
00397 }
00398
00399 SYMTAB_EXPORT Symtab::Symtab() :
00400 imageOffset_(0),
00401 address_width_(sizeof(int)),
00402 object_type_(obj_Unknown),
00403 defaultNamespacePrefix(""),
00404 no_of_sections(0),
00405 newSectionInsertPoint(0),
00406 no_of_symbols(0),
00407 obj_private(NULL),
00408 _ref_cnt(1)
00409 {
00410 init_debug_symtabAPI();
00411 create_printf("%s[%d]: Created symtab via default constructor\n", FILE__, __LINE__);
00412 createDefaultModule();
00413 }
00414
00415 SYMTAB_EXPORT bool Symtab::isExec() const
00416 {
00417 return is_a_out;
00418 }
00419
00420 SYMTAB_EXPORT bool Symtab::isStripped()
00421 {
00422 #if defined(os_linux) || defined(os_freebsd)
00423 Region *sec;
00424 return !findRegion(sec,".symtab");
00425 #else
00426 return (no_of_symbols==0);
00427 #endif
00428 }
00429
00430 SYMTAB_EXPORT Offset Symtab::imageOffset() const
00431 {
00432 return imageOffset_;
00433 }
00434
00435 SYMTAB_EXPORT Offset Symtab::dataOffset() const
00436 {
00437 return dataOffset_;
00438 }
00439
00440 SYMTAB_EXPORT Offset Symtab::dataLength() const
00441 {
00442 return dataLen_;
00443 }
00444
00445 SYMTAB_EXPORT Offset Symtab::imageLength() const
00446 {
00447 return imageLen_;
00448 }
00449
00450 SYMTAB_EXPORT void Symtab::fixup_code_and_data(Offset newImageOffset,
00451 Offset newImageLength,
00452 Offset newDataOffset,
00453 Offset newDataLength)
00454 {
00455 imageOffset_ = newImageOffset;
00456 imageLen_ = newImageLength;
00457 dataOffset_ = newDataOffset;
00458 dataLen_ = newDataLength;
00459
00460
00461 }
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474 SYMTAB_EXPORT const char* Symtab::getInterpreterName() const
00475 {
00476 if (interpreter_name_.length())
00477 return interpreter_name_.c_str();
00478 return NULL;
00479 }
00480
00481 SYMTAB_EXPORT Offset Symtab::getEntryOffset() const
00482 {
00483 return entry_address_;
00484 }
00485
00486 SYMTAB_EXPORT Offset Symtab::getBaseOffset() const
00487 {
00488 return base_address_;
00489 }
00490
00491 SYMTAB_EXPORT Offset Symtab::getLoadOffset() const
00492 {
00493 return load_address_;
00494 }
00495
00496 SYMTAB_EXPORT Offset Symtab::getTOCoffset(Function *func) const
00497 {
00498 return getTOCoffset(func ? func->getOffset() : 0);
00499 }
00500
00501 SYMTAB_EXPORT Offset Symtab::getTOCoffset(Offset off) const
00502 {
00503 return obj_private->getTOCoffset(off);
00504 }
00505
00506 void Symtab::setTOCOffset(Offset off) {
00507 obj_private->setTOCoffset(off);
00508 return;
00509 }
00510
00511 SYMTAB_EXPORT string Symtab::getDefaultNamespacePrefix() const
00512 {
00513 return defaultNamespacePrefix;
00514 }
00515
00516
00517
00518 bool Symtab::buildDemangledName( const std::string &mangled,
00519 std::string &pretty,
00520 std::string &typed,
00521 bool nativeCompiler,
00522 supportedLanguages lang )
00523 {
00524
00525
00526
00527
00528
00529
00530 if ((mangled.length()>5) && (mangled.substr(0,5)==std::string("MPI__")))
00531 {
00532 return false;
00533 }
00534
00535
00536 if (lang == lang_Fortran
00537 || lang == lang_CMFortran
00538 || lang == lang_Fortran_with_pretty_debug )
00539 {
00540 if ( mangled[ mangled.length() - 1 ] == '_' )
00541 {
00542 char * demangled = P_strdup( mangled.c_str() );
00543 demangled[ mangled.length() - 1 ] = '\0';
00544 pretty = std::string( demangled );
00545
00546 free ( demangled );
00547 return true;
00548 }
00549 else
00550 {
00551
00552 return false;
00553 }
00554 }
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567 #if !defined(os_windows)
00568
00569 const char *atat;
00570
00571 if (NULL != (atat = strstr(mangled.c_str(), "@@")))
00572 {
00573 pretty = mangled.substr(0 ,
00574 (int)(atat - mangled.c_str()));
00575
00576
00577
00578
00579
00580
00581
00582 return true;
00583 }
00584
00585 #endif
00586
00587 bool retval = false;
00588
00589
00590 char * demangled = P_cplus_demangle( mangled.c_str(), nativeCompiler, false);
00591 if (demangled)
00592 {
00593 pretty = std::string( demangled );
00594 retval = true;
00595 }
00596
00597 char *t_demangled = P_cplus_demangle(mangled.c_str(), nativeCompiler, true);
00598 if (t_demangled && (strcmp(t_demangled, demangled) != 0))
00599 {
00600 typed = std::string(t_demangled);
00601 retval = true;
00602 }
00603
00604 if (demangled)
00605 free(demangled);
00606 if (t_demangled)
00607 free(t_demangled);
00608
00609 return retval;
00610 }
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625 bool Symtab::extractSymbolsFromFile(Object *linkedFile, std::vector<Symbol *> &raw_syms)
00626 {
00627 for (SymbolIter symIter(*linkedFile); symIter; symIter++) {
00628 Symbol *sym = symIter.currval();
00629 if (!sym) {
00630 fprintf(stderr, "%s[%d]: range error, stopping now\n", FILE__, __LINE__);
00631 return true;
00632 }
00633
00634
00635
00636
00637
00638
00639
00640 fixSymRegion(sym);
00641
00642
00643
00644
00645
00646 #if !defined(os_vxworks)
00647 if (sym->getRegion() == NULL && !sym->isAbsolute() && !sym->isCommonStorage()) {
00648 undefDynSyms.push_back(sym);
00649 continue;
00650 }
00651 #endif
00652
00653
00654
00655
00656
00657
00658 raw_syms.push_back(sym);
00659 }
00660
00661 return true;
00662 }
00663
00664 bool Symtab::fixSymRegion(Symbol *sym) {
00665 if (!sym->getRegion()) return true;
00666
00667 if (sym->getType() != Symbol::ST_FUNCTION &&
00668 sym->getType() != Symbol::ST_OBJECT) return true;
00669
00670 if (sym->getRegion()->getMemOffset() <= sym->getOffset() &&
00671 (sym->getRegion()->getMemOffset() + sym->getRegion()->getMemSize()) > sym->getOffset())
00672 return true;
00673
00674 sym->setRegion(findEnclosingRegion(sym->getOffset()));
00675
00676 return true;
00677 }
00678
00679
00680
00681
00682
00683
00684
00685 bool Symtab::fixSymModules(std::vector<Symbol *> &raw_syms)
00686 {
00687 for (unsigned i = 0; i < raw_syms.size(); i++) {
00688 fixSymModule(raw_syms[i]);
00689 }
00690 Object *obj = getObject();
00691 if (!obj) {
00692 #if !defined(os_vxworks)
00693 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
00694 #endif
00695 return false;
00696 }
00697 const std::vector<std::pair<std::string, Offset> > &mods = obj->modules_;
00698 for (unsigned i=0; i< mods.size(); i++) {
00699 getOrCreateModule(mods[i].first, mods[i].second);
00700 }
00701
00702 return true;
00703 }
00704
00705
00706
00707
00708
00709
00710
00711 bool Symtab::demangleSymbols(std::vector<Symbol *> &raw_syms)
00712 {
00713 for (unsigned i = 0; i < raw_syms.size(); i++) {
00714 demangleSymbol(raw_syms[i]);
00715 }
00716 return true;
00717 }
00718
00719
00720
00721
00722
00723
00724
00725
00726 bool Symtab::createIndices(std::vector<Symbol *> &raw_syms, bool undefined) {
00727 for (unsigned i = 0; i < raw_syms.size(); i++) {
00728 addSymbolToIndices(raw_syms[i], undefined);
00729 }
00730 return true;
00731 }
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741 bool Symtab::createAggregates()
00742 {
00743 #if !defined(os_vxworks)
00744
00745
00746 for (unsigned i = 0; i < everyDefinedSymbol.size(); i++)
00747 {
00748 if (!doNotAggregate(everyDefinedSymbol[i])) {
00749 addSymbolToAggregates(everyDefinedSymbol[i]);
00750 }
00751 }
00752 #endif
00753
00754 return true;
00755 }
00756
00757 bool Symtab::fixSymModule(Symbol *&sym)
00758 {
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768 Module *mod = NULL;
00769 if (getObjectType() == obj_SharedLib) {
00770 mod = getDefaultModule();
00771 }
00772 else {
00773 Object *obj = getObject();
00774 if (!obj)
00775 {
00776 #if !defined(os_vxworks)
00777 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
00778 #endif
00779 return false;
00780 }
00781 std::string modName = obj->findModuleForSym(sym);
00782 if (modName.length() == 0) {
00783 mod = getDefaultModule();
00784 }
00785 else {
00786 mod = getOrCreateModule(modName, sym->getOffset());
00787 }
00788 }
00789
00790
00791 if (!mod)
00792 return false;
00793
00794 sym->setModule(mod);
00795 return true;
00796 }
00797
00798 bool Symtab::demangleSymbol(Symbol *&sym) {
00799 bool typed_demangle = false;
00800 if (sym->getType() == Symbol::ST_FUNCTION) typed_demangle = true;
00801
00802
00803
00804 if (sym->getRegion() == NULL && !sym->isAbsolute() && !sym->isCommonStorage())
00805 typed_demangle = true;
00806
00807 if (typed_demangle) {
00808 Module *rawmod = sym->getModule();
00809
00810
00811
00812
00813
00814
00815
00816
00817 std::string mangled_name = sym->getMangledName();
00818 std::string working_name = mangled_name;
00819
00820 #if !defined(os_windows)
00821
00822 const char *p = strchr(working_name.c_str(), ':');
00823 if( p ) {
00824 unsigned nchars = p - mangled_name.c_str();
00825 working_name = std::string(mangled_name.c_str(), nchars);
00826 }
00827 #endif
00828
00829 std::string pretty_name = working_name;
00830 std::string typed_name = working_name;
00831
00832 if (!buildDemangledName(working_name, pretty_name, typed_name,
00833 nativeCompiler, (rawmod ? rawmod->language() : lang_Unknown))) {
00834 pretty_name = working_name;
00835 }
00836
00837 sym->prettyName_ = pretty_name;
00838 sym->typedName_ = typed_name;
00839 }
00840 else {
00841
00842
00843
00844 char *prettyName = P_cplus_demangle(sym->getMangledName().c_str(), nativeCompiler, false);
00845 if (prettyName) {
00846 sym->prettyName_ = std::string(prettyName);
00847
00848 free(prettyName);
00849 }
00850 }
00851
00852 return true;
00853 }
00854
00855 bool Symtab::addSymbolToIndices(Symbol *&sym, bool undefined)
00856 {
00857 assert(sym);
00858 if (!undefined) {
00859 everyDefinedSymbol.push_back(sym);
00860 symsByMangledName[sym->getMangledName()].push_back(sym);
00861 symsByPrettyName[sym->getPrettyName()].push_back(sym);
00862 symsByTypedName[sym->getTypedName()].push_back(sym);
00863 #if !defined(os_vxworks)
00864
00865 symsByOffset[sym->getOffset()].push_back(sym);
00866 #endif
00867 }
00868 else {
00869
00870 undefDynSymsByMangledName[sym->getMangledName()].push_back(sym);
00871 undefDynSymsByPrettyName[sym->getPrettyName()].push_back(sym);
00872 undefDynSymsByTypedName[sym->getTypedName()].push_back(sym);
00873
00874 }
00875 return true;
00876 }
00877
00878 bool Symtab::addSymbolToAggregates(Symbol *&sym)
00879 {
00880
00881 switch(sym->getType()) {
00882 case Symbol::ST_FUNCTION: {
00883
00884
00885
00886
00887
00888
00889 Function *func = NULL;
00890 findFuncByEntryOffset(func, sym->getOffset());
00891 if (!func) {
00892
00893
00894
00895 func = new Function(sym);
00896
00897 everyFunction.push_back(func);
00898 sorted_everyFunction = false;
00899 funcsByOffset[sym->getOffset()] = func;
00900 }
00901 else {
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911 if( func->getRegion() != sym->getRegion() ) {
00912 func = new Function(sym);
00913 everyFunction.push_back(func);
00914 sorted_everyFunction = false;
00915 }
00916 func->addSymbol(sym);
00917 }
00918 sym->setFunction(func);
00919
00920 break;
00921 }
00922 case Symbol::ST_TLS:
00923 case Symbol::ST_OBJECT: {
00924
00925 Variable *var = NULL;
00926 findVariableByOffset(var, sym->getOffset());
00927 if (!var) {
00928
00929
00930 var = new Variable(sym);
00931
00932 everyVariable.push_back(var);
00933 varsByOffset[sym->getOffset()] = var;
00934 }
00935 else {
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945 if( obj_RelocatableFile == getObjectType() &&
00946 ( var->getRegion() != sym->getRegion() ||
00947 NULL == sym->getRegion() ) )
00948 {
00949 var = new Variable(sym);
00950 everyVariable.push_back(var);
00951 }else{
00952 var->addSymbol(sym);
00953 }
00954 }
00955 sym->setVariable(var);
00956 break;
00957 }
00958 default: {
00959 break;
00960 }
00961 }
00962 return true;
00963 }
00964
00965
00966
00967
00968
00969
00970
00971
00972 bool Symtab::doNotAggregate(Symbol *&sym) {
00973 if (sym->getMangledName().compare(0, strlen("_L_lock_"), "_L_lock_") == 0) {
00974 return true;
00975 }
00976 if (sym->getMangledName().compare(0, strlen("_L_unlock_"), "_L_unlock_") == 0) {
00977 return true;
00978 }
00979
00980 #if 0
00981
00982
00983
00984 if (sym->getRegion() && sym->getRegion()->getRegionName() == ".opd") {
00985 return true;
00986 }
00987 #endif
00988 return false;
00989 }
00990
00991
00992
00993 bool Symtab::updateIndices(Symbol *sym, std::string newName, NameType nameType) {
00994 if (nameType & mangledName) {
00995
00996 symsByMangledName[newName].push_back(sym);
00997 }
00998 if (nameType & prettyName) {
00999
01000 symsByPrettyName[newName].push_back(sym);
01001 }
01002 if (nameType & typedName) {
01003
01004 symsByTypedName[newName].push_back(sym);
01005 }
01006 return true;
01007 }
01008
01009 #if 0
01010
01011
01012
01013
01014
01015 #if defined(ppc64_linux)
01016
01017
01018
01019
01020
01021
01022 void Symtab::checkPPC64DescriptorSymbols(Object *linkedFile)
01023 {
01024
01025 for(SymbolIter symIter(*linkedFile); symIter;symIter++)
01026 {
01027 Symbol *lookUp = symIter.currval();
01028 const char *np = lookUp->getMangledName().c_str();
01029 if(!np)
01030 continue;
01031
01032 if(np[0] == '.' && (lookUp->getType() == Symbol::ST_FUNCTION))
01033 {
01034 std::vector<Symbol *>syms;
01035 std::string newName = np+1;
01036 if(linkedFile->get_symbols(newName, syms) && (syms[0]->getSize() == 24 || syms[0]->getSize() == 0))
01037 {
01038
01039 lookUp->mangledNames[0] = newName;
01040
01041
01042 syms[0]->type_ = Symbol::ST_NOTYPE;
01043 }
01044 }
01045 }
01046
01047 }
01048
01049 #endif
01050 #endif
01051
01052
01053
01054
01055 void Symtab::setModuleLanguages(dyn_hash_map<std::string, supportedLanguages> *mod_langs)
01056 {
01057 if (!mod_langs->size())
01058 return;
01059
01060 std::vector<Module *> *modlist;
01061 Module *currmod = NULL;
01062 modlist = &_mods;
01063
01064
01065 for (unsigned int i = 0; i < modlist->size(); ++i)
01066 {
01067 currmod = (*modlist)[i];
01068 supportedLanguages currLang;
01069 if (currmod->isShared()) {
01070 continue;
01071 }
01072
01073 const std::string fn = currmod->fileName();
01074 if (mod_langs->find(currmod->fileName()) != mod_langs->end())
01075 {
01076 currLang = (*mod_langs)[fn];
01077 }
01078 else if (fn.rfind(".s") != std::string::npos ||
01079 fn.rfind(".asm") != std::string::npos)
01080 {
01081 currLang = lang_Assembly;
01082 }
01083 else if (fn.rfind(".c") != std::string::npos)
01084 {
01085 currLang = lang_C;
01086 }
01087 else if (fn.rfind(".cpp") != std::string::npos ||
01088 fn.rfind(".cc") != std::string::npos ||
01089 fn.rfind(".C") != std::string::npos)
01090 {
01091 currLang = lang_CPlusPlus;
01092 }
01093 else
01094 {
01095 continue;
01096 }
01097 currmod->setLanguage(currLang);
01098 }
01099 }
01100
01101 void Symtab::createDefaultModule() {
01102 Module *mod = NULL;
01103 if (getObjectType() == obj_SharedLib) {
01104 mod = new Module(lang_Unknown,
01105 imageOffset_,
01106 name(),
01107 this);
01108 }
01109 else {
01110 mod = new Module(lang_Unknown,
01111 imageOffset_,
01112 #if defined(os_vxworks)
01113
01114
01115 name(),
01116 #else
01117 "DEFAULT_MODULE",
01118 #endif
01119 this);
01120 }
01121 modsByFileName[mod->fileName()] = mod;
01122 modsByFullName[mod->fullName()] = mod;
01123 _mods.push_back(mod);
01124 }
01125
01126
01127
01128 Module *Symtab::getOrCreateModule(const std::string &modName,
01129 const Offset modAddr)
01130 {
01131 std::string nameToUse;
01132 if (modName.length() > 0)
01133 nameToUse = modName;
01134 else
01135 nameToUse = "DEFAULT_MODULE";
01136
01137 Module *fm = NULL;
01138 if (findModuleByName(fm, nameToUse))
01139 {
01140 return fm;
01141 }
01142
01143 const char *str = nameToUse.c_str();
01144 int len = nameToUse.length();
01145 assert(len>0);
01146
01147
01148 if (str[len-1] == '/')
01149 return NULL;
01150
01151 return (newModule(nameToUse, modAddr, lang_Unknown));
01152 }
01153
01154 Module *Symtab::newModule(const std::string &name, const Offset addr, supportedLanguages lang)
01155 {
01156 Module *ret = NULL;
01157
01158
01159
01160 if (findModuleByName(ret, name))
01161 {
01162 return(ret);
01163 }
01164
01165
01166
01167
01168 std::string fileNm, fullNm;
01169 fullNm = name;
01170 fileNm = extract_pathname_tail(name);
01171
01172
01173 create_printf("%s[%d]: In %p: Creating new module '%s'/'%s'\n", FILE__, __LINE__, this, fileNm.c_str(), fullNm.c_str());
01174
01175 ret = new Module(lang, addr, fullNm, this);
01176 assert(ret);
01177
01178
01179
01180
01181
01182
01183
01184
01185 if (modsByFileName.end() != modsByFileName.find(ret->fileName()))
01186 {
01187 create_printf("%s[%d]: WARN: LEAK? already have module with name %s\n",
01188 FILE__, __LINE__, ret->fileName().c_str());
01189 }
01190
01191 if (modsByFullName.end() != modsByFullName.find(ret->fullName()))
01192 {
01193 create_printf("%s[%d]: WARN: LEAK? already have module with name %s\n",
01194 FILE__, __LINE__, ret->fullName().c_str());
01195 }
01196
01197 modsByFileName[ret->fileName()] = ret;
01198 modsByFullName[ret->fullName()] = ret;
01199 _mods.push_back(ret);
01200
01201 return (ret);
01202 }
01203
01204 Symtab::Symtab(std::string filename, bool defensive_bin, bool &err) :
01205 member_offset_(0),
01206 is_a_out(false),
01207 main_call_addr_(0),
01208 nativeCompiler(false),
01209 isLineInfoValid_(false),
01210 isTypeInfoValid_(false),
01211 isDefensiveBinary_(defensive_bin),
01212 obj_private(NULL),
01213 _ref_cnt(1)
01214 {
01215 init_debug_symtabAPI();
01216
01217 err = false;
01218
01219 create_printf("%s[%d]: created symtab for %s\n", FILE__, __LINE__, filename.c_str());
01220
01221 #if defined (os_windows)
01222 extern void fixup_filename(std::string &);
01223 fixup_filename(filename);
01224 #endif
01225
01226
01227 mf = MappedFile::createMappedFile(filename);
01228 if (!mf) {
01229 create_printf("%s[%d]: WARNING: creating symtab for %s, "
01230 "createMappedFile() failed\n", FILE__, __LINE__,
01231 filename.c_str());
01232 err = true;
01233 return;
01234 }
01235
01236 obj_private = new Object(mf, defensive_bin,
01237 symtab_log_perror, true);
01238 if (obj_private->hasError()) {
01239 err = true;
01240 return;
01241 }
01242
01243 if (!extractInfo(obj_private))
01244 {
01245 create_printf("%s[%d]: WARNING: creating symtab for %s, extractInfo() "
01246 "failed\n", FILE__, __LINE__, filename.c_str());
01247 err = true;
01248 }
01249
01250 member_name_ = mf->filename();
01251
01252 defaultNamespacePrefix = "";
01253 }
01254
01255 Symtab::Symtab(unsigned char *mem_image, size_t image_size,
01256 const std::string &name, bool defensive_bin, bool &err) :
01257 member_offset_(0),
01258 is_a_out(false),
01259 main_call_addr_(0),
01260 nativeCompiler(false),
01261 isLineInfoValid_(false),
01262 isTypeInfoValid_(false),
01263 isDefensiveBinary_(defensive_bin),
01264 obj_private(NULL),
01265 _ref_cnt(1)
01266 {
01267
01268 err = false;
01269
01270 create_printf("%s[%d]: created symtab for memory image at addr %u\n",
01271 FILE__, __LINE__, mem_image);
01272
01273
01274 mf = MappedFile::createMappedFile(mem_image, image_size, name);
01275 if (!mf) {
01276 create_printf("%s[%d]: WARNING: creating symtab for memory image at "
01277 "addr %u, createMappedFile() failed\n", FILE__, __LINE__,
01278 mem_image);
01279 err = true;
01280 return;
01281 }
01282
01283 obj_private = new Object(mf, defensive_bin,
01284 symtab_log_perror, true);
01285 if (obj_private->hasError()) {
01286 err = true;
01287 return;
01288 }
01289
01290 if (!extractInfo(obj_private))
01291 {
01292 create_printf("%s[%d]: WARNING: creating symtab for memory image at addr"
01293 "%u, extractInfo() failed\n", FILE__, __LINE__, mem_image);
01294 err = true;
01295 }
01296
01297 member_name_ = mf->filename();
01298
01299 defaultNamespacePrefix = "";
01300 }
01301
01302
01303 #if defined(os_aix)
01304 Symtab::Symtab(std::string filename, std::string member_name, Offset offset,
01305 bool &err, void *base) :
01306 member_name_(member_name),
01307 member_offset_(offset),
01308 is_a_out(false),
01309 main_call_addr_(0),
01310 nativeCompiler(false),
01311 isLineInfoValid_(false),
01312 isTypeInfoValid_(false),
01313 obj_private(NULL),
01314 _ref_cnt(1)
01315 {
01316 mf = MappedFile::createMappedFile(filename);
01317 assert(mf);
01318 obj_private = new Object(mf, member_name, offset, symtab_log_perror, base);
01319 if (obj_private->hasError()) {
01320 err = true;
01321 return;
01322 }
01323 err = !extractInfo(obj_private);
01324 defaultNamespacePrefix = "";
01325
01326 create_printf("%s[%d]: created symtab for %s(%s)\n", FILE__, __LINE__, filename.c_str(),
01327 member_name.c_str());
01328 }
01329 #else
01330 Symtab::Symtab(std::string, std::string, Offset, bool &, void *)
01331 {
01332 assert(0);
01333 }
01334 #endif
01335
01336 #if defined(os_aix) // is this ever used on AIX?
01337 Symtab::Symtab(char *mem_image, size_t image_size, std::string member_name,
01338 Offset offset, bool &err, void *base) :
01339 member_name_(member_name),
01340 member_offset_(offset),
01341 is_a_out(false),
01342 main_call_addr_(0),
01343 nativeCompiler(false),
01344 isLineInfoValid_(false),
01345 isTypeInfoValid_(false),
01346 _ref_cnt(1)
01347 {
01348 mf = MappedFile::createMappedFile(mem_image, image_size);
01349 assert(mf);
01350 obj_private = new Object(mf, mf, member_name, offset, symtab_log_perror, base);
01351 if (obj_private->hasError()) {
01352 err = true;
01353 return;
01354 }
01355 err = !extractInfo(obj_private);
01356 defaultNamespacePrefix = "";
01357 }
01358 #else
01359 Symtab::Symtab(char *, size_t, std::string , Offset, bool &, void *)
01360 {
01361 assert(0);
01362 }
01363 #endif
01364
01365 bool sort_reg_by_addr(const Region* a, const Region* b)
01366 {
01367 if (a->getMemOffset() == b->getMemOffset())
01368 return a->getMemSize() < b->getMemSize();
01369 return a->getMemOffset() < b->getMemOffset();
01370 }
01371
01372 extern void print_symbols( std::vector< Symbol *>& allsymbols );
01373 extern void print_symbol_map( dyn_hash_map< std::string, std::vector< Symbol *> > *symbols);
01374
01375 bool Symtab::extractInfo(Object *linkedFile)
01376 {
01377 #if defined(TIMED_PARSE)
01378 struct timeval starttime;
01379 gettimeofday(&starttime, NULL);
01380 #endif
01381
01382
01383
01384
01385
01386
01387
01388
01389 imageOffset_ = linkedFile->code_off();
01390 dataOffset_ = linkedFile->data_off();
01391
01392 imageLen_ = linkedFile->code_len();
01393 dataLen_ = linkedFile->data_len();
01394
01395 if (0 == imageLen_ || 0 == linkedFile->code_ptr())
01396 {
01397
01398 #if !defined(os_aix)
01399 if (0 == linkedFile->code_ptr()) {
01400
01401
01402
01403 linkedFile->code_ptr_ = (char *) linkedFile->code_off();
01404 }
01405 else
01406 #endif
01407 {
01408 if( object_type_ != obj_RelocatableFile ||
01409 linkedFile->code_ptr() == 0)
01410 {
01411 serr = Obj_Parsing;
01412 return false;
01413 }
01414 }
01415 }
01416
01417
01418
01419
01420
01421
01422 no_of_sections = linkedFile->no_of_sections();
01423 newSectionInsertPoint = no_of_sections;
01424 no_of_symbols = linkedFile->no_of_symbols();
01425
01426 isStaticBinary_ = linkedFile->isStaticBinary();
01427
01428 hasRel_ = false;
01429 hasRela_ = false;
01430 hasReldyn_ = false;
01431 hasReladyn_ = false;
01432 hasRelplt_ = false;
01433 hasRelaplt_ = false;
01434 regions_ = linkedFile->getAllRegions();
01435
01436 for (unsigned index=0;index<regions_.size();index++)
01437 {
01438 regions_[index]->setSymtab(this);
01439
01440 if ( regions_[index]->isLoadable() )
01441 {
01442 if ( (regions_[index]->getRegionPermissions() == Region::RP_RX)
01443 || (isDefensiveBinary_ &&
01444 regions_[index]->getRegionPermissions() == Region::RP_RW)
01445 || (regions_[index]->getRegionPermissions() == Region::RP_RWX))
01446 {
01447 codeRegions_.push_back(regions_[index]);
01448 }
01449 else
01450 {
01451 dataRegions_.push_back(regions_[index]);
01452 }
01453 }
01454
01455 regionsByEntryAddr[regions_[index]->getMemOffset()] = regions_[index];
01456
01457 if (regions_[index]->getRegionType() == Region::RT_REL)
01458 {
01459 hasRel_ = true;
01460 }
01461
01462 if (regions_[index]->getRegionType() == Region::RT_RELA)
01463 {
01464 hasRela_ = true;
01465 }
01466
01467 #if defined(os_linux) || defined(os_freebsd)
01468 hasReldyn_ = linkedFile->hasReldyn();
01469 hasReladyn_ = linkedFile->hasReladyn();
01470 hasRelplt_ = linkedFile->hasRelplt();
01471 hasRelaplt_ = linkedFile->hasRelaplt();
01472 #endif
01473
01474 }
01475
01476
01477 std::sort(codeRegions_.begin(), codeRegions_.end(), sort_reg_by_addr);
01478 std::sort(dataRegions_.begin(), dataRegions_.end(), sort_reg_by_addr);
01479 std::sort(regions_.begin(), regions_.end(), sort_reg_by_addr);
01480
01481
01482 address_width_ = linkedFile->getAddressWidth();
01483 is_a_out = linkedFile->is_aout();
01484 code_ptr_ = linkedFile->code_ptr();
01485 data_ptr_ = linkedFile->data_ptr();
01486
01487 if (linkedFile->interpreter_name())
01488 interpreter_name_ = std::string(linkedFile->interpreter_name());
01489
01490 entry_address_ = linkedFile->getEntryAddress();
01491 base_address_ = linkedFile->getBaseAddress();
01492 load_address_ = linkedFile->getLoadAddress();
01493 object_type_ = linkedFile->objType();
01494 is_eel_ = linkedFile->isEEL();
01495 linkedFile->getSegments(segments_);
01496
01497 #if !defined(os_aix) && !defined(os_windows)
01498 linkedFile->getDependencies(deps_);
01499 #endif
01500
01501 #if defined (os_aix)
01502
01503 linkedFile->get_stab_info(stabstr_, nstabs_, stabs_, stringpool_);
01504 linkedFile->get_line_info(nlines_, lines_, fdptr_);
01505 #endif
01506
01507 #if defined(os_aix) || defined(os_linux) || defined(os_freebsd)
01508
01509
01510 nativeCompiler = parseCompilerType(linkedFile);
01511
01512 #endif
01513
01514
01515
01516
01517
01518 std::vector<Symbol *> raw_syms;
01519
01520 #ifdef BINEDIT_DEBUG
01521 printf("== from linkedFile...\n");
01522 print_symbol_map(linkedFile->getAllSymbols());
01523 #endif
01524
01525 if (!extractSymbolsFromFile(linkedFile, raw_syms))
01526 {
01527 serr = Syms_To_Functions;
01528 return false;
01529 }
01530
01531
01532
01533
01534 createDefaultModule();
01535
01536 if (!fixSymModules(raw_syms))
01537 {
01538 serr = Syms_To_Functions;
01539 return false;
01540 }
01541 Object *obj = getObject();
01542 if (!obj)
01543 {
01544 #if !defined(os_vxworks)
01545 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
01546 #endif
01547 return false;
01548 }
01549 obj->clearSymsToMods();
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559 dyn_hash_map<std::string, supportedLanguages> mod_langs;
01560 linkedFile->getModuleLanguageInfo(&mod_langs);
01561 setModuleLanguages(&mod_langs);
01562
01563
01564
01565
01566 if (!demangleSymbols(raw_syms))
01567 {
01568 serr = Syms_To_Functions;
01569 return false;
01570 }
01571
01572 if (!demangleSymbols(undefDynSyms)) {
01573 serr = Syms_To_Functions;
01574 return false;
01575 }
01576
01577 if (!createIndices(raw_syms, false))
01578 {
01579 serr = Syms_To_Functions;
01580 return false;
01581 }
01582
01583 if (!createIndices(undefDynSyms, true))
01584 {
01585 serr = Syms_To_Functions;
01586 return false;
01587 }
01588
01589 if (!createAggregates())
01590 {
01591 serr = Syms_To_Functions;
01592 return false;
01593 }
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603 linkedFile->getAllExceptions(excpBlocks);
01604
01605 vector<relocationEntry >fbt;
01606 linkedFile->get_func_binding_table(fbt);
01607 for(unsigned i=0; i<fbt.size();i++)
01608 relocation_table_.push_back(fbt[i]);
01609 return true;
01610 }
01611
01612 Symtab::Symtab(const Symtab& obj) :
01613 LookupInterface(),
01614 Serializable(),
01615 AnnotatableSparse(),
01616 _ref_cnt(1)
01617 {
01618 create_printf("%s[%d]: Creating symtab 0x%p from symtab 0x%p\n", FILE__, __LINE__, this, &obj);
01619
01620 member_name_ = obj.member_name_;
01621 member_offset_ = obj.member_offset_;
01622 imageOffset_ = obj.imageOffset_;
01623 imageLen_ = obj.imageLen_;
01624 dataOffset_ = obj.dataOffset_;
01625 dataLen_ = obj.dataLen_;
01626 isDefensiveBinary_ = obj.isDefensiveBinary_;
01627
01628 isLineInfoValid_ = obj.isLineInfoValid_;
01629 isTypeInfoValid_ = obj.isTypeInfoValid_;
01630
01631 is_a_out = obj.is_a_out;
01632 main_call_addr_ = obj.main_call_addr_;
01633
01634 nativeCompiler = obj.nativeCompiler;
01635 defaultNamespacePrefix = obj.defaultNamespacePrefix;
01636
01637
01638 no_of_sections = obj.no_of_sections;
01639 unsigned i;
01640
01641 for (i=0;i<obj.regions_.size();i++) {
01642 regions_.push_back(new Region(*(obj.regions_[i])));
01643 regions_.back()->setSymtab(this);
01644 }
01645
01646 for (i=0;i<regions_.size();i++)
01647 regionsByEntryAddr[regions_[i]->getMemOffset()] = regions_[i];
01648
01649
01650
01651 for (i=0;i<obj._mods.size();i++)
01652 {
01653 Module *m = new Module(*(obj._mods[i]));
01654 _mods.push_back(m);
01655 modsByFileName[m->fileName()] = m;
01656 modsByFullName[m->fullName()] = m;
01657 fprintf(stderr, "%s[%d]: copy ctor creating new module %s\n",
01658 FILE__, __LINE__, m->fileName().c_str());
01659 }
01660
01661 for (i=0; i<relocation_table_.size();i++)
01662 {
01663 relocation_table_.push_back(relocationEntry(obj.relocation_table_[i]));
01664 }
01665
01666 for (i=0;i<excpBlocks.size();i++)
01667 {
01668 excpBlocks.push_back(new ExceptionBlock(*(obj.excpBlocks[i])));
01669 }
01670
01671 deps_ = obj.deps_;
01672 }
01673
01674
01675
01676 bool Symtab::isValidOffset(const Offset where) const
01677 {
01678 return isCode(where) || isData(where);
01679 }
01680
01681
01682
01683
01684 bool Symtab::isCode(const Offset where) const
01685 {
01686 #if defined(os_vxworks)
01687
01688
01689 #endif
01690
01691 if (!codeRegions_.size())
01692 {
01693 fprintf(stderr, "%s[%d] No code regions in %s \n",
01694 __FILE__, __LINE__, mf->filename().c_str());
01695 return false;
01696 }
01697
01698
01699 int first = 0;
01700 int last = codeRegions_.size() - 1;
01701
01702 while (last >= first)
01703 {
01704 Region *curreg = codeRegions_[(first + last) / 2];
01705 if (where >= curreg->getMemOffset()
01706 && where < (curreg->getMemOffset()
01707 + curreg->getMemSize()))
01708 {
01709 if (curreg->getRegionType() == Region::RT_BSS)
01710 return false;
01711 return true;
01712 }
01713 else if (where < curreg->getMemOffset())
01714 {
01715 last = ((first + last) / 2) - 1;
01716 }
01717 else if (where >= (curreg->getMemOffset() + curreg->getMemSize()))
01718 {
01719 first = ((first + last) / 2) + 1;
01720 }
01721 else
01722 {
01723
01724
01725 return false;
01726 }
01727 }
01728
01729 return false;
01730 }
01731
01732
01733
01734 bool Symtab::isData(const Offset where) const
01735 {
01736 if (!dataRegions_.size())
01737 {
01738 fprintf(stderr, "%s[%d] No data regions in %s \n",
01739 __FILE__,__LINE__,mf->filename().c_str());
01740 return false;
01741 }
01742
01743 int first = 0;
01744 int last = dataRegions_.size() - 1;
01745
01746 while (last >= first)
01747 {
01748 Region *curreg = dataRegions_[(first + last) / 2];
01749
01750 if ( (where >= curreg->getMemOffset())
01751 && (where < (curreg->getMemOffset() + curreg->getMemSize())))
01752 {
01753 return true;
01754 }
01755 else if (where < curreg->getMemOffset())
01756 {
01757 last = ((first + last) / 2) - 1;
01758 }
01759 else
01760 {
01761 first = ((first + last) / 2) + 1;
01762 }
01763 }
01764
01765 return false;
01766 }
01767
01768 SYMTAB_EXPORT bool Symtab::getFuncBindingTable(std::vector<relocationEntry> &fbt) const
01769 {
01770 fbt = relocation_table_;
01771 return true;
01772 }
01773
01774 SYMTAB_EXPORT bool Symtab::updateFuncBindingTable(Offset stub_addr, Offset plt_addr)
01775 {
01776 int stub_idx = -1, plt_idx = -1;
01777
01778 for (unsigned i = 0; i < relocation_table_.size(); ++i) {
01779 if (stub_addr == relocation_table_[i].target_addr())
01780 stub_idx = i;
01781 if (plt_addr == relocation_table_[i].target_addr())
01782 plt_idx = i;
01783 if (stub_idx >= 0 && plt_idx >= 0)
01784 break;
01785 }
01786 if (stub_idx >= 0 && plt_idx >= 0) {
01787 relocation_table_[stub_idx] = relocation_table_[plt_idx];
01788 relocation_table_[stub_idx].setTargetAddr(stub_addr);
01789 return true;
01790 }
01791 return false;
01792 }
01793
01794 SYMTAB_EXPORT std::vector<std::string> &Symtab::getDependencies(){
01795 return deps_;
01796 }
01797
01798 SYMTAB_EXPORT Archive *Symtab::getParentArchive() const {
01799 return parentArchive_;
01800 }
01801
01802 Symtab::~Symtab()
01803 {
01804
01805
01806
01807
01808 #if 1
01809
01810 for (unsigned i = 0; i < regions_.size(); i++)
01811 {
01812 delete regions_[i];
01813 }
01814
01815 regions_.clear();
01816 codeRegions_.clear();
01817 dataRegions_.clear();
01818 regionsByEntryAddr.clear();
01819
01820 std::vector<Region *> *user_regions = NULL;
01821 getAnnotation(user_regions, UserRegionsAnno);
01822
01823 if (user_regions)
01824 {
01825 for (unsigned i = 0; i < user_regions->size(); ++i)
01826 delete (*user_regions)[i];
01827 user_regions->clear();
01828 }
01829
01830
01831 everyDefinedSymbol.clear();
01832 undefDynSyms.clear();
01833 undefDynSymsByMangledName.clear();
01834 undefDynSymsByPrettyName.clear();
01835 undefDynSymsByTypedName.clear();
01836
01837
01838 symsByOffset.clear();
01839 symsByMangledName.clear();
01840 symsByPrettyName.clear();
01841 symsByTypedName.clear();
01842
01843 for (unsigned i = 0; i < everyFunction.size(); i++)
01844 {
01845 delete everyFunction[i];
01846 }
01847
01848 everyFunction.clear();
01849 funcsByOffset.clear();
01850
01851 for (unsigned i = 0; i < everyVariable.size(); i++)
01852 {
01853 delete everyVariable[i];
01854 }
01855
01856 everyVariable.clear();
01857 varsByOffset.clear();
01858
01859 for (unsigned i = 0; i < _mods.size(); i++)
01860 {
01861 delete _mods[i];
01862 }
01863 _mods.clear();
01864 modsByFileName.clear();
01865 modsByFullName.clear();
01866
01867 for (unsigned i=0;i<excpBlocks.size();i++)
01868 delete excpBlocks[i];
01869
01870 create_printf("%s[%d]: Symtab::~Symtab removing %p from allSymtabs\n",
01871 FILE__, __LINE__, this);
01872
01873 deps_.clear();
01874
01875 for (unsigned i = 0; i < allSymtabs.size(); i++)
01876 {
01877 if (allSymtabs[i] == this)
01878 allSymtabs.erase(allSymtabs.begin()+i);
01879 }
01880
01881
01882
01883 if( obj_private ) delete obj_private;
01884
01885
01886 if (mf) MappedFile::closeMappedFile(mf);
01887 #endif
01888 }
01889
01890 #if !defined(SERIALIZATION_DISABLED)
01891 bool Symtab::exportXML(string file)
01892 {
01893 #if defined (cap_serialization)
01894 try
01895 {
01896 SerContext<Symtab> *scs = new SerContext<Symtab>(this, file);
01897 serialize(file, scs, ser_xml);
01898 #if 0
01899 SerContext<Symtab> *scs = new SerContext<Symtab>(this);
01900 SerializerXML *ser = new SerializerXML(scs, "XMLTranslator", file, sd_serialize, true);
01901 serialize(ser, "Symtab");
01902 #endif
01903 #if 0
01904 SerializerXML sb("XMLTranslator", file, sd_serialize, true);
01905 serialize(&sb, "Symtab");
01906 #endif
01907 }
01908 catch (const SerializerError &err)
01909 {
01910 fprintf(stderr, "%s[%d]: error serializing xml: %s\n", FILE__, __LINE__, err.what());
01911 return false;
01912 }
01913
01914 return false;
01915 #else
01916 fprintf(stderr, "%s[%d]: WARNING: cannot produce %s, serialization not available\n", FILE__, __LINE__, file.c_str());
01917 return false;
01918 #endif
01919 }
01920
01921 bool Symtab::exportBin(string file)
01922 {
01923 try
01924 {
01925 SerContext<Symtab> *scs = new SerContext<Symtab>(this, file);
01926 serialize(file, scs, ser_bin);
01927
01928 return true;
01929 }
01930
01931 catch (const SerializerError &err)
01932 {
01933 if (err.code() == SerializerError::ser_err_disabled)
01934 {
01935 fprintf(stderr, "%s[%d]: WARN: serialization is disabled for file %s\n",
01936 FILE__, __LINE__, file.c_str());
01937 return false;
01938 }
01939
01940 fprintf(stderr, "%s[%d]: %s\n\tfrom: %s[%d]\n", FILE__, __LINE__,
01941 err.what(), err.file().c_str(), err.line());
01942 }
01943
01944 fprintf(stderr, "%s[%d]: error doing binary serialization\n", __FILE__, __LINE__);
01945 return false;
01946 }
01947
01948 Symtab *Symtab::importBin(std::string file)
01949 {
01950 #if defined (cap_serialization)
01951 MappedFile *mf= MappedFile::createMappedFile(file);
01952 if (!mf)
01953 {
01954 fprintf(stderr, "%s[%d]: failed to map file %s\n", FILE__, __LINE__, file.c_str());
01955 return NULL;
01956 }
01957
01958 Symtab *st = new Symtab(mf);
01959
01960 try
01961 {
01962 SerContext<Symtab> *scs = new SerContext<Symtab>(st, file);
01963 if (!st->deserialize(file, scs))
01964 {
01965 delete st;
01966 return NULL;
01967 }
01968
01969 return st;
01970 }
01971
01972 catch (const SerializerError &err)
01973 {
01974 if (err.code() == SerializerError::ser_err_disabled)
01975 {
01976 serialize_printf("%s[%d]: WARN: serialization is disabled for file %s\n",
01977 FILE__, __LINE__, file.c_str());
01978 fprintf(stderr, "%s[%d]: WARN: serialization is disabled for file %s\n",
01979 FILE__, __LINE__, file.c_str());
01980 return NULL;
01981 }
01982
01983 serialize_printf("%s[%d]: %s\n\tfrom: %s[%d]\n", FILE__, __LINE__,
01984 err.what(), err.file().c_str(), err.line());
01985 fprintf(stderr, "%s[%d]: %s\n\tfrom: %s[%d]\n", FILE__, __LINE__,
01986 err.what(), err.file().c_str(), err.line());
01987 }
01988
01989
01990 serialize_printf("%s[%d]: error doing binary deserialization\n", __FILE__, __LINE__);
01991 delete st;
01992 return NULL;
01993 #else
01994 serialize_printf("%s[%d]: WARNING: cannot produce %s, serialization not available\n", FILE__, __LINE__, file.c_str());
01995 return NULL;
01996 #endif
01997 }
01998
01999 #else
02000 bool Symtab::exportXML(string)
02001 {
02002 return false;
02003 }
02004
02005 bool Symtab::exportBin(string)
02006 {
02007 return false;
02008 }
02009
02010 Symtab *Symtab::importBin(std::string)
02011 {
02012 return NULL;
02013 }
02014 #endif
02015
02016 bool Symtab::openFile(Symtab *&obj, void *mem_image, size_t size,
02017 std::string name, def_t def_bin)
02018 {
02019 bool err = false;
02020 #if defined(TIMED_PARSE)
02021 struct timeval starttime;
02022 gettimeofday(&starttime, NULL);
02023 #endif
02024
02025 obj = new Symtab((unsigned char *) mem_image, size, name, (def_bin == Defensive), err);
02026
02027 #if defined(TIMED_PARSE)
02028 struct timeval endtime;
02029 gettimeofday(&endtime, NULL);
02030 unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
02031 unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
02032 unsigned long difftime = lendtime - lstarttime;
02033 double dursecs = difftime/(1000 );
02034 cout << __FILE__ << ":" << __LINE__ <<": openFile "<< filename<< " took "<<dursecs <<" msecs" << endl;
02035 #endif
02036 if(!err)
02037 {
02038 allSymtabs.push_back(obj);
02039 }
02040 else
02041 {
02042 delete obj;
02043 obj = NULL;
02044 }
02045
02046 return !err;
02047 }
02048
02049 bool Symtab::closeSymtab(Symtab *st)
02050 {
02051 bool found = false;
02052 if (!st) return false;
02053
02054 --(st->_ref_cnt);
02055
02056 std::vector<Symtab *>::reverse_iterator iter;
02057 for (iter = allSymtabs.rbegin(); iter != allSymtabs.rend() ; iter++)
02058 {
02059 if (*iter == st)
02060 {
02061 found = true;
02062 if(0 == st->_ref_cnt) {
02063 allSymtabs.erase(iter.base() -1);
02064 break;
02065 }
02066 }
02067 }
02068 if(0 == st->_ref_cnt)
02069 delete(st);
02070 return found;
02071 }
02072
02073 Symtab *Symtab::findOpenSymtab(std::string filename)
02074 {
02075 unsigned numSymtabs = allSymtabs.size();
02076 for (unsigned u=0; u<numSymtabs; u++)
02077 {
02078 assert(allSymtabs[u]);
02079 if (filename == allSymtabs[u]->file() &&
02080 allSymtabs[u]->mf->canBeShared())
02081 {
02082 allSymtabs[u]->_ref_cnt++;
02083
02084 return allSymtabs[u];
02085 }
02086 }
02087 return NULL;
02088 }
02089
02090 bool Symtab::openFile(Symtab *&obj, std::string filename, def_t def_binary)
02091 {
02092 bool err = false;
02093 #if defined(TIMED_PARSE)
02094 struct timeval starttime;
02095 gettimeofday(&starttime, NULL);
02096 #endif
02097
02098
02099
02100
02101 if ( filename.find("/proc") == std::string::npos)
02102 {
02103 obj = findOpenSymtab(filename);
02104 if (obj)
02105 {
02106
02107 return true;
02108 }
02109 }
02110
02111
02112 #if defined (cap_serialization)
02113 #if 0
02114 obj = importBin(filename);
02115
02116 if (NULL == obj)
02117 {
02118 if (deserializeEnforced<Symtab>(filename))
02119 {
02120 serialize_printf("%s[%d]: aborting new symtab, expected deserialize failed\n",
02121 FILE__, __LINE__);
02122 fprintf(stderr, "%s[%d]: aborting new symtab, expected deserialize failed\n",
02123 FILE__, __LINE__);
02124 return false;
02125 }
02126
02127 }
02128 else
02129 {
02130
02131 return true;
02132 }
02133 #endif
02134 #endif
02135
02136 obj = new Symtab(filename, (def_binary == Defensive), err);
02137
02138 #if defined(TIMED_PARSE)
02139 struct timeval endtime;
02140 gettimeofday(&endtime, NULL);
02141 unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
02142 unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
02143 unsigned long difftime = lendtime - lstarttime;
02144 double dursecs = difftime/(1000 );
02145 cout << __FILE__ << ":" << __LINE__ <<": openFile "<< filename<< " took "<<dursecs <<" msecs" << endl;
02146 #endif
02147
02148 if (!err)
02149 {
02150 if (filename.find("/proc") == std::string::npos)
02151 allSymtabs.push_back(obj);
02152
02153
02154 #if defined (cap_serialization)
02155 #if 0
02156 serialize_printf("%s[%d]: doing bin-serialize for %s\n",
02157 FILE__, __LINE__, filename.c_str());
02158
02159 if (!obj->exportBin(filename))
02160 {
02161 serialize_printf("%s[%d]: failed to export symtab\n", FILE__, __LINE__);
02162 }
02163 else
02164 serialize_printf("%s[%d]: did bin-serialize for %s\n",
02165 FILE__, __LINE__, filename.c_str());
02166 #endif
02167 #endif
02168
02169 }
02170 else
02171 {
02172 create_printf("%s[%d]: WARNING: failed to open symtab for %s\n",
02173 FILE__, __LINE__, filename.c_str());
02174 delete obj;
02175 obj = NULL;
02176 }
02177
02178
02179 return !err;
02180 }
02181
02182 bool Symtab::addRegion(Offset vaddr, void *data, unsigned int dataSize, std::string name,
02183 Region::RegionType rType_, bool loadable, unsigned long memAlign, bool tls)
02184 {
02185 Region *sec;
02186 unsigned i;
02187 if (loadable)
02188 {
02189 sec = new Region(newSectionInsertPoint, name, vaddr, dataSize, vaddr,
02190 dataSize, (char *)data, Region::RP_R, rType_, true, tls, memAlign);
02191 sec->setSymtab(this);
02192
02193 regions_.insert(regions_.begin()+newSectionInsertPoint, sec);
02194
02195 for (i = newSectionInsertPoint+1; i < regions_.size(); i++)
02196 {
02197 regions_[i]->setRegionNumber(regions_[i]->getRegionNumber() + 1);
02198 }
02199
02200 if ( (sec->getRegionType() == Region::RT_TEXT)
02201 || (sec->getRegionType() == Region::RT_TEXTDATA))
02202 {
02203 codeRegions_.push_back(sec);
02204 std::sort(codeRegions_.begin(), codeRegions_.end(), sort_reg_by_addr);
02205 }
02206
02207 if ( (sec->getRegionType() == Region::RT_DATA)
02208 || (sec->getRegionType() == Region::RT_TEXTDATA))
02209 {
02210 dataRegions_.push_back(sec);
02211 std::sort(dataRegions_.begin(), dataRegions_.end(), sort_reg_by_addr);
02212 }
02213 }
02214 else
02215 {
02216 sec = new Region(regions_.size()+1, name, vaddr, dataSize, 0, 0,
02217 (char *)data, Region::RP_R, rType_, loadable, tls, memAlign);
02218 sec->setSymtab(this);
02219 regions_.push_back(sec);
02220 }
02221
02222 addUserRegion(sec);
02223 std::sort(regions_.begin(), regions_.end(), sort_reg_by_addr);
02224 return true;
02225 }
02226
02227 bool Symtab::addUserRegion(Region *reg)
02228 {
02229 std::vector<Region *> *user_regions = NULL;
02230
02231 if (!getAnnotation(user_regions, UserRegionsAnno))
02232 {
02233 user_regions = new std::vector<Region *>();
02234 if (!addAnnotation(user_regions, UserRegionsAnno))
02235 {
02236 fprintf(stderr, "%s[%d]: failed to addAnnotation here\n", FILE__, __LINE__);
02237 return false;
02238 }
02239 }
02240
02241 if (!user_regions)
02242 {
02243 fprintf(stderr, "%s[%d]: failed to addAnnotation here\n", FILE__, __LINE__);
02244 return false;
02245 }
02246
02247 user_regions->push_back(reg);
02248
02249 return true;
02250 }
02251
02252 bool Symtab::addUserType(Type *t)
02253 {
02254 std::vector<Type *> *user_types = NULL;
02255
02256
02257
02258 if (!getAnnotation(user_types, UserTypesAnno))
02259 {
02260 user_types = new std::vector<Type *>();
02261 if (!addAnnotation(user_types, UserTypesAnno))
02262 {
02263 fprintf(stderr, "%s[%d]: failed to addAnnotation here\n", FILE__, __LINE__);
02264 return false;
02265 }
02266 }
02267 if (!user_types)
02268 {
02269 fprintf(stderr, "%s[%d]: failed to addAnnotation here\n", FILE__, __LINE__);
02270 return false;
02271 }
02272
02273 user_types->push_back(t);
02274
02275 return true;
02276 }
02277
02278 bool Symtab::addRegion(Region *sec)
02279 {
02280 regions_.push_back(sec);
02281 sec->setSymtab(this);
02282 std::sort(regions_.begin(), regions_.end(), sort_reg_by_addr);
02283 addUserRegion(sec);
02284 return true;
02285 }
02286
02287 void Symtab::parseLineInformation()
02288 {
02289 dyn_hash_map<std::string, LineInformation> *lineInfo = new dyn_hash_map <std::string, LineInformation>;
02290
02291
02292 Object *linkedFile = getObject();
02293 if (!linkedFile)
02294 {
02295 #if !defined(os_vxworks)
02296 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
02297 #endif
02298 return;
02299 }
02300 linkedFile->parseFileLineInfo(this, *lineInfo);
02301
02302 isLineInfoValid_ = true;
02303 dyn_hash_map <std::string, LineInformation>::iterator iter;
02304
02305 for (iter = lineInfo->begin(); iter!=lineInfo->end(); iter++)
02306 {
02307 Module *mod = NULL;
02308 bool result = findModuleByName(mod, iter->first);
02309 if (!result) {
02310 mod = getDefaultModule();
02311 }
02312
02313 LineInformation *lineInformation = mod->getLineInformation();
02314 if (!lineInformation)
02315 {
02316 mod->setLineInfo(&(iter->second));
02317 }
02318 else
02319 {
02320 lineInformation->addLineInfo(&(iter->second));
02321 mod->setLineInfo(lineInformation);
02322 }
02323 }
02324 }
02325
02326 SYMTAB_EXPORT bool Symtab::getAddressRanges(std::vector<pair<Offset, Offset> >&ranges,
02327 std::string lineSource, unsigned int lineNo)
02328 {
02329 unsigned int originalSize = ranges.size();
02330
02331
02332
02333 for ( unsigned int i = 0; i < _mods.size(); i++ )
02334 {
02335 LineInformation *lineInformation = _mods[i]->getLineInformation();
02336
02337 if (lineInformation)
02338 lineInformation->getAddressRanges( lineSource.c_str(), lineNo, ranges );
02339
02340 }
02341
02342 if ( ranges.size() != originalSize )
02343 return true;
02344
02345 fprintf(stderr, "%s[%d]: failing to getAdressRanges for %s[%d]\n", FILE__, __LINE__, lineSource.c_str(), lineNo);
02346 return false;
02347 }
02348
02349 SYMTAB_EXPORT bool Symtab::getSourceLines(std::vector<Statement *> &lines, Offset addressInRange)
02350 {
02351 unsigned int originalSize = lines.size();
02352
02353
02354 for ( unsigned int i = 0; i < _mods.size(); i++ )
02355 {
02356 LineInformation *lineInformation = _mods[i]->getLineInformation();
02357
02358 if (lineInformation)
02359 lineInformation->getSourceLines( addressInRange, lines );
02360
02361 }
02362
02363 if ( lines.size() != originalSize )
02364 return true;
02365
02366 return false;
02367
02368 }
02369
02370 SYMTAB_EXPORT bool Symtab::getSourceLines(std::vector<LineNoTuple> &lines, Offset addressInRange)
02371 {
02372 unsigned int originalSize = lines.size();
02373
02374
02375 for ( unsigned int i = 0; i < _mods.size(); i++ )
02376 {
02377 LineInformation *lineInformation = _mods[i]->getLineInformation();
02378
02379 if (lineInformation)
02380 lineInformation->getSourceLines( addressInRange, lines );
02381
02382 }
02383
02384 if ( lines.size() != originalSize )
02385 return true;
02386
02387 return false;
02388 }
02389
02390 SYMTAB_EXPORT bool Symtab::addLine(std::string lineSource, unsigned int lineNo,
02391 unsigned int lineOffset, Offset lowInclAddr,
02392 Offset highExclAddr)
02393 {
02394 Module *mod;
02395
02396 if (!findModuleByName(mod, lineSource))
02397 {
02398 std::string fileNm = extract_pathname_tail(lineSource);
02399
02400 if (!findModuleByName(mod, fileNm))
02401 {
02402 if (!findModuleByName(mod, mf->pathname()))
02403 return false;
02404 }
02405 }
02406
02407 LineInformation *lineInfo = mod->getLineInformation();
02408
02409 if (!lineInfo)
02410 return false;
02411
02412 return (lineInfo->addLine(lineSource.c_str(), lineNo, lineOffset,
02413 lowInclAddr, highExclAddr));
02414 }
02415
02416 SYMTAB_EXPORT bool Symtab::addAddressRange( Offset lowInclusiveAddr, Offset highExclusiveAddr,
02417 std::string lineSource, unsigned int lineNo,
02418 unsigned int lineOffset)
02419 {
02420 Module *mod;
02421
02422 if (!findModuleByName(mod, lineSource))
02423 {
02424 std::string fileNm = extract_pathname_tail(lineSource);
02425
02426 if (!findModuleByName(mod, fileNm))
02427 return false;
02428 }
02429
02430 LineInformation *lineInfo = mod->getLineInformation();
02431
02432 if (!lineInfo)
02433 return false;
02434
02435 return (lineInfo->addAddressRange(lowInclusiveAddr, highExclusiveAddr,
02436 lineSource.c_str(), lineNo, lineOffset));
02437 }
02438
02439 void Symtab::setTruncateLinePaths(bool value)
02440 {
02441 getObject()->setTruncateLinePaths(value);
02442 }
02443
02444 bool Symtab::getTruncateLinePaths()
02445 {
02446 return getObject()->getTruncateLinePaths();
02447 }
02448
02449 void Symtab::parseTypes()
02450 {
02451 Object *linkedFile = getObject();
02452 if (!linkedFile)
02453 {
02454 #if !defined(os_vxworks)
02455 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
02456 #endif
02457 return;
02458 }
02459 linkedFile->parseTypeInfo(this);
02460 isTypeInfoValid_ = true;
02461
02462 for (unsigned int i = 0; i < _mods.size(); ++i)
02463 {
02464 typeCollection *tc = typeCollection::getModTypeCollection(_mods[i]);
02465
02466 if (!_mods[i]->addAnnotation(tc, ModuleTypeInfoAnno))
02467 {
02468 fprintf(stderr, "%s[%d]: failed to addAnnotation here\n", FILE__, __LINE__);
02469 }
02470 }
02471
02472
02473
02474
02475
02476 typeCollection::fileToTypesMap.clear();
02477
02478 }
02479
02480 bool Symtab::addType(Type *type)
02481 {
02482 bool result = addUserType(type);
02483 if (!result)
02484 return false;
02485
02486 return true;
02487 }
02488
02489 SYMTAB_EXPORT vector<Type *> *Symtab::getAllstdTypes()
02490 {
02491 return stdTypes()->getAllTypes();
02492 }
02493
02494 SYMTAB_EXPORT vector<Type *> *Symtab::getAllbuiltInTypes()
02495 {
02496 return builtInTypes()->getAllBuiltInTypes();
02497 }
02498
02499 SYMTAB_EXPORT bool Symtab::findType(Type *&type, std::string name)
02500 {
02501 parseTypesNow();
02502
02503 if (!_mods.size())
02504 return false;
02505
02506 for (unsigned int i = 0; i < _mods.size(); ++i)
02507 {
02508 typeCollection *tc = _mods[i]->getModuleTypes();
02509 if (!tc) continue;
02510 type = tc->findType(name);
02511 if (type) return true;
02512 }
02513
02514 if (type == NULL)
02515 return false;
02516
02517 return true;
02518 }
02519
02520 SYMTAB_EXPORT Type *Symtab::findType(unsigned type_id)
02521 {
02522 Type *t = NULL;
02523 parseTypesNow();
02524
02525 if (!_mods.size())
02526 {
02527
02528 return NULL;
02529 }
02530
02531 for (unsigned int i = 0; i < _mods.size(); ++i)
02532 {
02533 typeCollection *tc = _mods[i]->getModuleTypes();
02534 if (!tc) continue;
02535 t = tc->findType(type_id);
02536 if (t) break;
02537 }
02538
02539 if (t == NULL)
02540 {
02541 if (builtInTypes())
02542 {
02543 t = builtInTypes()->findBuiltInType(type_id);
02544 if (t) return t;
02545 }
02546 else
02547 {
02548
02549 }
02550
02551 if (stdTypes())
02552 {
02553 t = stdTypes()->findType(type_id);
02554 if (t) return t;
02555 }
02556 else
02557 {
02558
02559 }
02560
02561 return NULL;
02562 }
02563
02564 return t;
02565 }
02566
02567 SYMTAB_EXPORT bool Symtab::findVariableType(Type *&type, std::string name)
02568 {
02569 parseTypesNow();
02570
02571 if (!_mods.size())
02572 return false;
02573
02574
02575 for (unsigned int i = 0; i < _mods.size(); ++i)
02576 {
02577 typeCollection *tc = _mods[i]->getModuleTypes();
02578 if (!tc) continue;
02579 type = tc->findVariableType(name);
02580 if (type) break;
02581 }
02582
02583 if (type == NULL)
02584 return false;
02585
02586 return true;
02587 }
02588
02589 SYMTAB_EXPORT bool Symtab::findLocalVariable(std::vector<localVar *>&vars, std::string name)
02590 {
02591 parseTypesNow();
02592 unsigned origSize = vars.size();
02593
02594 for (unsigned i = 0; i < everyFunction.size(); i++)
02595 {
02596 everyFunction[i]->findLocalVariable(vars, name);
02597 }
02598
02599 if (vars.size()>origSize)
02600 return true;
02601
02602 return false;
02603 }
02604
02605 SYMTAB_EXPORT bool Symtab::hasRel() const
02606 {
02607 return hasRel_;
02608 }
02609
02610 SYMTAB_EXPORT bool Symtab::hasRela() const
02611 {
02612 return hasRela_;
02613 }
02614
02615 SYMTAB_EXPORT bool Symtab::hasReldyn() const
02616 {
02617 return hasReldyn_;
02618 }
02619
02620 SYMTAB_EXPORT bool Symtab::hasReladyn() const
02621 {
02622 return hasReladyn_;
02623 }
02624
02625 SYMTAB_EXPORT bool Symtab::hasRelplt() const
02626 {
02627 return hasRelplt_;
02628 }
02629
02630 SYMTAB_EXPORT bool Symtab::hasRelaplt() const
02631 {
02632 return hasRelaplt_;
02633 }
02634
02635 SYMTAB_EXPORT bool Symtab::isStaticBinary() const
02636 {
02637 return isStaticBinary_;
02638 }
02639
02640 bool Symtab::setDefaultNamespacePrefix(string &str)
02641 {
02642 defaultNamespacePrefix = str;
02643 return true;
02644 }
02645
02646 SYMTAB_EXPORT bool Symtab::emitSymbols(Object *linkedFile,std::string filename, unsigned flag)
02647 {
02648
02649 std::vector<Symbol *> allSyms;
02650 allSyms.insert(allSyms.end(), everyDefinedSymbol.begin(), everyDefinedSymbol.end());
02651
02652
02653 map<string, std::vector<Symbol *> >::iterator iter;
02654 std::vector<Symbol *>::iterator siter;
02655
02656 allSyms.insert(allSyms.end(), undefDynSyms.begin(), undefDynSyms.end());
02657
02658
02659 return linkedFile->emitDriver(this, filename, allSyms, flag);
02660 }
02661
02662 SYMTAB_EXPORT bool Symtab::emit(std::string filename, unsigned flag)
02663 {
02664 Object *obj = getObject();
02665 if (!obj)
02666 {
02667 #if !defined(os_vxworks)
02668 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
02669 #endif
02670 return false;
02671 }
02672 obj->mf->setSharing(false);
02673 return emitSymbols(obj, filename, flag);
02674 }
02675
02676 SYMTAB_EXPORT void Symtab::addDynLibSubstitution(std::string oldName, std::string newName)
02677 {
02678 dynLibSubs[oldName] = newName;
02679 }
02680
02681 SYMTAB_EXPORT std::string Symtab::getDynLibSubstitution(std::string name)
02682 {
02683 #ifdef BINEDIT_DEBUG
02684 map<std::string, std::string>::iterator iter = dynLibSubs.begin();
02685
02686 printf ("substitutions for %s:\n", mf->filename().c_str());
02687
02688 while (iter != dynLibSubs.end())
02689 {
02690 printf(" \"%s\" => \"%s\"\n", iter->first.c_str(), iter->second.c_str());
02691 iter++;
02692 }
02693 #endif
02694
02695 map<std::string, std::string>::iterator loc = dynLibSubs.find(name);
02696
02697 if (loc == dynLibSubs.end())
02698 return name;
02699 else
02700 return loc->second;
02701 }
02702
02703 SYMTAB_EXPORT bool Symtab::getSegments(vector<Segment> &segs) const
02704 {
02705 segs = segments_;
02706
02707 if (!segments_.size())
02708 return false;
02709
02710 return true;
02711 }
02712
02713 SYMTAB_EXPORT bool Symtab::getMappedRegions(std::vector<Region *> &mappedRegs) const
02714 {
02715 unsigned origSize = mappedRegs.size();
02716
02717 for (unsigned i = 0; i < regions_.size(); i++)
02718 {
02719 if (regions_[i]->isLoadable())
02720 mappedRegs.push_back(regions_[i]);
02721 }
02722
02723 if (mappedRegs.size() > origSize)
02724 return true;
02725
02726 return false;
02727 }
02728
02729 SYMTAB_EXPORT bool Symtab::fixup_RegionAddr(const char* name, Offset memOffset, long memSize)
02730 {
02731 Region *sec;
02732
02733 if (!findRegion(sec, name)) {
02734 return false;
02735 }
02736
02737 vector<relocationEntry> relocs;
02738 Object *obj = getObject();
02739
02740
02741 if (obj) {
02742 obj->get_func_binding_table(relocs);
02743
02744
02745
02746
02747 for (unsigned i=0; i < relocs.size(); i++) {
02748 Offset value = relocs[i].rel_addr();
02749 relocs[i].setRelAddr(memOffset + value);
02750
02751
02752
02753 }
02754 }
02755 relocation_table_ = relocs;
02756
02757 vector<relocationEntry> &relref = sec->getRelocations();
02758 for (unsigned i=0; i < relref.size(); i++) {
02759 Offset value = relref[i].rel_addr();
02760 relref[i].setRelAddr(memOffset + value);
02761
02762
02763
02764 }
02765
02766 #if defined(_MSC_VER)
02767 regionsByEntryAddr.erase(sec->getMemOffset());
02768 #endif
02769
02770
02771
02772
02773
02774 sec->setMemOffset(memOffset);
02775 sec->setMemSize(memSize);
02776
02777 #if defined(_MSC_VER)
02778 regionsByEntryAddr[sec->getMemOffset()] = sec;
02779 #endif
02780
02781 std::sort(codeRegions_.begin(), codeRegions_.end(), sort_reg_by_addr);
02782 std::sort(dataRegions_.begin(), dataRegions_.end(), sort_reg_by_addr);
02783 std::sort(regions_.begin(), regions_.end(), sort_reg_by_addr);
02784 return true;
02785 }
02786
02787 SYMTAB_EXPORT bool Symtab::fixup_SymbolAddr(const char* name, Offset newOffset)
02788 {
02789
02790 if (symsByMangledName.count(name) == 0) return false;
02791
02792 if (symsByMangledName[name].size() != 1)
02793 fprintf(stderr, "*** Found %zu symbols with name %s. Expecting 1.\n",
02794 symsByMangledName[name].size(), name);
02795 Symbol *sym = symsByMangledName[name][0];
02796
02797
02798 Offset oldOffset = sym->getOffset();
02799 sym->setOffset(newOffset);
02800
02801
02802
02803
02804
02805
02806 if (symsByOffset.count(oldOffset)) {
02807 std::vector<Symbol *>::iterator iter = symsByOffset[oldOffset].begin();
02808 while (iter != symsByOffset[oldOffset].end()) {
02809 if (*iter == sym) {
02810 symsByOffset[oldOffset].erase(iter);
02811 iter = symsByOffset[oldOffset].begin();
02812
02813 } else iter++;
02814 }
02815 }
02816 if (!findSymbolByOffset(newOffset))
02817 symsByOffset[newOffset].push_back(sym);
02818
02819
02820 if (!doNotAggregate(sym)) {
02821 addSymbolToAggregates(sym);
02822 }
02823
02824 return true;
02825 }
02826
02827 SYMTAB_EXPORT bool Symtab::updateRegion(const char* name, void *buffer, unsigned size)
02828 {
02829 Region *sec;
02830
02831 if (!findRegion(sec, name))
02832 return false;
02833
02834 sec->setPtrToRawData(buffer, size);
02835
02836 return true;
02837 }
02838
02839 SYMTAB_EXPORT bool Symtab::updateCode(void *buffer, unsigned size)
02840 {
02841 return updateRegion(".text", buffer, size);
02842 }
02843
02844 SYMTAB_EXPORT bool Symtab::updateData(void *buffer, unsigned size)
02845 {
02846 return updateRegion(".data", buffer, size);
02847 }
02848
02849 SYMTAB_EXPORT Offset Symtab::getFreeOffset(unsigned size)
02850 {
02851
02852
02853 Offset highWaterMark = 0;
02854 Offset secoffset = 0;
02855 Offset prevSecoffset = 0;
02856 Object *linkedFile = getObject();
02857 if (!linkedFile)
02858 {
02859 #if !defined(os_vxworks)
02860 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
02861 #endif
02862 return 0;
02863 }
02864
02865 for (unsigned i = 0; i < regions_.size(); i++)
02866 {
02867 Offset end = regions_[i]->getMemOffset() + regions_[i]->getMemSize();
02868 if (regions_[i]->getMemOffset() == 0)
02869 continue;
02870
02871 prevSecoffset = secoffset;
02872
02873 unsigned region_offset = (unsigned)((char *)(regions_[i]->getPtrToRawData())
02874 - linkedFile->mem_image());
02875
02876 if (region_offset < (unsigned)prevSecoffset)
02877 {
02878 secoffset += regions_[i]->getMemSize();
02879 }
02880 else
02881 {
02882 secoffset = (char *)(regions_[i]->getPtrToRawData()) - linkedFile->mem_image();
02883 secoffset += regions_[i]->getMemSize();
02884 }
02885
02886
02887
02888
02889
02890 if (end > highWaterMark)
02891 {
02892
02893 newSectionInsertPoint = i+1;
02894 highWaterMark = end;
02895 }
02896
02897 if ( (i < (regions_.size()-2))
02898 && ((end + size) < regions_[i+1]->getMemOffset()))
02899 {
02900
02901
02902
02903
02904
02905 newSectionInsertPoint = i+1;
02906 highWaterMark = end;
02907 break;
02908 }
02909 }
02910
02911
02912 #if defined (os_windows)
02913 Object *obj = getObject();
02914 if (!obj)
02915 {
02916 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
02917 return 0;
02918 }
02919 unsigned pgSize = obj->getSecAlign();
02920
02921 Offset newaddr = highWaterMark - (highWaterMark & (pgSize-1));
02922 while(newaddr < highWaterMark)
02923 newaddr += pgSize;
02924
02925 return newaddr;
02926
02927 #else
02928 unsigned pgSize = P_getpagesize();
02929
02930 #if defined(os_linux)
02931
02932 Object *obj = getObject();
02933 if (!obj)
02934 {
02935 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
02936 return 0;
02937 }
02938 bool isBlueGeneQ = obj->isBlueGeneQ();
02939 bool isBlueGeneP = obj->isBlueGeneP();
02940 bool hasNoteSection = obj->hasNoteSection();
02941 bool isStaticBinary = obj->isStaticBinary();
02942
02943
02944
02945
02946
02947 if ((isBlueGeneQ && !isStaticBinary) || (isBlueGeneP && hasNoteSection)) {
02948 pgSize = 0x100000;
02949 } else if( isBlueGeneQ && isStaticBinary ) {
02950
02951
02952
02953
02954
02955
02956
02957
02958 pgSize = 64;
02959 }
02960
02961
02962 #endif
02963 Offset newaddr = highWaterMark - (highWaterMark & (pgSize-1));
02964 if(newaddr < highWaterMark)
02965 newaddr += pgSize;
02966 return newaddr;
02967 #endif
02968 }
02969
02970 SYMTAB_EXPORT ObjectType Symtab::getObjectType() const
02971 {
02972 return object_type_;
02973 }
02974
02975 SYMTAB_EXPORT Dyninst::Architecture Symtab::getArchitecture()
02976 {
02977 return getObject()->getArch();
02978 }
02979
02980 SYMTAB_EXPORT char *Symtab::mem_image() const
02981 {
02982 return (char *)mf->base_addr();
02983 }
02984
02985 SYMTAB_EXPORT std::string Symtab::file() const
02986 {
02987 assert(mf);
02988 return mf->pathname();
02989 }
02990
02991 SYMTAB_EXPORT std::string Symtab::name() const
02992 {
02993 return mf->filename();
02994 }
02995
02996 SYMTAB_EXPORT std::string Symtab::memberName() const
02997 {
02998 return member_name_;
02999 }
03000
03001 SYMTAB_EXPORT unsigned Symtab::getNumberofRegions() const
03002 {
03003 return no_of_sections;
03004 }
03005
03006 SYMTAB_EXPORT unsigned Symtab::getNumberofSymbols() const
03007 {
03008 return no_of_symbols;
03009 }
03010
03011 bool Symtab::setup_module_up_ptrs(SerializerBase *, Symtab *st)
03012 {
03013 std::vector<Module *> &mods = st->_mods;
03014
03015 for (unsigned int i = 0; i < mods.size(); ++i)
03016 {
03017 Module *m = mods[i];
03018 m->exec_ = st;
03019 }
03020
03021 return true;
03022 }
03023
03024 bool Symtab::fixup_relocation_symbols(SerializerBase *, Symtab *st)
03025 {
03026 std::vector<Module *> &mods = st->_mods;
03027
03028 for (unsigned int i = 0; i < mods.size(); ++i)
03029 {
03030 Module *m = mods[i];
03031 m->exec_ = st;
03032 }
03033
03034 return true;
03035 }
03036
03037 void Symtab::rebuild_symbol_hashes(SerializerBase *sb)
03038 {
03039 if (!is_input(sb))
03040 return;
03041
03042 for (unsigned long i = 0; i < everyDefinedSymbol.size(); ++i)
03043 {
03044 Symbol *s = everyDefinedSymbol[i];
03045 assert(s);
03046 const std::string &pn = s->getPrettyName();
03047 const std::string &mn = s->getMangledName();
03048 const std::string tn = s->getTypedName();
03049
03050 symsByPrettyName[pn].push_back(s);
03051 symsByMangledName[mn].push_back(s);
03052 symsByTypedName[tn].push_back(s);
03053 symsByOffset[s->getOffset()].push_back(s);
03054 }
03055 }
03056
03057 void Symtab::rebuild_funcvar_hashes(SerializerBase *sb)
03058 {
03059 if (!is_input(sb))
03060 return;
03061 for (unsigned int i = 0; i < everyFunction.size(); ++i)
03062 {
03063 Function *f = everyFunction[i];
03064 funcsByOffset[f->getOffset()] = f;
03065 }
03066 for (unsigned int i = 0; i < everyVariable.size(); ++i)
03067 {
03068 Variable *v = everyVariable[i];
03069 varsByOffset[v->getOffset()] = v;
03070 }
03071 }
03072 void Symtab::rebuild_module_hashes(SerializerBase *sb)
03073 {
03074 if (!is_input(sb))
03075 return;
03076 for (unsigned int i = 0; i < _mods.size(); ++i)
03077 {
03078 Module *m = _mods[i];
03079 modsByFileName[m->fileName()] = m;
03080 modsByFullName[m->fullName()] = m;
03081 }
03082 }
03083 void Symtab::rebuild_region_indexes(SerializerBase *sb) THROW_SPEC (SerializerError)
03084 {
03085 if (!is_input(sb))
03086 return;
03087
03088 for (unsigned int i = 0; i < regions_.size(); ++i)
03089 {
03090 Region *r = regions_[i];
03091
03092 if ( r->isLoadable() )
03093 {
03094 if ((r->getRegionPermissions() == Region::RP_RX)
03095 || (r->getRegionPermissions() == Region::RP_RWX))
03096 codeRegions_.push_back(r);
03097 else
03098 dataRegions_.push_back(r);
03099 }
03100
03101
03102
03103
03104 regionsByEntryAddr[r->getMemOffset()] = r;
03105 }
03106
03107 std::sort(codeRegions_.begin(), codeRegions_.end(), sort_reg_by_addr);
03108 std::sort(dataRegions_.begin(), dataRegions_.end(), sort_reg_by_addr);
03109 }
03110
03111 #if !defined(SERIALIZATION_DISABLED)
03112 Serializable *Symtab::serialize_impl(SerializerBase *sb,
03113 const char *tag) THROW_SPEC (SerializerError)
03114 {
03115 serialize_printf("%s[%d]: welcome to Symtab::serialize_impl\n",
03116 FILE__, __LINE__);
03117 if (is_input(sb))
03118 {
03119
03120
03121
03122
03123
03124
03125
03126
03127 }
03128
03129 ifxml_start_element(sb, tag);
03130 gtranslate(sb, imageOffset_, "imageOffset");
03131 gtranslate(sb, imageLen_, "imageLen");
03132 gtranslate(sb, dataOffset_, "dataOff");
03133 gtranslate(sb, dataLen_, "dataLen");
03134 gtranslate(sb, is_a_out, "isExec");
03135 gtranslate(sb, _mods, "Modules", "Module");
03136 rebuild_module_hashes(sb);
03137 if (is_input(sb))
03138 {
03139
03140
03141
03142 isTypeInfoValid_ = true;
03143 isLineInfoValid_ = true;
03144 }
03145 gtranslate(sb, regions_, "Regions", "Region");
03146 rebuild_region_indexes(sb);
03147 gtranslate(sb, everyDefinedSymbol, "EveryDefinedSymbol", "Symbol");
03148 rebuild_symbol_hashes(sb);
03149 gtranslate(sb, relocation_table_, "RelocationTable", "RelocationTableEntry");
03150 gtranslate(sb, everyFunction, "EveryFunction", "Function");
03151 gtranslate(sb, everyVariable, "EveryVariable", "Variable");
03152 rebuild_funcvar_hashes(sb);
03153
03154
03155
03156
03157 gtranslate(sb, excpBlocks, "ExceptionBlocks", "ExceptionBlock");
03158 ifxml_end_element(sb, tag);
03159
03160 sb->magic_check(FILE__, __LINE__);
03161 #if 0
03162 ifinput(Symtab::setup_module_up_ptrs, sb, this);
03163 ifinput(fixup_relocation_symbols, sb, this);
03164 #endif
03165
03166 if (is_input(sb))
03167 {
03168 dyn_hash_map<Address, Symbol *> *map_p = NULL;
03169 if (getAnnotation(map_p, IdToSymAnno) && (NULL != map_p))
03170 {
03171 if (!removeAnnotation(IdToSymAnno))
03172 {
03173 fprintf(stderr, "%s[%d]: failed to remove id-to-sym map\n",
03174 FILE__, __LINE__);
03175 }
03176 delete map_p;
03177 }
03178 }
03179 serialize_printf("%s[%d]: leaving Symtab::serialize_impl\n", FILE__, __LINE__);
03180 return NULL;
03181 }
03182 #else
03183 Serializable *Symtab::serialize_impl(SerializerBase *, const char *) THROW_SPEC (SerializerError)
03184 {
03185 return NULL;
03186 }
03187 #endif
03188
03189 SYMTAB_EXPORT LookupInterface::LookupInterface()
03190 {
03191 }
03192
03193 SYMTAB_EXPORT LookupInterface::~LookupInterface()
03194 {
03195 }
03196
03197
03198 SYMTAB_EXPORT ExceptionBlock::ExceptionBlock(Offset tStart,
03199 unsigned tSize,
03200 Offset cStart)
03201 : tryStart_(tStart), trySize_(tSize), catchStart_(cStart), hasTry_(true)
03202 {
03203 }
03204
03205 SYMTAB_EXPORT ExceptionBlock::ExceptionBlock(Offset cStart)
03206 : tryStart_(0), trySize_(0), catchStart_(cStart), hasTry_(false)
03207 {
03208 }
03209
03210 SYMTAB_EXPORT ExceptionBlock::ExceptionBlock(const ExceptionBlock &eb) :
03211 Serializable(),
03212 tryStart_(eb.tryStart_), trySize_(eb.trySize_),
03213 catchStart_(eb.catchStart_), hasTry_(eb.hasTry_)
03214 {
03215 }
03216 SYMTAB_EXPORT bool ExceptionBlock::hasTry() const
03217 {
03218 return hasTry_;
03219 }
03220
03221 SYMTAB_EXPORT Offset ExceptionBlock::tryStart() const
03222 {
03223 return tryStart_;
03224 }
03225
03226 SYMTAB_EXPORT Offset ExceptionBlock::tryEnd() const
03227 {
03228 return tryStart_ + trySize_;
03229 }
03230
03231 SYMTAB_EXPORT Offset ExceptionBlock::trySize() const
03232 {
03233 return trySize_;
03234 }
03235
03236 SYMTAB_EXPORT bool ExceptionBlock::contains(Offset a) const
03237 {
03238 return (a >= tryStart_ && a < tryStart_ + trySize_);
03239 }
03240
03241 #if !defined(SERIALIZATION_DISABLED)
03242 Serializable * ExceptionBlock::serialize_impl(SerializerBase *sb, const char *tag) THROW_SPEC (SerializerError)
03243 {
03244 ifxml_start_element(sb, tag);
03245 gtranslate(sb, tryStart_, "tryStart");
03246 gtranslate(sb, trySize_, "trySize");
03247 gtranslate(sb, catchStart_, "catchStart");
03248 gtranslate(sb, hasTry_, "hasTry");
03249 ifxml_end_element(sb, tag);
03250 return NULL;
03251 }
03252 #else
03253 Serializable * ExceptionBlock::serialize_impl(SerializerBase *, const char *) THROW_SPEC (SerializerError)
03254 {
03255 return NULL;
03256 }
03257 #endif
03258
03259 SYMTAB_EXPORT relocationEntry::relocationEntry() :
03260 target_addr_(0),
03261 rel_addr_(0),
03262 addend_(0),
03263 rtype_(Region::RT_REL),
03264 name_(""),
03265 dynref_(NULL),
03266 relType_(0)
03267 {
03268 }
03269
03270 SYMTAB_EXPORT relocationEntry::relocationEntry(Offset ta, Offset ra, std::string n,
03271 Symbol *dynref, unsigned long relType) :
03272 target_addr_(ta),
03273 rel_addr_(ra),
03274 addend_(0),
03275 rtype_(Region::RT_REL),
03276 name_(n),
03277 dynref_(dynref),
03278 relType_(relType)
03279 {
03280 }
03281
03282 SYMTAB_EXPORT relocationEntry::relocationEntry(Offset ta, Offset ra, Offset add,
03283 std::string n, Symbol *dynref, unsigned long relType) :
03284 target_addr_(ta),
03285 rel_addr_(ra),
03286 addend_(add),
03287 rtype_(Region::RT_REL),
03288 name_(n),
03289 dynref_(dynref),
03290 relType_(relType)
03291 {
03292 }
03293
03294 SYMTAB_EXPORT relocationEntry::relocationEntry(Offset ra, std::string n,
03295 Symbol *dynref, unsigned long relType, Region::RegionType rtype) :
03296 target_addr_(0),
03297 rel_addr_(ra),
03298 addend_(0),
03299 rtype_(rtype),
03300 name_(n),
03301 dynref_(dynref),
03302 relType_(relType),
03303 rel_struct_addr_(0)
03304 {
03305 }
03306
03307 SYMTAB_EXPORT relocationEntry::relocationEntry(Offset ta, Offset ra, Offset add,
03308 std::string n, Symbol *dynref, unsigned long relType,
03309 Region::RegionType rtype) :
03310 target_addr_(ta),
03311 rel_addr_(ra),
03312 addend_(add),
03313 rtype_(rtype),
03314 name_(n),
03315 dynref_(dynref),
03316 relType_(relType)
03317 {
03318 }
03319
03320 SYMTAB_EXPORT Offset relocationEntry::target_addr() const
03321 {
03322 return target_addr_;
03323 }
03324
03325 SYMTAB_EXPORT void relocationEntry::setTargetAddr(const Offset off)
03326 {
03327 target_addr_ = off;
03328 }
03329
03330 SYMTAB_EXPORT Offset relocationEntry::rel_addr() const
03331 {
03332 return rel_addr_;
03333 }
03334
03335 SYMTAB_EXPORT void relocationEntry::setRelAddr(const Offset value)
03336 {
03337 rel_addr_ = value;
03338 }
03339
03340 SYMTAB_EXPORT const string &relocationEntry::name() const
03341 {
03342 return name_;
03343 }
03344
03345 SYMTAB_EXPORT Symbol *relocationEntry::getDynSym() const
03346 {
03347 return dynref_;
03348 }
03349
03350 SYMTAB_EXPORT bool relocationEntry::addDynSym(Symbol *dynref)
03351 {
03352 dynref_ = dynref;
03353 return true;
03354 }
03355
03356 SYMTAB_EXPORT Region::RegionType relocationEntry::regionType() const
03357 {
03358 return rtype_;
03359 }
03360
03361 SYMTAB_EXPORT unsigned long relocationEntry::getRelType() const
03362 {
03363 return relType_;
03364 }
03365
03366 SYMTAB_EXPORT Offset relocationEntry::addend() const
03367 {
03368 return addend_;
03369 }
03370
03371 SYMTAB_EXPORT void relocationEntry::setAddend(const Offset value)
03372 {
03373 addend_ = value;
03374 }
03375
03376 SYMTAB_EXPORT void relocationEntry::setRegionType(const Region::RegionType value)
03377 {
03378 rtype_ = value;
03379 }
03380
03381 SYMTAB_EXPORT void relocationEntry::setName(const std::string &newName) {
03382 name_ = newName;
03383 }
03384
03385 bool relocationEntry::operator==(const relocationEntry &r) const
03386 {
03387 if (target_addr_ != r.target_addr_) return false;
03388 if (rel_addr_ != r.rel_addr_) return false;
03389 if (addend_ != r.addend_) return false;
03390 if (rtype_ != r.rtype_) return false;
03391 if (name_ != r.name_) return false;
03392 if (relType_ != r.relType_) return false;
03393 if (dynref_ && !r.dynref_) return false;
03394 if (!dynref_ && r.dynref_) return false;
03395 if (dynref_)
03396 {
03397 if (dynref_->getMangledName() != r.dynref_->getMangledName()) return false;
03398 if (dynref_->getOffset() != r.dynref_->getOffset()) return false;
03399 }
03400
03401 return true;
03402 }
03403
03404 #if !defined(SERIALIZATION_DISABLED)
03405 Serializable *relocationEntry::serialize_impl(SerializerBase *sb, const char *tag) THROW_SPEC (SerializerError)
03406 {
03407
03408
03409 std::string symname = dynref_ ? dynref_->getName() : std::string("");
03410 Offset symoff = dynref_ ? dynref_->getOffset() : (Offset) -1;
03411
03412 ifxml_start_element(sb, tag);
03413 gtranslate(sb, target_addr_, "targetAddress");
03414 gtranslate(sb, rel_addr_, "relocationAddress");
03415 gtranslate(sb, addend_, "Addend");
03416 gtranslate(sb, name_, "relocationName");
03417 gtranslate(sb, rtype_, Region::regionType2Str, "regionType");
03418 gtranslate(sb, relType_, "relocationType");
03419 gtranslate(sb, symname, "SymbolName");
03420 gtranslate(sb, symoff, "SymbolOffset");
03421 ifxml_end_element(sb, tag);
03422
03423 if (sb->isInput())
03424 {
03425 dynref_ = NULL;
03426 if (symname != std::string(""))
03427 {
03428
03429 if (symoff == (Offset) -1)
03430 {
03431 fprintf(stderr, "%s[%d]: inconsistent symname and offset combo!\n",
03432 FILE__, __LINE__);
03433 }
03434
03435 SerContextBase *scb = sb->getContext();
03436 if (!scb)
03437 {
03438 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
03439 SER_ERR("FIXME");
03440 }
03441
03442 SerContext<Symtab> *scs = dynamic_cast<SerContext<Symtab> *>(scb);
03443
03444 if (!scs)
03445 {
03446 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
03447 SER_ERR("FIXME");
03448 }
03449
03450 Symtab *st = scs->getScope();
03451
03452 if (!st)
03453 {
03454 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
03455 SER_ERR("FIXME");
03456 }
03457
03458 std::vector<Symbol *> *syms = st->findSymbolByOffset(symoff);
03459 if (!syms || !syms->size())
03460 {
03461 serialize_printf("%s[%d]: cannot find symbol by offset %p\n",
03462 FILE__, __LINE__, (void *)symoff);
03463 return NULL;
03464 }
03465
03466
03467
03468
03469 dynref_ = (*syms)[0];
03470 }
03471 }
03472 return NULL;
03473 }
03474 #else
03475 Serializable *relocationEntry::serialize_impl(SerializerBase *, const char *) THROW_SPEC (SerializerError)
03476 {
03477 return NULL;
03478 }
03479 #endif
03480
03481 ostream & Dyninst::SymtabAPI::operator<< (ostream &os, const relocationEntry &r)
03482 {
03483 if( r.getDynSym() != NULL ) {
03484 os << "Name: " << setw(20) << ( "'" + r.getDynSym()->getMangledName() + "'" );
03485 }else{
03486 os << "Name: " << setw(20) << r.name();
03487 }
03488 os << " Offset: " << std::hex << std::setfill('0') << setw(8) << r.rel_addr()
03489 << std::dec << std::setfill(' ')
03490 << " Offset: " << std::hex << std::setfill('0') << setw(8) << r.target_addr()
03491 << std::dec << std::setfill(' ')
03492 << " Addend: " << r.addend()
03493 << " Region: " << Region::regionType2Str(r.regionType())
03494 << " Type: " << setw(15) << relocationEntry::relType2Str(r.getRelType())
03495 << "(" << r.getRelType() << ")";
03496 if( r.getDynSym() != NULL ) {
03497 os << " Symbol Offset: " << std::hex << std::setfill('0') << setw(8) << r.getDynSym()->getOffset();
03498 os << std::setfill(' ');
03499 if( r.getDynSym()->isCommonStorage() ) {
03500 os << " COM";
03501 }else if( r.getDynSym()->getRegion() == NULL ) {
03502 os << " UND";
03503 }
03504 }
03505 return os;
03506 }
03507
03508 const char *Symbol::symbolType2Str(SymbolType t)
03509 {
03510 switch (t)
03511 {
03512 CASE_RETURN_STR(ST_UNKNOWN);
03513 CASE_RETURN_STR(ST_FUNCTION);
03514 CASE_RETURN_STR(ST_OBJECT);
03515 CASE_RETURN_STR(ST_MODULE);
03516 CASE_RETURN_STR(ST_SECTION);
03517 CASE_RETURN_STR(ST_TLS);
03518 CASE_RETURN_STR(ST_DELETED);
03519 CASE_RETURN_STR(ST_NOTYPE);
03520 CASE_RETURN_STR(ST_INDIRECT);
03521 };
03522
03523 return "invalid symbol type";
03524 }
03525
03526 const char *Symbol::symbolLinkage2Str(SymbolLinkage t)
03527 {
03528 switch (t)
03529 {
03530 CASE_RETURN_STR(SL_UNKNOWN);
03531 CASE_RETURN_STR(SL_GLOBAL);
03532 CASE_RETURN_STR(SL_LOCAL);
03533 CASE_RETURN_STR(SL_WEAK);
03534 };
03535
03536 return "invalid symbol linkage";
03537 }
03538
03539 const char *Symbol::symbolTag2Str(SymbolTag t)
03540 {
03541 switch (t)
03542 {
03543 CASE_RETURN_STR(TAG_UNKNOWN);
03544 CASE_RETURN_STR(TAG_USER);
03545 CASE_RETURN_STR(TAG_LIBRARY);
03546 CASE_RETURN_STR(TAG_INTERNAL);
03547 };
03548
03549 return "invalid symbol tag";
03550 }
03551
03552 const char *Symbol::symbolVisibility2Str(SymbolVisibility t)
03553 {
03554 switch(t) {
03555 CASE_RETURN_STR(SV_UNKNOWN);
03556 CASE_RETURN_STR(SV_DEFAULT);
03557 CASE_RETURN_STR(SV_INTERNAL);
03558 CASE_RETURN_STR(SV_HIDDEN);
03559 CASE_RETURN_STR(SV_PROTECTED);
03560 }
03561 return "invalid symbol visibility";
03562 }
03563
03564 bool Symtab::hasStackwalkDebugInfo()
03565 {
03566
03567 Object *obj = getObject();
03568 if (!obj)
03569 {
03570 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
03571 return false;
03572 }
03573 return obj->hasFrameDebugInfo();
03574 }
03575
03576 bool Symtab::getRegValueAtFrame(Address pc,
03577 Dyninst::MachRegister reg,
03578 Dyninst::MachRegisterVal ®_result,
03579 MemRegReader *reader)
03580 {
03581 Object *obj = getObject();
03582 if (!obj)
03583 {
03584 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
03585 return false;
03586 }
03587 return obj->getRegValueAtFrame(pc, reg, reg_result, reader);
03588 }
03589
03590 Object *Symtab::getObject()
03591 {
03592 if (obj_private)
03593 return obj_private;
03594
03595
03596
03597
03598
03599
03600 fprintf(stderr, "%s[%d]: FIXME: request for object that does not exist!\n", FILE__, __LINE__);
03601 return NULL;
03602
03603
03604 }
03605
03606 void Symtab::parseTypesNow()
03607 {
03608 if (isTypeInfoValid_)
03609 return;
03610
03611 parseTypes();
03612 }
03613
03614 #if defined (cap_serialization)
03615
03616
03617
03618
03619 bool dummy_for_ser_instance(std::string file, SerializerBase *sb)
03620 {
03621 if (file == std::string("no_such_file"))
03622 {
03623 if (!sb)
03624 {
03625 fprintf(stderr, "%s[%d]: really should not happen\n", FILE__, __LINE__);
03626 return false;
03627 }
03628 fprintf(stderr, "%s[%d]: WARN: disabled serializer init here\n", FILE__, __LINE__);
03629 }
03630 return true;
03631 }
03632
03633 #endif
03634
03635
03636 #if !defined(SERIALIZATION_DISABLED)
03637 SYMTAB_EXPORT SerializerBase *nonpublic_make_bin_symtab_serializer(Symtab *t, std::string file)
03638 {
03639 SerializerBin *ser;
03640 SerContext<Symtab> *scs = new SerContext<Symtab>(t, file);
03641 ser = new SerializerBin(scs, "SerializerBin", file, sd_serialize, false);
03642 return ser;
03643 }
03644
03645 SYMTAB_EXPORT SerializerBase *nonpublic_make_bin_symtab_deserializer(Symtab *t, std::string file)
03646 {
03647 SerializerBin *ser;
03648 SerContext<Symtab> *scs = new SerContext<Symtab>(t, file);
03649 ser = new SerializerBin(scs, "DeserializerBin", file, sd_deserialize, false);
03650 return ser;
03651 }
03652
03653 SYMTAB_EXPORT void nonpublic_free_bin_symtab_serializer(SerializerBase *sb)
03654 {
03655 SerializerBin *sbin = dynamic_cast<SerializerBin *>(sb);
03656 if (sbin)
03657 {
03658 delete(sbin);
03659 }
03660 else
03661 fprintf(stderr, "%s[%d]: FIXME\n", FILE__, __LINE__);
03662
03663 }
03664 #endif
03665
03666 SYMTAB_EXPORT Offset Symtab::getElfDynamicOffset()
03667 {
03668 #if defined(os_linux) || defined(os_freebsd)
03669 Object *obj = getObject();
03670 if (!obj)
03671 {
03672 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
03673 return 0;
03674 }
03675 return obj->getDynamicAddr();
03676 #else
03677 return 0;
03678 #endif
03679 }
03680
03681 SYMTAB_EXPORT bool Symtab::removeLibraryDependency(std::string lib)
03682 {
03683 #if defined(os_aix) || defined(os_windows)
03684 return false;
03685 #else
03686 Object *obj = getObject();
03687 if (!obj) {
03688 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
03689 return false;
03690 }
03691 return obj->removePrereqLibrary(lib);
03692 #endif
03693 }
03694
03695 SYMTAB_EXPORT bool Symtab::addLibraryPrereq(std::string name)
03696 {
03697 #if defined(os_aix)
03698 return false;
03699 #endif
03700
03701 Object *obj = getObject();
03702 if (!obj)
03703 {
03704 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
03705 return false;
03706 }
03707
03708 size_t size = name.find_last_of("/");
03709 size_t lastBS = name.find_last_of("\\");
03710 if (lastBS > size) {
03711 size = lastBS;
03712 }
03713
03714 string filename = name.substr(size+1);
03715
03716 #if ! defined(os_windows)
03717 obj->insertPrereqLibrary(filename);
03718 #else
03719
03720
03721
03722 Symtab *symtab = Symtab::findOpenSymtab(name);
03723 if (!symtab) {
03724 if (!Symtab::openFile(symtab, name)) {
03725 return false;
03726 }
03727 }
03728
03729
03730 vector<Symbol*> funcs;
03731 symtab->getAllSymbolsByType(funcs, Symbol::ST_FUNCTION);
03732 vector<Symbol*>::iterator fit = funcs.begin();
03733 for (; fit != funcs.end() && !(*fit)->isInDynSymtab(); fit++);
03734 if (fit == funcs.end()) {
03735 return false;
03736 }
03737
03738 string funcName = string((*fit)->getPrettyName());
03739 if (funcName.empty()) {
03740 funcName = string((*fit)->getMangledName());
03741 if (funcName.empty()) {
03742 assert(0);
03743 return false;
03744 }
03745 }
03746 symtab->getObject()->addReference((*fit)->getOffset(),
03747 name,
03748 funcName);
03749 obj->addReference((*fit)->getOffset(), filename, funcName);
03750 #endif
03751 return true;
03752 }
03753
03754 SYMTAB_EXPORT bool Symtab::addSysVDynamic(long name, long value)
03755 {
03756 #if defined(os_linux) || defined(os_freebsd)
03757 Object *obj = getObject();
03758 if (!obj)
03759 {
03760 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
03761 return false;
03762 }
03763 obj->insertDynamicEntry(name, value);
03764 return true;
03765 #else
03766 return false;
03767 #endif
03768 }
03769
03770 SYMTAB_EXPORT bool Symtab::addExternalSymbolReference(Symbol *externalSym, Region *localRegion,
03771 relocationEntry localRel)
03772 {
03773
03774 localRel.setRegionType(getObject()->getRelType());
03775
03776
03777
03778
03779
03780 Symbol *symRef = new Symbol(externalSym->getMangledName(),
03781 externalSym->getType(),
03782 Symbol::SL_GLOBAL,
03783 Symbol::SV_DEFAULT,
03784 (Address)0,
03785 getDefaultModule(),
03786 NULL,
03787 externalSym->getSize(),
03788 true,
03789 false);
03790
03791 if( !addSymbol(symRef, externalSym) ) return false;
03792
03793 localRegion->addRelocationEntry(localRel);
03794
03795
03796
03797 explicitSymtabRefs_.insert(externalSym->getSymtab());
03798
03799 return true;
03800 }
03801
03802
03803
03804 SYMTAB_EXPORT bool Symtab::addTrapHeader_win(Address ptr)
03805 {
03806 #if defined(os_windows)
03807 getObject()->setTrapHeader(ptr);
03808 return true;
03809 #else
03810 ptr = ptr;
03811 assert(0);
03812 return false;
03813 #endif
03814 }
03815
03816 bool Symtab::getExplicitSymtabRefs(std::set<Symtab *> &refs) {
03817 refs = explicitSymtabRefs_;
03818 return (refs.size() != 0);
03819 }
03820
03821 SYMTAB_EXPORT bool Symtab::addLinkingResource(Archive *library) {
03822 linkingResources_.push_back(library);
03823
03824 return true;
03825 }
03826
03827 SYMTAB_EXPORT bool Symtab::getLinkingResources(std::vector<Archive *> &libs) {
03828 libs = linkingResources_;
03829 return (linkingResources_.size() != 0);
03830 }
03831
03832 SYMTAB_EXPORT Address Symtab::getLoadAddress()
03833 {
03834 #if defined(os_linux) || defined(os_freebsd) || defined(os_aix)
03835 return getObject()->getLoadAddress();
03836 #else
03837 return 0x0;
03838 #endif
03839 }
03840
03841 SYMTAB_EXPORT bool Symtab::isDefensiveBinary() const
03842 {
03843 return isDefensiveBinary_;
03844 }
03845
03846 SYMTAB_EXPORT bool Symtab::canBeShared()
03847 {
03848 return mf->canBeShared();
03849 }
03850
03851 SYMTAB_EXPORT Offset Symtab::getInitOffset()
03852 {
03853 #if defined(os_linux) || defined(os_freebsd)
03854 return getObject()->getInitAddr();
03855 #else
03856 return 0x0;
03857 #endif
03858
03859 }
03860
03861 SYMTAB_EXPORT Offset Symtab::getFiniOffset()
03862 {
03863 #if defined(os_linux) || defined(os_freebsd)
03864 return getObject()->getFiniAddr();
03865 #else
03866 return 0x0;
03867 #endif
03868
03869 }
03870
03871 void Symtab::getSegmentsSymReader(std::vector<SymSegment> &segs) {
03872 #if !defined(os_windows)
03873 obj_private->getSegmentsSymReader(segs);
03874 #endif
03875 }
03876
03877