Node.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 
00032 // Node class implementation
00033 
00034 #include "Graph.h"
00035 #include "Edge.h"
00036 #include "Node.h"
00037 #include <assert.h>
00038 
00039 #include "common/h/NodeIterator.h"
00040 
00041 // Nodes are quite simple; they have an Insn, an Absloc, and a set of Edges.
00042 
00043 using namespace Dyninst;
00044 
00045 const Address Node::INVALID_ADDR = (Address) -1;
00046 
00047 void Node::addInEdge(const EdgePtr in) {
00048    ins_.insert(in);
00049 }
00050  
00051 void Node::addOutEdge(const EdgePtr out) {
00052    outs_.insert(out);
00053 }   
00054 
00055 void Node::ins(NodeIterator &begin, NodeIterator &end) {
00056     // Ins and outs are currently stored as sets of edges.
00057     // We need an iterator that translates them...
00058     begin = NodeIterator(new NodeFromEdgeSet(ins_.begin(), NodeFromEdgeSet::source));
00059     end = NodeIterator(new NodeFromEdgeSet(ins_.end(), NodeFromEdgeSet::source));
00060 }
00061 
00062 void Node::outs(NodeIterator &begin, NodeIterator &end) {
00063     begin = NodeIterator(new NodeFromEdgeSet(outs_.begin(), NodeFromEdgeSet::target));
00064     end = NodeIterator(new NodeFromEdgeSet(outs_.end(), NodeFromEdgeSet::target));
00065 }
00066 
00067 void Node::ins(EdgeIterator &begin, EdgeIterator &end) {
00068     // Iteration over a pre-existing set is easy...
00069     begin = EdgeIterator(new EdgeIteratorSet(ins_.begin()));
00070     end = EdgeIterator(new EdgeIteratorSet(ins_.end()));
00071 }
00072 
00073 void Node::outs(EdgeIterator &begin, EdgeIterator &end) {
00074     // Iteration over a pre-existing set is easy...
00075     begin = EdgeIterator(new EdgeIteratorSet(outs_.begin()));
00076     end = EdgeIterator(new EdgeIteratorSet(outs_.end()));
00077 }
00078 
00079 bool Node::hasInEdges() {
00080     return !ins_.empty();
00081 }
00082 
00083 bool Node::hasOutEdges() {
00084     return !outs_.empty();
00085 }
00086 
00087 void Node::forwardClosure(NodeIterator &begin, NodeIterator &end) {
00088     end = NodeIterator(new NodeSearchIterator());
00089 
00090     if (!hasOutEdges()) {
00091         begin = end;
00092     }
00093     else {
00094         NodeIterator outBegin, outEnd;
00095         outs(outBegin, outEnd);
00096         begin = NodeIterator(new NodeSearchIterator(outBegin, outEnd, NodeSearchIterator::out, NodeSearchIterator::breadth));
00097     }
00098 }
00099 
00100 void Node::backwardClosure(NodeIterator &begin, NodeIterator &end) {
00101     end = NodeIterator(new NodeSearchIterator());
00102 
00103     if (!hasInEdges()) {
00104         begin = end;
00105     }
00106     else {
00107         NodeIterator inBegin, inEnd;
00108         ins(inBegin, inEnd);
00109         begin = NodeIterator(new NodeSearchIterator(inBegin, inEnd, NodeSearchIterator::in, NodeSearchIterator::breadth));
00110     }
00111 }
00112 
00113 
00114 Node::Ptr PhysicalNode::createNode(Address addr) {
00115     return Node::Ptr(new PhysicalNode(addr));
00116 }
00117 
00118 Node::Ptr PhysicalNode::copy() {
00119     return Node::Ptr(new PhysicalNode(addr()));
00120 }
00121 
00122 std::string PhysicalNode::format() const {
00123     char buf[256];
00124     sprintf(buf, "N_0x%lx", addr());
00125     return std::string(buf);
00126 }
00127 
00128 std::string VirtualNode::defaultName("N_VIRTUAL");
00129 
00130 Node::Ptr VirtualNode::createNode() {
00131     return Node::Ptr(new VirtualNode());
00132 }
00133 
00134 Node::Ptr VirtualNode::createNode(std::string name) {
00135     return Node::Ptr(new VirtualNode(name));
00136 }
00137 
00138 Node::Ptr VirtualNode::copy() {
00139     return Node::Ptr(new VirtualNode(name_));
00140 }
00141 
00142 std::string VirtualNode::format() const {
00143     return name_;
00144 }
00145 
00146 // Prefix...
00147 NodeIterator &NodeIterator::operator++() {
00148     if (!iter_) return *this;
00149     
00150     iter_->inc();
00151     return *this;
00152 }
00153 
00154 // Postfix...
00155 NodeIterator NodeIterator::operator++(int) {
00156     NodeIterator ret = *this;
00157     ++(*this);
00158     return ret;    
00159 }
00160 
00161 // Prefix...
00162 NodeIterator &NodeIterator::operator--() {
00163     if (!iter_) return *this;
00164     
00165     iter_->dec();
00166     return *this;
00167 }
00168 
00169 // Postfix...
00170 NodeIterator NodeIterator::operator--(int) {
00171     NodeIterator ret = *this;
00172     --(*this);
00173     return ret;    
00174 }
00175 
00176 
00177 Node::Ptr NodeIterator::operator*() const {
00178     if (!iter_) return Node::Ptr();
00179 
00180     return iter_->get();
00181 }
00182 
00183 bool NodeIterator::operator!=(const NodeIterator &rhs) const {
00184     if (!iter_) {
00185         return (rhs.iter_ != NULL);
00186     }
00187     return !iter_->equals(rhs.iter_);
00188 }
00189 
00190 bool NodeIterator::operator==(const NodeIterator &rhs) const {
00191     if (!iter_) {
00192         return (rhs.iter_ == NULL);
00193     }
00194     return iter_->equals(rhs.iter_);
00195 }
00196 
00197 NodeIterator &NodeIterator::operator=(const NodeIterator &rhs) {
00198     if (iter_) delete iter_;
00199     iter_ = rhs.copy();
00200     return *this;
00201 }
00202 
00203 NodeIterator::NodeIterator() : iter_(NULL) {
00204 }
00205 
00206 NodeIterator::NodeIterator(NodeIteratorImpl *iter) :
00207     iter_(iter) {
00208 }
00209 
00210 NodeIterator::NodeIterator(const NodeIterator &rhs) :
00211     iter_(rhs.copy()) {
00212 }
00213 
00214 NodeIterator::~NodeIterator() { 
00215     if (iter_) delete iter_;
00216 }
00217 
00218 NodeIteratorImpl *NodeIterator::copy() const {
00219     if (iter_ == NULL) return NULL;
00220     return iter_->copy();
00221 }
00222 
00223 Graph::Ptr Node::forwardSubgraph() {
00224     // We want to copy this node and every node reachable from
00225     // it along a forward direction. This node will become the
00226     // entry for a new subgraph. 
00227 
00228     // TODO: this is a generic graph by definition, as nodes
00229     // have no idea what type of graph they belong to. Is that
00230     // the right thing? 
00231 
00232     Graph::Ptr ret = Graph::createGraph();
00233     
00234     Node::Ptr newEntry = copy();
00235     ret->insertEntryNode(newEntry);
00236     
00237     std::set<Node::Ptr> visited;
00238     std::queue<std::pair<Node::Ptr, Node::Ptr> > worklist;
00239 
00240     // We don't have a shared pointer to the current node. 
00241     // However, we do have an edge, which has a weak pointer. 
00242 
00243     if (outs_.empty()) return ret;
00244     Node::Ptr thisPtr = (*outs_.begin())->source();
00245 
00246     worklist.push(std::make_pair(thisPtr, newEntry));
00247 
00248     while (!worklist.empty()) {
00249         // First is the original node, second the copy
00250         std::pair<Node::Ptr, Node::Ptr> src = worklist.front(); 
00251         worklist.pop();
00252 
00253         if (visited.find(src.first) != visited.end()) continue;
00254         visited.insert(src.first);
00255 
00256         NodeIterator b, e;
00257         src.first->outs(b, e);
00258 
00259         if (b == e) {
00260             ret->insertExitNode(src.second);
00261         }
00262 
00263         for (; b != e; ++b) {
00264             std::pair<Node::Ptr, Node::Ptr> targ = std::make_pair(*b, (*b)->copy());
00265             ret->insertPair(src.second, targ.second);
00266             worklist.push(targ);
00267         } 
00268     }
00269     return ret;
00270 }
00271 
00272 Graph::Ptr Node::backwardSubgraph() {
00273     // We want to copy this node and every node reachable from
00274     // it along a forward direction. This node will become the
00275     // entry for a new subgraph. 
00276 
00277     // TODO: this is a generic graph by definition, as nodes
00278     // have no idea what type of graph they belong to. Is that
00279     // the right thing? 
00280 
00281     Graph::Ptr ret = Graph::createGraph();
00282     
00283     Node::Ptr newExit = copy();
00284     ret->insertExitNode(newExit);
00285     
00286     std::set<Node::Ptr> visited;
00287     std::queue<std::pair<Node::Ptr, Node::Ptr> > worklist;
00288     
00289     // See comment in nearly-identical code above...
00290     if (ins_.empty()) return ret;
00291     Node::Ptr thisPtr = (*ins_.begin())->target();
00292 
00293     worklist.push(std::make_pair(thisPtr, newExit));
00294 
00295     while (!worklist.empty()) {
00296         // First is the original node, second the copy
00297         std::pair<Node::Ptr, Node::Ptr> targ = worklist.front(); 
00298         worklist.pop();
00299 
00300         if (visited.find(targ.first) != visited.end()) continue;
00301         visited.insert(targ.first);
00302 
00303         NodeIterator b, e;
00304 
00305         targ.first->ins(b, e);
00306 
00307         if (b == e) {
00308             ret->insertEntryNode(targ.second);
00309         }
00310 
00311         for (; b != e; ++b) {
00312             std::pair<Node::Ptr, Node::Ptr> src = std::make_pair(*b, (*b)->copy());
00313             ret->insertPair(src.second, targ.second);
00314             worklist.push(src);
00315         } 
00316     }
00317     return ret;
00318 }
00319 
00320 void Node::deleteInEdge(EdgeIterator e) {
00321   ins_.erase(*e);
00322 }
00323 
00324 void Node::deleteOutEdge(EdgeIterator e) {
00325   outs_.erase(*e);
00326 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1