about summary refs log tree commit diff stats
path: root/miasm2/expression/simplifications_common.py
diff options
context:
space:
mode:
authorFabrice Desclaux <fabrice.desclaux@cea.fr>2015-06-05 14:24:04 +0200
committerFabrice Desclaux <fabrice.desclaux@cea.fr>2015-06-05 15:09:09 +0200
commit1e2af3d56a06810e3044b89b73a54cd88f49a4f4 (patch)
tree1a7501ff44b9b6516f61fd60bf333d9938b2bd11 /miasm2/expression/simplifications_common.py
parent1cd6af8fa196f9ce799e383aa8897d9ad35bb2d2 (diff)
downloadmiasm-1e2af3d56a06810e3044b89b73a54cd88f49a4f4.tar.gz
miasm-1e2af3d56a06810e3044b89b73a54cd88f49a4f4.zip
Expression/Simplification: add slice/compose
Diffstat (limited to 'miasm2/expression/simplifications_common.py')
-rw-r--r--miasm2/expression/simplifications_common.py33
1 files changed, 32 insertions, 1 deletions
diff --git a/miasm2/expression/simplifications_common.py b/miasm2/expression/simplifications_common.py
index ab3e2e82..b8c78692 100644
--- a/miasm2/expression/simplifications_common.py
+++ b/miasm2/expression/simplifications_common.py
@@ -416,12 +416,43 @@ def simp_slice(e_s, e):
         new_e = ExprSlice(e.arg.arg, e.start + e.arg.start,
                           e.start + e.arg.start + (e.stop - e.start))
         return new_e
-    # Slice(Compose(A), x) => Slice(A, y)
     elif isinstance(e.arg, ExprCompose):
+        # Slice(Compose(A), x) => Slice(A, y)
         for a in e.arg.args:
             if a[1] <= e.start and a[2] >= e.stop:
                 new_e = a[0][e.start - a[1]:e.stop - a[1]]
                 return new_e
+        # Slice(Compose(A, B, C), x) => Compose(A, B, C) with truncated A/B/C
+        out = []
+        for arg, s_start, s_stop in e.arg.args:
+            # arg is before slice start
+            if e.start >= s_stop:
+                continue
+            # arg is after slice stop
+            elif e.stop <= s_start:
+                continue
+            # arg is fully included in slice
+            elif e.start <= s_start and s_stop <= e.stop:
+                out.append((arg, s_start, s_stop))
+                continue
+            # arg is truncated at start
+            if e.start > s_start:
+                slice_start = e.start - s_start
+                a_start = 0
+            else:
+                # arg is not truncated at start
+                slice_start = 0
+                a_start = s_start - e.start
+            # a is truncated at stop
+            if e.stop < s_stop:
+                slice_stop = arg.size + e.stop - s_stop - slice_start
+                a_stop = e.stop - e.start
+            else:
+                slice_stop = arg.size
+                a_stop = s_stop - e.start
+            out.append((arg[slice_start:slice_stop], a_start, a_stop))
+        return ExprCompose(out)
+
     # ExprMem(x, size)[:A] => ExprMem(x, a)
     # XXXX todo hum, is it safe?
     elif (isinstance(e.arg, ExprMem) and