Variable.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 // $Id: Object.C,v 1.31 2008/11/03 15:19:25 jaw Exp $
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     //fprintf(stderr, "%s[%d]:  setting variable %s to type id %d\n", FILE__, __LINE__, prettyName.c_str(), type ? type->getID() : 0xdeadbeef);
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     //fprintf(stderr, "%s[%d]:  welcome to Variable::serialize\n", FILE__, __LINE__);
00081     if (!sb)
00082     {
00083         SER_ERR("bad paramater sb");
00084     }
00085 
00086     //  Use typeID as unique identifier
00087     //  magic numbers stink, but we use both positive and negative numbers for type ids
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             //  remove this check
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    // We're referencing a frame base; must have a function or this
00264    // is corrupted data. 
00265    assert(func_);
00266 
00267    std::vector<VariableLocation> &func_fp = func_->getFramePtr();
00268 
00269    //#define DEBUG
00270 
00271 #ifdef DEBUG
00272    cerr << "Expanding location for variable " << name_ 
00273     << " / " << hex << this << dec << endl;
00274 #endif
00275 
00276    /*
00277    if (func_fp.empty()) {
00278       cerr << "Error: function " << hex << func_
00279            << " / " << func_->getAllMangledNames()[0] << " has no frame pointer!" << endl;
00280    }
00281    */
00282    if (func_fp.empty())
00283       return;
00284 
00285    // We need to break loc into a list matching the address
00286    // ranges of func_fp. 
00287    
00288    // Also, combine our frame offset with func_fp[...]'s frame
00289    // offset and use its register.
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          // Done, the frame base is after the variable
00307          break;
00308       }
00309 
00310       if (fphiPC < varlowPC) {
00311          // No overlap yet, continue
00312          continue;
00313       }
00314 
00315 
00316       // low is MAX(varlowPC, fplowPC)
00317       Offset low = (varlowPC < fplowPC) ? fplowPC : varlowPC;
00318 
00319       // high is MIN(varhiPC, fphiPC)
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     //XXX jdd 5/25/99 More to do later
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       // Here we get clever
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     //  Use typeID as unique identifier
00440     //  magic numbers stink, but we use both positive and negative numbers for type ids
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                 //  This should probably throw, but let's play nice for now
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
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1