Aggregate.C

Go to the documentation of this file.
00001 /*
00002  * See the dyninst/COPYRIGHT file for copyright information.
00003  * 
00004  * We provide the Paradyn Tools (below described as "Paradyn")
00005  * on an AS IS basis, and do not warrant its validity or performance.
00006  * We reserve the right to update, modify, or discontinue this
00007  * software at any time.  We shall have no obligation to supply such
00008  * updates or modifications or any other form of support to you.
00009  * 
00010  * By your use of Paradyn, you understand and agree that we (or any
00011  * other person or entity with proprietary rights in Paradyn) are
00012  * under no obligation to provide either maintenance services,
00013  * update services, notices of latent defects, or correction of
00014  * defects for Paradyn.
00015  * 
00016  * This library is free software; you can redistribute it and/or
00017  * modify it under the terms of the GNU Lesser General Public
00018  * License as published by the Free Software Foundation; either
00019  * version 2.1 of the License, or (at your option) any later version.
00020  * 
00021  * This library is distributed in the hope that it will be useful,
00022  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00024  * Lesser General Public License for more details.
00025  * 
00026  * You should have received a copy of the GNU Lesser General Public
00027  * License along with this library; if not, write to the Free Software
00028  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
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     // We keep a "primary" module, which is defined as "anything not DEFAULT_MODULE".
00120     if (module_ == NULL) {
00121         module_ = sym->getModule();
00122     }
00123     else if (module_->fileName() == "DEFAULT_MODULE") {
00124         module_ = sym->getModule();
00125     }
00126     // else keep current module.
00127 
00128     // No need to re-add symbols.
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     // We need to add the symbol names (if they aren't there already)
00137     // We can have multiple identical names - for example, there are
00138     // often two symbols for main (static and dynamic symbol table)
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     // Check to see if we're duplicating
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     // Add a symbol representing this name
00227     // We only do this for mangled names since we don't have access
00228     // to a name mangler
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     // Check to see if we're duplicating
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   // Check to see if we're duplicating
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         // This was the only one; so add it back in and update our address
00292         // in the Symtab.
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                 //fprintf(stderr, "%s[%d]: failed to find type in module(%s) collection\n", 
00317                 //      FILE__, __LINE__, module_->fileName().c_str());
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         //SER_ERR("FIXME");
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             //  This should probably throw, but let's play nice for now
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         //  This should probably throw, but let's play nice for now
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         //  sanity check to make sure that all our symbols share the same offset
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         //  This sucks, but apparently there are symbols that are somehow
00465         //  not getting their aggregate fields set properly (before serialize
00466         //  presumably), strangely only affects 64bit cases.  Here we try
00467         //  to correct for this by setting the aggregate values of all symbols
00468         //  at this Offset.  This lookup should be avoided by solving the problem
00469         //  somewhere else (at the source, wherever it is that the rogue symbols
00470         //  are being created and/or lost)
00471         //  
00472         //  Maybe it is also somehow possible that spurious symbols are being
00473         //  created and indexed during deserialize.
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         //  Arguably we should be able to reconstruct these name lists from the set of 
00562         //  symbols, right?  
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             //  just compare offset and a couple other params
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 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1