Skip to content

Instantly share code, notes, and snippets.

@dberlin
Created February 11, 2019 02:53
Show Gist options
  • Save dberlin/39013640d89f08ec285a04e68d7197bf to your computer and use it in GitHub Desktop.
Save dberlin/39013640d89f08ec285a04e68d7197bf to your computer and use it in GitHub Desktop.
diff --git a/include/retdec/llvmir2hll/graphs/cfg/cfg_traversal.h b/include/retdec/llvmir2hll/graphs/cfg/cfg_traversal.h
index 4905a90..4a9849a 100644
--- a/include/retdec/llvmir2hll/graphs/cfg/cfg_traversal.h
+++ b/include/retdec/llvmir2hll/graphs/cfg/cfg_traversal.h
@@ -7,6 +7,9 @@
#ifndef RETDEC_LLVMIR2HLL_GRAPHS_CFG_CFG_TRAVERSAL_H
#define RETDEC_LLVMIR2HLL_GRAPHS_CFG_CFG_TRAVERSAL_H
+#include <unordered_map>
+#include <unordered_set>
+
#include "retdec/llvmir2hll/graphs/cfg/cfg.h"
#include "retdec/llvmir2hll/support/smart_ptr.h"
#include "retdec/llvmir2hll/support/types.h"
@@ -82,6 +85,9 @@ protected:
/// Should the traversal be stopped?
bool stopTraversal;
+ std::unordered_map<ShPtr<CFG::Node>, unsigned int> nodeIDMap;
+ std::unordered_set<ShPtr<CFG::Node>> visitedNodes;
+
private:
bool performTraversalImpl(ShPtr<CFG::Node> startNode,
CFG::stmt_iterator startStmtIter);
diff --git a/src/llvmir2hll/graphs/cfg/cfg_traversal.cpp b/src/llvmir2hll/graphs/cfg/cfg_traversal.cpp
index 1422d94..47d4262 100644
--- a/src/llvmir2hll/graphs/cfg/cfg_traversal.cpp
+++ b/src/llvmir2hll/graphs/cfg/cfg_traversal.cpp
@@ -26,6 +26,9 @@ namespace llvmir2hll {
CFGTraversal::CFGTraversal(ShPtr<CFG> cfg, bool defaultCurrRetVal):
cfg(cfg), currRetVal(defaultCurrRetVal), stopTraversal(false) {
PRECONDITION_NON_NULL(cfg);
+ unsigned int nodeId = 0;
+ for (auto I = cfg->node_begin(), E = cfg->node_end(); I != E; ++I)
+ nodeIDMap[*I] = ++nodeId;
}
/**
@@ -47,14 +50,17 @@ bool CFGTraversal::performTraversal(ShPtr<Statement> startStmt) {
PRECONDITION_NON_NULL(startStmt);
PRECONDITION(!isa<EmptyStmt>(startStmt),
"a CFG traversal cannot start from an empty statement");
-
+ visitedNodes.clear();
+ llvm::errs() << "Visit start\n";
// Initialization.
stopTraversal = false;
CFG::StmtInNode startStmtInNode(cfg->getNodeForStmt(startStmt));
ASSERT_MSG(startStmtInNode.first,
"the statement `" << startStmt << "` is not in the CFG");
- return performTraversalImpl(startStmtInNode.first, startStmtInNode.second);
+ auto retVal = performTraversalImpl(startStmtInNode.first, startStmtInNode.second);
+ llvm::errs() << "Visit end\n";
+ return retVal;
}
/**
@@ -72,6 +78,9 @@ bool CFGTraversal::performTraversalFromSuccessors(ShPtr<Statement> stmt) {
PRECONDITION_NON_NULL(stmt);
PRECONDITION(!isa<EmptyStmt>(stmt),
"a CFG traversal cannot start from an empty statement");
+ visitedNodes.clear();
+ llvm::errs() << "Going from successors\n";
+ llvm::errs() << "Visit start\n";
// Initialization.
stopTraversal = false;
@@ -83,10 +92,14 @@ bool CFGTraversal::performTraversalFromSuccessors(ShPtr<Statement> stmt) {
if (stmtInNode.second != stmtInNode.first->stmt_end()) {
// It has a successor in the same node, so start traversing from the
// successor.
- return performTraversalImpl(stmtInNode.first, ++stmtInNode.second);
+ auto retVal = performTraversalImpl(stmtInNode.first, ++stmtInNode.second);
+ llvm::errs() << "Visit end\n";
+ return retVal;
}
// It is the last statement in the node, so traverse all node successors.
- return traverseNodeSuccessors(stmtInNode.first);
+ auto retVal = traverseNodeSuccessors(stmtInNode.first);
+ llvm::errs() << "Visit end\n";
+ return retVal;
}
/**
@@ -168,6 +181,12 @@ bool CFGTraversal::getCurrRetVal() const {
*/
bool CFGTraversal::performTraversalImpl(ShPtr<CFG::Node> node,
CFG::stmt_iterator stmtIter) {
+ if (!visitedNodes.insert(node).second) {
+ return getEndRetVal();
+ }
+ llvm::errs() << "Visiting node " << nodeIDMap.at(node) << "\n";
+
+
while (stmtIter != node->stmt_end()) {
// We're not at the end of the node, so check the statement under
// stmtIter.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment