about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAjax <commial@gmail.com>2017-08-09 15:47:41 +0200
committerAjax <commial@gmail.com>2017-09-05 13:39:23 +0200
commit06f2c39c95602f995d5d7d36e6dbd82dd5524cfc (patch)
tree54466725194880559cea6b106603c5132b29e8c4
parentd806661d8407f580578e51194dbf3c3520b399b2 (diff)
downloadmiasm-06f2c39c95602f995d5d7d36e6dbd82dd5524cfc.tar.gz
miasm-06f2c39c95602f995d5d7d36e6dbd82dd5524cfc.zip
DSE: separate solution decision and solution computation
Avoid potential useless and costly Solver.check
-rw-r--r--miasm2/analysis/dse.py19
1 files changed, 14 insertions, 5 deletions
diff --git a/miasm2/analysis/dse.py b/miasm2/analysis/dse.py
index 74cc87e9..a4a3efd9 100644
--- a/miasm2/analysis/dse.py
+++ b/miasm2/analysis/dse.py
@@ -26,8 +26,9 @@ On branch, if the decision is symbolic, one can also collect "path constraints"
 and inverse them to produce new inputs potentially reaching new paths.
 
 Basically, this is done through DSEPathConstraint. In order to produce a new
-solution, one can extend this class, and override 'handle_solution' to
-produce a solution which fit its needs.
+solution, one can extend this class, and override 'handle_solution' to produce a
+solution which fit its needs. It could avoid computing new solution by
+overriding 'produce_solution'.
 
 If one is only interested in constraints associated to its path, the option
 "produce_solution" should be set to False, to speed up emulation.
@@ -448,7 +449,8 @@ class DSEPathConstraint(DSEEngine):
     to a new path.
 
     In order to produce a new solution, one can extend this class, and override
-    'handle_solution' to produce a solution which fit its needs.
+    'handle_solution' to produce a solution which fit its needs. It could avoid
+    computing new solution by overriding 'produce_solution'.
 
     If one is only interested in constraints associated to its path, the option
     "produce_solution" should be set to False, to speed up emulation.
@@ -469,7 +471,7 @@ class DSEPathConstraint(DSEEngine):
         assert z3 is not None
 
         # Init PathConstraint specifics structures
-        self.produce_solution = produce_solution
+        self._produce_solution = produce_solution
         self.cur_solver = z3.Solver()
         self.new_solutions = {} # destination -> set of model
         self.z3_trans = Translator.to_language("z3")
@@ -496,6 +498,13 @@ class DSEPathConstraint(DSEEngine):
         """
         self.new_solutions.setdefault(destination, set()).add(model)
 
+    def produce_solution(self, destination):
+        """Called to determine if a solution for @destination should be test for
+        satisfiability and computed
+        @destination: Expr instance of the target @destination
+        """
+        return self._produce_solution
+
     def handle(self, cur_addr):
         symb_pc = self.eval_expr(self.ir_arch.IRDst)
         possibilities = possible_values(symb_pc)
@@ -547,7 +556,7 @@ class DSEPathConstraint(DSEEngine):
                     # Add path constraint
                     cur_path_constraint = path_constraint
 
-                elif self.produce_solution:
+                elif self.produce_solution(possibility.value):
                     # Looking for a new solution
                     self.cur_solver.push()
                     for cons in path_constraint: