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
00032
00033 #include "Annotatable.h"
00034 #include "common/h/serialize.h"
00035
00036 #include "Symtab.h"
00037 #include "symutil.h"
00038 #include "Module.h"
00039 #include "Collections.h"
00040 #include "Function.h"
00041 #include "dynutil/h/VariableLocation.h"
00042 #include "symtabAPI/src/Object.h"
00043
00044 #if !defined(os_windows)
00045 #include "dwarf/h/dwarfFrameParser.h"
00046 #endif
00047
00048 #include "annotations.h"
00049 #include <iterator>
00050 #include <algorithm>
00051
00052 #include <iostream>
00053
00054 using namespace std;
00055 using namespace Dyninst;
00056 using namespace Dyninst::SymtabAPI;
00057
00058 Function::Function(Symbol *sym)
00059 : Aggregate(sym),
00060 retType_(NULL),
00061 framePtrRegNum_(-1),
00062 frameBaseExpanded_(false),
00063 functionSize_(0)
00064 {}
00065
00066 Function::Function()
00067 : Aggregate(),
00068 retType_(NULL),
00069 framePtrRegNum_(-1),
00070 frameBaseExpanded_(false),
00071 functionSize_(0)
00072 {}
00073
00074 Type * Function::getReturnType() const
00075 {
00076 return retType_;
00077 }
00078
00079 bool Function::setReturnType(Type *newType)
00080 {
00081 retType_ = newType;
00082 return true;
00083 }
00084
00085 int Function::getFramePtrRegnum() const
00086 {
00087 return framePtrRegNum_;
00088 }
00089
00090 bool Function::setFramePtrRegnum(int regnum)
00091 {
00092 framePtrRegNum_ = regnum;
00093 return true;
00094 }
00095
00096 Offset Function::getPtrOffset() const
00097 {
00098 Offset retval = 0;
00099 for (unsigned i = 0; i < symbols_.size(); ++i) {
00100 Offset tmp_off = symbols_[i]->getPtrOffset();
00101 if (tmp_off) {
00102 if (retval == 0) retval = tmp_off;
00103 assert(retval == tmp_off);
00104 }
00105 }
00106 return retval;
00107 }
00108
00109 Offset Function::getTOCOffset() const
00110 {
00111 Offset retval = 0;
00112 for (unsigned i = 0; i < symbols_.size(); ++i) {
00113 Offset tmp_toc = symbols_[i]->getLocalTOC();
00114 if (tmp_toc) {
00115 if (retval == 0) retval = tmp_toc;
00116 assert(retval == tmp_toc);
00117 }
00118 }
00119 return retval;
00120 }
00121
00122 std::vector<Dyninst::VariableLocation> &Function::getFramePtrRefForInit() {
00123 return frameBase_;
00124 }
00125
00126 std::vector<Dyninst::VariableLocation> &Function::getFramePtr()
00127 {
00128 if (frameBaseExpanded_)
00129 return frameBase_;
00130
00131 frameBaseExpanded_ = true;
00132
00133 std::vector<VariableLocation> orig;
00134 orig.swap(frameBase_);
00135
00136 for (unsigned i = 0; i < orig.size(); ++i) {
00137 expandLocation(orig[i], frameBase_);
00138 }
00139
00140 return frameBase_;
00141 }
00142
00143 bool Function::setFramePtr(vector<VariableLocation> *locs)
00144 {
00145 frameBase_.clear();
00146 std::copy(locs->begin(), locs->end(), std::back_inserter(frameBase_));
00147 return true;
00148 }
00149
00150 void Function::expandLocation(const VariableLocation &loc,
00151 std::vector<VariableLocation> &ret) {
00152
00153
00154 assert(loc.mr_reg != Dyninst::FrameBase);
00155
00156 #if defined(os_windows)
00157 ret.push_back(loc);
00158 return;
00159 #else
00160 if (loc.mr_reg != Dyninst::CFA) {
00161 ret.push_back(loc);
00162 return;
00163 }
00164
00165 Dyninst::Dwarf::DwarfFrameParser::Ptr frameParser =
00166 Dyninst::Dwarf::DwarfFrameParser::create(*module_->exec()->getObject()->dwarf->frame_dbg(),
00167 module_->exec()->getObject()->getArch());
00168
00169 std::vector<VariableLocation> FDEs;
00170 Dyninst::Dwarf::FrameErrors_t err;
00171 frameParser->getRegsForFunction(getOffset(),
00172 Dyninst::CFA,
00173 FDEs,
00174 err);
00175
00176
00177 if (FDEs.empty()) {
00178
00179 return;
00180 }
00181
00182
00183
00184
00185 std::vector<VariableLocation>::iterator i;
00186 for (i = FDEs.begin(); i != FDEs.end(); i++)
00187 {
00188 Offset fdelowPC = i->lowPC;
00189 Offset fdehiPC = i->hiPC;
00190
00191 Offset frame_lowPC = loc.lowPC;
00192 Offset frame_hiPC = loc.hiPC;
00193
00194 if (frame_hiPC < fdehiPC) {
00195
00196
00197 break;
00198 }
00199
00200
00201 Offset low = (frame_lowPC < fdelowPC) ? fdelowPC : frame_lowPC;
00202
00203
00204 Offset high = (frame_hiPC < fdehiPC) ? frame_hiPC : fdehiPC;
00205
00206 VariableLocation newloc;
00207
00208 newloc.stClass = loc.stClass;
00209 newloc.refClass = loc.refClass;
00210 newloc.mr_reg = i->mr_reg;
00211 newloc.frameOffset = loc.frameOffset + i->frameOffset;
00212 newloc.lowPC = low;
00213 newloc.hiPC = high;
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229 ret.push_back(newloc);
00230 }
00231 return;
00232 #endif
00233 }
00234
00235 bool Function::findLocalVariable(std::vector<localVar *> &vars, std::string name)
00236 {
00237 module_->exec()->parseTypesNow();
00238
00239 localVarCollection *lvs = NULL, *lps = NULL;
00240 bool res1 = false, res2 = false;
00241 res1 = getAnnotation(lvs, FunctionLocalVariablesAnno);
00242 res2 = getAnnotation(lps, FunctionParametersAnno);
00243
00244 if (!res1 && !res2)
00245 return false;
00246
00247 unsigned origSize = vars.size();
00248
00249 if (lvs)
00250 {
00251 localVar *var = lvs->findLocalVar(name);
00252 if (var)
00253 vars.push_back(var);
00254 }
00255
00256 if (lps)
00257 {
00258 localVar *var = lps->findLocalVar(name);
00259 if (var)
00260 vars.push_back(var);
00261 }
00262
00263 if (vars.size() > origSize)
00264 return true;
00265
00266 return false;
00267 }
00268
00269 bool Function::getLocalVariables(std::vector<localVar *> &vars)
00270 {
00271 module_->exec()->parseTypesNow();
00272
00273 localVarCollection *lvs = NULL;
00274 if (!getAnnotation(lvs, FunctionLocalVariablesAnno))
00275 {
00276 return false;
00277 }
00278 if (!lvs)
00279 {
00280 return false;
00281 }
00282
00283 std::vector<localVar *> &p = *lvs->getAllVars();
00284 std::copy(p.begin(), p.end(), back_inserter(vars));
00285
00286 if (p.empty())
00287 return false;
00288 return true;
00289 }
00290
00291 bool Function::getParams(std::vector<localVar *> ¶ms)
00292 {
00293 module_->exec()->parseTypesNow();
00294
00295 localVarCollection *lvs = NULL;
00296 if (!getAnnotation(lvs, FunctionParametersAnno))
00297 {
00298 if (!setupParams())
00299 {
00300 return false;
00301 }
00302
00303 if (!getAnnotation(lvs, FunctionParametersAnno))
00304 {
00305 return false;
00306 }
00307 }
00308
00309 if (!lvs)
00310 return false;
00311
00312 std::vector<localVar *> &p = *lvs->getAllVars();
00313 std::copy(p.begin(), p.end(), back_inserter(params));
00314
00315 if (p.empty())
00316 return false;
00317 return true;
00318 }
00319
00320 bool Function::addLocalVar(localVar *locVar)
00321 {
00322 localVarCollection *lvs = NULL;
00323
00324 if (!getAnnotation(lvs, FunctionLocalVariablesAnno))
00325 {
00326 lvs = new localVarCollection();
00327
00328 if (!addAnnotation(lvs, FunctionLocalVariablesAnno))
00329 {
00330 return false;
00331 }
00332 }
00333 if (!lvs)
00334 return false;
00335
00336 lvs->addLocalVar(locVar);
00337 return true;
00338 }
00339
00340 bool Function::addParam(localVar *param)
00341 {
00342 localVarCollection *ps = NULL;
00343 if (!setupParams())
00344 {
00345 return false;
00346 }
00347
00348 if (!getAnnotation(ps, FunctionParametersAnno))
00349 {
00350 return false;
00351 }
00352
00353 ps->addLocalVar(param);
00354
00355 return true;
00356 }
00357
00358 bool Function::setupParams()
00359 {
00360 localVarCollection *ps = NULL;
00361
00362 if (!getAnnotation(ps, FunctionParametersAnno))
00363 {
00364 ps = new localVarCollection();
00365
00366 if (!addAnnotation(ps, FunctionParametersAnno))
00367 {
00368 fprintf(stderr, "%s[%d]: failed to add local var collecton anno\n",
00369 FILE__, __LINE__);
00370 return false;
00371 }
00372 }
00373
00374 return true;
00375 }
00376
00377 Function::~Function()
00378 {
00379 localVarCollection *lvs = NULL;
00380 if (getAnnotation(lvs, FunctionLocalVariablesAnno) && (NULL != lvs))
00381 {
00382 if (!removeAnnotation(FunctionLocalVariablesAnno))
00383 {
00384 fprintf(stderr, "%s[%d]: ERROR removing local vars\n", FILE__, __LINE__);
00385 }
00386 delete lvs;
00387 }
00388
00389 localVarCollection *lps = NULL;
00390 if (getAnnotation(lps, FunctionParametersAnno) && (NULL != lps))
00391 {
00392 if (!removeAnnotation(FunctionParametersAnno))
00393 {
00394 fprintf(stderr, "%s[%d]: ERROR removing params\n", FILE__, __LINE__);
00395 }
00396 delete lps;
00397 }
00398
00399 }
00400
00401 #if !defined(SERIALIZATION_DISABLED)
00402 Serializable *Function::serialize_impl(SerializerBase *sb, const char *tag) THROW_SPEC (SerializerError)
00403 {
00404 if (!sb) SER_ERR("bad paramater sb");
00405
00406
00407
00408
00409 unsigned int t_id = retType_ ? retType_->getID() : (unsigned int) 0xdeadbeef;
00410
00411 ifxml_start_element(sb, tag);
00412 gtranslate(sb, t_id, "typeID");
00413 gtranslate(sb, framePtrRegNum_, "framePointerRegister");
00414 #if 0
00415 gtranslate(sb, frameBase_, "framePointerLocationList");
00416 #endif
00417 Aggregate::serialize_aggregate(sb);
00418 ifxml_end_element(sb, tag);
00419 if (sb->isInput())
00420 {
00421 if (t_id == 0xdeadbeef)
00422 retType_ = NULL;
00423 else
00424 restore_type_by_id(sb, retType_, t_id);
00425 #if 0
00426 for (unsigned long i = 0; i < symbols_.size(); ++i)
00427 {
00428 symbols_[i]->setFunction(this);
00429 assert(symbols_[i]->isFunction());
00430 }
00431 #endif
00432 }
00433
00434 serialize_printf("%s[%d]: Function(%p--%s)::%s\n", FILE__, __LINE__, this,
00435 getAllPrettyNames().size() ? getAllPrettyNames()[0].c_str() : "UNNAMED_FUNCTION",
00436 sb->isInput() ? "deserialize" : "serialize");
00437 return NULL;
00438 }
00439 #else
00440 Serializable *Function::serialize_impl(SerializerBase *, const char *) THROW_SPEC (SerializerError)
00441 {
00442 return NULL;
00443 }
00444 #endif
00445
00446 bool Function::removeSymbol(Symbol *sym)
00447 {
00448 removeSymbolInt(sym);
00449 if (symbols_.empty()) {
00450 module_->exec()->deleteFunction(this);
00451 }
00452 return true;
00453 }
00454
00455 std::ostream &operator<<(std::ostream &os, const Dyninst::VariableLocation &l)
00456 {
00457 const char *stc = storageClass2Str(l.stClass);
00458 const char *strc = storageRefClass2Str(l.refClass);
00459 os << "{"
00460 << "storageClass=" << stc
00461 << " storageRefClass=" << strc
00462 << " reg=" << l.mr_reg.name()
00463 << " frameOffset=" << l.frameOffset
00464 << " lowPC=" << l.lowPC
00465 << " hiPC=" << l.hiPC
00466 << "}";
00467 return os;
00468 }
00469
00470 std::ostream &operator<<(std::ostream &os, const Dyninst::SymtabAPI::Function &f)
00471 {
00472 Type *retType = (const_cast<Function &>(f)).getReturnType();
00473
00474 std::string tname(retType ? retType->getName() : "no_type");
00475 const Aggregate *ag = dynamic_cast<const Aggregate *>(&f);
00476 assert(ag);
00477
00478 os << "Function{"
00479 << " type=" << tname
00480 << " framePtrRegNum_=" << f.getFramePtrRegnum()
00481 << " FramePtrLocationList=[";
00482 #if 0
00483 for (unsigned int i = 0; i < f.frameBase_.size(); ++i)
00484 {
00485 os << f.frameBase_[i];
00486 if ( (i + 1) < f.frameBase_.size())
00487 os << ", ";
00488 }
00489 #endif
00490 os << "] ";
00491 os << *ag;
00492 os << "}";
00493 return os;
00494
00495 }
00496
00497 bool Function::operator==(const Function &f)
00498 {
00499 if (retType_ && !f.retType_)
00500 return false;
00501 if (!retType_ && f.retType_)
00502 return false;
00503 if (retType_)
00504 if (retType_->getID() != f.retType_->getID())
00505 {
00506 return false;
00507 }
00508
00509 if (framePtrRegNum_ != f.framePtrRegNum_)
00510 return false;
00511
00512 #if 0
00513 if (frameBase_.size() != f.frameBase_.size())
00514 return false;
00515
00516 for (unsigned int i = 0; i < frameBase_.size(); ++i)
00517 {
00518 if (frameBase_[i] == frameBase_[i])
00519 return false;
00520 }
00521 #endif
00522
00523 return ((Aggregate &)(*this)) == ((Aggregate &)f);
00524 }
00525