about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorFabrice Desclaux <fabrice.desclaux@cea.fr>2019-11-21 14:53:16 +0100
committerFabrice Desclaux <fabrice.desclaux@cea.fr>2019-11-21 15:09:04 +0100
commit9ac74510eb5c9ed0ba6234ba4215f0b147b71e5d (patch)
treecd4cdd6474d3d76a7c68e8d17681e3072dd7d24d
parentcc565ff0c1875793ac153eb6f163d88c0dcab3de (diff)
downloadmiasm-9ac74510eb5c9ed0ba6234ba4215f0b147b71e5d.tar.gz
miasm-9ac74510eb5c9ed0ba6234ba4215f0b147b71e5d.zip
Asmblock: fix instruction generation
Instruction length can change from forecast
-rw-r--r--miasm/core/asmblock.py19
1 files changed, 17 insertions, 2 deletions
diff --git a/miasm/core/asmblock.py b/miasm/core/asmblock.py
index 7f3265e0..591f8e9a 100644
--- a/miasm/core/asmblock.py
+++ b/miasm/core/asmblock.py
@@ -1227,8 +1227,23 @@ def assemble_block(mnemo, block, loc_db, conservative=False):
             instr.fixDstOffset()
 
         old_l = instr.l
-        cached_candidate, _ = conservative_asm(mnemo, instr, loc_db,
-                                               conservative)
+        cached_candidate, _ = conservative_asm(
+            mnemo, instr, loc_db,
+            conservative
+        )
+        if len(cached_candidate) != instr.l:
+            # The output instruction length is different from the one we guessed
+            # Retry assembly with updated length
+            instr.l = len(cached_candidate)
+            instr.args = saved_args
+            instr.args = instr.resolve_args_with_symbols(loc_db)
+            if instr.dstflow():
+                instr.fixDstOffset()
+            cached_candidate, _ = conservative_asm(
+                mnemo, instr, loc_db,
+                conservative
+            )
+            assert len(cached_candidate) == instr.l
 
         # Restore original arguments
         instr.args = saved_args