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 "Variable.h"
00041 #include "Aggregate.h"
00042 #include "Function.h"
00043 #include <iterator>
00044
00045 #include "symtabAPI/src/Object.h"
00046
00047 #include <iostream>
00048
00049 using namespace std;
00050 using namespace Dyninst;
00051 using namespace Dyninst::SymtabAPI;
00052
00053
00054 Variable::Variable(Symbol *sym) :
00055 Aggregate(sym),
00056 type_(NULL)
00057 {
00058 }
00059
00060 Variable::Variable() :
00061 Aggregate(),
00062 type_(NULL)
00063 {
00064 }
00065 void Variable::setType(Type *type)
00066 {
00067
00068 type_ = type;
00069 }
00070
00071 Type* Variable::getType()
00072 {
00073 module_->exec()->parseTypesNow();
00074 return type_;
00075 }
00076
00077 #if !defined(SERIALIZATION_DISABLED)
00078 Serializable *Variable::serialize_impl(SerializerBase *sb, const char *tag) THROW_SPEC (SerializerError)
00079 {
00080
00081 if (!sb)
00082 {
00083 SER_ERR("bad paramater sb");
00084 }
00085
00086
00087
00088 unsigned int t_id = type_ ? type_->getID() : (unsigned int) 0xdeadbeef;
00089
00090 try
00091 {
00092 ifxml_start_element(sb, tag);
00093 gtranslate(sb, t_id, "typeID");
00094 Aggregate::serialize_aggregate(sb);
00095 ifxml_end_element(sb, tag);
00096
00097 serialize_printf("%s[%d]: %sSERIALIZED VARIABLE %s, %lu syms\n",
00098 FILE__, __LINE__,
00099 sb->isInput() ? "DE" : "",
00100 getAllPrettyNames().size() ? getAllPrettyNames()[0].c_str() : "no_name",
00101 symbols_.size());
00102
00103 if (sb->isInput())
00104 {
00105 if (t_id == 0xdeadbeef)
00106 {
00107 type_ = NULL;
00108 }
00109 else
00110 {
00111 restore_type_by_id(sb, type_, t_id);
00112 }
00113 }
00114 else
00115 {
00116 #if 0
00117 Dyninst::ScopedSerializerBase<Dyninst::SymtabAPI::Symtab> *ssb = dynamic_cast<Dyninst::ScopedSerializerBase<Dyninst::SymtabAPI::Symtab> *>(sb);
00118
00119 if (!ssb)
00120 {
00121 fprintf(stderr, "%s[%d]: SERIOUS: FIXME, sb is_bin = %s, sb = %p\n", FILE__, __LINE__, sb->isBin() ? "true" : "false", sb);
00122 SerializerBin<Symtab> *sbst = dynamic_cast<SerializerBin<Symtab> *> (sb);
00123 if (NULL == sbst)
00124 {
00125 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
00126 }
00127 SER_ERR("FIXME");
00128 }
00129
00130 Symtab *st = ssb->getScope();
00131 #endif
00132 SerContextBase *scb = sb->getContext();
00133 if (!scb)
00134 {
00135 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
00136 SER_ERR("FIXME");
00137 }
00138
00139 SerContext<Symtab> *scs = dynamic_cast<SerContext<Symtab> *>(scb);
00140
00141 if (!scs)
00142 {
00143 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
00144 SER_ERR("FIXME");
00145 }
00146
00147 Symtab *st = scs->getScope();
00148
00149
00150
00151 if ((t_id != 0xdeadbeef) && !st->findType(t_id))
00152 {
00153 fprintf(stderr, "%s[%d]: ERROR: serialize bad type %s\n", FILE__, __LINE__, type_->getName().c_str());
00154 }
00155 }
00156 }
00157 SER_CATCH(tag);
00158
00159 return NULL;
00160 }
00161 #else
00162 Serializable *Variable::serialize_impl(SerializerBase *, const char *) THROW_SPEC (SerializerError)
00163 {
00164 return NULL;
00165 }
00166 #endif
00167
00168 std::ostream &operator<<(std::ostream &os, const Dyninst::SymtabAPI::Variable &v)
00169 {
00170 Type *var_t = (const_cast<Variable &>(v)).getType();
00171 std::string tname(var_t ? var_t->getName() : "no_type");
00172 const Aggregate *ag = dynamic_cast<const Aggregate *>(&v);
00173 assert(ag);
00174
00175 os << "Variable{"
00176 << " type="
00177 << tname
00178 << " ";
00179 os << *ag;
00180 os << "}";
00181 return os;
00182
00183 }
00184 bool Variable::operator==(const Variable &v)
00185 {
00186 if (type_ && !v.type_)
00187 return false;
00188 if (!type_ && v.type_)
00189 return false;
00190 if (type_)
00191 if (type_->getID() != v.type_->getID())
00192 {
00193 return false;
00194 }
00195 return ((Aggregate &)(*this)) == ((Aggregate &)v);
00196 }
00197
00198 bool Variable::removeSymbol(Symbol *sym)
00199 {
00200 removeSymbolInt(sym);
00201 if (symbols_.empty()) {
00202 module_->exec()->deleteVariable(this);
00203 }
00204 return true;
00205 }
00206
00207 localVar::localVar(std::string name, Type *typ, std::string fileName,
00208 int lineNum, Function *f, std::vector<VariableLocation> *locs) :
00209 Serializable(),
00210 name_(name),
00211 type_(typ),
00212 fileName_(fileName),
00213 lineNum_(lineNum),
00214 func_(f),
00215 locsExpanded_(false)
00216 {
00217 type_->incrRefCount();
00218
00219 if (locs)
00220 {
00221 std::copy(locs->begin(), locs->end(), std::back_inserter(locs_));
00222 }
00223 }
00224
00225 localVar::localVar(localVar &lvar) :
00226 Serializable()
00227 {
00228 name_ = lvar.name_;
00229 type_ = lvar.type_;
00230 fileName_ = lvar.fileName_;
00231 lineNum_ = lvar.lineNum_;
00232 func_ = lvar.func_;
00233 locsExpanded_ = lvar.locsExpanded_;
00234
00235 std::copy(lvar.locs_.begin(), lvar.locs_.end(),
00236 std::back_inserter(locs_));
00237
00238 if (type_ != NULL)
00239 {
00240 type_->incrRefCount();
00241 }
00242 }
00243
00244 bool localVar::addLocation(VariableLocation &location)
00245 {
00246 if (!locsExpanded_) {
00247 locs_.push_back(location);
00248 return true;
00249 }
00250
00251 expandLocation(location, locs_);
00252 return true;
00253 }
00254
00255 void localVar::expandLocation(const VariableLocation &loc,
00256 std::vector<VariableLocation> &ret) {
00257 if (loc.mr_reg != Dyninst::FrameBase) {
00258 ret.push_back(loc);
00259 return;
00260 }
00261
00262
00263
00264
00265 assert(func_);
00266
00267 std::vector<VariableLocation> &func_fp = func_->getFramePtr();
00268
00269
00270
00271 #ifdef DEBUG
00272 cerr << "Expanding location for variable " << name_
00273 << " / " << hex << this << dec << endl;
00274 #endif
00275
00276
00277
00278
00279
00280
00281
00282 if (func_fp.empty())
00283 return;
00284
00285
00286
00287
00288
00289
00290
00291 std::vector<VariableLocation>::iterator i;
00292 for (i = func_fp.begin(); i != func_fp.end(); i++)
00293 {
00294 Offset fplowPC = i->lowPC;
00295 Offset fphiPC = i->hiPC;
00296
00297 Offset varlowPC = loc.lowPC;
00298 Offset varhiPC = loc.hiPC;
00299 #ifdef DEBUG
00300 cerr << "var range: " << hex
00301 << varlowPC << ".." << varhiPC << endl;
00302 cerr << "frame range: " << hex
00303 << fplowPC << ".." << fphiPC << dec << endl;
00304 #endif
00305 if (fplowPC > varhiPC) {
00306
00307 break;
00308 }
00309
00310 if (fphiPC < varlowPC) {
00311
00312 continue;
00313 }
00314
00315
00316
00317 Offset low = (varlowPC < fplowPC) ? fplowPC : varlowPC;
00318
00319
00320 Offset high = (varhiPC < fphiPC) ? varhiPC : fphiPC;
00321
00322 VariableLocation newloc;
00323
00324 newloc.stClass = loc.stClass;
00325 newloc.refClass = loc.refClass;
00326 newloc.mr_reg = i->mr_reg;
00327 newloc.frameOffset = loc.frameOffset + i->frameOffset;
00328 newloc.lowPC = low;
00329 newloc.hiPC = high;
00330
00331 #ifdef DEBUG
00332 cerr << "Created variable location ["
00333 << hex << newloc.lowPC << ".." << newloc.hiPC
00334 << "], reg " << newloc.mr_reg.name()
00335 << " /w/ offset " << newloc.frameOffset
00336 << " = (" << loc.frameOffset
00337 << "+" << i->frameOffset << ")"
00338 << ", "
00339 << storageClass2Str(newloc.stClass)
00340 << ", "
00341 << storageRefClass2Str(newloc.refClass) << endl;
00342 #endif
00343 ret.push_back(newloc);
00344 }
00345 return;
00346 }
00347
00348 localVar::~localVar()
00349 {
00350
00351 type_->decrRefCount();
00352 }
00353
00354 void localVar::fixupUnknown(Module *module)
00355 {
00356 if (type_->getDataClass() == dataUnknownType)
00357 {
00358 Type *otype = type_;
00359 typeCollection *tc = typeCollection::getModTypeCollection(module);
00360 assert(tc);
00361 type_ = tc->findType(type_->getID());
00362
00363 if (type_)
00364 {
00365 type_->incrRefCount();
00366 otype->decrRefCount();
00367 }
00368 else
00369 type_ = otype;
00370 }
00371 }
00372
00373 std::string &localVar::getName()
00374 {
00375 return name_;
00376 }
00377
00378 Type *localVar::getType()
00379 {
00380 return type_;
00381 }
00382
00383 bool localVar::setType(Type *newType)
00384 {
00385 type_ = newType;
00386 return true;
00387 }
00388
00389 int localVar::getLineNum()
00390 {
00391 return lineNum_;
00392 }
00393
00394 std::string &localVar::getFileName()
00395 {
00396 return fileName_;
00397 }
00398
00399 std::vector<Dyninst::VariableLocation> &localVar::getLocationLists()
00400 {
00401 if (!locsExpanded_) {
00402
00403 std::vector<VariableLocation> orig;
00404 locs_.swap(orig);
00405 for (unsigned i = 0; i < orig.size(); ++i) {
00406 expandLocation(orig[i], locs_);
00407 }
00408
00409 locsExpanded_ = true;
00410 }
00411
00412 return locs_;
00413 }
00414
00415 bool localVar::operator==(const localVar &l)
00416 {
00417 if (type_ && !l.type_) return false;
00418 if (!type_ && l.type_) return false;
00419
00420 if (type_)
00421 {
00422 if (type_->getID() != l.type_->getID())
00423 return false;
00424 }
00425
00426 if (name_ != l.name_) return false;
00427 if (fileName_ != l.fileName_) return false;
00428 if (lineNum_ != l.lineNum_) return false;
00429
00430 if (locs_ != l.locs_) return false;
00431
00432 return true;
00433 }
00434
00435 #if !defined(SERIALIZATION_DISABLED)
00436 Serializable *localVar::serialize_impl(SerializerBase *sb, const char *tag) THROW_SPEC(SerializerError)
00437 {
00438 serialize_printf("%s[%d]: welcome to localVar::serialize_impl\n", FILE__, __LINE__);
00439
00440
00441 unsigned int t_id = (unsigned int) 0xdeadbeef;
00442 if (sb->isOutput()) t_id = type_ ? type_->getID() : (unsigned int) 0xdeadbeef;
00443
00444 ifxml_start_element(sb, tag);
00445 gtranslate(sb, name_, "Name");
00446 gtranslate(sb, fileName_, "FileName");
00447 gtranslate(sb, lineNum_, "LineNumber");
00448 gtranslate(sb, t_id, "TypeID");
00449 gtranslate(sb, locs_, "Locations", "Location");
00450 ifxml_end_element(sb, tag);
00451
00452 serialize_printf("%s[%d]: %sserialize localVar %s\n", FILE__, __LINE__, sb->isInput() ? "de" : "", name_.c_str());
00453
00454 if (sb->isInput())
00455 {
00456 if (t_id == 0xdeadbeef)
00457 {
00458 type_ = NULL;
00459 }
00460 else
00461 {
00462 SerContextBase *scb = sb->getContext();
00463 if (!scb)
00464 {
00465 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
00466 SER_ERR("FIXME");
00467 }
00468
00469 SerContext<Symtab> *scs = dynamic_cast<SerContext<Symtab> *>(scb);
00470
00471 if (!scs)
00472 {
00473 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
00474 SER_ERR("FIXME");
00475 }
00476
00477 Symtab *st = scs->getScope();
00478
00479 if (!st)
00480 {
00481 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
00482 SER_ERR("FIXME");
00483 }
00484
00485 type_ = st->findType(t_id);
00486
00487 if (!type_)
00488 {
00489
00490 serialize_printf("%s[%d]: FIXME: cannot find type with id %d\n", FILE__, __LINE__, t_id);
00491 }
00492 }
00493
00494 }
00495 serialize_printf("%s[%d]: %sserialized localVar %s, done\n", FILE__, __LINE__, sb->isInput() ? "de" : "", name_.c_str());
00496 return NULL;
00497 }
00498 #else
00499 Serializable *localVar::serialize_impl(SerializerBase *, const char *) THROW_SPEC(SerializerError)
00500 {
00501 return NULL;
00502 }
00503 #endif