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 "symutil.h"
00032 #include "Symbol.h"
00033 #include "Module.h"
00034 #include "Symtab.h"
00035 #include "Aggregate.h"
00036 #include "Function.h"
00037 #include "Variable.h"
00038 #include <string>
00039 #include "annotations.h"
00040
00041 #include <iostream>
00042
00043
00044 using namespace Dyninst;
00045 using namespace SymtabAPI;
00046
00047 #if !defined(SERIALIZATION_DISABLED)
00048 bool addSymID(SerializerBase *sb, Symbol *sym, Address id)
00049 {
00050 assert(id);
00051 assert(sym);
00052 assert(sb);
00053
00054 SerContextBase *scb = sb->getContext();
00055 if (!scb)
00056 {
00057 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
00058 return false;
00059 }
00060
00061 SerContext<Symtab> *scs = dynamic_cast<SerContext<Symtab> *>(scb);
00062
00063 if (!scs)
00064 {
00065 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
00066 return false;
00067 }
00068
00069 Symtab *st = scs->getScope();
00070
00071 if (!st)
00072 {
00073 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
00074 return false;
00075 }
00076
00077 dyn_hash_map<Address, Symbol *> *smap = NULL;
00078
00079 if (!st->getAnnotation(smap, IdToSymAnno))
00080 {
00081 smap = new dyn_hash_map<Address, Symbol *>();
00082
00083 if (!st->addAnnotation(smap, IdToSymAnno))
00084 {
00085 fprintf(stderr, "%s[%d]: ERROR: failed to add IdToSymMap anno to Symtab\n",
00086 FILE__, __LINE__);
00087 return false;
00088 }
00089 }
00090
00091 assert(smap);
00092
00093 if (serializer_debug_flag())
00094 {
00095 dyn_hash_map<Address, Symbol *>::iterator iter = smap->find(id);
00096 if (iter != smap->end())
00097 {
00098 fprintf(stderr, "%s[%d]: WARNING: already have mapping for IdToSym\n",
00099 FILE__, __LINE__);
00100 }
00101 }
00102
00103 (*smap)[id] = sym;
00104 return true;
00105 }
00106
00107 Symbol * getSymForID(SerializerBase *sb, Address id)
00108 {
00109 assert(id);
00110 assert(sb);
00111
00112 SerContextBase *scb = sb->getContext();
00113 if (!scb)
00114 {
00115 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
00116 return NULL;
00117 }
00118
00119 SerContext<Symtab> *scs = dynamic_cast<SerContext<Symtab> *>(scb);
00120
00121 if (!scs)
00122 {
00123 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
00124 return NULL;
00125 }
00126
00127 Symtab *st = scs->getScope();
00128
00129 if (!st)
00130 {
00131 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
00132 return NULL;
00133 }
00134
00135 dyn_hash_map<Address, Symbol *> *smap = NULL;
00136 if (!st->getAnnotation(smap, IdToSymAnno))
00137 {
00138 fprintf(stderr, "%s[%d]: ERROR: failed to find IdToSymMap anno on Symtab\n",
00139 FILE__, __LINE__);
00140 return NULL;
00141 }
00142 assert(smap);
00143 dyn_hash_map<Address, Symbol *>::iterator iter = smap->find(id);
00144 if (iter == smap->end())
00145 {
00146 fprintf(stderr, "%s[%d]: ERROR: failed to find id %p in IdToSymMap\n",
00147 FILE__, __LINE__, (void *)id);
00148 return NULL;
00149 }
00150 return iter->second;
00151 }
00152 #else
00153 bool addSymID(SerializerBase *, Symbol *, Address)
00154 {
00155 return false;
00156 }
00157
00158 Symbol * getSymForID(SerializerBase *, Address)
00159 {
00160 return NULL;
00161 }
00162 #endif
00163
00164 Symbol *Symbol::magicEmitElfSymbol() {
00165
00166
00167 return new Symbol("",
00168 ST_NOTYPE,
00169 SL_LOCAL,
00170 SV_DEFAULT,
00171 0,
00172 NULL,
00173 NULL,
00174 0,
00175 false,
00176 false);
00177 }
00178
00179 SYMTAB_EXPORT const string& Symbol::getMangledName() const
00180 {
00181 return mangledName_;
00182 }
00183
00184 SYMTAB_EXPORT const string& Symbol::getPrettyName() const
00185 {
00186 return prettyName_;
00187 }
00188
00189 SYMTAB_EXPORT const string& Symbol::getTypedName() const
00190 {
00191 return typedName_;
00192 }
00193
00194 bool Symbol::setOffset(Offset newOffset)
00195 {
00196 offset_ = newOffset;
00197 return true;
00198 }
00199
00200 bool Symbol::setPtrOffset(Offset newOffset)
00201 {
00202 ptr_offset_ = newOffset;
00203 return true;
00204 }
00205
00206 bool Symbol::setLocalTOC(Offset toc)
00207 {
00208 localTOC_ = toc;
00209 return true;
00210 }
00211
00212 SYMTAB_EXPORT bool Symbol::setModule(Module *mod)
00213 {
00214 module_ = mod;
00215 return true;
00216 }
00217
00218 SYMTAB_EXPORT bool Symbol::isFunction() const
00219 {
00220 return (getFunction() != NULL);
00221 }
00222
00223 SYMTAB_EXPORT bool Symbol::setFunction(Function *func)
00224 {
00225 aggregate_ = func;
00226 return true;
00227 }
00228
00229 SYMTAB_EXPORT Function * Symbol::getFunction() const
00230 {
00231 if (aggregate_ == NULL)
00232 return NULL;
00233 return dynamic_cast<Function *>(aggregate_);
00234 }
00235
00236 SYMTAB_EXPORT bool Symbol::isVariable() const
00237 {
00238 return (getVariable() != NULL);
00239 }
00240
00241 SYMTAB_EXPORT bool Symbol::setVariable(Variable *var)
00242 {
00243 aggregate_ = var;
00244 return true;
00245 }
00246
00247 SYMTAB_EXPORT Variable * Symbol::getVariable() const
00248 {
00249 return dynamic_cast<Variable *>(aggregate_);
00250 }
00251
00252 SYMTAB_EXPORT bool Symbol::setSize(unsigned ns)
00253 {
00254 size_ = ns;
00255 return true;
00256 }
00257
00258 SYMTAB_EXPORT bool Symbol::setRegion(Region *r)
00259 {
00260 region_ = r;
00261 return true;
00262 }
00263
00264 SYMTAB_EXPORT Symbol::SymbolTag Symbol::tag() const
00265 {
00266 return tag_;
00267 }
00268
00269
00270 SYMTAB_EXPORT bool Symbol::setSymbolType(SymbolType sType)
00271 {
00272 if ((sType != ST_UNKNOWN)&&
00273 (sType != ST_FUNCTION)&&
00274 (sType != ST_OBJECT)&&
00275 (sType != ST_MODULE)&&
00276 (sType != ST_NOTYPE) &&
00277 (sType != ST_INDIRECT))
00278 return false;
00279
00280 SymbolType oldType = type_;
00281 type_ = sType;
00282 if (module_ && module_->exec())
00283 module_->exec()->changeType(this, oldType);
00284
00285
00286
00287 return true;
00288 }
00289
00290 SYMTAB_EXPORT bool Symbol::setVersionFileName(std::string &fileName)
00291 {
00292 std::string *fn_p = NULL;
00293 if (getAnnotation(fn_p, SymbolFileNameAnno))
00294 {
00295 if (!fn_p)
00296 {
00297 fprintf(stderr, "%s[%d]: inconsistency here\n", FILE__, __LINE__);
00298 }
00299 else
00300 {
00301 fprintf(stderr, "%s[%d]: WARNING, already have filename set for symbol %s\n",
00302 FILE__, __LINE__, getMangledName().c_str());
00303 }
00304 return false;
00305 }
00306 else
00307 {
00308
00309 std::string *fn = new std::string(fileName);
00310 if (!addAnnotation(fn, SymbolFileNameAnno))
00311 {
00312 fprintf(stderr, "%s[%d]: failed to add anno here\n", FILE__, __LINE__);
00313 return false;
00314 }
00315 return true;
00316 }
00317
00318 return false;
00319 }
00320
00321 SYMTAB_EXPORT bool Symbol::setVersions(std::vector<std::string> &vers)
00322 {
00323 std::vector<std::string> *vn_p = NULL;
00324 if (getAnnotation(vn_p, SymbolVersionNamesAnno))
00325 {
00326 if (!vn_p)
00327 {
00328 fprintf(stderr, "%s[%d]: inconsistency here\n", FILE__, __LINE__);
00329 }
00330 else
00331 fprintf(stderr, "%s[%d]: WARNING, already have versions set for symbol %s\n", FILE__, __LINE__, getMangledName().c_str());
00332 return false;
00333 }
00334 else
00335 {
00336 if (!addAnnotation(&vers, SymbolVersionNamesAnno))
00337 {
00338 fprintf(stderr, "%s[%d]: failed to add anno here\n", FILE__, __LINE__);
00339 }
00340 }
00341
00342 return true;
00343 }
00344
00345 SYMTAB_EXPORT bool Symbol::getVersionFileName(std::string &fileName)
00346 {
00347 std::string *fn_p = NULL;
00348
00349 if (getAnnotation(fn_p, SymbolFileNameAnno))
00350 {
00351 if (!fn_p)
00352 {
00353 fprintf(stderr, "%s[%d]: inconsistency here\n", FILE__, __LINE__);
00354 }
00355 else
00356 fileName = *fn_p;
00357
00358 return true;
00359 }
00360
00361 return false;
00362 }
00363
00364 SYMTAB_EXPORT bool Symbol::getVersions(std::vector<std::string> *&vers)
00365 {
00366 std::vector<std::string> *vn_p = NULL;
00367
00368 if (getAnnotation(vn_p, SymbolVersionNamesAnno))
00369 {
00370 if (!vn_p)
00371 {
00372 fprintf(stderr, "%s[%d]: inconsistency here\n", FILE__, __LINE__);
00373 }
00374 else
00375 {
00376 vers = vn_p;
00377 return true;
00378 }
00379 }
00380
00381 return false;
00382 }
00383
00384 SYMTAB_EXPORT bool Symbol::setMangledName(std::string name)
00385 {
00386 mangledName_ = name;
00387 setStrIndex(-1);
00388 return true;
00389 }
00390 Serializable *Symbol::serialize_impl(SerializerBase *, const char *) THROW_SPEC (SerializerError)
00391 {
00392 return NULL;
00393 }
00394
00395 void Symbol::restore_module_and_region(SerializerBase *, std::string &, Offset) THROW_SPEC (SerializerError)
00396 {
00397 }
00398
00399 std::ostream& Dyninst::SymtabAPI::operator<< (ostream &os, const Symbol &s)
00400 {
00401 return os << "{"
00402 << " mangled=" << s.getMangledName()
00403 << " pretty=" << s.getPrettyName()
00404 << " module=" << s.module_
00405
00406 << " type=" << s.symbolType2Str(s.type_)
00407
00408 << " linkage=" << s.symbolLinkage2Str(s.linkage_)
00409 << " offset=0x" << hex << s.offset_ << dec
00410 << " size=0x" << hex << s.size_ << dec
00411 << " ptr_offset=0x" << hex << s.ptr_offset_ << dec
00412 << " localTOC=0x" << hex << s.localTOC_ << dec
00413
00414 << " tag=" << s.symbolTag2Str(s.tag_)
00415 << " isAbs=" << s.isAbsolute_
00416 << " isCommon=" << s.isCommonStorage_
00417 << (s.isFunction() ? " [FUNC]" : "")
00418 << (s.isVariable() ? " [VAR]" : "")
00419 << (s.isInSymtab() ? "[STA]" : "[DYN]")
00420 << " }";
00421 }
00422
00423 Offset tryStart_;
00424 unsigned trySize_;
00425 Offset catchStart_;
00426 bool hasTry_;
00427
00428 ostream & Dyninst::SymtabAPI::operator<< (ostream &s, const ExceptionBlock &eb)
00429 {
00430 s << "tryStart=" << eb.tryStart_
00431 << "trySize=" << eb.trySize_
00432 << "catchStart=" << eb.catchStart_
00433 << "hasTry=" << eb.trySize_ ;
00434 return s;
00435 }
00436
00437 bool Symbol::operator==(const Symbol& s) const
00438 {
00439
00440
00441
00442 if (!region_ && s.region_) return false;
00443 if (region_ && !s.region_) return false;
00444 if (region_)
00445 {
00446 if (region_->getDiskOffset() != s.region_->getDiskOffset())
00447 return false;
00448 }
00449
00450
00451 if (!module_ && s.module_) return false;
00452 if (module_ && !s.module_) return false;
00453 if (module_)
00454 {
00455 if (module_->fullName() != s.module_->fullName())
00456 return false;
00457 }
00458
00459 return ( (type_ == s.type_)
00460 && (linkage_ == s.linkage_)
00461 && (offset_ == s.offset_)
00462 && (size_ == s.size_)
00463 && (isDynamic_ == s.isDynamic_)
00464 && (isAbsolute_ == s.isAbsolute_)
00465 && (isCommonStorage_ == s.isCommonStorage_)
00466 && (versionHidden_ == s.versionHidden_)
00467 && (mangledName_ == s.mangledName_)
00468 && (prettyName_ == s.prettyName_)
00469 && (typedName_ == s.typedName_));
00470 }
00471
00472 Symtab *Symbol::getSymtab() const {
00473 return module_->exec();
00474 }
00475
00476 Symbol::Symbol () :
00477 module_(NULL),
00478 type_(ST_NOTYPE),
00479 internal_type_(0),
00480 linkage_(SL_UNKNOWN),
00481 visibility_(SV_UNKNOWN),
00482 offset_(0),
00483 ptr_offset_(0),
00484 localTOC_(0),
00485 region_(NULL),
00486 referring_(NULL),
00487 size_(0),
00488 isDynamic_(false),
00489 isAbsolute_(false),
00490 aggregate_(NULL),
00491 mangledName_(Symbol::emptyString),
00492 prettyName_(Symbol::emptyString),
00493 typedName_(Symbol::emptyString),
00494 tag_(TAG_UNKNOWN) ,
00495 index_(-1),
00496 strindex_(-1),
00497 isCommonStorage_(false),
00498 versionHidden_(false)
00499 {
00500 }
00501
00502 Symbol::Symbol(const std::string& name,
00503 SymbolType t,
00504 SymbolLinkage l,
00505 SymbolVisibility v,
00506 Offset o,
00507 Module *module,
00508 Region *r,
00509 unsigned s,
00510 bool d,
00511 bool a,
00512 int index,
00513 int strindex,
00514 bool cs):
00515 module_(module),
00516 type_(t),
00517 internal_type_(0),
00518 linkage_(l),
00519 visibility_(v),
00520 offset_(o),
00521 ptr_offset_(0),
00522 localTOC_(0),
00523 region_(r),
00524 referring_(NULL),
00525 size_(s),
00526 isDynamic_(d),
00527 isAbsolute_(a),
00528 aggregate_(NULL),
00529 mangledName_(name),
00530 prettyName_(name),
00531 typedName_(name),
00532 tag_(TAG_UNKNOWN),
00533 index_(index),
00534 strindex_(strindex),
00535 isCommonStorage_(cs),
00536 versionHidden_(false)
00537 {
00538 }
00539
00540 Symbol::~Symbol ()
00541 {
00542 std::string *sfa_p = NULL;
00543
00544 if (getAnnotation(sfa_p, SymbolFileNameAnno))
00545 {
00546 if (!removeAnnotation(SymbolFileNameAnno))
00547 {
00548 fprintf(stderr, "%s[%d]: failed to remove file name anno\n",
00549 FILE__, __LINE__);
00550 }
00551 delete (sfa_p);
00552 }
00553 }
00554
00555 void Symbol::setReferringSymbol(Symbol* referringSymbol)
00556 {
00557 referring_= referringSymbol;
00558 }
00559
00560 Symbol* Symbol::getReferringSymbol() {
00561 return referring_;
00562 }