2 * See the dyninst/COPYRIGHT file for copyright information.
4 * We provide the Paradyn Tools (below described as "Paradyn")
5 * on an AS IS basis, and do not warrant its validity or performance.
6 * We reserve the right to update, modify, or discontinue this
7 * software at any time. We shall have no obligation to supply such
8 * updates or modifications or any other form of support to you.
10 * By your use of Paradyn, you understand and agree that we (or any
11 * other person or entity with proprietary rights in Paradyn) are
12 * under no obligation to provide either maintenance services,
13 * update services, notices of latent defects, or correction of
14 * defects for Paradyn.
16 * This library is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU Lesser General Public
18 * License as published by the Free Software Foundation; either
19 * version 2.1 of the License, or (at your option) any later version.
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Lesser General Public License for more details.
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
37 #include "common/h/Timer.h"
38 #include "common/h/debugOstream.h"
39 #include "common/h/serialize.h"
40 #include "common/h/pathName.h"
42 #include "Serialization.h"
46 #include "Collections.h"
50 #include "symtabAPI/src/Object.h"
52 #include "boost/tuple/tuple.hpp"
54 using namespace Dyninst;
55 using namespace Dyninst::SymtabAPI;
58 static Symbol deletedSymbol(std::string("DeletedSymbol"), Symbol::ST_DELETED, Symbol::SL_UNKNOWN, Symbol::SV_UNKNOWN, 0);
60 * We're changing the type of a symbol. Therefore we need to rip it out of the indices
61 * for whatever it used to be (also, aggregations) and put it in the new ones.
65 bool Symtab::changeType(Symbol *sym, Symbol::SymbolType oldType)
68 case Symbol::ST_FUNCTION: {
69 Function *func = NULL;
70 if (findFuncByEntryOffset(func, sym->getOffset())) {
71 // Remove this symbol from the function
72 func->removeSymbol(sym);
73 // What if we removed the last symbol from the function?
74 // Argh. Ah, well. Users may do that - leave it there for now.
79 case Symbol::ST_OBJECT: {
81 if (findVariableByOffset(var, sym->getOffset())) {
82 var->removeSymbol(sym);
87 case Symbol::ST_MODULE: {
88 // TODO Module should be an Aggregation
95 addSymbolToIndices(sym, false);
96 addSymbolToAggregates(sym);
101 bool Symtab::deleteFunction(Function *func) {
102 // First, remove the function
103 everyFunction.erase(std::remove(everyFunction.begin(), everyFunction.end(), func), everyFunction.end());
104 /* std::vector<Function *>::iterator iter;
105 for (iter = everyFunction.begin(); iter != everyFunction.end(); iter++) {
106 if ((*iter) == func) {
107 everyFunction.erase(iter);
111 funcsByOffset.erase(func->getOffset());
113 // Now handle the Aggregate stuff
114 return deleteAggregate(func);
117 bool Symtab::deleteVariable(Variable *var) {
118 // First, remove the function
119 everyVariable.erase(std::remove(everyVariable.begin(), everyVariable.end(), var), everyVariable.end());
121 varsByOffset.erase(var->getOffset());
122 return deleteAggregate(var);
125 bool Symtab::deleteAggregate(Aggregate *agg) {
126 std::vector<Symbol *> syms;
127 agg->getSymbols(syms);
130 for (unsigned i = 0; i < syms.size(); i++) {
131 if (!deleteSymbolFromIndices(syms[i]))
137 bool Symtab::deleteSymbolFromIndices(Symbol *sym) {
138 // Remove from global indices
139 std::vector<Symbol *>::iterator iter;
141 // everyDefinedSymbol
142 for (iter = everyDefinedSymbol.begin(); iter != everyDefinedSymbol.end(); iter++)
144 // we use indexes in this vector as a unique id for symbols, so mark
145 // as deleted w/out changing vector
146 if ((*iter) == sym) (*iter) = &deletedSymbol;
148 undefDynSymsByMangledName[sym->getMangledName()].erase(std::remove(undefDynSymsByMangledName[sym->getMangledName()].begin(),
149 undefDynSymsByMangledName[sym->getMangledName()].end(), sym),
150 undefDynSymsByMangledName[sym->getMangledName()].end());
151 undefDynSymsByPrettyName[sym->getPrettyName()].erase(std::remove(undefDynSymsByPrettyName[sym->getPrettyName()].begin(),
152 undefDynSymsByPrettyName[sym->getPrettyName()].end(), sym),
153 undefDynSymsByPrettyName[sym->getPrettyName()].end());
154 undefDynSymsByTypedName[sym->getTypedName()].erase(std::remove(undefDynSymsByTypedName[sym->getTypedName()].begin(),
155 undefDynSymsByTypedName[sym->getTypedName()].end(), sym),
156 undefDynSymsByTypedName[sym->getTypedName()].end());
157 undefDynSyms.erase(std::remove(undefDynSyms.begin(), undefDynSyms.end(), sym), undefDynSyms.end());
159 symsByOffset[sym->getOffset()].erase(std::remove(symsByOffset[sym->getOffset()].begin(), symsByOffset[sym->getOffset()].end(),
160 sym), symsByOffset[sym->getOffset()].end());
161 symsByMangledName[sym->getMangledName()].erase(std::remove(symsByMangledName[sym->getMangledName()].begin(),
162 symsByMangledName[sym->getMangledName()].end(), sym),
163 symsByMangledName[sym->getMangledName()].end());
164 symsByPrettyName[sym->getPrettyName()].erase(std::remove(symsByPrettyName[sym->getPrettyName()].begin(),
165 symsByPrettyName[sym->getPrettyName()].end(), sym),
166 symsByPrettyName[sym->getPrettyName()].end());
167 symsByTypedName[sym->getTypedName()].erase(std::remove(symsByTypedName[sym->getTypedName()].begin(),
168 symsByTypedName[sym->getTypedName()].end(), sym),
169 symsByTypedName[sym->getTypedName()].end());
173 bool Symtab::deleteSymbol(Symbol *sym)
175 if (sym->aggregate_) {
176 sym->aggregate_->removeSymbol(sym);
179 return deleteSymbolFromIndices(sym);
182 bool Symtab::changeSymbolOffset(Symbol *sym, Offset newOffset) {
183 // If we aren't part of an aggregate, change the symbol offset
184 // and update symsByOffset.
185 // If we are part of an aggregate and the only symbol element,
186 // do that and update funcsByOffset or varsByOffset.
187 // If we are and not the only symbol, do 1), remove from
188 // the aggregate, and make a new aggregate.
190 Offset oldOffset = sym->offset_;
191 std::vector<Symbol *>::iterator iter;
192 for (iter = symsByOffset[oldOffset].begin();
193 iter != symsByOffset[oldOffset].end();
195 if ((*iter) == sym) {
196 symsByOffset[oldOffset].erase(iter);
200 sym->offset_ = newOffset;
201 symsByOffset[newOffset].push_back(sym);
203 if (sym->aggregate_ == NULL) return true;
205 return sym->aggregate_->changeSymbolOffset(sym);
209 bool Symtab::changeAggregateOffset(Aggregate *agg, Offset oldOffset, Offset newOffset) {
210 Function *func = dynamic_cast<Function *>(agg);
211 Variable *var = dynamic_cast<Variable *>(agg);
214 funcsByOffset.erase(oldOffset);
215 if (funcsByOffset.find(newOffset) == funcsByOffset.end())
216 funcsByOffset[newOffset] = func;
218 // Already someone there... odd, so don't do anything.
222 varsByOffset.erase(oldOffset);
223 if (varsByOffset.find(newOffset) == varsByOffset.end())
224 varsByOffset[newOffset] = var;
226 // Already someone there... odd, so don't do anything.
232 bool Symtab::addSymbol(Symbol *newSym, Symbol *referringSymbol)
234 if (!newSym || !referringSymbol ) return false;
236 if( !referringSymbol->getSymtab()->isStaticBinary() ) {
237 if (!newSym->isInDynSymtab()) return false;
239 newSym->setReferringSymbol(referringSymbol);
241 string filename = referringSymbol->getModule()->exec()->name();
242 vector<string> *vers, *newSymVers = new vector<string>;
243 newSym->setVersionFileName(filename);
246 bool ret = newSym->getVersionFileName(rstr);
249 fprintf(stderr, "%s[%d]: failed to getVersionFileName(%s)\n",
250 FILE__, __LINE__, rstr.c_str());
253 if (referringSymbol->getVersions(vers) && vers != NULL && vers->size() > 0)
255 newSymVers->push_back((*vers)[0]);
256 newSym->setVersions(*newSymVers);
259 newSym->setReferringSymbol(referringSymbol);
262 return addSymbol(newSym);
265 bool Symtab::addSymbol(Symbol *newSym)
271 // Expected default behavior: if there is no
272 // module use the default.
273 if (newSym->getModule() == NULL) {
274 newSym->setModule(getDefaultModule());
277 // If there aren't any pretty names, create them
278 if (newSym->getPrettyName() == "") {
279 demangleSymbol(newSym);
282 // Add to appropriate indices
283 addSymbolToIndices(newSym, false);
286 addSymbolToAggregates(newSym);
292 Function *Symtab::createFunction(std::string name,
299 if (!findRegion(reg, ".text") && !isDefensiveBinary()) {
300 assert(0 && "could not find text region");
301 fprintf(stderr, "%s[%d]: could not find text region\n", FILE__, __LINE__);
306 reg = findEnclosingRegion(offset);
310 fprintf(stderr, "%s[%d]: could not find region for func at %lx\n",
311 FILE__, __LINE__,offset);
315 // Let's get the module hammered out.
317 mod = getDefaultModule();
320 // Check to see if we contain this module...
322 for (unsigned i = 0; i < _mods.size(); i++) {
323 if (_mods[i] == mod) {
329 fprintf(stderr, "Mod is %p/%s\n",
330 mod, mod->fileName().c_str());
331 for (unsigned i = 0; i < _mods.size(); i++) {
332 fprintf(stderr, "Matched against %p/%s\n",
333 _mods[i], _mods[i]->fileName().c_str());
335 fprintf(stderr, "This %p; mod symtab %p\n",
338 assert(0 && "passed invalid module\n");
342 Symbol *statSym = new Symbol(name,
352 Symbol *dynSym = new Symbol(name,
363 if (!addSymbol(statSym) || !addSymbol(dynSym)) {
364 assert(0 && "failed to add symbol\n");
365 fprintf(stderr, "%s[%d]: symtab failed to addSymbol\n", FILE__, __LINE__);
369 Function *func = statSym->getFunction();
371 assert(0 && "failed aggregate creation");
372 fprintf(stderr, "%s[%d]: symtab failed to create function\n", FILE__, __LINE__);
381 Variable *Symtab::createVariable(std::string name,
388 if (!findRegion(reg, ".data") {
389 fprintf(stderr, "%s[%d]: could not find %s region\n", FILE__, __LINE__, regionName.c_str());
394 fprintf(stderr, "%s[%d]: could not find data region\n", FILE__, __LINE__);
398 // Let's get the module hammered out.
400 mod = getDefaultModule();
402 // Check to see if we contain this module...
404 for (unsigned i = 0; i < _mods.size(); i++) {
405 if (_mods[i] == mod) {
410 if (!found) return NULL;
412 Symbol *statSym = new Symbol(name,
422 Symbol *dynSym = new Symbol(name,
433 statSym->setModule(mod);
434 dynSym->setModule(mod);
436 if (!addSymbol(statSym) || !addSymbol(dynSym)) {
437 fprintf(stderr, "%s[%d]: symtab failed to addSymbol\n", FILE__, __LINE__);
441 Variable *var = statSym->getVariable();
443 fprintf(stderr, "%s[%d]: symtab failed to create var\n", FILE__, __LINE__);
450 SYMTAB_EXPORT bool Symtab::updateRelocations(Address start,
454 for (unsigned i = 0; i < codeRegions_.size(); ++i) {
455 codeRegions_[i]->updateRelocations(start, end, oldsym, newsym);