Graph.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 // Graph class implementation
00032 
00033 #include "Graph.h"
00034 #include "Edge.h"
00035 #include "Node.h"
00036 #include <assert.h>
00037 
00038 #include "../h/NodeIterator.h"
00039 #include <iostream>
00040 
00041 using namespace Dyninst;
00042 
00043 const Dyninst::Address Graph::INITIAL_ADDR = (Address) -1;
00044 
00045 void Graph::entryNodes(NodeIterator &begin, NodeIterator &end) {
00046     begin = NodeIterator(new NodeIteratorSet(entryNodes_.begin()));
00047     end = NodeIterator(new NodeIteratorSet(entryNodes_.end()));
00048     return;
00049 }
00050 
00051 void Graph::exitNodes(NodeIterator &begin, NodeIterator &end) {
00052     // std::cerr << "exitNodes called: " << exitNodes_.size() << " nodes" << std::endl;
00053     begin = NodeIterator(new NodeIteratorSet(exitNodes_.begin()));
00054     end = NodeIterator(new NodeIteratorSet(exitNodes_.end()));
00055     return;
00056 }
00057 
00058 void Graph::allNodes(NodeIterator &begin, NodeIterator &end) {
00059     // std::cerr << "AllNodes called: " << nodes_.size() << " nodes" << std::endl;
00060     begin = NodeIterator(new NodeIteratorSet(nodes_.begin()));
00061     end = NodeIterator(new NodeIteratorSet(nodes_.end()));
00062     return;
00063 }
00064 
00065 bool Graph::find(Address addr, NodeIterator &begin, NodeIterator &end) {
00066     NodeMap::iterator iter = nodesByAddr_.find(addr);
00067     if (iter == nodesByAddr_.end()) return false;
00068 
00069     begin = NodeIterator(new NodeIteratorSet(iter->second.begin()));
00070     end = NodeIterator(new NodeIteratorSet(iter->second.end()));
00071     return true;
00072 }
00073 
00074 Graph::Graph() {};
00075 
00076 Graph::Ptr Graph::createGraph() {
00077     return Graph::Ptr(new Graph());
00078 }
00079 
00080 void Graph::insertPair(NodePtr source, NodePtr target, EdgePtr e) {
00081     // TODO handle parameter edge types.
00082    if (!e) {
00083       e = Edge::createEdge(source, target);
00084    }
00085    else {
00086       e->setSource(source);
00087       e->setTarget(target);
00088    }
00089    
00090    source->addOutEdge(e);
00091    target->addInEdge(e);
00092    
00093    addNode(source);
00094    addNode(target);
00095 }
00096 
00097 void Graph::insertEntryNode(NodePtr entry) {
00098     addNode(entry);
00099     entryNodes_.insert(entry);
00100 }
00101 
00102 void Graph::insertExitNode(NodePtr exit) {
00103     addNode(exit);
00104     exitNodes_.insert(exit);
00105 }
00106 
00107 void Graph::markAsEntryNode(NodePtr entry) {
00108     entryNodes_.insert(entry);
00109 }
00110 
00111 void Graph::markAsExitNode(NodePtr exit) {
00112     exitNodes_.insert(exit);
00113 }
00114 
00115 void Graph::addNode(Node::Ptr node) {
00116   //if (node->hasInEdges() || node->hasOutEdges()) return;
00117     nodes_.insert(node);
00118     if (!node->isVirtual()) {
00119         nodesByAddr_[node->addr()].insert(node);
00120     }        
00121     // std::cerr << "\t\t After addNode: " << nodes_.size() << " nodes" << std::endl;
00122     // std::cerr << "\t\t\t adding " << node << std::endl;
00123 }
00124 
00125 
00126 // Fancy-shmancy predicate based search methods...
00127 
00128 bool Graph::find(NodePredicate::Ptr pred, NodeIterator &begin, NodeIterator &end) {
00129     // We could try to be lazy here, but you have a hard time determining if you're
00130     // done a priori. So instead we pre-look-up and hand that set into a copy-based
00131     // set iterator. 
00132     NodeIterator allBegin, allEnd;
00133     allNodes(allBegin, allEnd);
00134     begin = NodeIterator(new NodeIteratorPredicateObj(pred, allBegin, allEnd));
00135     end = NodeIterator(new NodeIteratorPredicateObj(pred, allEnd, allEnd));
00136     return (begin != end);
00137 }
00138                          
00139 bool Graph::find(NodePredicateFunc pred, void *user_arg, NodeIterator &begin, NodeIterator &end) {
00140     // We could try to be lazy here, but you have a hard time determining if you're
00141     // done a priori. So instead we pre-look-up and hand that set into a copy-based
00142     // set iterator. 
00143     NodeIterator allBegin, allEnd;
00144     allNodes(allBegin, allEnd);
00145     begin = NodeIterator(new NodeIteratorPredicateFunc(pred, user_arg, allBegin, allEnd));
00146     end = NodeIterator(new NodeIteratorPredicateFunc(pred, user_arg, allEnd, allEnd));
00147     return (begin != end);
00148 }
00149 
00150 void Graph::deleteNode(NodePtr node) {
00151   //std::cerr << "Deleting node " << node << std::endl;
00152   // Remove from the graph map
00153   // Remove from any edges that point to this one
00154 
00155   nodes_.erase(node);
00156 
00157   NodeMap::iterator iter2 = nodesByAddr_.find(node->addr());
00158   if (iter2 != nodesByAddr_.end()) {
00159     iter2->second.erase(node);
00160   }
00161 
00162   entryNodes_.erase(node);
00163   exitNodes_.erase(node);
00164 
00165   EdgeIterator e1, e2;
00166   node->ins(e1, e2);
00167   for (; e1 != e2; ++e1) {
00168     (*e1)->source()->deleteOutEdge(e1);
00169   }
00170 
00171   node->outs(e1, e2);
00172   for (; e1 != e2; ++e1) {
00173     (*e1)->target()->deleteInEdge(e1);
00174   }
00175 }
00176     
00177 bool Graph::isEntryNode(NodePtr node) {
00178   return (entryNodes_.find(node) != entryNodes_.end());
00179 }
00180 
00181 
00182 bool Graph::isExitNode(NodePtr node) {
00183   return (exitNodes_.find(node) != exitNodes_.end());
00184 }
00185 
00186 unsigned Graph::size() const {
00187    return nodes_.size();
00188 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1