about summary refs log tree commit diff stats
path: root/miasm2/analysis/depgraph.py
diff options
context:
space:
mode:
authorAjax <commial@gmail.com>2015-04-21 17:05:30 +0200
committerAjax <commial@gmail.com>2015-04-24 08:11:36 +0200
commit6802ed9182af2d63fafbed638ff03ca71602c78f (patch)
tree8a9c99c077b52c0e89b86b5a61bc1d1f076f5593 /miasm2/analysis/depgraph.py
parent44531d3b9a4fe31dfa70ae148acb7b04ae65b2c2 (diff)
downloadmiasm-6802ed9182af2d63fafbed638ff03ca71602c78f.tar.gz
miasm-6802ed9182af2d63fafbed638ff03ca71602c78f.zip
DepGraph: Extend FollowExpr to include relative methods
Diffstat (limited to 'miasm2/analysis/depgraph.py')
-rw-r--r--miasm2/analysis/depgraph.py53
1 files changed, 33 insertions, 20 deletions
diff --git a/miasm2/analysis/depgraph.py b/miasm2/analysis/depgraph.py
index 16e332d4..14070eef 100644
--- a/miasm2/analysis/depgraph.py
+++ b/miasm2/analysis/depgraph.py
@@ -374,7 +374,34 @@ class DependencyResult(object):
                 for depnode in self.input}
 
 
-FollowExpr = namedtuple("FollowExpr", ["follow", "element"])
+class FollowExpr(object):
+    "Stand for an element (expression, depnode, ...) to follow or not"
+
+    def __init__(self, follow, element):
+        self.follow = follow
+        self.element = element
+
+    @staticmethod
+    def to_depnodes(follow_exprs, label, line, modifier):
+        """Build a set of FollowExpr(DependencyNode) from the @follow_exprs set
+        of FollowExpr"""
+        dependencies = set()
+        for follow_expr in follow_exprs:
+            dependencies.add(FollowExpr(follow_expr.follow,
+                                        DependencyNode(label,
+                                                       follow_expr.element,
+                                                       line,
+                                                       modifier=modifier)))
+        return dependencies
+
+    @staticmethod
+    def extract_depnodes(follow_exprs, only_follow=False):
+        """Extract depnodes from a set of FollowExpr(Depnodes)
+        @only_follow: (optional) extract only elements to follow"""
+        return set(follow_expr.element
+                   for follow_expr in follow_exprs
+                   if not(only_follow) or follow_expr.follow)
+
 
 class DependencyGraph(object):
     """Implementation of a dependency graph
@@ -475,18 +502,6 @@ class DependencyGraph(object):
         LINE_NB must be > 0"""
         return self._get_irs(depnode.label)[depnode.line_nb - 1]
 
-    @staticmethod
-    def _followExpr_to_depnodes(follow_exprs, label, line, modifier):
-        "Build a set of DependencyNode from the @follow_exprs set of FollowExpr"
-        dependencies = set()
-        for follow_expr in follow_exprs:
-            dependencies.add(FollowExpr(follow_expr.follow,
-                                        DependencyNode(label,
-                                                       follow_expr.element,
-                                                       line,
-                                                       modifier=modifier)))
-        return dependencies
-
     def _resolve_depNode(self, depnode):
         """Compute and return the dependencies involved by @depnode
         Return a set of FollowExpr"""
@@ -517,8 +532,8 @@ class DependencyGraph(object):
                 read = set([FollowExpr(True, depnode.element)])
 
             ## Build output
-            output = self._followExpr_to_depnodes(read, depnode.label,
-                                                  depnode.line_nb - 1, modifier)
+            output = FollowExpr.to_depnodes(read, depnode.label,
+                                                        depnode.line_nb - 1, modifier)
 
         return output
 
@@ -545,13 +560,11 @@ class DependencyGraph(object):
 
             # Find dependency of the current depnode
             sub_depnodes = self._resolve_depNode(depnode)
-            depdict.cache[depnode] = set(follow_expr.element
-                                         for follow_expr in sub_depnodes)
+            depdict.cache[depnode] = FollowExpr.extract_depnodes(sub_depnodes)
 
             # Add to the worklist its dependencies
-            todo.update(set(follow_expr.element
-                            for follow_expr in sub_depnodes
-                            if follow_expr.follow))
+            todo.update(FollowExpr.extract_depnodes(sub_depnodes,
+                                                    only_follow=True))
 
         # Pending states will be override in cache
         for depnode in depdict.pending: