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
00032
00033 #include "symutil.h"
00034 #include "Annotatable.h"
00035 #include "common/h/serialize.h"
00036
00037 #include "Symtab.h"
00038 #include "Module.h"
00039 #include "Region.h"
00040 #include "Collections.h"
00041 #include "annotations.h"
00042 #include "Symbol.h"
00043
00044 #include "Aggregate.h"
00045 #include "Function.h"
00046 #include "Variable.h"
00047
00048 #include "symtabAPI/src/Object.h"
00049
00050 #include <iostream>
00051
00052 using namespace std;
00053 using namespace Dyninst;
00054 using namespace Dyninst::SymtabAPI;
00055
00056 string Symbol::emptyString("");
00057
00058
00059
00060 bool ____sym_hdr_printed = false;
00061 void print_symbols( std::vector< Symbol *>& allsymbols ) {
00062 FILE* fd = stdout;
00063 Symbol *sym;
00064 std::string modname;
00065 if (!____sym_hdr_printed) {
00066 fprintf(fd, "%-20s %-15s %-10s %5s SEC TYP LN VIS INFO\n",
00067 "SYMBOL", "MODULE", "ADDR", "SIZE");
00068 ____sym_hdr_printed = true;
00069 }
00070 for (unsigned i=0; i<allsymbols.size(); i++) {
00071 sym = allsymbols[i];
00072 modname = (sym->getModule() ? sym->getModule()->fileName() : "");
00073
00074
00075
00076
00077 if (1) {
00078 fprintf(fd, "%-20s %-15s 0x%08x %5u %3u",
00079 sym->getMangledName().substr(0,20).c_str(),
00080
00081 "",
00082 (unsigned)sym->getOffset(),
00083 (unsigned)sym->getSize(),
00084 sym->getRegion() ? sym->getRegion()->getRegionNumber() : 0
00085 );
00086 switch (sym->getType()) {
00087 case Symbol::ST_FUNCTION: fprintf(fd, " FUN"); break;
00088 case Symbol::ST_TLS: fprintf(fd, " TLS"); break;
00089 case Symbol::ST_OBJECT: fprintf(fd, " OBJ"); break;
00090 case Symbol::ST_MODULE: fprintf(fd, " MOD"); break;
00091 case Symbol::ST_SECTION: fprintf(fd, " SEC"); break;
00092 case Symbol::ST_DELETED: fprintf(fd, " DEL"); break;
00093 case Symbol::ST_NOTYPE: fprintf(fd, " - "); break;
00094 default:
00095 case Symbol::ST_UNKNOWN: fprintf(fd, " ???"); break;
00096 }
00097 switch (sym->getLinkage()) {
00098 case Symbol::SL_UNKNOWN: fprintf(fd, " ??"); break;
00099 case Symbol::SL_GLOBAL: fprintf(fd, " GL"); break;
00100 case Symbol::SL_LOCAL: fprintf(fd, " LO"); break;
00101 case Symbol::SL_WEAK: fprintf(fd, " WK"); break;
00102 }
00103 switch (sym->getVisibility()) {
00104 case Symbol::SV_UNKNOWN: fprintf(fd, " ???"); break;
00105 case Symbol::SV_DEFAULT: fprintf(fd, " - "); break;
00106 case Symbol::SV_INTERNAL: fprintf(fd, " INT"); break;
00107 case Symbol::SV_HIDDEN: fprintf(fd, " HID"); break;
00108 case Symbol::SV_PROTECTED: fprintf(fd, " PRO"); break;
00109 }
00110 fprintf(fd, " ");
00111 if (sym->isInSymtab())
00112 fprintf(fd, " STA");
00113 if (sym->isInDynSymtab())
00114 fprintf(fd, " DYN");
00115 if (sym->isAbsolute())
00116 fprintf(fd, " ABS");
00117 std::string fileName;
00118 std::vector<std::string> *vers;
00119 if (sym->getVersionFileName(fileName))
00120 fprintf(fd, " [%s]", fileName.c_str());
00121 if (sym->getVersions(vers)) {
00122 fprintf(fd, " {");
00123 for (unsigned j=0; j < vers->size(); j++) {
00124 if (j > 0)
00125 fprintf(fd, ", ");
00126 fprintf(fd, "%s", (*vers)[j].c_str());
00127 }
00128 fprintf(fd, "}");
00129 }
00130 fprintf(fd,"\n");
00131 }
00132 }
00133 }
00134 void print_symbol_map( dyn_hash_map< std::string, std::vector< Symbol *> > *symbols) {
00135 dyn_hash_map< std::string, std::vector< Symbol *> >::iterator siter = symbols->begin();
00136 int total_syms = 0;
00137 while (siter != symbols->end()) {
00138 print_symbols(siter->second);
00139 total_syms += siter->second.size();
00140 siter++;
00141 }
00142 printf("%d total symbol(s)\n", total_syms);
00143 }
00144
00145
00146
00147 const char *Dyninst::SymtabAPI::supportedLanguages2Str(supportedLanguages s)
00148 {
00149 switch(s) {
00150 CASE_RETURN_STR(lang_Unknown);
00151 CASE_RETURN_STR(lang_Assembly);
00152 CASE_RETURN_STR(lang_C);
00153 CASE_RETURN_STR(lang_CPlusPlus);
00154 CASE_RETURN_STR(lang_GnuCPlusPlus);
00155 CASE_RETURN_STR(lang_Fortran);
00156 CASE_RETURN_STR(lang_Fortran_with_pretty_debug);
00157 CASE_RETURN_STR(lang_CMFortran);
00158 };
00159 return "bad_language";
00160 }
00161
00162
00163 bool Dyninst::SymtabAPI::symbol_compare(const Symbol *s1, const Symbol *s2)
00164 {
00165
00166 Offset s1_addr = s1->getOffset();
00167 Offset s2_addr = s2->getOffset();
00168 if (s1_addr > s2_addr)
00169 return false;
00170 if (s1_addr < s2_addr)
00171 return true;
00172
00173
00174
00175 if ((s1->getType() != Symbol::ST_FUNCTION) && (s2->getType() == Symbol::ST_FUNCTION))
00176 return true;
00177 if ((s2->getType() != Symbol::ST_FUNCTION) && (s1->getType() == Symbol::ST_FUNCTION))
00178 return false;
00179
00180
00181
00182 if ((s1->getLinkage() == Symbol::SL_GLOBAL) && (s2->getLinkage() != Symbol::SL_GLOBAL))
00183 return true;
00184 if ((s2->getLinkage() == Symbol::SL_GLOBAL) && (s1->getLinkage() != Symbol::SL_GLOBAL))
00185 return false;
00186
00187
00188
00189 if ((s1->getLinkage() == Symbol::SL_LOCAL) && (s2->getLinkage() != Symbol::SL_LOCAL))
00190 return true;
00191 if ((s2->getLinkage() == Symbol::SL_LOCAL) && (s1->getLinkage() != Symbol::SL_LOCAL))
00192 return false;
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 return (s1 < s2);
00204 }
00205
00206
00207 bool AObject::needs_function_binding() const
00208 {
00209 return false;
00210 }
00211
00212 bool AObject::get_func_binding_table(std::vector<relocationEntry> &) const
00213 {
00214 return false;
00215 }
00216
00217 bool AObject::get_func_binding_table_ptr(const std::vector<relocationEntry> *&) const
00218 {
00219 return false;
00220 }
00221
00222 bool AObject::addRelocationEntry(relocationEntry &)
00223 {
00224 return true;
00225 }
00226
00227 char *AObject::mem_image() const
00228 {
00229 return NULL;
00230 }
00231
00232 SYMTAB_EXPORT ExceptionBlock::~ExceptionBlock()
00233 {
00234 }
00235
00236 SYMTAB_EXPORT ExceptionBlock::ExceptionBlock() : tryStart_(0), trySize_(0),
00237 catchStart_(0), hasTry_(false)
00238 {
00239 }
00240
00241 SYMTAB_EXPORT Offset ExceptionBlock::catchStart() const
00242 {
00243 return catchStart_;
00244 }
00245
00246 #ifdef DEBUG
00247 ostream &operator<<(ostream &os, relocationEntry &q) {
00248 return q.operator<<(os);
00249 }
00250 #endif
00251
00252
00253
00254
00255
00256
00257
00258
00259 SYMTAB_EXPORT unsigned AObject::nsymbols () const
00260 {
00261 unsigned n = 0;
00262 for (dyn_hash_map<std::string, std::vector<Symbol *> >::const_iterator i = symbols_.begin();
00263 i != symbols_.end();
00264 i++) {
00265 n += i->second.size();
00266 }
00267 return n;
00268 }
00269
00270 SYMTAB_EXPORT bool AObject::get_symbols(string & name,
00271 std::vector<Symbol *> &symbols )
00272 {
00273 if ( symbols_.find(name) == symbols_.end()) {
00274 return false;
00275 }
00276
00277 symbols = symbols_[name];
00278 return true;
00279 }
00280
00281 SYMTAB_EXPORT char* AObject::code_ptr () const
00282 {
00283 return code_ptr_;
00284 }
00285
00286 SYMTAB_EXPORT Offset AObject::code_off () const
00287 {
00288 return code_off_;
00289 }
00290
00291 SYMTAB_EXPORT Offset AObject::code_len () const
00292 {
00293 return code_len_;
00294 }
00295
00296 SYMTAB_EXPORT char* AObject::data_ptr () const
00297 {
00298 return data_ptr_;
00299 }
00300
00301 SYMTAB_EXPORT Offset AObject::data_off () const
00302 {
00303 return data_off_;
00304 }
00305
00306 SYMTAB_EXPORT Offset AObject::data_len () const
00307 {
00308 return data_len_;
00309 }
00310
00311 SYMTAB_EXPORT bool AObject::is_aout() const
00312 {
00313 return is_aout_;
00314 }
00315
00316 SYMTAB_EXPORT bool AObject::isDynamic() const
00317 {
00318 return is_dynamic_;
00319 }
00320
00321 SYMTAB_EXPORT unsigned AObject::no_of_sections() const
00322 {
00323 return no_of_sections_;
00324 }
00325
00326 SYMTAB_EXPORT unsigned AObject::no_of_symbols() const
00327 {
00328 return no_of_symbols_;
00329 }
00330
00331 SYMTAB_EXPORT bool AObject::getAllExceptions(std::vector<ExceptionBlock *>&excpBlocks) const
00332 {
00333 for (unsigned i=0;i<catch_addrs_.size();i++)
00334 excpBlocks.push_back(new ExceptionBlock(catch_addrs_[i]));
00335
00336 return true;
00337 }
00338
00339 SYMTAB_EXPORT std::vector<Region *> AObject::getAllRegions() const
00340 {
00341 return regions_;
00342 }
00343
00344 SYMTAB_EXPORT Offset AObject::loader_off() const
00345 {
00346 return loader_off_;
00347 }
00348
00349 SYMTAB_EXPORT unsigned AObject::loader_len() const
00350 {
00351 return loader_len_;
00352 }
00353
00354
00355 SYMTAB_EXPORT int AObject::getAddressWidth() const
00356 {
00357 return addressWidth_nbytes;
00358 }
00359
00360 SYMTAB_EXPORT bool AObject::have_deferred_parsing(void) const
00361 {
00362 return deferredParse;
00363 }
00364
00365 SYMTAB_EXPORT void * AObject::getErrFunc() const
00366 {
00367 return (void *) err_func_;
00368 }
00369
00370 SYMTAB_EXPORT dyn_hash_map< string, std::vector< Symbol *> > *AObject::getAllSymbols()
00371 {
00372 return &(symbols_);
00373 }
00374
00375 SYMTAB_EXPORT AObject::~AObject()
00376 {
00377 using std::string;
00378 using std::vector;
00379
00380 dyn_hash_map<string,vector<Symbol *> >::iterator it = symbols_.begin();
00381 for( ; it != symbols_.end(); ++it) {
00382 vector<Symbol *> & v = (*it).second;
00383 for(unsigned i=0;i<v.size();++i)
00384 delete v[i];
00385 v.clear();
00386 }
00387 }
00388
00389
00390 SYMTAB_EXPORT AObject::AObject(MappedFile *mf_, void (*err_func)(const char *))
00391 : mf(mf_), code_ptr_(0), code_off_(0),
00392 code_len_(0), data_ptr_(0), data_off_(0), data_len_(0),loader_off_(0),
00393 loader_len_(0), is_dynamic_(false), has_error(false), is_static_binary_(false), deferredParse(false), err_func_(err_func),
00394 addressWidth_nbytes(4)
00395 {
00396 }
00397
00398 SYMTAB_EXPORT AObject::AObject(const AObject &obj)
00399 : mf(obj.mf), symbols_(obj.symbols_),
00400 code_ptr_(obj.code_ptr_), code_off_(obj.code_off_),
00401 code_len_(obj.code_len_), data_ptr_(obj.data_ptr_),
00402 data_off_(obj.data_off_), data_len_(obj.data_len_),
00403 loader_off_(obj.loader_off_), loader_len_(obj.loader_len_), is_dynamic_(obj.is_dynamic_),
00404 has_error(obj.has_error), is_static_binary_(obj.is_static_binary_),
00405 deferredParse(false), err_func_(obj.err_func_), addressWidth_nbytes(4)
00406 {
00407 }
00408
00409
00410 supportedLanguages AObject::pickLanguage(string &working_module, char *working_options,
00411 supportedLanguages working_lang)
00412 {
00413 supportedLanguages lang = lang_Unknown;
00414 static int sticky_fortran_modifier_flag = 0;
00415
00416 string::size_type len = working_module.length();
00417 if((len>2) && (working_module.substr(len-2,2) == string(".c"))) lang = lang_C;
00418 else if ((len>2) && (working_module.substr(len-2,2) == string(".C"))) lang = lang_CPlusPlus;
00419 else if ((len>4) && (working_module.substr(len-4,4) == string(".cpp"))) lang = lang_CPlusPlus;
00420 else if ((len>2) && (working_module.substr(len-2,2) == string(".F"))) lang = lang_Fortran;
00421 else if ((len>2) && (working_module.substr(len-2,2) == string(".f"))) lang = lang_Fortran;
00422 else if ((len>3) && (working_module.substr(len-3,3) == string(".cc"))) lang = lang_C;
00423 else if ((len>2) && (working_module.substr(len-2,2) == string(".a"))) lang = lang_Assembly;
00424 else if ((len>2) && (working_module.substr(len-2,2) == string(".S"))) lang = lang_Assembly;
00425 else if ((len>2) && (working_module.substr(len-2,2) == string(".s"))) lang = lang_Assembly;
00426 else
00427 {
00428
00429 if (working_options)
00430 {
00431
00432
00433 if (strstr(working_options, "gcc"))
00434 lang = lang_C;
00435 else if (strstr(working_options, "g++"))
00436 lang = lang_CPlusPlus;
00437 }
00438 }
00439
00440
00441
00442 if (working_lang == lang_Fortran)
00443 {
00444 if (sticky_fortran_modifier_flag)
00445 {
00446
00447 working_lang = lang_Fortran_with_pretty_debug;
00448 }
00449 else if (working_options)
00450 {
00451 char *dbg_gen = NULL;
00452
00453 if (NULL != (dbg_gen = strstr(working_options, "DBG_GEN=")))
00454 {
00455
00456
00457 char *dbg_gen_ver_maj = dbg_gen + strlen("DBG_GEN=");
00458
00459 char *next_dot = strchr(dbg_gen_ver_maj, '.');
00460 if (NULL != next_dot)
00461 {
00462 next_dot = '\0';
00463 int ver_maj = atoi(dbg_gen_ver_maj);
00464
00465 if (ver_maj < 3)
00466 {
00467 working_lang = lang_Fortran_with_pretty_debug;
00468 sticky_fortran_modifier_flag = 1;
00469
00470 }
00471 }
00472 }
00473 }
00474 }
00475 return lang;
00476 }
00477
00478 SymbolIter::SymbolIter( Object & obj )
00479 : symbols(obj.getAllSymbols()), currentPositionInVector(0)
00480 {
00481 symbolIterator = obj.getAllSymbols()->begin();
00482 }
00483
00484 SymbolIter::SymbolIter( const SymbolIter & src )
00485 : symbols(src.symbols),currentPositionInVector(0),
00486 symbolIterator( src.symbolIterator )
00487 {
00488 }
00489
00490 SymbolIter::~SymbolIter ()
00491 {
00492 }
00493
00494
00495 void SymbolIter::reset ()
00496 {
00497 currentPositionInVector = 0;
00498 symbolIterator = symbols->begin();
00499 }
00500
00501 SymbolIter::operator bool() const
00502 {
00503 return (symbolIterator!=symbols->end());
00504 }
00505
00506 void SymbolIter::operator++ ( int )
00507 {
00508 if ( currentPositionInVector + 1 < (symbolIterator->second).size())
00509 {
00510 currentPositionInVector++;
00511 return;
00512 }
00513
00514
00515 currentPositionInVector = 0;
00516 symbolIterator++;
00517 }
00518
00519 const string & SymbolIter::currkey() const
00520 {
00521 return symbolIterator->first;
00522 }
00523
00524
00525
00526
00527 Symbol *SymbolIter::currval()
00528 {
00529 if (currentPositionInVector >= symbolIterator->second.size())
00530 {
00531 fprintf(stderr, "%s[%d]: OUT OF RANGE\n", FILE__, __LINE__);
00532 return NULL;
00533 }
00534 return ((symbolIterator->second)[ currentPositionInVector ]);
00535 }
00536
00537 const std::string AObject::findModuleForSym(Symbol *sym) {
00538 return symsToModules_[sym];
00539 }
00540
00541 void AObject::clearSymsToMods() {
00542 symsToModules_.clear();
00543 }
00544
00545 bool AObject::hasError() const
00546 {
00547 return has_error;
00548 }
00549
00550 void AObject::setTruncateLinePaths(bool)
00551 {
00552 }
00553
00554 bool AObject::getTruncateLinePaths()
00555 {
00556 return false;
00557 }