Node.C
Go to the documentation of this file.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
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
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
00057
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
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
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
00147 NodeIterator &NodeIterator::operator++() {
00148 if (!iter_) return *this;
00149
00150 iter_->inc();
00151 return *this;
00152 }
00153
00154
00155 NodeIterator NodeIterator::operator++(int) {
00156 NodeIterator ret = *this;
00157 ++(*this);
00158 return ret;
00159 }
00160
00161
00162 NodeIterator &NodeIterator::operator--() {
00163 if (!iter_) return *this;
00164
00165 iter_->dec();
00166 return *this;
00167 }
00168
00169
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
00225
00226
00227
00228
00229
00230
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
00241
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
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
00274
00275
00276
00277
00278
00279
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
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
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 }