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 <string>
00033
00034 #include "symutil.h"
00035
00036 #include "Collections.h"
00037 #include "Symtab.h"
00038 #include "Module.h"
00039 #include "Variable.h"
00040 #include "Serialization.h"
00041
00042 #include "common/h/headers.h"
00043 #include "common/h/serialize.h"
00044
00045 using namespace std;
00046 using namespace Dyninst;
00047 using namespace Dyninst::SymtabAPI;
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 localVarCollection::~localVarCollection()
00060 {
00061 std::vector<localVar *>::iterator li = localVars.begin();
00062 for(;li!=localVars.end();li++)
00063 {
00064 delete *li;
00065 }
00066
00067 localVars.clear();
00068 }
00069
00070
00071
00072
00073
00074
00075
00076 bool localVarCollection::addItem_impl(localVar * var)
00077 {
00078 localVars.push_back(var);
00079 return true;
00080 }
00081
00082 void localVarCollection::addLocalVar(localVar * var)
00083 {
00084 if (!addItem(var))
00085 {
00086 fprintf(stderr, "%s[%d]: ERROR adding localVar\n", FILE__, __LINE__);
00087 }
00088 }
00089
00090
00091
00092
00093
00094
00095
00096 localVar *localVarCollection::findLocalVar(std::string &name){
00097
00098 std::vector<localVar *>::iterator li = localVars.begin();
00099 for(;li!=localVars.end();li++)
00100 {
00101 if (name == (*li)->getName()) {
00102 return *li;
00103 }
00104 }
00105 return NULL;
00106 }
00107
00108
00109
00110
00111
00112 std::vector<localVar *> *localVarCollection::getAllVars()
00113 {
00114 return &localVars;
00115 }
00116
00117 #if !defined(SERIALIZATION_DISABLED)
00118 Serializable *localVarCollection::ac_serialize_impl(SerializerBase *s, const char *tag) THROW_SPEC (SerializerError)
00119 {
00120 unsigned short lvmagic = 72;
00121 serialize_printf("%s[%d]: welcome to localVarCollection: ac_serialize_impl\n",
00122 FILE__, __LINE__);
00123 ifxml_start_element(s, tag);
00124 gtranslate(s, lvmagic, "LocalVarMagicID");
00125 gtranslate(s, localVars, "LocalVariables");
00126 s->magic_check(FILE__, __LINE__);
00127 ifxml_end_element(s, tag);
00128
00129 if (lvmagic != 72)
00130 {
00131 fprintf(stderr, "\n\n%s[%d]: FIXME: out-of-sync\n\n\n", FILE__, __LINE__);
00132 }
00133
00134 serialize_printf("%s[%d]: localVarCollection: ac_serialize_impl, translate done\n", FILE__, __LINE__);
00135
00136 if (s->isInput())
00137 {
00138
00139 for (unsigned int i = 0; i < localVars.size(); ++i)
00140 {
00141 localVar *lv = localVars[i];
00142 assert(lv);
00143 }
00144 serialize_printf("%s[%d]: deserialized %ld local vars\n", FILE__, __LINE__, localVars.size());
00145 }
00146 else
00147 serialize_printf("%s[%d]: serialized %ld local vars\n", FILE__, __LINE__, localVars.size());
00148
00149 return NULL;
00150 }
00151 #else
00152 Serializable *localVarCollection::ac_serialize_impl(SerializerBase *, const char *) THROW_SPEC (SerializerError)
00153 {
00154 return NULL;
00155 }
00156 #endif
00157
00158
00159 dyn_hash_map<void *, typeCollection *> typeCollection::fileToTypesMap;
00160 #if 0
00161 dyn_hash_map<int, std::vector<std::pair<dataClass, Type **> > > typeCollection::deferred_lookups;
00162 #endif
00163 dyn_hash_map<int, std::vector<std::pair<dataClass, Type **> > *> *deferred_lookups_p = NULL;
00164
00165 void typeCollection::addDeferredLookup(int tid, dataClass tdc,Type **th)
00166 {
00167 if (!deferred_lookups_p)
00168 deferred_lookups_p = new dyn_hash_map<int, std::vector<std::pair<dataClass, Type **> > *>();
00169 dyn_hash_map<int, std::vector<std::pair<dataClass, Type **> > *> &deferred_lookups = *deferred_lookups_p;
00170 dyn_hash_map<int, std::vector<std::pair<dataClass, Type **> > *>::iterator iter;
00171
00172 iter = deferred_lookups.find(tid);
00173 if (iter == deferred_lookups.end())
00174 deferred_lookups[tid] = new std::vector<std::pair<dataClass, Type **> >();
00175 deferred_lookups[tid]->push_back(std::make_pair(tdc, th));
00176 }
00177
00178 bool typeCollection::doDeferredLookups(typeCollection *primary_tc)
00179 {
00180 if (!deferred_lookups_p) return true;
00181 dyn_hash_map<int, std::vector<std::pair<dataClass, Type **> > *> &deferred_lookups = *deferred_lookups_p;
00182 bool err = false;
00183 dyn_hash_map<int, std::vector<std::pair<dataClass, Type **> > *>::iterator iter;
00184 for (iter = deferred_lookups.begin(); iter != deferred_lookups.end(); iter++)
00185 {
00186 std::vector<std::pair<dataClass, Type **> > *to_assign = iter->second;
00187 if (!to_assign)
00188 {
00189 fprintf(stderr, "%s[%d]: FIXME!\n", FILE__, __LINE__);
00190 }
00191
00192 if (!to_assign->size())
00193 {
00194 fprintf(stderr, "%s[%d]: No lookups for id %d, weird\n",
00195 FILE__, __LINE__, iter->first);
00196 continue;
00197 }
00198
00199 for (unsigned int i = 0; i < to_assign->size(); ++i)
00200 {
00201 dataClass ldc = (*to_assign)[i].first;
00202 Type **th = (*to_assign)[i].second;
00203
00204 Type *t = primary_tc->findType(iter->first);
00205 if (t && (t->getDataClass() != ldc)) t = NULL;
00206
00207 if (!t)
00208 {
00209 if (Symtab::builtInTypes())
00210 {
00211 t = Symtab::builtInTypes()->findBuiltInType(iter->first);
00212 if (t && (t->getDataClass() != ldc)) t = NULL;
00213 }
00214 }
00215 if (!t)
00216 {
00217 if (Symtab::stdTypes())
00218 {
00219 t = Symtab::stdTypes()->findType(iter->first);
00220 if (t && (t->getDataClass() != ldc)) t = NULL;
00221 }
00222 }
00223 if (!t)
00224 {
00225 int nfound = 0;
00226 dyn_hash_map<void *, typeCollection *>::iterator tciter;
00227 for (tciter = fileToTypesMap.begin(); tciter != fileToTypesMap.end(); tciter++)
00228 {
00229 Type *localt = NULL;
00230 if (tciter->second == primary_tc) continue;
00231 localt = tciter->second->findType(iter->first);
00232 if (localt)
00233 {
00234 if (localt->getDataClass() != ldc)
00235 continue;
00236 nfound++;
00237 if (t)
00238 {
00239 #if 0
00240 fprintf(stderr, "%s[%d]: WARN: found %d types w/ID %d (so far)\n",
00241 FILE__, __LINE__, nfound, iter->first);
00242 fprintf(stderr, "%s[%d]: have %s vs, %s\n", FILE__, __LINE__,
00243 dataClass2Str(t->getDataClass()),
00244 dataClass2Str(localt->getDataClass()));
00245 #endif
00246 }
00247 t = localt;
00248 }
00249
00250 }
00251 }
00252 if (t)
00253 {
00254 *th = t;
00255 }
00256 if (!t)
00257 {
00258 fprintf(stderr, "%s[%d]: FIXME: cannot find type id %d\n",
00259 FILE__, __LINE__, iter->first);
00260 err = true;
00261 continue;
00262 }
00263 }
00264 }
00265 deferred_lookups.clear();
00266 return (!err);
00267 }
00268
00269
00270
00271
00272
00273 #if 0
00274 typeCollection *typeCollection::getGlobalTypeCollection()
00275 {
00276 typeCollection *tc = new typeCollection();
00277
00278 return tc;
00279 }
00280 #endif
00281
00282 typeCollection *typeCollection::getModTypeCollection(Module *mod)
00283 {
00284 if (!mod) return NULL;
00285 dyn_hash_map<void *, typeCollection *>::iterator iter = fileToTypesMap.find((void *)mod);
00286
00287 if ( iter != fileToTypesMap.end())
00288 {
00289 return iter->second;
00290 }
00291
00292 typeCollection *newTC = new typeCollection();
00293 fileToTypesMap[(void *)mod] = newTC;
00294 return newTC;
00295 }
00296
00297 #if 0
00298 void typeCollection::freeTypeCollection(typeCollection *tc) {
00299 assert(tc);
00300 tc->refcount--;
00301 if (tc->refcount == 0) {
00302 dyn_hash_map<Module *, typeCollection *>::iterator iter = fileToTypesMap.begin();
00303 for (; iter!= fileToTypesMap.end(); iter++) {
00304 if (iter->second == tc) {
00305 fileToTypesMap.erase(iter->first);
00306 break;
00307 }
00308 }
00309 delete tc;
00310 }
00311 }
00312 #endif
00313
00314
00315
00316
00317
00318
00319
00320 typeCollection::typeCollection() :
00321 typesByName(),
00322 globalVarsByName(),
00323 typesByID(),
00324 dwarfParsed_(false)
00325 {
00326
00327 }
00328
00329
00330
00331
00332
00333
00334
00335 typeCollection::~typeCollection()
00336 {
00337
00338
00339
00340
00341 #if 0
00342 dictionary_hash_iter<std::string, type *> ti(typesByName);
00343 dictionary_hash_iter<int, type *> tid(typesByID);
00344 dictionary_hash_iter<std::string, type *> gi(globalVarsByName);
00345
00346 std::string gname;
00347 std::string name;
00348 type *type;
00349 int id;
00350 while (tid.next(id, type))
00351 delete type;
00352
00353
00354
00355 while (ti.next(name, type))
00356 type = NULL;
00357
00358
00359 while (gi.next(name, type))
00360 delete type;
00361
00362 for (dictionary_hash_iter<int, type *> it = typesByID.begin();
00363 it != typesByID.end();
00364 it ++) {
00365 (*it)->decrRefCount();
00366 }
00367 for (dictionary_hash_iter<std::string, type *> it2 = typesByName.begin();
00368 it2 != typesByName.end();
00369 it2 ++) {
00370 (*it2)->decrRefCount();
00371 }
00372 #endif
00373 }
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385 Type *typeCollection::findType(std::string name)
00386 {
00387 if (typesByName.find(name) != typesByName.end())
00388 return typesByName[name];
00389 else if (Symtab::builtInTypes())
00390 return Symtab::builtInTypes()->findBuiltInType(name);
00391 else
00392 return NULL;
00393 }
00394
00395 Type *typeCollection::findTypeLocal(std::string name)
00396 {
00397 if (typesByName.find(name) != typesByName.end())
00398 return typesByName[name];
00399 else
00400 return NULL;
00401 }
00402
00403 Type *typeCollection::findTypeLocal(const int ID)
00404 {
00405 if (typesByID.find(ID) != typesByID.end())
00406 return typesByID[ID];
00407 else
00408 return NULL;
00409 }
00410
00411
00412 Type * typeCollection::findOrCreateType( const int ID )
00413 {
00414 if ( typesByID.find(ID) != typesByID.end())
00415 {
00416 return typesByID[ID];
00417 }
00418
00419 Type * returnType = NULL;
00420
00421 if ( Symtab::builtInTypes() )
00422 {
00423 returnType = Symtab::builtInTypes()->findBuiltInType(ID);
00424
00425 if (returnType)
00426 return returnType;
00427 }
00428
00429
00430 returnType = Type::createPlaceholder(ID);
00431 assert( returnType != NULL );
00432
00433
00434 addType( returnType );
00435
00436 return returnType;
00437 }
00438
00439 Type *typeCollection::findType(const int ID)
00440 {
00441 if (typesByID.find(ID) != typesByID.end())
00442 return typesByID[ID];
00443 else
00444 {
00445 Type *ret = NULL;
00446
00447 if (Symtab::builtInTypes())
00448 ret = Symtab::builtInTypes()->findBuiltInType(ID);
00449
00450 return ret;
00451 }
00452 }
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463 Type *typeCollection::findVariableType(std::string &name)
00464 {
00465 if (globalVarsByName.find(name) != globalVarsByName.end())
00466 return globalVarsByName[name];
00467 else
00468 return (Type *) NULL;
00469 }
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479 void typeCollection::addType(Type *type)
00480 {
00481 if(type->getName() != "") {
00482 typesByName[type->getName()] = type;
00483 type->incrRefCount();
00484 }
00485
00486
00487
00488
00489
00490
00491 typesByID[type->getID()] = type;
00492 type->incrRefCount();
00493 }
00494
00495 void typeCollection::addGlobalVariable(std::string &name, Type *type)
00496 {
00497
00498 globalVarsByName[name] = type;
00499 }
00500
00501 void typeCollection::clearNumberedTypes()
00502 {
00503 for (dyn_hash_map<int, Type *>::iterator it = typesByID.begin();
00504 it != typesByID.end();
00505 it ++)
00506 {
00507 if (it->second)
00508 it->second->decrRefCount();
00509 else
00510 fprintf(stderr, "%s[%d]: FIXME\n", FILE__, __LINE__);
00511 }
00512
00513 typesByID.clear();
00514 }
00515
00516
00517
00518
00519
00520 std::vector<Type *> *typeCollection::getAllTypes() {
00521 std::vector<Type *> *typesVec = new std::vector<Type *>;
00522
00523
00524
00525 for (dyn_hash_map<string, Type *>::iterator it = typesByName.begin();
00526 it != typesByName.end();
00527 it ++) {
00528 typesVec->push_back(it->second);
00529 }
00530 if(!typesVec->size()){
00531 delete typesVec;
00532 return NULL;
00533 }
00534 return typesVec;
00535 }
00536
00537 vector<pair<string, Type *> > *typeCollection::getAllGlobalVariables() {
00538 vector<pair<string, Type *> > *varsVec = new vector<pair<string, Type *> >;
00539 for(dyn_hash_map<string, Type *>::iterator it = globalVarsByName.begin();
00540 it != globalVarsByName.end(); it++) {
00541 varsVec->push_back(pair<string, Type *>(it->first, it->second));
00542 }
00543 if(!varsVec->size()){
00544 delete varsVec;
00545 return NULL;
00546 }
00547 return varsVec;
00548 }
00549
00550 #if !defined(SERIALIZATION_DISABLED)
00551 Serializable *typeCollection::serialize_impl(SerializerBase *sb, const char *tag) THROW_SPEC (SerializerError)
00552 {
00553 serialize_printf("%s[%d]: enter typeCollection::serialize_impl\n", FILE__, __LINE__);
00554
00555 std::vector<std::pair<std::string, int> > gvars;
00556 dyn_hash_map<std::string, Type *>::iterator iter;
00557 for (iter = globalVarsByName.begin(); iter != globalVarsByName.end(); iter++)
00558 gvars.push_back(std::make_pair(iter->first, iter->second->getID()));
00559
00560 std::vector<Type *> ltypes;
00561 dyn_hash_map<int, Type *>::iterator iter2;
00562 for (iter2 = typesByID.begin(); iter2 != typesByID.end(); iter2++)
00563 {
00564 if (!iter2->second) assert(0);
00565
00566
00567 assert (iter2->first == iter2->second->getID());
00568 ltypes.push_back(iter2->second);
00569 }
00570
00571 ifxml_start_element(sb, tag);
00572
00573 gtranslate(sb, ltypes, "TypesInCollection", "TypeEntry");
00574 gtranslate(sb, gvars, "GlobalVarNameToTypeMap", "GlobalVarType");
00575 gtranslate(sb, dwarfParsed_, "DwarfParsedFlag");
00576 ifxml_end_element(sb, tag);
00577
00578 if (is_input(sb))
00579 {
00580 for (unsigned int i = 0; i < ltypes.size(); ++i)
00581 {
00582 typesByID[ltypes[i]->getID()] = ltypes[i];
00583 }
00584 doDeferredLookups(this);
00585
00586 for (unsigned int i = 0; i < gvars.size(); ++i)
00587 {
00588 dyn_hash_map<int, Type *>::iterator iter = typesByID.find(gvars[i].second);
00589 if (iter == typesByID.end())
00590 {
00591 serialize_printf("%s[%d]: cannot find type w/ID %d\n",
00592 FILE__, __LINE__, gvars[i].second);
00593 continue;
00594 }
00595 Type *t = iter->second;
00596 globalVarsByName[gvars[i].first] = t;
00597 }
00598
00599 dyn_hash_map<int, Type *>::iterator iter;
00600 for (iter = typesByID.begin(); iter != typesByID.end(); iter++)
00601 typesByName[iter->second->getName()] = iter->second;
00602 }
00603
00604 serialize_printf("%s[%d]: leave typeCollection::serialize_impl\n", FILE__, __LINE__);
00605
00606 return NULL;
00607 }
00608 #else
00609 Serializable *typeCollection::serialize_impl(SerializerBase *, const char *) THROW_SPEC (SerializerError)
00610 {
00611 return NULL;
00612 }
00613 #endif
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623 builtInTypeCollection::builtInTypeCollection()
00624 {
00625
00626 }
00627
00628
00629
00630
00631
00632
00633
00634 builtInTypeCollection::~builtInTypeCollection()
00635 {
00636 dyn_hash_map<std::string, Type *>::iterator bit = builtInTypesByName.begin();
00637 dyn_hash_map<int, Type *>::iterator bitid = builtInTypesByID.begin();
00638
00639
00640 for(;bit!=builtInTypesByName.end();bit++)
00641 bit->second->decrRefCount();
00642
00643 for(;bitid!=builtInTypesByID.end();bitid++)
00644 bitid->second->decrRefCount();
00645 }
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658 Type *builtInTypeCollection::findBuiltInType(std::string &name)
00659 {
00660 if (builtInTypesByName.find(name) != builtInTypesByName.end())
00661 return builtInTypesByName[name];
00662 else
00663 return (Type *)NULL;
00664 }
00665
00666 Type *builtInTypeCollection::findBuiltInType(const int ID)
00667 {
00668 if (builtInTypesByID.find(ID) != builtInTypesByID.end())
00669 return builtInTypesByID[ID];
00670 else
00671 return (Type *)NULL;
00672 }
00673
00674 void builtInTypeCollection::addBuiltInType(Type *type)
00675 {
00676 if(type->getName() != "") {
00677 builtInTypesByName[type->getName()] = type;
00678 type->incrRefCount();
00679 }
00680
00681 builtInTypesByID[type->getID()] = type;
00682 type->incrRefCount();
00683 }
00684
00685 std::vector<Type *> *builtInTypeCollection::getAllBuiltInTypes() {
00686 std::vector<Type *> *typesVec = new std::vector<Type *>;
00687 for (dyn_hash_map<int, Type *>::iterator it = builtInTypesByID.begin();
00688 it != builtInTypesByID.end();
00689 it ++) {
00690 typesVec->push_back(it->second);
00691 }
00692 if(!typesVec->size()){
00693 free(typesVec);
00694 return NULL;
00695 }
00696 return typesVec;
00697 }