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 #include "dyntypes.h"
00031 #include "Annotatable.h"
00032 #include "Serialization.h"
00033 #include "common/h/serialize.h"
00034
00035 #include "Symtab.h"
00036 #include "symutil.h"
00037 #include "Module.h"
00038 #include "Collections.h"
00039
00040 #include "Function.h"
00041 #include "Variable.h"
00042
00043 #include "symtabAPI/src/Object.h"
00044
00045
00046 #include "Aggregate.h"
00047 #include "Symbol.h"
00048
00049 using namespace std;
00050 using namespace Dyninst;
00051 using namespace Dyninst::SymtabAPI;
00052
00053 Aggregate::Aggregate() :
00054 module_(NULL), firstSymbol(NULL), offset_(0L)
00055 {
00056 }
00057
00058 Aggregate::Aggregate(Symbol *sym) :
00059 module_(NULL), firstSymbol(NULL), offset_(0L)
00060 {
00061 assert(sym);
00062 module_ = sym->getModule();
00063 symbols_.push_back(sym);
00064 firstSymbol = symbols_[0];
00065 offset_ = firstSymbol->getOffset();
00066 mangledNames_.push_back(sym->getMangledName());
00067 prettyNames_.push_back(sym->getPrettyName());
00068 typedNames_.push_back(sym->getTypedName());
00069 }
00070
00071
00072 Offset Aggregate::getOffset() const
00073 {
00074 if (!firstSymbol)
00075 {
00076 fprintf(stderr, "%s[%d]: ERROR: Aggregate w/out symbols\n", FILE__, __LINE__);
00077 return (Offset) 0L;
00078 }
00079 return offset_;
00080 }
00081
00082 unsigned Aggregate::getSize() const
00083 {
00084 if (!firstSymbol)
00085 {
00086 fprintf(stderr, "%s[%d]: ERROR: Aggregate w/out symbols\n", FILE__, __LINE__);
00087 return (unsigned) 0;
00088 }
00089 return firstSymbol->getSize();
00090 }
00091
00092 Region * Aggregate::getRegion() const
00093 {
00094 if (!firstSymbol)
00095 {
00096 fprintf(stderr, "%s[%d]: ERROR: Aggregate w/out symbols\n", FILE__, __LINE__);
00097 return NULL;
00098 }
00099 return firstSymbol->getRegion();
00100 }
00101
00102 const vector<std::string> &Aggregate::getAllMangledNames()
00103 {
00104 return mangledNames_;
00105 }
00106
00107 const vector<std::string> &Aggregate::getAllPrettyNames()
00108 {
00109 return prettyNames_;
00110 }
00111
00112 const vector<std::string> &Aggregate::getAllTypedNames()
00113 {
00114 return typedNames_;
00115 }
00116
00117 bool Aggregate::addSymbol(Symbol *sym) {
00118
00119
00120 if (module_ == NULL) {
00121 module_ = sym->getModule();
00122 }
00123 else if (module_->fileName() == "DEFAULT_MODULE") {
00124 module_ = sym->getModule();
00125 }
00126
00127
00128
00129 for (unsigned i = 0; i < symbols_.size(); ++i)
00130 if (sym == symbols_[i]) return true;
00131
00132 symbols_.push_back(sym);
00133 firstSymbol = symbols_[0];
00134 offset_ = firstSymbol->getOffset();
00135
00136
00137
00138
00139
00140 bool found = false;
00141 for (unsigned j = 0; j < mangledNames_.size(); j++) {
00142 if (sym->getMangledName() == mangledNames_[j]) {
00143 found = true;
00144 break;
00145 }
00146 }
00147 if (!found) mangledNames_.push_back(sym->getMangledName());
00148
00149 found = false;
00150
00151 for (unsigned j = 0; j < prettyNames_.size(); j++) {
00152 if (sym->getPrettyName() == prettyNames_[j]) {
00153 found = true;
00154 break;
00155 }
00156 }
00157 if (!found) prettyNames_.push_back(sym->getPrettyName());
00158
00159 found = false;
00160 for (unsigned j = 0; j < typedNames_.size(); j++) {
00161 if (sym->getTypedName() == typedNames_[j]) {
00162 found = true;
00163 break;
00164 }
00165 }
00166 if (!found) typedNames_.push_back(sym->getTypedName());
00167
00168 return true;
00169 }
00170
00171 bool Aggregate::removeSymbolInt(Symbol *sym) {
00172 std::vector<Symbol *>::iterator iter;
00173 for (iter = symbols_.begin(); iter != symbols_.end(); iter++) {
00174 if ((*iter) == sym) {
00175 symbols_.erase(iter);
00176 break;
00177 }
00178 }
00179 if (symbols_.size() > 0) {
00180 firstSymbol = symbols_[0];
00181 offset_ = firstSymbol->getOffset();
00182 } else {
00183 firstSymbol = NULL;
00184 offset_ = 0L;
00185 }
00186 return true;
00187 }
00188
00189 bool Aggregate::getSymbols(std::vector<Symbol *> &syms) const
00190 {
00191 syms = symbols_;
00192 return true;
00193 }
00194
00195 Symbol * Aggregate::getFirstSymbol() const
00196 {
00197 return firstSymbol;
00198 }
00199
00200 SYMTAB_EXPORT bool Aggregate::addMangledName(string name, bool isPrimary)
00201 {
00202
00203 for (unsigned i = 0; i < mangledNames_.size(); i++) {
00204 if (mangledNames_[i] == name)
00205 return false;
00206 }
00207
00208 if (isPrimary) {
00209 std::vector<std::string>::iterator iter = mangledNames_.begin();
00210 mangledNames_.insert(iter, name);
00211 }
00212 else
00213 mangledNames_.push_back(name);
00214
00215 Symbol *staticSym = NULL;
00216 Symbol *dynamicSym = NULL;
00217 for (unsigned i = 0; i < symbols_.size(); ++i) {
00218 if (symbols_[i]->isInDynSymtab()) {
00219 dynamicSym = symbols_[i];
00220 }
00221 if (symbols_[i]->isInSymtab()) {
00222 staticSym = symbols_[i];
00223 }
00224 }
00225
00226
00227
00228
00229 if (staticSym) {
00230 Symbol *newSym = new Symbol(*staticSym);
00231 newSym->setMangledName(name);
00232 module_->exec()->demangleSymbol(newSym);
00233 newSym->isDynamic_ = false;
00234 module_->exec()->addSymbol(newSym);
00235 }
00236 if (dynamicSym) {
00237 Symbol *newSym = new Symbol(*dynamicSym);
00238 newSym->setMangledName(name);
00239 module_->exec()->demangleSymbol(newSym);
00240 newSym->isDynamic_ = true;
00241 module_->exec()->addSymbol(newSym);
00242 }
00243
00244 return true;
00245 }
00246
00247 SYMTAB_EXPORT bool Aggregate::addPrettyName(string name, bool isPrimary)
00248 {
00249
00250 for (unsigned i = 0; i < prettyNames_.size(); i++) {
00251 if (prettyNames_[i] == name)
00252 return false;
00253 }
00254
00255 if (isPrimary) {
00256 std::vector<std::string>::iterator iter = prettyNames_.begin();
00257 prettyNames_.insert(iter, name);
00258 }
00259 else
00260 prettyNames_.push_back(name);
00261
00262 return true;
00263 }
00264
00265 SYMTAB_EXPORT bool Aggregate::addTypedName(string name, bool isPrimary)
00266 {
00267
00268 for (unsigned i = 0; i < typedNames_.size(); i++) {
00269 if (typedNames_[i] == name)
00270 return false;
00271 }
00272
00273 if (isPrimary) {
00274 std::vector<std::string>::iterator iter = typedNames_.begin();
00275 typedNames_.insert(iter, name);
00276 }
00277 else
00278 typedNames_.push_back(name);
00279 return true;
00280 }
00281
00282 bool Aggregate::changeSymbolOffset(Symbol *sym)
00283 {
00284 Offset oldOffset = getOffset();
00285 unsigned int old_count = symbols_.size();
00286
00287 removeSymbolInt(sym);
00288 if (old_count == symbols_.size()) return true;
00289
00290 if (symbols_.empty()) {
00291
00292
00293 symbols_.push_back(sym);
00294 firstSymbol = symbols_[0];
00295 offset_ = firstSymbol->getOffset();
00296 module_->exec()->changeAggregateOffset(this, oldOffset, getOffset());
00297
00298 } else {
00299 module_->exec()->addSymbolToAggregates(sym);
00300 }
00301 return true;
00302 }
00303
00304 #if !defined(SERIALIZATION_DISABLED)
00305 void Aggregate::restore_type_by_id(SerializerBase *sb, Type *&t,
00306 unsigned t_id) THROW_SPEC (SerializerError)
00307 {
00308 if (module_)
00309 {
00310 typeCollection *tc = module_->getModuleTypesPrivate();
00311 if (tc)
00312 {
00313 t = tc->findType(t_id);
00314 if (!t)
00315 {
00316
00317
00318 }
00319 }
00320 else
00321 {
00322 fprintf(stderr, "%s[%d]: no types for module\n", FILE__, __LINE__);
00323 }
00324 }
00325 else
00326 {
00327 fprintf(stderr, "%s[%d]: bad deserialization order??\n", FILE__, __LINE__);
00328
00329 }
00330
00331 if (!t)
00332 {
00333 SerContextBase *scb = sb->getContext();
00334 if (!scb)
00335 {
00336 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
00337 SER_ERR("FIXME");
00338 }
00339
00340 SerContext<Symtab> *scs = dynamic_cast<SerContext<Symtab> *>(scb);
00341
00342 if (!scs)
00343 {
00344 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
00345 SER_ERR("FIXME");
00346 }
00347
00348 Symtab *st = scs->getScope();
00349
00350 if (!st)
00351 {
00352 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
00353 SER_ERR("FIXME");
00354 }
00355
00356 t = st->findType(t_id);
00357
00358 if (!t)
00359 {
00360
00361 fprintf(stderr, "%s[%d]: FIXME: cannot find type with id %d\n", FILE__, __LINE__, t_id);
00362 std::vector<Module *> mods;
00363 if (!st->getAllModules(mods))
00364 {
00365 fprintf(stderr, "%s[%d]: failed to get all modules\n", FILE__, __LINE__);
00366 }
00367 for (unsigned int i = 0; i < mods.size(); ++i)
00368 {
00369 std::vector<Type *> *modtypes = mods[i]->getAllTypes();
00370 fprintf(stderr, "%s[%d]: module %s has %ld types\n", FILE__, __LINE__, mods[i]->fileName().c_str(), (signed long) (modtypes ? modtypes->size() : -1));
00371 if (mods[i]->getModuleTypesPrivate()->findType(t_id))
00372 fprintf(stderr, "%s[%d]: found type %d in mod %s\n", FILE__, __LINE__, t_id, mods[i]->fileName().c_str());
00373 }
00374 }
00375 }
00376 }
00377 #else
00378 void Aggregate::restore_type_by_id(SerializerBase *, Type *&,
00379 unsigned ) THROW_SPEC (SerializerError)
00380 {
00381 }
00382 #endif
00383
00384 #if !defined(SERIALIZATION_DISABLED)
00385 void Aggregate::restore_module_by_name(SerializerBase *sb,
00386 std::string &mname) THROW_SPEC (SerializerError)
00387 {
00388 if (!sb)
00389 {
00390 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
00391 SER_ERR("FIXME");
00392 }
00393
00394 SerContextBase *scb = sb->getContext();
00395 if (!scb)
00396 {
00397 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
00398 SER_ERR("FIXME");
00399 }
00400
00401 SerContext<Symtab> *scs = dynamic_cast<SerContext<Symtab> *>(scb);
00402
00403 if (!scs)
00404 {
00405 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
00406 SER_ERR("FIXME");
00407 }
00408
00409 Symtab *st = scs->getScope();
00410
00411
00412 if (!st)
00413 {
00414 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
00415 SER_ERR("FIXME");
00416 }
00417
00418 if (!st->findModuleByName(module_, mname) || !(module_))
00419 {
00420
00421 fprintf(stderr, "%s[%d]: FIXME: aggregate w/out module: %s\n", FILE__, __LINE__, mname.c_str());
00422 }
00423 }
00424 #else
00425 void Aggregate::restore_module_by_name(SerializerBase *, std::string &) THROW_SPEC (SerializerError)
00426 {
00427 }
00428 #endif
00429
00430 extern Symbol * getSymForID(SerializerBase *sb, Address id);
00431
00432 #if !defined(SERIALIZATION_DISABLED)
00433 void Aggregate::rebuild_symbol_vector(SerializerBase *sb, std::vector<Address> &symids) THROW_SPEC (SerializerError)
00434 {
00435 Offset off_accum = 0;
00436 for (unsigned long i = 0; i < symids.size(); ++i)
00437 {
00438 Symbol *sym = getSymForID(sb, symids[i]);
00439 if (!sym)
00440 {
00441 fprintf(stderr, "%s[%d]: ERROR rebuilding aggregate: ", __FILE__, __LINE__);
00442 fprintf(stderr, "cannot find symbol for id %p\n", (void *) symids[i]);
00443 continue;
00444 }
00445
00446 symbols_.push_back(sym);
00447 firstSymbol = symbols_[0];
00448 offset_ = firstSymbol->getOffset();
00449
00450
00451 if (serializer_debug_flag())
00452 {
00453 if (!off_accum)
00454 off_accum = sym->getOffset();
00455 else
00456 {
00457 if (sym->getOffset() != off_accum)
00458 {
00459 fprintf(stderr, "%s[%d]: INTERNAL ERROR: mismatch offsets: %p--%p\n", FILE__, __LINE__, (void *)off_accum, (void *)sym->getOffset());
00460 }
00461 }
00462 }
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474 SerContextBase *scb = sb->getContext();
00475 if (!scb)
00476 {
00477 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
00478 SER_ERR("FIXME");
00479 }
00480
00481 SerContext<Symtab> *scs = dynamic_cast<SerContext<Symtab> *>(scb);
00482
00483 if (!scs)
00484 {
00485 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
00486 SER_ERR("FIXME");
00487 }
00488
00489 Symtab *st = scs->getScope();
00490
00491 if (!st)
00492 {
00493 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
00494 SER_ERR("FIXME");
00495 }
00496 std::vector<Symbol *> *syms = st->findSymbolByOffset(sym->getOffset());
00497 for (unsigned long j = 0; j < syms->size(); ++j)
00498 {
00499 (*syms)[j]->aggregate_ = this;
00500 }
00501 }
00502 }
00503 #else
00504 void Aggregate::rebuild_symbol_vector(SerializerBase *, std::vector<Address> &) THROW_SPEC (SerializerError)
00505 {
00506 }
00507 #endif
00508
00509 std::ostream &operator<<(std::ostream &os, const Dyninst::SymtabAPI::Aggregate &a)
00510 {
00511 std::string modname = a.module_ ? a.module_->fullName() : std::string("no_mod");
00512 os << "Aggregate{"
00513 << " Module=" << modname
00514 << " MangledNames=[";
00515 for (unsigned int i = 0; i < a.mangledNames_.size(); ++i)
00516 {
00517 os << a.mangledNames_[i];
00518 if ((i + 1) < a.mangledNames_.size())
00519 os << ", ";
00520 }
00521 os << "]";
00522
00523 os << " PrettyNames=[";
00524 for (unsigned int i = 0; i < a.prettyNames_.size(); ++i)
00525 {
00526 os << a.prettyNames_[i];
00527 if ((i + 1) < a.prettyNames_.size())
00528 os << ", ";
00529 }
00530 os << "]";
00531
00532 os << " TypedNames=[";
00533 for (unsigned int i = 0; i < a.typedNames_.size(); ++i)
00534 {
00535 os << a.typedNames_[i];
00536 if ((i + 1) < a.typedNames_.size())
00537 os << ", ";
00538 }
00539 os << "]";
00540 os << " }";
00541
00542 return os;
00543 }
00544
00545 #if !defined(SERIALIZATION_DISABLED)
00546 void Aggregate::serialize_aggregate(SerializerBase * sb, const char * tag) THROW_SPEC (SerializerError)
00547 {
00548 std::string modname = module_ ? module_->fullName() : std::string("");
00549 std::vector<Address> symids;
00550 for (unsigned long i = 0; i < symbols_.size(); ++i)
00551 {
00552 assert(symbols_[i]);
00553 assert(sizeof(Address) == sizeof(void *));
00554 symids.push_back((Address) symbols_[i]);
00555 }
00556
00557 try
00558 {
00559 ifxml_start_element(sb, tag);
00560 gtranslate(sb, modname, "moduleName");
00561
00562
00563 gtranslate(sb, mangledNames_, "mangledNameList");
00564 gtranslate(sb, prettyNames_, "prettyNameList");
00565 gtranslate(sb, typedNames_, "typedNameList");
00566 #if 0
00567 gtranslate(sb, symbols_, "aggregatedSymbols", "aggregateSymbol");
00568 gtranslate(sb, sym_offsets, "symbolOffsetList");
00569 #endif
00570 gtranslate(sb, symids, "symbolIDList");
00571 ifxml_end_element(sb, tag);
00572
00573 if (sb->isBin() && sb->isInput())
00574 {
00575 restore_module_by_name(sb, modname);
00576 rebuild_symbol_vector(sb, symids);
00577 }
00578
00579 #if 0
00580 if (sb->isBin() && sb->isInput())
00581 {
00582 fprintf(stderr, "%s[%d]: DESERIALIZE AGGREGATE %s, %lu offsets\n", FILE__, __LINE__, prettyNames_.size() ? prettyNames_[0].c_str() : "no_names", sym_offsets.size());
00583 rebuild_symbol_vector(sb, &sym_offsets);
00584 }
00585 #endif
00586 }
00587 SER_CATCH(tag);
00588
00589 serialize_printf("%s[%d]: %sSERIALIZE AGGREGATE, nsyms = %lu\n", FILE__, __LINE__,
00590 sb->isInput() ? "DE" : "", symbols_.size());
00591 }
00592 #else
00593 void Aggregate::serialize_aggregate(SerializerBase *, const char *) THROW_SPEC (SerializerError)
00594 {
00595 }
00596 #endif
00597 bool Aggregate::operator==(const Aggregate &a)
00598 {
00599 if (mangledNames_.size() != a.mangledNames_.size()) return false;
00600 if (prettyNames_.size() != a.prettyNames_.size()) return false;
00601 if (typedNames_.size() != a.typedNames_.size()) return false;
00602 if (symbols_.size() != a.symbols_.size()) return false;
00603 if (module_ && !a.module_) return false;
00604 if (!module_ && a.module_) return false;
00605 if (module_ && (module_->fullName() != a.module_->fullName())) return false;
00606
00607 for (unsigned int i = 0; i < mangledNames_.size(); ++i)
00608 {
00609 if (mangledNames_[i] != a.mangledNames_[i]) return false;
00610 }
00611 for (unsigned int i = 0; i < prettyNames_.size(); ++i)
00612 {
00613 if (prettyNames_[i] != a.prettyNames_[i]) return false;
00614 }
00615 for (unsigned int i = 0; i < typedNames_.size(); ++i)
00616 {
00617 if (typedNames_[i] != a.typedNames_[i]) return false;
00618 }
00619 for (unsigned int i = 0; i < symbols_.size(); ++i)
00620 {
00621 Symbol *s1 = symbols_[i];
00622 Symbol *s2 = a.symbols_[i];
00623 if (s1 && !s2) return false;
00624 if (!s1 && s2) return false;
00625 if (!s1)
00626 fprintf(stderr, "%s[%d]: WARN: NULL Symbol pointer here\n", FILE__, __LINE__);
00627 else
00628 {
00629
00630 if (s1->getOffset() != s2->getOffset()) return false;
00631 if (s1->getType() != s2->getType()) return false;
00632 if (s1->getSize() != s2->getSize()) return false;
00633 }
00634 }
00635
00636 return true;
00637 }