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 <stdlib.h>
00033 #include <assert.h>
00034 #include <string.h>
00035 #include <algorithm>
00036
00037 #include "common/h/Timer.h"
00038 #include "common/h/debugOstream.h"
00039 #include "common/h/serialize.h"
00040 #include "common/h/pathName.h"
00041
00042 #include "Serialization.h"
00043 #include "Symtab.h"
00044 #include "Symbol.h"
00045 #include "Module.h"
00046 #include "Collections.h"
00047 #include "Function.h"
00048 #include "Variable.h"
00049
00050 #include "symtabAPI/src/Object.h"
00051
00052 #include "boost/tuple/tuple.hpp"
00053
00054 using namespace Dyninst;
00055 using namespace Dyninst::SymtabAPI;
00056 using namespace std;
00057
00058 static Symbol deletedSymbol(std::string("DeletedSymbol"), Symbol::ST_DELETED, Symbol::SL_UNKNOWN, Symbol::SV_UNKNOWN, 0);
00059
00060
00061
00062
00063
00064
00065 bool Symtab::changeType(Symbol *sym, Symbol::SymbolType oldType)
00066 {
00067 switch (oldType) {
00068 case Symbol::ST_FUNCTION: {
00069 Function *func = NULL;
00070 if (findFuncByEntryOffset(func, sym->getOffset())) {
00071
00072 func->removeSymbol(sym);
00073
00074
00075 break;
00076 }
00077 }
00078 case Symbol::ST_TLS:
00079 case Symbol::ST_OBJECT: {
00080 Variable *var = NULL;
00081 if (findVariableByOffset(var, sym->getOffset())) {
00082 var->removeSymbol(sym);
00083
00084 }
00085 break;
00086 }
00087 case Symbol::ST_MODULE: {
00088
00089 break;
00090 }
00091 default:
00092 break;
00093 }
00094
00095 addSymbolToIndices(sym, false);
00096 addSymbolToAggregates(sym);
00097
00098 return true;
00099 }
00100
00101 bool Symtab::deleteFunction(Function *func) {
00102
00103 everyFunction.erase(std::remove(everyFunction.begin(), everyFunction.end(), func), everyFunction.end());
00104
00105
00106
00107
00108
00109
00110
00111 funcsByOffset.erase(func->getOffset());
00112
00113
00114 return deleteAggregate(func);
00115 }
00116
00117 bool Symtab::deleteVariable(Variable *var) {
00118
00119 everyVariable.erase(std::remove(everyVariable.begin(), everyVariable.end(), var), everyVariable.end());
00120
00121 varsByOffset.erase(var->getOffset());
00122 return deleteAggregate(var);
00123 }
00124
00125 bool Symtab::deleteAggregate(Aggregate *agg) {
00126 std::vector<Symbol *> syms;
00127 agg->getSymbols(syms);
00128
00129 bool ret = true;
00130 for (unsigned i = 0; i < syms.size(); i++) {
00131 if (!deleteSymbolFromIndices(syms[i]))
00132 ret = false;
00133 }
00134 return ret;
00135 }
00136
00137 bool Symtab::deleteSymbolFromIndices(Symbol *sym) {
00138
00139 std::vector<Symbol *>::iterator iter;
00140
00141
00142 for (iter = everyDefinedSymbol.begin(); iter != everyDefinedSymbol.end(); iter++)
00143 {
00144
00145
00146 if ((*iter) == sym) (*iter) = &deletedSymbol;
00147 }
00148 undefDynSymsByMangledName[sym->getMangledName()].erase(std::remove(undefDynSymsByMangledName[sym->getMangledName()].begin(),
00149 undefDynSymsByMangledName[sym->getMangledName()].end(), sym),
00150 undefDynSymsByMangledName[sym->getMangledName()].end());
00151 undefDynSymsByPrettyName[sym->getPrettyName()].erase(std::remove(undefDynSymsByPrettyName[sym->getPrettyName()].begin(),
00152 undefDynSymsByPrettyName[sym->getPrettyName()].end(), sym),
00153 undefDynSymsByPrettyName[sym->getPrettyName()].end());
00154 undefDynSymsByTypedName[sym->getTypedName()].erase(std::remove(undefDynSymsByTypedName[sym->getTypedName()].begin(),
00155 undefDynSymsByTypedName[sym->getTypedName()].end(), sym),
00156 undefDynSymsByTypedName[sym->getTypedName()].end());
00157 undefDynSyms.erase(std::remove(undefDynSyms.begin(), undefDynSyms.end(), sym), undefDynSyms.end());
00158
00159 symsByOffset[sym->getOffset()].erase(std::remove(symsByOffset[sym->getOffset()].begin(), symsByOffset[sym->getOffset()].end(),
00160 sym), symsByOffset[sym->getOffset()].end());
00161 symsByMangledName[sym->getMangledName()].erase(std::remove(symsByMangledName[sym->getMangledName()].begin(),
00162 symsByMangledName[sym->getMangledName()].end(), sym),
00163 symsByMangledName[sym->getMangledName()].end());
00164 symsByPrettyName[sym->getPrettyName()].erase(std::remove(symsByPrettyName[sym->getPrettyName()].begin(),
00165 symsByPrettyName[sym->getPrettyName()].end(), sym),
00166 symsByPrettyName[sym->getPrettyName()].end());
00167 symsByTypedName[sym->getTypedName()].erase(std::remove(symsByTypedName[sym->getTypedName()].begin(),
00168 symsByTypedName[sym->getTypedName()].end(), sym),
00169 symsByTypedName[sym->getTypedName()].end());
00170 return true;
00171 }
00172
00173 bool Symtab::deleteSymbol(Symbol *sym)
00174 {
00175 if (sym->aggregate_) {
00176 sym->aggregate_->removeSymbol(sym);
00177 }
00178
00179 return deleteSymbolFromIndices(sym);
00180 }
00181
00182 bool Symtab::changeSymbolOffset(Symbol *sym, Offset newOffset) {
00183
00184
00185
00186
00187
00188
00189
00190 Offset oldOffset = sym->offset_;
00191 std::vector<Symbol *>::iterator iter;
00192 for (iter = symsByOffset[oldOffset].begin();
00193 iter != symsByOffset[oldOffset].end();
00194 iter++) {
00195 if ((*iter) == sym) {
00196 symsByOffset[oldOffset].erase(iter);
00197 break;
00198 }
00199 }
00200 sym->offset_ = newOffset;
00201 symsByOffset[newOffset].push_back(sym);
00202
00203 if (sym->aggregate_ == NULL) return true;
00204 else
00205 return sym->aggregate_->changeSymbolOffset(sym);
00206
00207 }
00208
00209 bool Symtab::changeAggregateOffset(Aggregate *agg, Offset oldOffset, Offset newOffset) {
00210 Function *func = dynamic_cast<Function *>(agg);
00211 Variable *var = dynamic_cast<Variable *>(agg);
00212
00213 if (func) {
00214 funcsByOffset.erase(oldOffset);
00215 if (funcsByOffset.find(newOffset) == funcsByOffset.end())
00216 funcsByOffset[newOffset] = func;
00217 else {
00218
00219 }
00220 }
00221 if (var) {
00222 varsByOffset.erase(oldOffset);
00223 if (varsByOffset.find(newOffset) == varsByOffset.end())
00224 varsByOffset[newOffset] = var;
00225 else {
00226
00227 }
00228 }
00229 return true;
00230 }
00231
00232 bool Symtab::addSymbol(Symbol *newSym, Symbol *referringSymbol)
00233 {
00234 if (!newSym || !referringSymbol ) return false;
00235
00236 if( !referringSymbol->getSymtab()->isStaticBinary() ) {
00237 if (!newSym->isInDynSymtab()) return false;
00238
00239 newSym->setReferringSymbol(referringSymbol);
00240
00241 string filename = referringSymbol->getModule()->exec()->name();
00242 vector<string> *vers, *newSymVers = new vector<string>;
00243 newSym->setVersionFileName(filename);
00244 std::string rstr;
00245
00246 bool ret = newSym->getVersionFileName(rstr);
00247 if (!ret)
00248 {
00249 fprintf(stderr, "%s[%d]: failed to getVersionFileName(%s)\n",
00250 FILE__, __LINE__, rstr.c_str());
00251 }
00252
00253 if (referringSymbol->getVersions(vers) && vers != NULL && vers->size() > 0)
00254 {
00255 newSymVers->push_back((*vers)[0]);
00256 newSym->setVersions(*newSymVers);
00257 }
00258 }else{
00259 newSym->setReferringSymbol(referringSymbol);
00260 }
00261
00262 return addSymbol(newSym);
00263 }
00264
00265 bool Symtab::addSymbol(Symbol *newSym)
00266 {
00267 if (!newSym) {
00268 return false;
00269 }
00270
00271
00272
00273 if (newSym->getModule() == NULL) {
00274 newSym->setModule(getDefaultModule());
00275 }
00276
00277
00278 if (newSym->getPrettyName() == "") {
00279 demangleSymbol(newSym);
00280 }
00281
00282
00283 addSymbolToIndices(newSym, false);
00284
00285
00286 addSymbolToAggregates(newSym);
00287
00288 return true;
00289 }
00290
00291
00292 Function *Symtab::createFunction(std::string name,
00293 Offset offset,
00294 size_t sz,
00295 Module *mod)
00296 {
00297 Region *reg = NULL;
00298
00299 if (!findRegion(reg, ".text") && !isDefensiveBinary()) {
00300 assert(0 && "could not find text region");
00301 fprintf(stderr, "%s[%d]: could not find text region\n", FILE__, __LINE__);
00302 return NULL;
00303 }
00304
00305 if (!reg) {
00306 reg = findEnclosingRegion(offset);
00307 }
00308
00309 if (!reg) {
00310 fprintf(stderr, "%s[%d]: could not find region for func at %lx\n",
00311 FILE__, __LINE__,offset);
00312 return NULL;
00313 }
00314
00315
00316 if (mod == NULL) {
00317 mod = getDefaultModule();
00318 }
00319
00320
00321 bool found = false;
00322 for (unsigned i = 0; i < _mods.size(); i++) {
00323 if (_mods[i] == mod) {
00324 found = true;
00325 break;
00326 }
00327 }
00328 if (!found) {
00329 fprintf(stderr, "Mod is %p/%s\n",
00330 mod, mod->fileName().c_str());
00331 for (unsigned i = 0; i < _mods.size(); i++) {
00332 fprintf(stderr, "Matched against %p/%s\n",
00333 _mods[i], _mods[i]->fileName().c_str());
00334 }
00335 fprintf(stderr, "This %p; mod symtab %p\n",
00336 this, mod->exec());
00337
00338 assert(0 && "passed invalid module\n");
00339 return NULL;
00340 }
00341
00342 Symbol *statSym = new Symbol(name,
00343 Symbol::ST_FUNCTION,
00344 Symbol::SL_GLOBAL,
00345 Symbol::SV_DEFAULT,
00346 offset,
00347 mod,
00348 reg,
00349 sz,
00350 false,
00351 false);
00352 Symbol *dynSym = new Symbol(name,
00353 Symbol::ST_FUNCTION,
00354 Symbol::SL_GLOBAL,
00355 Symbol::SV_DEFAULT,
00356 offset,
00357 mod,
00358 reg,
00359 sz,
00360 true,
00361 false);
00362
00363 if (!addSymbol(statSym) || !addSymbol(dynSym)) {
00364 assert(0 && "failed to add symbol\n");
00365 fprintf(stderr, "%s[%d]: symtab failed to addSymbol\n", FILE__, __LINE__);
00366 return NULL;
00367 }
00368
00369 Function *func = statSym->getFunction();
00370 if (!func) {
00371 assert(0 && "failed aggregate creation");
00372 fprintf(stderr, "%s[%d]: symtab failed to create function\n", FILE__, __LINE__);
00373 return NULL;
00374 }
00375
00376 return func;
00377 }
00378
00379
00380
00381 Variable *Symtab::createVariable(std::string name,
00382 Offset offset,
00383 size_t sz,
00384 Module *mod)
00385 {
00386 Region *reg = NULL;
00387 #if 0
00388 if (!findRegion(reg, ".data") {
00389 fprintf(stderr, "%s[%d]: could not find %s region\n", FILE__, __LINE__, regionName.c_str());
00390 return NULL;
00391 }
00392
00393 if (!reg) {
00394 fprintf(stderr, "%s[%d]: could not find data region\n", FILE__, __LINE__);
00395 return NULL;
00396 }
00397 #endif
00398
00399 if (mod == NULL) {
00400 mod = getDefaultModule();
00401 }
00402
00403 bool found = false;
00404 for (unsigned i = 0; i < _mods.size(); i++) {
00405 if (_mods[i] == mod) {
00406 found = true;
00407 break;
00408 }
00409 }
00410 if (!found) return NULL;
00411
00412 Symbol *statSym = new Symbol(name,
00413 Symbol::ST_OBJECT,
00414 Symbol::SL_GLOBAL,
00415 Symbol::SV_DEFAULT,
00416 offset,
00417 mod,
00418 reg,
00419 sz,
00420 false,
00421 false);
00422 Symbol *dynSym = new Symbol(name,
00423 Symbol::ST_OBJECT,
00424 Symbol::SL_GLOBAL,
00425 Symbol::SV_DEFAULT,
00426 offset,
00427 mod,
00428 reg,
00429 sz,
00430 true,
00431 false);
00432
00433 statSym->setModule(mod);
00434 dynSym->setModule(mod);
00435
00436 if (!addSymbol(statSym) || !addSymbol(dynSym)) {
00437 fprintf(stderr, "%s[%d]: symtab failed to addSymbol\n", FILE__, __LINE__);
00438 return NULL;
00439 }
00440
00441 Variable *var = statSym->getVariable();
00442 if (!var) {
00443 fprintf(stderr, "%s[%d]: symtab failed to create var\n", FILE__, __LINE__);
00444 return NULL;
00445 }
00446
00447 return var;
00448 }
00449
00450 SYMTAB_EXPORT bool Symtab::updateRelocations(Address start,
00451 Address end,
00452 Symbol *oldsym,
00453 Symbol *newsym) {
00454 for (unsigned i = 0; i < codeRegions_.size(); ++i) {
00455 codeRegions_[i]->updateRelocations(start, end, oldsym, newsym);
00456 }
00457 return true;
00458 }
00459