Symtab-edit.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 
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  * We're changing the type of a symbol. Therefore we need to rip it out of the indices
00061  * for whatever it used to be (also, aggregations) and put it in the new ones. 
00062  * Oy. 
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             // Remove this symbol from the function
00072             func->removeSymbol(sym);
00073             // What if we removed the last symbol from the function?
00074             // Argh. Ah, well. Users may do that - leave it there for now.
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             // See above
00084         }
00085         break;
00086     }
00087     case Symbol::ST_MODULE: {
00088         // TODO Module should be an Aggregation
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     // First, remove the function
00103     everyFunction.erase(std::remove(everyFunction.begin(), everyFunction.end(), func), everyFunction.end());
00104 /*    std::vector<Function *>::iterator iter;
00105     for (iter = everyFunction.begin(); iter != everyFunction.end(); iter++) {
00106         if ((*iter) == func) {
00107             everyFunction.erase(iter);
00108         }
00109     }
00110 */
00111     funcsByOffset.erase(func->getOffset());
00112 
00113     // Now handle the Aggregate stuff
00114     return deleteAggregate(func);
00115 }
00116 
00117 bool Symtab::deleteVariable(Variable *var) {
00118     // First, remove the function
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     // Remove from global indices
00139     std::vector<Symbol *>::iterator iter;
00140 
00141     // everyDefinedSymbol
00142     for (iter = everyDefinedSymbol.begin(); iter != everyDefinedSymbol.end(); iter++) 
00143     {
00144         //  we use indexes in this vector as a unique id for symbols, so mark
00145         //  as deleted w/out changing vector
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     // If we aren't part of an aggregate, change the symbol offset
00184     // and update symsByOffset.
00185     // If we are part of an aggregate and the only symbol element,
00186     // do that and update funcsByOffset or varsByOffset.
00187     // If we are and not the only symbol, do 1), remove from 
00188     // the aggregate, and make a new aggregate.
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             // Already someone there... odd, so don't do anything.
00219         }
00220     }
00221     if (var) {
00222         varsByOffset.erase(oldOffset);
00223         if (varsByOffset.find(newOffset) == varsByOffset.end())
00224             varsByOffset[newOffset] = var;
00225         else {
00226             // Already someone there... odd, so don't do anything.
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    // Expected default behavior: if there is no
00272    // module use the default.
00273    if (newSym->getModule() == NULL) {
00274       newSym->setModule(getDefaultModule());
00275    }
00276    
00277    // If there aren't any pretty names, create them
00278    if (newSym->getPrettyName() == "") {
00279       demangleSymbol(newSym);
00280    }
00281    
00282    // Add to appropriate indices
00283    addSymbolToIndices(newSym, false);
00284    
00285    // And to aggregates
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     // Let's get the module hammered out. 
00316     if (mod == NULL) {
00317         mod = getDefaultModule();
00318     }
00319 
00320     // Check to see if we contain this module...
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     // Let's get the module hammered out. 
00399     if (mod == NULL) {
00400         mod = getDefaultModule();
00401     }
00402     // Check to see if we contain this module...
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 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1