about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xexample/asm/shellcode.py4
-rw-r--r--example/asm/simple.py4
-rw-r--r--example/disasm/callback.py2
-rw-r--r--example/disasm/full.py4
-rw-r--r--example/expression/access_c.py2
-rw-r--r--example/expression/asm_to_ir.py4
-rw-r--r--example/expression/solve_condition_stp.py10
-rw-r--r--example/ida/depgraph.py2
-rw-r--r--example/ida/graph_ir.py2
-rw-r--r--miasm2/analysis/binary.py2
-rw-r--r--miasm2/analysis/depgraph.py2
-rw-r--r--miasm2/analysis/disasm_cb.py2
-rw-r--r--miasm2/arch/aarch64/arch.py2
-rw-r--r--miasm2/arch/aarch64/disasm.py2
-rw-r--r--miasm2/arch/aarch64/jit.py6
-rw-r--r--miasm2/arch/arm/disasm.py2
-rw-r--r--miasm2/arch/arm/jit.py6
-rw-r--r--miasm2/arch/mips32/disasm.py2
-rw-r--r--miasm2/arch/mips32/ira.py2
-rw-r--r--miasm2/arch/mips32/jit.py6
-rw-r--r--miasm2/arch/msp430/disasm.py2
-rw-r--r--miasm2/arch/msp430/jit.py4
-rw-r--r--miasm2/arch/x86/arch.py2
-rw-r--r--miasm2/arch/x86/disasm.py2
-rw-r--r--miasm2/arch/x86/jit.py8
-rw-r--r--miasm2/core/asmbloc.py1559
-rw-r--r--miasm2/core/asmblock.py1555
-rw-r--r--miasm2/core/cpu.py6
-rw-r--r--miasm2/core/parse_asm.py40
-rw-r--r--miasm2/ir/ir.py2
-rw-r--r--miasm2/ir/symbexec.py4
-rw-r--r--miasm2/ir/translators/C.py4
-rw-r--r--miasm2/ir/translators/smt2.py2
-rw-r--r--miasm2/ir/translators/z3_ir.py2
-rw-r--r--miasm2/jitter/codegen.py2
-rw-r--r--miasm2/jitter/jitcore.py20
-rw-r--r--miasm2/jitter/jitcore_cc_base.py2
-rw-r--r--miasm2/jitter/jitcore_llvm.py2
-rw-r--r--miasm2/jitter/llvmconvert.py12
-rw-r--r--test/analysis/depgraph.py2
-rw-r--r--test/arch/aarch64/unit/asm_test.py4
-rw-r--r--test/arch/mips32/unit/asm_test.py4
-rwxr-xr-xtest/arch/x86/sem.py4
-rw-r--r--test/arch/x86/unit/asm_test.py4
-rw-r--r--test/core/asmblock.py (renamed from test/core/asmbloc.py)2
-rwxr-xr-xtest/core/parse_asm.py2
-rw-r--r--test/core/sembuilder.py2
-rw-r--r--test/ir/analysis.py2
-rw-r--r--test/ir/translators/z3_ir.py2
-rwxr-xr-xtest/test_all.py2
50 files changed, 1669 insertions, 1659 deletions
diff --git a/example/asm/shellcode.py b/example/asm/shellcode.py
index 20fa02d8..bacb65fb 100755
--- a/example/asm/shellcode.py
+++ b/example/asm/shellcode.py
@@ -5,7 +5,7 @@ from pdb import pm
 from elfesteem import pe_init
 from elfesteem.strpatchwork import StrPatchwork
 
-from miasm2.core import parse_asm, asmbloc
+from miasm2.core import parse_asm, asmblock
 from miasm2.analysis.machine import Machine
 from miasm2.core.interval import interval
 
@@ -79,7 +79,7 @@ for block in blocks:
 open("graph.dot", "w").write(blocks.dot())
 
 # Apply patches
-patches = asmbloc.asm_resolve_final(machine.mn,
+patches = asmblock.asm_resolve_final(machine.mn,
                                     blocks,
                                     symbol_pool,
                                     dst_interval)
diff --git a/example/asm/simple.py b/example/asm/simple.py
index 7ab403f4..62d2ff80 100644
--- a/example/asm/simple.py
+++ b/example/asm/simple.py
@@ -2,7 +2,7 @@ from pdb import pm
 from pprint import pprint
 
 from miasm2.arch.x86.arch import mn_x86
-from miasm2.core import parse_asm, asmbloc
+from miasm2.core import parse_asm, asmblock
 
 
 # Assemble code
@@ -25,7 +25,7 @@ loop:
 symbol_pool.set_offset(symbol_pool.getby_name("main"), 0x0)
 
 # Spread information and resolve instructions offset
-patches = asmbloc.asm_resolve_final(mn_x86, blocks, symbol_pool)
+patches = asmblock.asm_resolve_final(mn_x86, blocks, symbol_pool)
 
 # Show resolved blocks
 for block in blocks:
diff --git a/example/disasm/callback.py b/example/disasm/callback.py
index 20ffe962..06159138 100644
--- a/example/disasm/callback.py
+++ b/example/disasm/callback.py
@@ -1,5 +1,5 @@
 from miasm2.core.bin_stream import bin_stream_str
-from miasm2.core.asmbloc import AsmLabel, AsmConstraint, expr_is_label
+from miasm2.core.asmblock import AsmLabel, AsmConstraint, expr_is_label
 from miasm2.arch.x86.disasm import dis_x86_32, cb_x86_funcs
 
 
diff --git a/example/disasm/full.py b/example/disasm/full.py
index f28decbb..e768e21c 100644
--- a/example/disasm/full.py
+++ b/example/disasm/full.py
@@ -4,7 +4,7 @@ from argparse import ArgumentParser
 from pdb import pm
 
 from miasm2.analysis.binary import Container
-from miasm2.core.asmbloc import log_asmbloc, AsmLabel, AsmCFG
+from miasm2.core.asmblock import log_asmblock, AsmLabel, AsmCFG
 from miasm2.expression.expression import ExprId
 from miasm2.core.interval import interval
 from miasm2.analysis.machine import Machine
@@ -56,7 +56,7 @@ parser.add_argument('-c', "--rawbinary", default=False, action="store_true",
 args = parser.parse_args()
 
 if args.verbose:
-    log_asmbloc.setLevel(logging.DEBUG)
+    log_asmblock.setLevel(logging.DEBUG)
 
 log.info('Load binary')
 if args.rawbinary:
diff --git a/example/expression/access_c.py b/example/expression/access_c.py
index 1df51b00..eabc3770 100644
--- a/example/expression/access_c.py
+++ b/example/expression/access_c.py
@@ -58,7 +58,7 @@ ExprCompose(var1, 0) => var1
 def find_call(ira):
     """Returns (irb, index) which call"""
 
-    for irb in ira.blocs.values():
+    for irb in ira.blocks.values():
         out = set()
         if len(irb.irs) < 2:
             continue
diff --git a/example/expression/asm_to_ir.py b/example/expression/asm_to_ir.py
index 4193f31d..b28f8a81 100644
--- a/example/expression/asm_to_ir.py
+++ b/example/expression/asm_to_ir.py
@@ -3,7 +3,7 @@ from pdb import pm
 from miasm2.arch.x86.arch import mn_x86
 from miasm2.core import parse_asm
 from miasm2.expression.expression import *
-from miasm2.core import asmbloc
+from miasm2.core import asmblock
 from miasm2.arch.x86.ira import ir_a_x86_32
 
 
@@ -31,7 +31,7 @@ for block in blocks:
 
 print "symbols:"
 print symbol_pool
-patches = asmbloc.asm_resolve_final(mn_x86, blocks, symbol_pool)
+patches = asmblock.asm_resolve_final(mn_x86, blocks, symbol_pool)
 
 # Translate to IR
 ir_arch = ir_a_x86_32(symbol_pool)
diff --git a/example/expression/solve_condition_stp.py b/example/expression/solve_condition_stp.py
index fb227345..03d652cf 100644
--- a/example/expression/solve_condition_stp.py
+++ b/example/expression/solve_condition_stp.py
@@ -9,7 +9,7 @@ from miasm2.arch.x86.arch import *
 from miasm2.arch.x86.regs import *
 from miasm2.arch.x86.sem import *
 from miasm2.core.bin_stream import bin_stream_str
-from miasm2.core import asmbloc
+from miasm2.core import asmblock
 from miasm2.expression.expression import get_rw
 from miasm2.ir.symbexec import SymbolicExecutionEngine
 from miasm2.expression.simplifications import expr_simp
@@ -36,7 +36,7 @@ if not args:
 
 
 def get_block(ir_arch, mdis, ad):
-    if isinstance(ad, asmbloc.AsmLabel):
+    if isinstance(ad, asmblock.AsmLabel):
         l = ad
     else:
         l = mdis.symbol_pool.getby_offset_create(ad)
@@ -87,8 +87,8 @@ def emul_symb(ir_arch, mdis, states_todo, states_done):
             p2[ad.cond] = ExprInt(1, ad.cond.size)
             ad1 = expr_simp(sb.eval_expr(ad.replace_expr(c1), {}))
             ad2 = expr_simp(sb.eval_expr(ad.replace_expr(c2), {}))
-            if not (isinstance(ad1, ExprInt) or (isinstance(ad1, ExprId) and isinstance(ad1.name, asmbloc.AsmLabel)) and
-                    isinstance(ad2, ExprInt) or (isinstance(ad2, ExprId) and isinstance(ad2.name, asmbloc.AsmLabel))):
+            if not (isinstance(ad1, ExprInt) or (isinstance(ad1, ExprId) and isinstance(ad1.name, asmblock.AsmLabel)) and
+                    isinstance(ad2, ExprInt) or (isinstance(ad2, ExprId) and isinstance(ad2.name, asmblock.AsmLabel))):
                 print str(ad1), str(ad2)
                 raise ValueError("zarb condition")
             conds1 = list(conds) + c1.items()
@@ -106,7 +106,7 @@ def emul_symb(ir_arch, mdis, states_todo, states_done):
         elif isinstance(ad, ExprInt):
             ad = int(ad.arg)
             states_todo.add((ad, sb.symbols.copy(), tuple(conds)))
-        elif isinstance(ad, ExprId) and isinstance(ad.name, asmbloc.AsmLabel):
+        elif isinstance(ad, ExprId) and isinstance(ad.name, asmblock.AsmLabel):
             if isinstance(ad, ExprId):
                 ad = ad.name
             states_todo.add((ad, sb.symbols.copy(), tuple(conds)))
diff --git a/example/ida/depgraph.py b/example/ida/depgraph.py
index 50c73a54..faec2857 100644
--- a/example/ida/depgraph.py
+++ b/example/ida/depgraph.py
@@ -2,7 +2,7 @@ import os
 import tempfile
 
 from miasm2.core.bin_stream_ida import bin_stream_ida
-from miasm2.core.asmbloc import *
+from miasm2.core.asmblock import *
 from miasm2.expression import expression as m2_expr
 
 from miasm2.expression.simplifications import expr_simp
diff --git a/example/ida/graph_ir.py b/example/ida/graph_ir.py
index 250eebfc..3aac0281 100644
--- a/example/ida/graph_ir.py
+++ b/example/ida/graph_ir.py
@@ -5,7 +5,7 @@ import tempfile
 from idaapi import GraphViewer
 
 from miasm2.core.bin_stream_ida import bin_stream_ida
-from miasm2.core.asmbloc import *
+from miasm2.core.asmblock import *
 from miasm2.expression.simplifications import expr_simp
 from miasm2.expression.expression import *
 from miasm2.analysis.data_analysis import inter_bloc_flow, \
diff --git a/miasm2/analysis/binary.py b/miasm2/analysis/binary.py
index 38a6be15..4ff9dac0 100644
--- a/miasm2/analysis/binary.py
+++ b/miasm2/analysis/binary.py
@@ -2,7 +2,7 @@ import logging
 
 from miasm2.core.bin_stream import bin_stream_str, bin_stream_elf, bin_stream_pe
 from miasm2.jitter.csts import PAGE_READ
-from miasm2.core.asmbloc import AsmSymbolPool
+from miasm2.core.asmblock import AsmSymbolPool
 
 
 log = logging.getLogger("binary")
diff --git a/miasm2/analysis/depgraph.py b/miasm2/analysis/depgraph.py
index f500a736..bab4d2bc 100644
--- a/miasm2/analysis/depgraph.py
+++ b/miasm2/analysis/depgraph.py
@@ -2,7 +2,7 @@
 
 import miasm2.expression.expression as m2_expr
 from miasm2.core.graph import DiGraph
-from miasm2.core.asmbloc import AsmLabel, expr_is_int_or_label, expr_is_label
+from miasm2.core.asmblock import AsmLabel, expr_is_int_or_label, expr_is_label
 from miasm2.expression.simplifications import expr_simp
 from miasm2.ir.symbexec import SymbolicExecutionEngine
 from miasm2.ir.ir import IRBlock, AssignBlock
diff --git a/miasm2/analysis/disasm_cb.py b/miasm2/analysis/disasm_cb.py
index b3ddc99e..284a2c99 100644
--- a/miasm2/analysis/disasm_cb.py
+++ b/miasm2/analysis/disasm_cb.py
@@ -2,7 +2,7 @@
 
 from miasm2.expression.expression import ExprInt, ExprId, ExprMem, MatchExpr
 from miasm2.expression.simplifications import expr_simp
-from miasm2.core.asmbloc \
+from miasm2.core.asmblock \
     import AsmSymbolPool, AsmConstraintNext, AsmConstraintTo
 from miasm2.core.utils import upck32
 # from miasm2.core.graph import DiGraph
diff --git a/miasm2/arch/aarch64/arch.py b/miasm2/arch/aarch64/arch.py
index f352f547..6f95df99 100644
--- a/miasm2/arch/aarch64/arch.py
+++ b/miasm2/arch/aarch64/arch.py
@@ -8,7 +8,7 @@ from collections import defaultdict
 from miasm2.core.bin_stream import bin_stream
 import regs as regs_module
 from regs import *
-from miasm2.core.asmbloc import AsmLabel
+from miasm2.core.asmblock import AsmLabel
 from miasm2.core.cpu import log as log_cpu
 from miasm2.expression.modint import uint32, uint64
 import math
diff --git a/miasm2/arch/aarch64/disasm.py b/miasm2/arch/aarch64/disasm.py
index a15ce306..a8604fe5 100644
--- a/miasm2/arch/aarch64/disasm.py
+++ b/miasm2/arch/aarch64/disasm.py
@@ -1,4 +1,4 @@
-from miasm2.core.asmbloc import disasmEngine
+from miasm2.core.asmblock import disasmEngine
 from miasm2.arch.aarch64.arch import mn_aarch64
 
 cb_aarch64_funcs = []
diff --git a/miasm2/arch/aarch64/jit.py b/miasm2/arch/aarch64/jit.py
index 6910f5cf..255bb91d 100644
--- a/miasm2/arch/aarch64/jit.py
+++ b/miasm2/arch/aarch64/jit.py
@@ -1,7 +1,7 @@
 import logging
 
 from miasm2.jitter.jitload import jitter, named_arguments
-from miasm2.core import asmbloc
+from miasm2.core import asmblock
 from miasm2.core.utils import pck64, upck64
 from miasm2.arch.aarch64.sem import ir_aarch64b, ir_aarch64l
 
@@ -15,7 +15,7 @@ class jitter_aarch64l(jitter):
     max_reg_arg = 8
 
     def __init__(self, *args, **kwargs):
-        sp = asmbloc.AsmSymbolPool()
+        sp = asmblock.AsmSymbolPool()
         jitter.__init__(self, ir_aarch64l(sp), *args, **kwargs)
         self.vm.set_little_endian()
 
@@ -64,6 +64,6 @@ class jitter_aarch64l(jitter):
 class jitter_aarch64b(jitter_aarch64l):
 
     def __init__(self, *args, **kwargs):
-        sp = asmbloc.AsmSymbolPool()
+        sp = asmblock.AsmSymbolPool()
         jitter.__init__(self, ir_aarch64b(sp), *args, **kwargs)
         self.vm.set_big_endian()
diff --git a/miasm2/arch/arm/disasm.py b/miasm2/arch/arm/disasm.py
index 4d300f11..3f6ea4d5 100644
--- a/miasm2/arch/arm/disasm.py
+++ b/miasm2/arch/arm/disasm.py
@@ -1,4 +1,4 @@
-from miasm2.core.asmbloc import AsmConstraint, disasmEngine
+from miasm2.core.asmblock import AsmConstraint, disasmEngine
 from miasm2.arch.arm.arch import mn_arm, mn_armt
 
 
diff --git a/miasm2/arch/arm/jit.py b/miasm2/arch/arm/jit.py
index af657514..70c708e1 100644
--- a/miasm2/arch/arm/jit.py
+++ b/miasm2/arch/arm/jit.py
@@ -1,7 +1,7 @@
 import logging
 
 from miasm2.jitter.jitload import jitter, named_arguments
-from miasm2.core import asmbloc
+from miasm2.core import asmblock
 from miasm2.core.utils import pck32, upck32
 from miasm2.arch.arm.sem import ir_armb, ir_arml
 
@@ -14,7 +14,7 @@ log.setLevel(logging.CRITICAL)
 class jitter_arml(jitter):
 
     def __init__(self, *args, **kwargs):
-        sp = asmbloc.AsmSymbolPool()
+        sp = asmblock.AsmSymbolPool()
         jitter.__init__(self, ir_arml(sp), *args, **kwargs)
         self.vm.set_little_endian()
 
@@ -62,6 +62,6 @@ class jitter_arml(jitter):
 class jitter_armb(jitter_arml):
 
     def __init__(self, *args, **kwargs):
-        sp = asmbloc.AsmSymbolPool()
+        sp = asmblock.AsmSymbolPool()
         jitter.__init__(self, ir_armb(sp), *args, **kwargs)
         self.vm.set_big_endian()
diff --git a/miasm2/arch/mips32/disasm.py b/miasm2/arch/mips32/disasm.py
index e5a70349..bdd800d5 100644
--- a/miasm2/arch/mips32/disasm.py
+++ b/miasm2/arch/mips32/disasm.py
@@ -1,4 +1,4 @@
-from miasm2.core.asmbloc import disasmEngine
+from miasm2.core.asmblock import disasmEngine
 from miasm2.arch.mips32.arch import mn_mips32
 
 
diff --git a/miasm2/arch/mips32/ira.py b/miasm2/arch/mips32/ira.py
index 630daa56..dd02ff50 100644
--- a/miasm2/arch/mips32/ira.py
+++ b/miasm2/arch/mips32/ira.py
@@ -4,7 +4,7 @@ from miasm2.expression.expression import ExprAff, ExprInt32, ExprId
 from miasm2.ir.ir import IntermediateRepresentation, IRBlock, AssignBlock
 from miasm2.ir.analysis import ira
 from miasm2.arch.mips32.sem import ir_mips32l, ir_mips32b
-from miasm2.core.asmbloc import expr_is_int_or_label, expr_is_label
+from miasm2.core.asmblock import expr_is_int_or_label, expr_is_label
 
 class ir_a_mips32l(ir_mips32l, ira):
     def __init__(self, symbol_pool=None):
diff --git a/miasm2/arch/mips32/jit.py b/miasm2/arch/mips32/jit.py
index c979b90b..0ba531f1 100644
--- a/miasm2/arch/mips32/jit.py
+++ b/miasm2/arch/mips32/jit.py
@@ -1,7 +1,7 @@
 import logging
 
 from miasm2.jitter.jitload import jitter
-from miasm2.core import asmbloc
+from miasm2.core import asmblock
 from miasm2.core.utils import pck32, upck32
 from miasm2.arch.mips32.sem import ir_mips32l, ir_mips32b
 from miasm2.jitter.codegen import CGen
@@ -77,7 +77,7 @@ class jitter_mips32l(jitter):
     C_Gen = mipsCGen
 
     def __init__(self, *args, **kwargs):
-        sp = asmbloc.AsmSymbolPool()
+        sp = asmblock.AsmSymbolPool()
         jitter.__init__(self, ir_mips32l(sp), *args, **kwargs)
         self.vm.set_little_endian()
 
@@ -101,6 +101,6 @@ class jitter_mips32l(jitter):
 class jitter_mips32b(jitter_mips32l):
 
     def __init__(self, *args, **kwargs):
-        sp = asmbloc.AsmSymbolPool()
+        sp = asmblock.AsmSymbolPool()
         jitter.__init__(self, ir_mips32b(sp), *args, **kwargs)
         self.vm.set_big_endian()
diff --git a/miasm2/arch/msp430/disasm.py b/miasm2/arch/msp430/disasm.py
index ac5d9cce..849cd675 100644
--- a/miasm2/arch/msp430/disasm.py
+++ b/miasm2/arch/msp430/disasm.py
@@ -1,4 +1,4 @@
-from miasm2.core.asmbloc import disasmEngine
+from miasm2.core.asmblock import disasmEngine
 from miasm2.arch.msp430.arch import mn_msp430
 
 
diff --git a/miasm2/arch/msp430/jit.py b/miasm2/arch/msp430/jit.py
index a78a619e..dd5fe94e 100644
--- a/miasm2/arch/msp430/jit.py
+++ b/miasm2/arch/msp430/jit.py
@@ -1,5 +1,5 @@
 from miasm2.jitter.jitload import jitter
-from miasm2.core import asmbloc
+from miasm2.core import asmblock
 from miasm2.core.utils import pck16, upck16
 from miasm2.arch.msp430.sem import ir_msp430
 
@@ -14,7 +14,7 @@ log.setLevel(logging.CRITICAL)
 class jitter_msp430(jitter):
 
     def __init__(self, *args, **kwargs):
-        sp = asmbloc.AsmSymbolPool()
+        sp = asmblock.AsmSymbolPool()
         jitter.__init__(self, ir_msp430(sp), *args, **kwargs)
         self.vm.set_little_endian()
 
diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py
index 55775a1a..d686cd55 100644
--- a/miasm2/arch/x86/arch.py
+++ b/miasm2/arch/x86/arch.py
@@ -7,7 +7,7 @@ from miasm2.core.cpu import *
 from collections import defaultdict
 import miasm2.arch.x86.regs as regs_module
 from miasm2.arch.x86.regs import *
-from miasm2.core.asmbloc import AsmLabel
+from miasm2.core.asmblock import AsmLabel
 
 log = logging.getLogger("x86_arch")
 console_handler = logging.StreamHandler()
diff --git a/miasm2/arch/x86/disasm.py b/miasm2/arch/x86/disasm.py
index 0ff55097..fc981c09 100644
--- a/miasm2/arch/x86/disasm.py
+++ b/miasm2/arch/x86/disasm.py
@@ -1,4 +1,4 @@
-from miasm2.core.asmbloc import disasmEngine
+from miasm2.core.asmblock import disasmEngine
 from miasm2.arch.x86.arch import mn_x86
 
 
diff --git a/miasm2/arch/x86/jit.py b/miasm2/arch/x86/jit.py
index 4861328b..cfdabf8c 100644
--- a/miasm2/arch/x86/jit.py
+++ b/miasm2/arch/x86/jit.py
@@ -1,7 +1,7 @@
 import logging
 
 from miasm2.jitter.jitload import jitter, named_arguments
-from miasm2.core import asmbloc
+from miasm2.core import asmblock
 from miasm2.core.utils import pck16, pck32, pck64, upck16, upck32, upck64
 from miasm2.arch.x86.sem import ir_x86_16, ir_x86_32, ir_x86_64
 from miasm2.jitter.codegen import CGen
@@ -37,7 +37,7 @@ class jitter_x86_16(jitter):
     C_Gen = x86_32_CGen
 
     def __init__(self, *args, **kwargs):
-        sp = asmbloc.AsmSymbolPool()
+        sp = asmblock.AsmSymbolPool()
         jitter.__init__(self, ir_x86_16(sp), *args, **kwargs)
         self.vm.set_little_endian()
         self.ir_arch.do_stk_segm = False
@@ -69,7 +69,7 @@ class jitter_x86_32(jitter):
     C_Gen = x86_32_CGen
 
     def __init__(self, *args, **kwargs):
-        sp = asmbloc.AsmSymbolPool()
+        sp = asmblock.AsmSymbolPool()
         jitter.__init__(self, ir_x86_32(sp), *args, **kwargs)
         self.vm.set_little_endian()
         self.ir_arch.do_stk_segm = False
@@ -129,7 +129,7 @@ class jitter_x86_64(jitter):
     C_Gen = x86_64_CGen
 
     def __init__(self, *args, **kwargs):
-        sp = asmbloc.AsmSymbolPool()
+        sp = asmblock.AsmSymbolPool()
         jitter.__init__(self, ir_x86_64(sp), *args, **kwargs)
         self.vm.set_little_endian()
         self.ir_arch.do_stk_segm = False
diff --git a/miasm2/core/asmbloc.py b/miasm2/core/asmbloc.py
index 669fd92d..54760f4e 100644
--- a/miasm2/core/asmbloc.py
+++ b/miasm2/core/asmbloc.py
@@ -1,1555 +1,10 @@
-#-*- coding:utf-8 -*-
-
-import logging
-import inspect
+"""
+This module will be removed in favour of asmblock.py
+Cause: French tipo.
+"""
 import warnings
-from collections import namedtuple
-
-import miasm2.expression.expression as m2_expr
-from miasm2.expression.simplifications import expr_simp
-from miasm2.expression.modint import moduint, modint
-from miasm2.core.utils import Disasm_Exception, pck
-from miasm2.core.graph import DiGraph, DiGraphSimplifier, MatchGraphJoker
-from miasm2.core.interval import interval
-
-
-log_asmbloc = logging.getLogger("asmblock")
-console_handler = logging.StreamHandler()
-console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s"))
-log_asmbloc.addHandler(console_handler)
-log_asmbloc.setLevel(logging.WARNING)
-
-
-def is_int(a):
-    return isinstance(a, int) or isinstance(a, long) or \
-        isinstance(a, moduint) or isinstance(a, modint)
-
-
-def expr_is_label(e):
-    return isinstance(e, m2_expr.ExprId) and isinstance(e.name, AsmLabel)
-
-
-def expr_is_int_or_label(e):
-    return isinstance(e, m2_expr.ExprInt) or \
-        (isinstance(e, m2_expr.ExprId) and isinstance(e.name, AsmLabel))
-
-
-class AsmLabel(object):
-
-    "Stand for an assembly label"
-
-    def __init__(self, name="", offset=None):
-        self.fixedblocs = False
-        if is_int(name):
-            name = "loc_%.16X" % (int(name) & 0xFFFFFFFFFFFFFFFF)
-        self.name = name
-        self.attrib = None
-        if offset is None:
-            self.offset = offset
-        else:
-            self.offset = int(offset)
-
-    def __str__(self):
-        if isinstance(self.offset, (int, long)):
-            return "%s:0x%08x" % (self.name, self.offset)
-        else:
-            return "%s:%s" % (self.name, str(self.offset))
-
-    def __repr__(self):
-        rep = '<%s ' % self.__class__.__name__
-        if self.name:
-            rep += repr(self.name) + ' '
-        rep += '>'
-        return rep
-
-
-class asm_label(AsmLabel):
-
-    def __init__(self, name="", offset=None):
-        warnings.warn('DEPRECATION WARNING: use "AsmLabel" instead of "asm_label"')
-        super(asm_label, self).__init__(name, offset)
-
-class AsmRaw(object):
-
-    def __init__(self, raw=""):
-        self.raw = raw
-
-    def __str__(self):
-        return repr(self.raw)
-
-
-class asm_raw(AsmRaw):
-
-    def __init__(self, raw=""):
-        warnings.warn('DEPRECATION WARNING: use "AsmRaw" instead of "asm_raw"')
-        super(asm_label, self).__init__(raw)
-
-
-class AsmConstraint(object):
-    c_to = "c_to"
-    c_next = "c_next"
-
-    def __init__(self, label, c_t=c_to):
-        # Sanity check
-        assert isinstance(label, AsmLabel)
-
-        self.label = label
-        self.c_t = c_t
-
-    def __str__(self):
-        return "%s:%s" % (str(self.c_t), str(self.label))
-
-
-class asm_constraint(AsmConstraint):
-
-    def __init__(self, label, c_t=AsmConstraint.c_to):
-        warnings.warn('DEPRECATION WARNING: use "AsmConstraint" instead of "asm_constraint"')
-        super(asm_constraint, self).__init__(label, c_t)
-
-
-class AsmConstraintNext(AsmConstraint):
-
-    def __init__(self, label):
-        super(AsmConstraintNext, self).__init__(
-            label, c_t=AsmConstraint.c_next)
-
-
-class asm_constraint_next(AsmConstraint):
-
-    def __init__(self, label):
-        warnings.warn('DEPRECATION WARNING: use "AsmConstraintNext" instead of "asm_constraint_next"')
-        super(asm_constraint_next, self).__init__(label)
-
-
-class AsmConstraintTo(AsmConstraint):
-
-    def __init__(self, label):
-        super(AsmConstraintTo, self).__init__(
-            label, c_t=AsmConstraint.c_to)
-
-class asm_constraint_to(AsmConstraint):
-
-    def __init__(self, label):
-        warnings.warn('DEPRECATION WARNING: use "AsmConstraintTo" instead of "asm_constraint_to"')
-        super(asm_constraint_to, self).__init__(label)
-
-
-class AsmBlock(object):
-
-    def __init__(self, label, alignment=1):
-        assert isinstance(label, AsmLabel)
-        self.bto = set()
-        self.lines = []
-        self.label = label
-        self.alignment = alignment
-
-    def __str__(self):
-        out = []
-        out.append(str(self.label))
-        for l in self.lines:
-            out.append(str(l))
-        if self.bto:
-            lbls = ["->"]
-            for l in self.bto:
-                if l is None:
-                    lbls.append("Unknown? ")
-                else:
-                    lbls.append(str(l) + " ")
-            lbls = '\t'.join(lbls)
-            out.append(lbls)
-        return '\n'.join(out)
-
-    def addline(self, l):
-        self.lines.append(l)
-
-    def addto(self, c):
-        assert isinstance(self.bto, set)
-        self.bto.add(c)
-
-    def split(self, offset, l):
-        log_asmbloc.debug('split at %x', offset)
-        i = -1
-        offsets = [x.offset for x in self.lines]
-        if not l.offset in offsets:
-            log_asmbloc.warning(
-                'cannot split bloc at %X ' % offset +
-                'middle instruction? default middle')
-            offsets.sort()
-            return None
-        new_bloc = AsmBlock(l)
-        i = offsets.index(offset)
-
-        self.lines, new_bloc.lines = self.lines[:i], self.lines[i:]
-        flow_mod_instr = self.get_flow_instr()
-        log_asmbloc.debug('flow mod %r', flow_mod_instr)
-        c = AsmConstraint(l, AsmConstraint.c_next)
-        # move dst if flowgraph modifier was in original bloc
-        # (usecase: split delayslot bloc)
-        if flow_mod_instr:
-            for xx in self.bto:
-                log_asmbloc.debug('lbl %s', xx)
-            c_next = set(
-                [x for x in self.bto if x.c_t == AsmConstraint.c_next])
-            c_to = [x for x in self.bto if x.c_t != AsmConstraint.c_next]
-            self.bto = set([c] + c_to)
-            new_bloc.bto = c_next
-        else:
-            new_bloc.bto = self.bto
-            self.bto = set([c])
-        return new_bloc
-
-    def get_range(self):
-        """Returns the offset hull of an AsmBlock"""
-        if len(self.lines):
-            return (self.lines[0].offset,
-                    self.lines[-1].offset + self.lines[-1].l)
-        else:
-            return 0, 0
-
-    def get_offsets(self):
-        return [x.offset for x in self.lines]
-
-    def add_cst(self, offset, c_t, symbol_pool):
-        if isinstance(offset, (int, long)):
-            l = symbol_pool.getby_offset_create(offset)
-        elif isinstance(offset, str):
-            l = symbol_pool.getby_name_create(offset)
-        elif isinstance(offset, AsmLabel):
-            l = offset
-        else:
-            raise ValueError('unknown offset type %r' % offset)
-        c = AsmConstraint(l, c_t)
-        self.bto.add(c)
-
-    def get_flow_instr(self):
-        if not self.lines:
-            return None
-        for i in xrange(-1, -1 - self.lines[0].delayslot - 1, -1):
-            if not 0 <= i < len(self.lines):
-                return None
-            l = self.lines[i]
-            if l.splitflow() or l.breakflow():
-                raise NotImplementedError('not fully functional')
-
-    def get_subcall_instr(self):
-        if not self.lines:
-            return None
-        delayslot = self.lines[0].delayslot
-        end_index = len(self.lines) - 1
-        ds_max_index = max(end_index - delayslot, 0)
-        for i in xrange(end_index, ds_max_index - 1, -1):
-            l = self.lines[i]
-            if l.is_subcall():
-                return l
-        return None
-
-    def get_next(self):
-        for x in self.bto:
-            if x.c_t == AsmConstraint.c_next:
-                return x.label
-        return None
-
-    @staticmethod
-    def _filter_constraint(constraints):
-        """Sort and filter @constraints for AsmBlock.bto
-        @constraints: non-empty set of AsmConstraint instance
-
-        Always the same type -> one of the constraint
-        c_next and c_to -> c_next
-        """
-        # Only one constraint
-        if len(constraints) == 1:
-            return next(iter(constraints))
-
-        # Constraint type -> set of corresponding constraint
-        cbytype = {}
-        for cons in constraints:
-            cbytype.setdefault(cons.c_t, set()).add(cons)
-
-        # Only one type -> any constraint is OK
-        if len(cbytype) == 1:
-            return next(iter(constraints))
-
-        # At least 2 types -> types = {c_next, c_to}
-        # c_to is included in c_next
-        return next(iter(cbytype[AsmConstraint.c_next]))
-
-    def fix_constraints(self):
-        """Fix next block constraints"""
-        # destination -> associated constraints
-        dests = {}
-        for constraint in self.bto:
-            dests.setdefault(constraint.label, set()).add(constraint)
-
-        self.bto = set(self._filter_constraint(constraints)
-                       for constraints in dests.itervalues())
-
-
-class asm_bloc(object):
-
-    def __init__(self, label, alignment=1):
-        warnings.warn('DEPRECATION WARNING: use "AsmBlock" instead of "asm_bloc"')
-        super(asm_bloc, self).__init__(label, alignment)
-
-
-class AsmBlockBad(AsmBlock):
-
-    """Stand for a *bad* ASM block (malformed, unreachable,
-    not disassembled, ...)"""
-
-    ERROR_TYPES = {-1: "Unknown error",
-                   0: "Unable to disassemble",
-                   1: "Null starting block",
-                   2: "Address forbidden by dont_dis",
-                   }
-
-    def __init__(self, label=None, alignment=1, errno=-1, *args, **kwargs):
-        """Instanciate an AsmBlock_bad.
-        @label, @alignement: same as AsmBlock.__init__
-        @errno: (optional) specify a error type associated with the block
-        """
-        super(AsmBlockBad, self).__init__(label, alignment, *args, **kwargs)
-        self._errno = errno
-
-    def __str__(self):
-        error_txt = self.ERROR_TYPES.get(self._errno, self._errno)
-        return "\n".join([str(self.label),
-                          "\tBad block: %s" % error_txt])
-
-    def addline(self, *args, **kwargs):
-        raise RuntimeError("An AsmBlockBad cannot have line")
-
-    def addto(self, *args, **kwargs):
-        raise RuntimeError("An AsmBlockBad cannot have bto")
-
-    def split(self, *args, **kwargs):
-        raise RuntimeError("An AsmBlockBad cannot be splitted")
-
-
-class asm_block_bad(AsmBlockBad):
-
-    def __init__(self, label=None, alignment=1, errno=-1, *args, **kwargs):
-        warnings.warn('DEPRECATION WARNING: use "AsmBlockBad" instead of "asm_block_bad"')
-        super(asm_block_bad, self).__init__(label, alignment, *args, **kwargs)
-
-
-class AsmSymbolPool(object):
-
-    def __init__(self):
-        self._labels = []
-        self._name2label = {}
-        self._offset2label = {}
-        self._label_num = 0
-
-    def add_label(self, name, offset=None):
-        """
-        Create and add a label to the symbol_pool
-        @name: label's name
-        @offset: (optional) label's offset
-        """
-        label = AsmLabel(name, offset)
-
-        # Test for collisions
-        if (label.offset in self._offset2label and
-                label != self._offset2label[label.offset]):
-            raise ValueError('symbol %s has same offset as %s' %
-                             (label, self._offset2label[label.offset]))
-        if (label.name in self._name2label and
-                label != self._name2label[label.name]):
-            raise ValueError('symbol %s has same name as %s' %
-                             (label, self._name2label[label.name]))
-
-        self._labels.append(label)
-        if label.offset is not None:
-            self._offset2label[label.offset] = label
-        if label.name != "":
-            self._name2label[label.name] = label
-        return label
-
-    def remove_label(self, label):
-        """
-        Delete a @label
-        """
-        self._name2label.pop(label.name, None)
-        self._offset2label.pop(label.offset, None)
-        if label in self._labels:
-            self._labels.remove(label)
-
-    def del_label_offset(self, label):
-        """Unpin the @label from its offset"""
-        self._offset2label.pop(label.offset, None)
-        label.offset = None
-
-    def getby_offset(self, offset):
-        """Retrieve label using its @offset"""
-        return self._offset2label.get(offset, None)
-
-    def getby_name(self, name):
-        """Retrieve label using its @name"""
-        return self._name2label.get(name, None)
-
-    def getby_name_create(self, name):
-        """Get a label from its @name, create it if it doesn't exist"""
-        label = self.getby_name(name)
-        if label is None:
-            label = self.add_label(name)
-        return label
-
-    def getby_offset_create(self, offset):
-        """Get a label from its @offset, create it if it doesn't exist"""
-        label = self.getby_offset(offset)
-        if label is None:
-            label = self.add_label(offset, offset)
-        return label
-
-    def rename_label(self, label, newname):
-        """Rename the @label name to @newname"""
-        if newname in self._name2label:
-            raise ValueError('Symbol already known')
-        self._name2label.pop(label.name, None)
-        label.name = newname
-        self._name2label[label.name] = label
-
-    def set_offset(self, label, offset):
-        """Pin the @label from at @offset
-        Note that there is a special case when the offset is a list
-        it happens when offsets are recomputed in resolve_symbol*
-        """
-        if label is None:
-            raise ValueError('label should not be None')
-        if not label.name in self._name2label:
-            raise ValueError('label %s not in symbol pool' % label)
-        if offset is not None and offset in self._offset2label:
-            raise ValueError('Conflict in label %s' % label)
-        self._offset2label.pop(label.offset, None)
-        label.offset = offset
-        if is_int(label.offset):
-            self._offset2label[label.offset] = label
-
-    @property
-    def items(self):
-        """Return all labels"""
-        return self._labels
-
-    def __str__(self):
-        return reduce(lambda x, y: x + str(y) + '\n', self._labels, "")
-
-    def __getitem__(self, item):
-        if item in self._name2label:
-            return self._name2label[item]
-        if item in self._offset2label:
-            return self._offset2label[item]
-        raise KeyError('unknown symbol %r' % item)
-
-    def __contains__(self, item):
-        return item in self._name2label or item in self._offset2label
-
-    def merge(self, symbol_pool):
-        """Merge with another @symbol_pool"""
-        self._labels += symbol_pool._labels
-        self._name2label.update(symbol_pool._name2label)
-        self._offset2label.update(symbol_pool._offset2label)
-
-    def gen_label(self):
-        """Generate a new unpinned label"""
-        label = self.add_label("lbl_gen_%.8X" % (self._label_num))
-        self._label_num += 1
-        return label
-
-
-class asm_symbol_pool(AsmSymbolPool):
-
-    def __init__(self):
-        warnings.warn('DEPRECATION WARNING: use "AsmSymbolPool" instead of "asm_symbol_pool"')
-        super(asm_symbol_pool, self).__init__()
-
-
-class AsmCFG(DiGraph):
-
-    """Directed graph standing for a ASM Control Flow Graph with:
-     - nodes: AsmBlock
-     - edges: constraints between blocks, synchronized with AsmBlock's "bto"
-
-    Specialized the .dot export and force the relation between block to be uniq,
-    and associated with a constraint.
-
-    Offer helpers on AsmCFG management, such as research by label, sanity
-    checking and mnemonic size guessing.
-    """
-
-    # Internal structure for pending management
-    AsmCFGPending = namedtuple("AsmCFGPending",
-                               ["waiter", "constraint"])
-
-    def __init__(self, *args, **kwargs):
-        super(AsmCFG, self).__init__(*args, **kwargs)
-        # Edges -> constraint
-        self.edges2constraint = {}
-        # Expected AsmLabel -> set( (src, dst), constraint )
-        self._pendings = {}
-        # Label2block built on the fly
-        self._label2block = {}
-
-    # Compatibility with old list API
-    def append(self, *args, **kwargs):
-        raise DeprecationWarning("AsmCFG is a graph, use add_node")
-
-    def remove(self, *args, **kwargs):
-        raise DeprecationWarning("AsmCFG is a graph, use del_node")
-
-    def __getitem__(self, *args, **kwargs):
-        raise DeprecationWarning("Order of AsmCFG elements is not reliable")
-
-    def __iter__(self):
-        """Iterator on AsmBlock composing the current graph"""
-        return iter(self._nodes)
-
-    def __len__(self):
-        """Return the number of blocks in AsmCFG"""
-        return len(self._nodes)
-
-    # Manage graph with associated constraints
-    def add_edge(self, src, dst, constraint):
-        """Add an edge to the graph
-        @src: AsmBlock instance, source
-        @dst: AsmBlock instance, destination
-        @constraint: constraint associated to this edge
-        """
-        # Sanity check
-        assert (src, dst) not in self.edges2constraint
-
-        # Add the edge to src.bto if needed
-        if dst.label not in [cons.label for cons in src.bto]:
-            src.bto.add(AsmConstraint(dst.label, constraint))
-
-        # Add edge
-        self.edges2constraint[(src, dst)] = constraint
-        super(AsmCFG, self).add_edge(src, dst)
-
-    def add_uniq_edge(self, src, dst, constraint):
-        """Add an edge from @src to @dst if it doesn't already exist"""
-        if (src not in self._nodes_succ or
-                dst not in self._nodes_succ[src]):
-            self.add_edge(src, dst, constraint)
-
-    def del_edge(self, src, dst):
-        """Delete the edge @src->@dst and its associated constraint"""
-        # Delete from src.bto
-        to_remove = [cons for cons in src.bto if cons.label == dst.label]
-        if to_remove:
-            assert len(to_remove) == 1
-            src.bto.remove(to_remove[0])
-
-        # Del edge
-        del self.edges2constraint[(src, dst)]
-        super(AsmCFG, self).del_edge(src, dst)
-
-    def add_node(self, block):
-        """Add the block @block to the current instance, if it is not already in
-        @block: AsmBlock instance
-
-        Edges will be created for @block.bto, if destinations are already in
-        this instance. If not, they will be resolved when adding these
-        aforementionned destinations.
-        `self.pendings` indicates which blocks are not yet resolved.
-        """
-        status = super(AsmCFG, self).add_node(block)
-        if not status:
-            return status
-
-        # Update waiters
-        if block.label in self._pendings:
-            for bblpend in self._pendings[block.label]:
-                self.add_edge(bblpend.waiter, block, bblpend.constraint)
-            del self._pendings[block.label]
-
-        # Synchronize edges with block destinations
-        self._label2block[block.label] = block
-        for constraint in block.bto:
-            dst = self._label2block.get(constraint.label,
-                                        None)
-            if dst is None:
-                # Block is yet unknown, add it to pendings
-                to_add = self.AsmCFGPending(waiter=block,
-                                            constraint=constraint.c_t)
-                self._pendings.setdefault(constraint.label,
-                                          set()).add(to_add)
-            else:
-                # Block is already in known nodes
-                self.add_edge(block, dst, constraint.c_t)
-
-        return status
-
-    def del_node(self, block):
-        super(AsmCFG, self).del_node(block)
-        del self._label2block[block.label]
-
-    def merge(self, graph):
-        """Merge with @graph, taking in account constraints"""
-        # -> add_edge(x, y, constraint)
-        for node in graph._nodes:
-            self.add_node(node)
-        for edge in graph._edges:
-            # Use "_uniq_" beacause the edge can already exist due to add_node
-            self.add_uniq_edge(*edge, constraint=graph.edges2constraint[edge])
-
-    def node2lines(self, node):
-        yield self.DotCellDescription(text=str(node.label.name),
-                                      attr={'align': 'center',
-                                            'colspan': 2,
-                                            'bgcolor': 'grey'})
-
-        if isinstance(node, AsmBlockBad):
-            yield [self.DotCellDescription(
-                text=node.ERROR_TYPES.get(node._errno,
-                                          node._errno),
-                                           attr={})]
-            raise StopIteration
-        for line in node.lines:
-            if self._dot_offset:
-                yield [self.DotCellDescription(text="%.8X" % line.offset,
-                                               attr={}),
-                       self.DotCellDescription(text=str(line), attr={})]
-            else:
-                yield self.DotCellDescription(text=str(line), attr={})
-
-    def node_attr(self, node):
-        if isinstance(node, AsmBlockBad):
-            return {'style': 'filled', 'fillcolor': 'red'}
-        return {}
-
-    def edge_attr(self, src, dst):
-        cst = self.edges2constraint.get((src, dst), None)
-        edge_color = "blue"
-
-        if len(self.successors(src)) > 1:
-            if cst == AsmConstraint.c_next:
-                edge_color = "red"
-            else:
-                edge_color = "limegreen"
-
-        return {"color": edge_color}
-
-    def dot(self, offset=False):
-        """
-        @offset: (optional) if set, add the corresponding offsets in each node
-        """
-        self._dot_offset = offset
-        return super(AsmCFG, self).dot()
-
-    # Helpers
-    @property
-    def pendings(self):
-        """Dictionary of label -> set(AsmCFGPending instance) indicating
-        which label are missing in the current instance.
-        A label is missing if a block which is already in nodes has constraints
-        with him (thanks to its .bto) and the corresponding block is not yet in
-        nodes
-        """
-        return self._pendings
-
-    def _build_label2block(self):
-        self._label2block = {block.label: block
-                             for block in self._nodes}
-
-    def label2block(self, label):
-        """Return the block corresponding to label @label
-        @label: AsmLabel instance or ExprId(AsmLabel) instance"""
-        return self._label2block[label]
-
-    def rebuild_edges(self):
-        """Consider blocks '.bto' and rebuild edges according to them, ie:
-        - update constraint type
-        - add missing edge
-        - remove no more used edge
-
-        This method should be called if a block's '.bto' in nodes have been
-        modified without notifying this instance to resynchronize edges.
-        """
-        self._build_label2block()
-        for block in self._nodes:
-            edges = []
-            # Rebuild edges from bto
-            for constraint in block.bto:
-                dst = self._label2block.get(constraint.label,
-                                            None)
-                if dst is None:
-                    # Missing destination, add to pendings
-                    self._pendings.setdefault(constraint.label,
-                                              set()).add(self.AsmCFGPending(block,
-                                                                            constraint.c_t))
-                    continue
-                edge = (block, dst)
-                edges.append(edge)
-                if edge in self._edges:
-                    # Already known edge, constraint may have changed
-                    self.edges2constraint[edge] = constraint.c_t
-                else:
-                    # An edge is missing
-                    self.add_edge(edge[0], edge[1], constraint.c_t)
-
-            # Remove useless edges
-            for succ in self.successors(block):
-                edge = (block, succ)
-                if edge not in edges:
-                    self.del_edge(*edge)
-
-    def get_bad_blocks(self):
-        """Iterator on AsmBlockBad elements"""
-        # A bad asm block is always a leaf
-        for block in self.leaves():
-            if isinstance(block, AsmBlockBad):
-                yield block
-
-    def get_bad_blocks_predecessors(self, strict=False):
-        """Iterator on block with an AsmBlockBad destination
-        @strict: (optional) if set, return block with only bad
-        successors
-        """
-        # Avoid returning the same block
-        done = set()
-        for badblock in self.get_bad_blocks():
-            for predecessor in self.predecessors_iter(badblock):
-                if predecessor not in done:
-                    if (strict and
-                        not all(isinstance(block, AsmBlockBad)
-                                for block in self.successors_iter(predecessor))):
-                        continue
-                    yield predecessor
-                    done.add(predecessor)
-
-    def sanity_check(self):
-        """Do sanity checks on blocks' constraints:
-        * no pendings
-        * no multiple next constraint to same block
-        * no next constraint to self
-        """
-
-        if len(self._pendings) != 0:
-            raise RuntimeError("Some blocks are missing: %s" % map(str,
-                                                                   self._pendings.keys()))
-
-        next_edges = {edge: constraint
-                      for edge, constraint in self.edges2constraint.iteritems()
-                      if constraint == AsmConstraint.c_next}
-
-        for block in self._nodes:
-            # No next constraint to self
-            if (block, block) in next_edges:
-                raise RuntimeError('Bad constraint: self in next')
-
-            # No multiple next constraint to same block
-            pred_next = list(pblock
-                             for (pblock, dblock) in next_edges
-                             if dblock == block)
-
-            if len(pred_next) > 1:
-                raise RuntimeError("Too many next constraints for bloc %r"
-                                   "(%s)" % (block.label,
-                                             map(lambda x: x.label, pred_next)))
-
-    def guess_blocks_size(self, mnemo):
-        """Asm and compute max block size
-        Add a 'size' and 'max_size' attribute on each block
-        @mnemo: metamn instance"""
-        for block in self._nodes:
-            size = 0
-            for instr in block.lines:
-                if isinstance(instr, AsmRaw):
-                    # for special AsmRaw, only extract len
-                    if isinstance(instr.raw, list):
-                        data = None
-                        if len(instr.raw) == 0:
-                            l = 0
-                        else:
-                            l = instr.raw[0].size / 8 * len(instr.raw)
-                    elif isinstance(instr.raw, str):
-                        data = instr.raw
-                        l = len(data)
-                    else:
-                        raise NotImplementedError('asm raw')
-                else:
-                    # Assemble the instruction to retrieve its len.
-                    # If the instruction uses symbol it will fail
-                    # In this case, the max_instruction_len is used
-                    try:
-                        candidates = mnemo.asm(instr)
-                        l = len(candidates[-1])
-                    except:
-                        l = mnemo.max_instruction_len
-                    data = None
-                instr.data = data
-                instr.l = l
-                size += l
-
-            block.size = size
-            block.max_size = size
-            log_asmbloc.info("size: %d max: %d", block.size, block.max_size)
-
-    def apply_splitting(self, symbol_pool, dis_block_callback=None, **kwargs):
-        """Consider @self' bto destinations and split block in @self if one of
-        these destinations jumps in the middle of this block.
-        In order to work, they must be only one block in @self per label in
-        @symbol_pool (which is true if @self come from the same disasmEngine).
-
-        @symbol_pool: AsmSymbolPool instance associated with @self'labels
-        @dis_block_callback: (optional) if set, this callback will be called on
-        new block destinations
-        @kwargs: (optional) named arguments to pass to dis_block_callback
-        """
-        # Get all possible destinations not yet resolved, with a resolved
-        # offset
-        block_dst = [label.offset
-                     for label in self.pendings
-                     if label.offset is not None]
-
-        todo = self.nodes().copy()
-        rebuild_needed = False
-
-        while todo:
-            # Find a block with a destination inside another one
-            cur_block = todo.pop()
-            range_start, range_stop = cur_block.get_range()
-
-            for off in block_dst:
-                if not (off > range_start and off < range_stop):
-                    continue
-
-                # `cur_block` must be splitted at offset `off`
-                label = symbol_pool.getby_offset_create(off)
-                new_b = cur_block.split(off, label)
-                log_asmbloc.debug("Split block %x", off)
-                if new_b is None:
-                    log_asmbloc.error("Cannot split %x!!", off)
-                    continue
-
-                # Remove pending from cur_block
-                # Links from new_b will be generated in rebuild_edges
-                for dst in new_b.bto:
-                    if dst.label not in self.pendings:
-                        continue
-                    self.pendings[dst.label] = set(pending for pending in self.pendings[dst.label]
-                                                   if pending.waiter != cur_block)
-
-                # The new block destinations may need to be disassembled
-                if dis_block_callback:
-                    offsets_to_dis = set(constraint.label.offset
-                                         for constraint in new_b.bto)
-                    dis_block_callback(cur_bloc=new_b,
-                                       offsets_to_dis=offsets_to_dis,
-                                       symbol_pool=symbol_pool, **kwargs)
-
-                # Update structure
-                rebuild_needed = True
-                self.add_node(new_b)
-
-                # The new block must be considered
-                todo.add(new_b)
-                range_start, range_stop = cur_block.get_range()
-
-        # Rebuild edges to match new blocks'bto
-        if rebuild_needed:
-            self.rebuild_edges()
-
-    def __str__(self):
-        out = []
-        for node in self.nodes():
-            out.append(str(node))
-        for nodeA, nodeB in self.edges():
-            out.append("%s -> %s" % (nodeA.label, nodeB.label))
-        return '\n'.join(out)
-
-    def __repr__(self):
-        return "<%s %s>" % (self.__class__.__name__, hex(id(self)))
-
-# Out of _merge_blocks to be computed only once
-_acceptable_block = lambda block: (not isinstance(block, AsmBlockBad) and
-                                   len(block.lines) > 0)
-_parent = MatchGraphJoker(restrict_in=False, filt=_acceptable_block)
-_son = MatchGraphJoker(restrict_out=False, filt=_acceptable_block)
-_expgraph = _parent >> _son
-
-
-def _merge_blocks(dg, graph):
-    """Graph simplification merging AsmBlock with one and only one son with this
-    son if this son has one and only one parent"""
-
-    # Blocks to ignore, because they have been removed from the graph
-    to_ignore = set()
-
-    for match in _expgraph.match(graph):
-
-        # Get matching blocks
-        block, succ = match[_parent], match[_son]
-
-        # Ignore already deleted blocks
-        if (block in to_ignore or
-            succ in to_ignore):
-            continue
-
-        # Remove block last instruction if needed
-        last_instr = block.lines[-1]
-        if last_instr.delayslot > 0:
-            # TODO: delayslot
-            raise RuntimeError("Not implemented yet")
-
-        if last_instr.is_subcall():
-            continue
-        if last_instr.breakflow() and last_instr.dstflow():
-            block.lines.pop()
-
-        # Merge block
-        block.lines += succ.lines
-        for nextb in graph.successors_iter(succ):
-            graph.add_edge(block, nextb, graph.edges2constraint[(succ, nextb)])
-
-        graph.del_node(succ)
-        to_ignore.add(succ)
-
-
-bbl_simplifier = DiGraphSimplifier()
-bbl_simplifier.enable_passes([_merge_blocks])
-
-
-def conservative_asm(mnemo, instr, symbols, conservative):
-    """
-    Asm instruction;
-    Try to keep original instruction bytes if it exists
-    """
-    candidates = mnemo.asm(instr, symbols)
-    if not candidates:
-        raise ValueError('cannot asm:%s' % str(instr))
-    if not hasattr(instr, "b"):
-        return candidates[0], candidates
-    if instr.b in candidates:
-        return instr.b, candidates
-    if conservative:
-        for c in candidates:
-            if len(c) == len(instr.b):
-                return c, candidates
-    return candidates[0], candidates
-
-
-def fix_expr_val(expr, symbols):
-    """Resolve an expression @expr using @symbols"""
-    def expr_calc(e):
-        if isinstance(e, m2_expr.ExprId):
-            s = symbols._name2label[e.name]
-            e = m2_expr.ExprInt(s.offset, e.size)
-        return e
-    result = expr.visit(expr_calc)
-    result = expr_simp(result)
-    if not isinstance(result, m2_expr.ExprInt):
-        raise RuntimeError('Cannot resolve symbol %s' % expr)
-    return result
-
-
-def fix_label_offset(symbol_pool, label, offset, modified):
-    """Fix the @label offset to @offset. If the @offset has changed, add @label
-    to @modified
-    @symbol_pool: current symbol_pool
-    """
-    if label.offset == offset:
-        return
-    symbol_pool.set_offset(label, offset)
-    modified.add(label)
-
-
-class BlockChain(object):
-
-    """Manage blocks linked with an asm_constraint_next"""
-
-    def __init__(self, symbol_pool, blocks):
-        self.symbol_pool = symbol_pool
-        self.blocks = blocks
-        self.place()
-
-    @property
-    def pinned(self):
-        """Return True iff at least one block is pinned"""
-        return self.pinned_block_idx is not None
-
-    def _set_pinned_block_idx(self):
-        self.pinned_block_idx = None
-        for i, block in enumerate(self.blocks):
-            if is_int(block.label.offset):
-                if self.pinned_block_idx is not None:
-                    raise ValueError("Multiples pinned block detected")
-                self.pinned_block_idx = i
-
-    def place(self):
-        """Compute BlockChain min_offset and max_offset using pinned block and
-        blocks' size
-        """
-        self._set_pinned_block_idx()
-        self.max_size = 0
-        for block in self.blocks:
-            self.max_size += block.max_size + block.alignment - 1
-
-        # Check if chain has one block pinned
-        if not self.pinned:
-            return
-
-        offset_base = self.blocks[self.pinned_block_idx].label.offset
-        assert(offset_base % self.blocks[self.pinned_block_idx].alignment == 0)
-
-        self.offset_min = offset_base
-        for block in self.blocks[:self.pinned_block_idx - 1:-1]:
-            self.offset_min -= block.max_size + \
-                (block.alignment - block.max_size) % block.alignment
-
-        self.offset_max = offset_base
-        for block in self.blocks[self.pinned_block_idx:]:
-            self.offset_max += block.max_size + \
-                (block.alignment - block.max_size) % block.alignment
-
-    def merge(self, chain):
-        """Best effort merge two block chains
-        Return the list of resulting blockchains"""
-        self.blocks += chain.blocks
-        self.place()
-        return [self]
-
-    def fix_blocks(self, modified_labels):
-        """Propagate a pinned to its blocks' neighbour
-        @modified_labels: store new pinned labels"""
-
-        if not self.pinned:
-            raise ValueError('Trying to fix unpinned block')
-
-        # Propagate offset to blocks before pinned block
-        pinned_block = self.blocks[self.pinned_block_idx]
-        offset = pinned_block.label.offset
-        if offset % pinned_block.alignment != 0:
-            raise RuntimeError('Bad alignment')
-
-        for block in self.blocks[:self.pinned_block_idx - 1:-1]:
-            new_offset = offset - block.size
-            new_offset = new_offset - new_offset % pinned_block.alignment
-            fix_label_offset(self.symbol_pool,
-                             block.label,
-                             new_offset,
-                             modified_labels)
-
-        # Propagate offset to blocks after pinned block
-        offset = pinned_block.label.offset + pinned_block.size
-
-        last_block = pinned_block
-        for block in self.blocks[self.pinned_block_idx + 1:]:
-            offset += (- offset) % last_block.alignment
-            fix_label_offset(self.symbol_pool,
-                             block.label,
-                             offset,
-                             modified_labels)
-            offset += block.size
-            last_block = block
-        return modified_labels
-
-
-class BlockChainWedge(object):
-
-    """Stand for wedges between blocks"""
-
-    def __init__(self, symbol_pool, offset, size):
-        self.symbol_pool = symbol_pool
-        self.offset = offset
-        self.max_size = size
-        self.offset_min = offset
-        self.offset_max = offset + size
-
-    def merge(self, chain):
-        """Best effort merge two block chains
-        Return the list of resulting blockchains"""
-        self.symbol_pool.set_offset(chain.blocks[0].label, self.offset_max)
-        chain.place()
-        return [self, chain]
-
-
-def group_constrained_blocks(symbol_pool, blocks):
-    """
-    Return the BlockChains list built from grouped asm blocks linked by
-    asm_constraint_next
-    @blocks: a list of asm block
-    """
-    log_asmbloc.info('group_constrained_blocks')
-
-    # Group adjacent blocks
-    remaining_blocks = list(blocks)
-    known_block_chains = {}
-    lbl2block = {block.label: block for block in blocks}
-
-    while remaining_blocks:
-        # Create a new block chain
-        block_list = [remaining_blocks.pop()]
-
-        # Find sons in remainings blocks linked with a next constraint
-        while True:
-            # Get next block
-            next_label = block_list[-1].get_next()
-            if next_label is None or next_label not in lbl2block:
-                break
-            next_block = lbl2block[next_label]
-
-            # Add the block at the end of the current chain
-            if next_block not in remaining_blocks:
-                break
-            block_list.append(next_block)
-            remaining_blocks.remove(next_block)
-
-        # Check if son is in a known block group
-        if next_label is not None and next_label in known_block_chains:
-            block_list += known_block_chains[next_label]
-            del known_block_chains[next_label]
-
-        known_block_chains[block_list[0].label] = block_list
-
-    out_block_chains = []
-    for label in known_block_chains:
-        chain = BlockChain(symbol_pool, known_block_chains[label])
-        out_block_chains.append(chain)
-    return out_block_chains
-
-
-def get_blockchains_address_interval(blockChains, dst_interval):
-    """Compute the interval used by the pinned @blockChains
-    Check if the placed chains are in the @dst_interval"""
-
-    allocated_interval = interval()
-    for chain in blockChains:
-        if not chain.pinned:
-            continue
-        chain_interval = interval([(chain.offset_min, chain.offset_max - 1)])
-        if chain_interval not in dst_interval:
-            raise ValueError('Chain placed out of destination interval')
-        allocated_interval += chain_interval
-    return allocated_interval
-
-
-def resolve_symbol(blockChains, symbol_pool, dst_interval=None):
-    """Place @blockChains in the @dst_interval"""
-
-    log_asmbloc.info('resolve_symbol')
-    if dst_interval is None:
-        dst_interval = interval([(0, 0xFFFFFFFFFFFFFFFF)])
-
-    forbidden_interval = interval(
-        [(-1, 0xFFFFFFFFFFFFFFFF + 1)]) - dst_interval
-    allocated_interval = get_blockchains_address_interval(blockChains,
-                                                          dst_interval)
-    log_asmbloc.debug('allocated interval: %s', allocated_interval)
-
-    pinned_chains = [chain for chain in blockChains if chain.pinned]
-
-    # Add wedge in forbidden intervals
-    for start, stop in forbidden_interval.intervals:
-        wedge = BlockChainWedge(
-            symbol_pool, offset=start, size=stop + 1 - start)
-        pinned_chains.append(wedge)
-
-    # Try to place bigger blockChains first
-    pinned_chains.sort(key=lambda x: x.offset_min)
-    blockChains.sort(key=lambda x: -x.max_size)
-
-    fixed_chains = list(pinned_chains)
-
-    log_asmbloc.debug("place chains")
-    for chain in blockChains:
-        if chain.pinned:
-            continue
-        fixed = False
-        for i in xrange(1, len(fixed_chains)):
-            prev_chain = fixed_chains[i - 1]
-            next_chain = fixed_chains[i]
-
-            if prev_chain.offset_max + chain.max_size < next_chain.offset_min:
-                new_chains = prev_chain.merge(chain)
-                fixed_chains[i - 1:i] = new_chains
-                fixed = True
-                break
-        if not fixed:
-            raise RuntimeError('Cannot find enough space to place blocks')
-
-    return [chain for chain in fixed_chains if isinstance(chain, BlockChain)]
-
-
-def filter_exprid_label(exprs):
-    """Extract labels from list of ExprId @exprs"""
-    return set(expr.name for expr in exprs if isinstance(expr.name, AsmLabel))
-
-
-def get_block_labels(block):
-    """Extract labels used by @block"""
-    symbols = set()
-    for instr in block.lines:
-        if isinstance(instr, AsmRaw):
-            if isinstance(instr.raw, list):
-                for expr in instr.raw:
-                    symbols.update(m2_expr.get_expr_ids(expr))
-        else:
-            for arg in instr.args:
-                symbols.update(m2_expr.get_expr_ids(arg))
-    labels = filter_exprid_label(symbols)
-    return labels
-
-
-def assemble_block(mnemo, block, symbol_pool, conservative=False):
-    """Assemble a @block using @symbol_pool
-    @conservative: (optional) use original bytes when possible
-    """
-    offset_i = 0
-
-    for instr in block.lines:
-        if isinstance(instr, AsmRaw):
-            if isinstance(instr.raw, list):
-                # Fix special AsmRaw
-                data = ""
-                for expr in instr.raw:
-                    expr_int = fix_expr_val(expr, symbol_pool)
-                    data += pck[expr_int.size](expr_int.arg)
-                instr.data = data
-
-            instr.offset = offset_i
-            offset_i += instr.l
-            continue
-
-        # Assemble an instruction
-        saved_args = list(instr.args)
-        instr.offset = block.label.offset + offset_i
-
-        # Replace instruction's arguments by resolved ones
-        instr.args = instr.resolve_args_with_symbols(symbol_pool)
-
-        if instr.dstflow():
-            instr.fixDstOffset()
-
-        old_l = instr.l
-        cached_candidate, _ = conservative_asm(mnemo, instr, symbol_pool,
-                                               conservative)
-
-        # Restore original arguments
-        instr.args = saved_args
-
-        # We need to update the block size
-        block.size = block.size - old_l + len(cached_candidate)
-        instr.data = cached_candidate
-        instr.l = len(cached_candidate)
-
-        offset_i += instr.l
-
-
-def asmbloc_final(mnemo, blocks, blockChains, symbol_pool, conservative=False):
-    """Resolve and assemble @blockChains using @symbol_pool until fixed point is
-    reached"""
-
-    log_asmbloc.debug("asmbloc_final")
-
-    # Init structures
-    lbl2block = {block.label: block for block in blocks}
-    blocks_using_label = {}
-    for block in blocks:
-        labels = get_block_labels(block)
-        for label in labels:
-            blocks_using_label.setdefault(label, set()).add(block)
-
-    block2chain = {}
-    for chain in blockChains:
-        for block in chain.blocks:
-            block2chain[block] = chain
-
-    # Init worklist
-    blocks_to_rework = set(blocks)
-
-    # Fix and re-assemble blocks until fixed point is reached
-    while True:
-
-        # Propagate pinned blocks into chains
-        modified_labels = set()
-        for chain in blockChains:
-            chain.fix_blocks(modified_labels)
-
-        for label in modified_labels:
-            # Retrive block with modified reference
-            if label in lbl2block:
-                blocks_to_rework.add(lbl2block[label])
-
-            # Enqueue blocks referencing a modified label
-            if label not in blocks_using_label:
-                continue
-            for block in blocks_using_label[label]:
-                blocks_to_rework.add(block)
-
-        # No more work
-        if not blocks_to_rework:
-            break
-
-        while blocks_to_rework:
-            block = blocks_to_rework.pop()
-            assemble_block(mnemo, block, symbol_pool, conservative)
-
-
-def asm_resolve_final(mnemo, blocks, symbol_pool, dst_interval=None):
-    """Resolve and assemble @blocks using @symbol_pool into interval
-    @dst_interval"""
-
-    blocks.sanity_check()
-
-    blocks.guess_blocks_size(mnemo)
-    blockChains = group_constrained_blocks(symbol_pool, blocks)
-    resolved_blockChains = resolve_symbol(
-        blockChains, symbol_pool, dst_interval)
-
-    asmbloc_final(mnemo, blocks, resolved_blockChains, symbol_pool)
-    patches = {}
-    output_interval = interval()
-
-    for block in blocks:
-        offset = block.label.offset
-        for instr in block.lines:
-            if not instr.data:
-                # Empty line
-                continue
-            assert len(instr.data) == instr.l
-            patches[offset] = instr.data
-            instruction_interval = interval([(offset, offset + instr.l - 1)])
-            if not (instruction_interval & output_interval).empty:
-                raise RuntimeError("overlapping bytes %X" % int(offset))
-            instr.offset = offset
-            offset += instr.l
-    return patches
-
-
-class disasmEngine(object):
-
-    """Disassembly engine, taking care of disassembler options and mutli-block
-    strategy.
-
-    Engine options:
-
-    + Object supporting membership test (offset in ..)
-     - dont_dis: stop the current disassembly branch if reached
-     - split_dis: force a basic block end if reached,
-                  with a next constraint on its successor
-     - dont_dis_retcall_funcs: stop disassembly after a call to one
-                               of the given functions
-
-    + On/Off
-     - follow_call: recursively disassemble CALL destinations
-     - dontdis_retcall: stop on CALL return addresses
-     - dont_dis_nulstart_bloc: stop if a block begin with a few \x00
-
-    + Number
-     - lines_wd: maximum block's size (in number of instruction)
-     - blocs_wd: maximum number of distinct disassembled block
-
-    + callback(arch, attrib, pool_bin, cur_bloc, offsets_to_dis,
-               symbol_pool)
-     - dis_bloc_callback: callback after each new disassembled block
-
-    The engine also tracks already handled block, for performance and to avoid
-    infinite cycling.
-    Addresses of disassembled block is in the attribute `job_done`.
-    To force a new disassembly, the targeted offset must first be removed from
-    this structure.
-    """
-
-    def __init__(self, arch, attrib, bin_stream, **kwargs):
-        """Instanciate a new disassembly engine
-        @arch: targeted architecture
-        @attrib: architecture attribute
-        @bin_stream: bytes source
-        @kwargs: (optional) custom options
-        """
-        self.arch = arch
-        self.attrib = attrib
-        self.bin_stream = bin_stream
-        self.symbol_pool = AsmSymbolPool()
-        self.job_done = set()
-
-        # Setup options
-        self.dont_dis = []
-        self.split_dis = []
-        self.follow_call = False
-        self.dontdis_retcall = False
-        self.lines_wd = None
-        self.blocs_wd = None
-        self.dis_bloc_callback = None
-        self.dont_dis_nulstart_bloc = False
-        self.dont_dis_retcall_funcs = set()
-
-        # Override options if needed
-        self.__dict__.update(kwargs)
-
-    def _dis_bloc(self, offset):
-        """Disassemble the block at offset @offset
-        Return the created AsmBlock and future offsets to disassemble
-        """
-
-        lines_cpt = 0
-        in_delayslot = False
-        delayslot_count = self.arch.delayslot
-        offsets_to_dis = set()
-        add_next_offset = False
-        label = self.symbol_pool.getby_offset_create(offset)
-        cur_block = AsmBlock(label)
-        log_asmbloc.debug("dis at %X", int(offset))
-        while not in_delayslot or delayslot_count > 0:
-            if in_delayslot:
-                delayslot_count -= 1
-
-            if offset in self.dont_dis:
-                if not cur_block.lines:
-                    self.job_done.add(offset)
-                    # Block is empty -> bad block
-                    cur_block = AsmBlockBad(label, errno=2)
-                else:
-                    # Block is not empty, stop the desassembly pass and add a
-                    # constraint to the next block
-                    cur_block.add_cst(offset, AsmConstraint.c_next,
-                                      self.symbol_pool)
-                break
-
-            if lines_cpt > 0 and offset in self.split_dis:
-                cur_block.add_cst(offset, AsmConstraint.c_next,
-                                  self.symbol_pool)
-                offsets_to_dis.add(offset)
-                break
-
-            lines_cpt += 1
-            if self.lines_wd is not None and lines_cpt > self.lines_wd:
-                log_asmbloc.debug("lines watchdog reached at %X", int(offset))
-                break
-
-            if offset in self.job_done:
-                cur_block.add_cst(offset, AsmConstraint.c_next,
-                                  self.symbol_pool)
-                break
-
-            off_i = offset
-            try:
-                instr = self.arch.dis(self.bin_stream, self.attrib, offset)
-            except (Disasm_Exception, IOError), e:
-                log_asmbloc.warning(e)
-                instr = None
-
-            if instr is None:
-                log_asmbloc.warning("cannot disasm at %X", int(off_i))
-                if not cur_block.lines:
-                    self.job_done.add(offset)
-                    # Block is empty -> bad block
-                    cur_block = AsmBlockBad(label, errno=0)
-                else:
-                    # Block is not empty, stop the desassembly pass and add a
-                    # constraint to the next block
-                    cur_block.add_cst(off_i, AsmConstraint.c_next,
-                                      self.symbol_pool)
-                break
-
-            # XXX TODO nul start block option
-            if self.dont_dis_nulstart_bloc and instr.b.count('\x00') == instr.l:
-                log_asmbloc.warning("reach nul instr at %X", int(off_i))
-                if not cur_block.lines:
-                    # Block is empty -> bad block
-                    cur_block = AsmBlockBad(label, errno=1)
-                else:
-                    # Block is not empty, stop the desassembly pass and add a
-                    # constraint to the next block
-                    cur_block.add_cst(off_i, AsmConstraint.c_next,
-                                      self.symbol_pool)
-                break
-
-            # special case: flow graph modificator in delayslot
-            if in_delayslot and instr and (instr.splitflow() or instr.breakflow()):
-                add_next_offset = True
-                break
-
-            self.job_done.add(offset)
-            log_asmbloc.debug("dis at %X", int(offset))
-
-            offset += instr.l
-            log_asmbloc.debug(instr)
-            log_asmbloc.debug(instr.args)
-
-            cur_block.addline(instr)
-            if not instr.breakflow():
-                continue
-            # test split
-            if instr.splitflow() and not (instr.is_subcall() and self.dontdis_retcall):
-                add_next_offset = True
-                pass
-            if instr.dstflow():
-                instr.dstflow2label(self.symbol_pool)
-                dst = instr.getdstflow(self.symbol_pool)
-                dstn = []
-                for d in dst:
-                    if isinstance(d, m2_expr.ExprId) and \
-                            isinstance(d.name, AsmLabel):
-                        dstn.append(d.name)
-                        if d.name.offset in self.dont_dis_retcall_funcs:
-                            add_next_offset = False
-                dst = dstn
-                if (not instr.is_subcall()) or self.follow_call:
-                    cur_block.bto.update(
-                        [AsmConstraint(x, AsmConstraint.c_to) for x in dst])
-
-            # get in delayslot mode
-            in_delayslot = True
-            delayslot_count = instr.delayslot
-
-        for c in cur_block.bto:
-            offsets_to_dis.add(c.label.offset)
-
-        if add_next_offset:
-            cur_block.add_cst(offset, AsmConstraint.c_next, self.symbol_pool)
-            offsets_to_dis.add(offset)
-
-        # Fix multiple constraints
-        cur_block.fix_constraints()
-
-        if self.dis_bloc_callback is not None:
-            self.dis_bloc_callback(mn=self.arch, attrib=self.attrib,
-                                   pool_bin=self.bin_stream, cur_bloc=cur_block,
-                                   offsets_to_dis=offsets_to_dis,
-                                   symbol_pool=self.symbol_pool)
-        return cur_block, offsets_to_dis
-
-    def dis_bloc(self, offset):
-        """Disassemble the block at offset @offset and return the created
-        AsmBlock
-        @offset: targeted offset to disassemble
-        """
-        current_block, _ = self._dis_bloc(offset)
-        return current_block
-
-    def dis_multibloc(self, offset, blocs=None):
-        """Disassemble every block reachable from @offset regarding
-        specific disasmEngine conditions
-        Return an AsmCFG instance containing disassembled blocks
-        @offset: starting offset
-        @blocs: (optional) AsmCFG instance of already disassembled blocks to
-                merge with
-        """
-        log_asmbloc.info("dis bloc all")
-        if blocs is None:
-            blocs = AsmCFG()
-        todo = [offset]
-
-        bloc_cpt = 0
-        while len(todo):
-            bloc_cpt += 1
-            if self.blocs_wd is not None and bloc_cpt > self.blocs_wd:
-                log_asmbloc.debug("blocs watchdog reached at %X", int(offset))
-                break
+from miasm2.core.asmblock import *
 
-            target_offset = int(todo.pop(0))
-            if (target_offset is None or
-                    target_offset in self.job_done):
-                continue
-            cur_block, nexts = self._dis_bloc(target_offset)
-            todo += nexts
-            blocs.add_node(cur_block)
+warnings.warn('DEPRECATION WARNING: use "asmblock" sub-module instead of "asmbloc"')
 
-        blocs.apply_splitting(self.symbol_pool,
-                              dis_block_callback=self.dis_bloc_callback,
-                              mn=self.arch, attrib=self.attrib,
-                              pool_bin=self.bin_stream)
-        return blocs
+log_asmbloc = log_asmblock
diff --git a/miasm2/core/asmblock.py b/miasm2/core/asmblock.py
new file mode 100644
index 00000000..eb4e3ef8
--- /dev/null
+++ b/miasm2/core/asmblock.py
@@ -0,0 +1,1555 @@
+#-*- coding:utf-8 -*-
+
+import logging
+import inspect
+import warnings
+from collections import namedtuple
+
+import miasm2.expression.expression as m2_expr
+from miasm2.expression.simplifications import expr_simp
+from miasm2.expression.modint import moduint, modint
+from miasm2.core.utils import Disasm_Exception, pck
+from miasm2.core.graph import DiGraph, DiGraphSimplifier, MatchGraphJoker
+from miasm2.core.interval import interval
+
+
+log_asmblock = logging.getLogger("asmblock")
+console_handler = logging.StreamHandler()
+console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s"))
+log_asmblock.addHandler(console_handler)
+log_asmblock.setLevel(logging.WARNING)
+
+
+def is_int(a):
+    return isinstance(a, int) or isinstance(a, long) or \
+        isinstance(a, moduint) or isinstance(a, modint)
+
+
+def expr_is_label(e):
+    return isinstance(e, m2_expr.ExprId) and isinstance(e.name, AsmLabel)
+
+
+def expr_is_int_or_label(e):
+    return isinstance(e, m2_expr.ExprInt) or \
+        (isinstance(e, m2_expr.ExprId) and isinstance(e.name, AsmLabel))
+
+
+class AsmLabel(object):
+
+    "Stand for an assembly label"
+
+    def __init__(self, name="", offset=None):
+        self.fixedblocs = False
+        if is_int(name):
+            name = "loc_%.16X" % (int(name) & 0xFFFFFFFFFFFFFFFF)
+        self.name = name
+        self.attrib = None
+        if offset is None:
+            self.offset = offset
+        else:
+            self.offset = int(offset)
+
+    def __str__(self):
+        if isinstance(self.offset, (int, long)):
+            return "%s:0x%08x" % (self.name, self.offset)
+        else:
+            return "%s:%s" % (self.name, str(self.offset))
+
+    def __repr__(self):
+        rep = '<%s ' % self.__class__.__name__
+        if self.name:
+            rep += repr(self.name) + ' '
+        rep += '>'
+        return rep
+
+
+class asm_label(AsmLabel):
+
+    def __init__(self, name="", offset=None):
+        warnings.warn('DEPRECATION WARNING: use "AsmLabel" instead of "asm_label"')
+        super(asm_label, self).__init__(name, offset)
+
+class AsmRaw(object):
+
+    def __init__(self, raw=""):
+        self.raw = raw
+
+    def __str__(self):
+        return repr(self.raw)
+
+
+class asm_raw(AsmRaw):
+
+    def __init__(self, raw=""):
+        warnings.warn('DEPRECATION WARNING: use "AsmRaw" instead of "asm_raw"')
+        super(asm_label, self).__init__(raw)
+
+
+class AsmConstraint(object):
+    c_to = "c_to"
+    c_next = "c_next"
+
+    def __init__(self, label, c_t=c_to):
+        # Sanity check
+        assert isinstance(label, AsmLabel)
+
+        self.label = label
+        self.c_t = c_t
+
+    def __str__(self):
+        return "%s:%s" % (str(self.c_t), str(self.label))
+
+
+class asm_constraint(AsmConstraint):
+
+    def __init__(self, label, c_t=AsmConstraint.c_to):
+        warnings.warn('DEPRECATION WARNING: use "AsmConstraint" instead of "asm_constraint"')
+        super(asm_constraint, self).__init__(label, c_t)
+
+
+class AsmConstraintNext(AsmConstraint):
+
+    def __init__(self, label):
+        super(AsmConstraintNext, self).__init__(
+            label, c_t=AsmConstraint.c_next)
+
+
+class asm_constraint_next(AsmConstraint):
+
+    def __init__(self, label):
+        warnings.warn('DEPRECATION WARNING: use "AsmConstraintNext" instead of "asm_constraint_next"')
+        super(asm_constraint_next, self).__init__(label)
+
+
+class AsmConstraintTo(AsmConstraint):
+
+    def __init__(self, label):
+        super(AsmConstraintTo, self).__init__(
+            label, c_t=AsmConstraint.c_to)
+
+class asm_constraint_to(AsmConstraint):
+
+    def __init__(self, label):
+        warnings.warn('DEPRECATION WARNING: use "AsmConstraintTo" instead of "asm_constraint_to"')
+        super(asm_constraint_to, self).__init__(label)
+
+
+class AsmBlock(object):
+
+    def __init__(self, label, alignment=1):
+        assert isinstance(label, AsmLabel)
+        self.bto = set()
+        self.lines = []
+        self.label = label
+        self.alignment = alignment
+
+    def __str__(self):
+        out = []
+        out.append(str(self.label))
+        for l in self.lines:
+            out.append(str(l))
+        if self.bto:
+            lbls = ["->"]
+            for l in self.bto:
+                if l is None:
+                    lbls.append("Unknown? ")
+                else:
+                    lbls.append(str(l) + " ")
+            lbls = '\t'.join(lbls)
+            out.append(lbls)
+        return '\n'.join(out)
+
+    def addline(self, l):
+        self.lines.append(l)
+
+    def addto(self, c):
+        assert isinstance(self.bto, set)
+        self.bto.add(c)
+
+    def split(self, offset, l):
+        log_asmblock.debug('split at %x', offset)
+        i = -1
+        offsets = [x.offset for x in self.lines]
+        if not l.offset in offsets:
+            log_asmblock.warning(
+                'cannot split bloc at %X ' % offset +
+                'middle instruction? default middle')
+            offsets.sort()
+            return None
+        new_bloc = AsmBlock(l)
+        i = offsets.index(offset)
+
+        self.lines, new_bloc.lines = self.lines[:i], self.lines[i:]
+        flow_mod_instr = self.get_flow_instr()
+        log_asmblock.debug('flow mod %r', flow_mod_instr)
+        c = AsmConstraint(l, AsmConstraint.c_next)
+        # move dst if flowgraph modifier was in original bloc
+        # (usecase: split delayslot bloc)
+        if flow_mod_instr:
+            for xx in self.bto:
+                log_asmblock.debug('lbl %s', xx)
+            c_next = set(
+                [x for x in self.bto if x.c_t == AsmConstraint.c_next])
+            c_to = [x for x in self.bto if x.c_t != AsmConstraint.c_next]
+            self.bto = set([c] + c_to)
+            new_bloc.bto = c_next
+        else:
+            new_bloc.bto = self.bto
+            self.bto = set([c])
+        return new_bloc
+
+    def get_range(self):
+        """Returns the offset hull of an AsmBlock"""
+        if len(self.lines):
+            return (self.lines[0].offset,
+                    self.lines[-1].offset + self.lines[-1].l)
+        else:
+            return 0, 0
+
+    def get_offsets(self):
+        return [x.offset for x in self.lines]
+
+    def add_cst(self, offset, c_t, symbol_pool):
+        if isinstance(offset, (int, long)):
+            l = symbol_pool.getby_offset_create(offset)
+        elif isinstance(offset, str):
+            l = symbol_pool.getby_name_create(offset)
+        elif isinstance(offset, AsmLabel):
+            l = offset
+        else:
+            raise ValueError('unknown offset type %r' % offset)
+        c = AsmConstraint(l, c_t)
+        self.bto.add(c)
+
+    def get_flow_instr(self):
+        if not self.lines:
+            return None
+        for i in xrange(-1, -1 - self.lines[0].delayslot - 1, -1):
+            if not 0 <= i < len(self.lines):
+                return None
+            l = self.lines[i]
+            if l.splitflow() or l.breakflow():
+                raise NotImplementedError('not fully functional')
+
+    def get_subcall_instr(self):
+        if not self.lines:
+            return None
+        delayslot = self.lines[0].delayslot
+        end_index = len(self.lines) - 1
+        ds_max_index = max(end_index - delayslot, 0)
+        for i in xrange(end_index, ds_max_index - 1, -1):
+            l = self.lines[i]
+            if l.is_subcall():
+                return l
+        return None
+
+    def get_next(self):
+        for x in self.bto:
+            if x.c_t == AsmConstraint.c_next:
+                return x.label
+        return None
+
+    @staticmethod
+    def _filter_constraint(constraints):
+        """Sort and filter @constraints for AsmBlock.bto
+        @constraints: non-empty set of AsmConstraint instance
+
+        Always the same type -> one of the constraint
+        c_next and c_to -> c_next
+        """
+        # Only one constraint
+        if len(constraints) == 1:
+            return next(iter(constraints))
+
+        # Constraint type -> set of corresponding constraint
+        cbytype = {}
+        for cons in constraints:
+            cbytype.setdefault(cons.c_t, set()).add(cons)
+
+        # Only one type -> any constraint is OK
+        if len(cbytype) == 1:
+            return next(iter(constraints))
+
+        # At least 2 types -> types = {c_next, c_to}
+        # c_to is included in c_next
+        return next(iter(cbytype[AsmConstraint.c_next]))
+
+    def fix_constraints(self):
+        """Fix next block constraints"""
+        # destination -> associated constraints
+        dests = {}
+        for constraint in self.bto:
+            dests.setdefault(constraint.label, set()).add(constraint)
+
+        self.bto = set(self._filter_constraint(constraints)
+                       for constraints in dests.itervalues())
+
+
+class asm_bloc(object):
+
+    def __init__(self, label, alignment=1):
+        warnings.warn('DEPRECATION WARNING: use "AsmBlock" instead of "asm_bloc"')
+        super(asm_bloc, self).__init__(label, alignment)
+
+
+class AsmBlockBad(AsmBlock):
+
+    """Stand for a *bad* ASM block (malformed, unreachable,
+    not disassembled, ...)"""
+
+    ERROR_TYPES = {-1: "Unknown error",
+                   0: "Unable to disassemble",
+                   1: "Null starting block",
+                   2: "Address forbidden by dont_dis",
+                   }
+
+    def __init__(self, label=None, alignment=1, errno=-1, *args, **kwargs):
+        """Instanciate an AsmBlock_bad.
+        @label, @alignement: same as AsmBlock.__init__
+        @errno: (optional) specify a error type associated with the block
+        """
+        super(AsmBlockBad, self).__init__(label, alignment, *args, **kwargs)
+        self._errno = errno
+
+    def __str__(self):
+        error_txt = self.ERROR_TYPES.get(self._errno, self._errno)
+        return "\n".join([str(self.label),
+                          "\tBad block: %s" % error_txt])
+
+    def addline(self, *args, **kwargs):
+        raise RuntimeError("An AsmBlockBad cannot have line")
+
+    def addto(self, *args, **kwargs):
+        raise RuntimeError("An AsmBlockBad cannot have bto")
+
+    def split(self, *args, **kwargs):
+        raise RuntimeError("An AsmBlockBad cannot be splitted")
+
+
+class asm_block_bad(AsmBlockBad):
+
+    def __init__(self, label=None, alignment=1, errno=-1, *args, **kwargs):
+        warnings.warn('DEPRECATION WARNING: use "AsmBlockBad" instead of "asm_block_bad"')
+        super(asm_block_bad, self).__init__(label, alignment, *args, **kwargs)
+
+
+class AsmSymbolPool(object):
+
+    def __init__(self):
+        self._labels = []
+        self._name2label = {}
+        self._offset2label = {}
+        self._label_num = 0
+
+    def add_label(self, name, offset=None):
+        """
+        Create and add a label to the symbol_pool
+        @name: label's name
+        @offset: (optional) label's offset
+        """
+        label = AsmLabel(name, offset)
+
+        # Test for collisions
+        if (label.offset in self._offset2label and
+                label != self._offset2label[label.offset]):
+            raise ValueError('symbol %s has same offset as %s' %
+                             (label, self._offset2label[label.offset]))
+        if (label.name in self._name2label and
+                label != self._name2label[label.name]):
+            raise ValueError('symbol %s has same name as %s' %
+                             (label, self._name2label[label.name]))
+
+        self._labels.append(label)
+        if label.offset is not None:
+            self._offset2label[label.offset] = label
+        if label.name != "":
+            self._name2label[label.name] = label
+        return label
+
+    def remove_label(self, label):
+        """
+        Delete a @label
+        """
+        self._name2label.pop(label.name, None)
+        self._offset2label.pop(label.offset, None)
+        if label in self._labels:
+            self._labels.remove(label)
+
+    def del_label_offset(self, label):
+        """Unpin the @label from its offset"""
+        self._offset2label.pop(label.offset, None)
+        label.offset = None
+
+    def getby_offset(self, offset):
+        """Retrieve label using its @offset"""
+        return self._offset2label.get(offset, None)
+
+    def getby_name(self, name):
+        """Retrieve label using its @name"""
+        return self._name2label.get(name, None)
+
+    def getby_name_create(self, name):
+        """Get a label from its @name, create it if it doesn't exist"""
+        label = self.getby_name(name)
+        if label is None:
+            label = self.add_label(name)
+        return label
+
+    def getby_offset_create(self, offset):
+        """Get a label from its @offset, create it if it doesn't exist"""
+        label = self.getby_offset(offset)
+        if label is None:
+            label = self.add_label(offset, offset)
+        return label
+
+    def rename_label(self, label, newname):
+        """Rename the @label name to @newname"""
+        if newname in self._name2label:
+            raise ValueError('Symbol already known')
+        self._name2label.pop(label.name, None)
+        label.name = newname
+        self._name2label[label.name] = label
+
+    def set_offset(self, label, offset):
+        """Pin the @label from at @offset
+        Note that there is a special case when the offset is a list
+        it happens when offsets are recomputed in resolve_symbol*
+        """
+        if label is None:
+            raise ValueError('label should not be None')
+        if not label.name in self._name2label:
+            raise ValueError('label %s not in symbol pool' % label)
+        if offset is not None and offset in self._offset2label:
+            raise ValueError('Conflict in label %s' % label)
+        self._offset2label.pop(label.offset, None)
+        label.offset = offset
+        if is_int(label.offset):
+            self._offset2label[label.offset] = label
+
+    @property
+    def items(self):
+        """Return all labels"""
+        return self._labels
+
+    def __str__(self):
+        return reduce(lambda x, y: x + str(y) + '\n', self._labels, "")
+
+    def __getitem__(self, item):
+        if item in self._name2label:
+            return self._name2label[item]
+        if item in self._offset2label:
+            return self._offset2label[item]
+        raise KeyError('unknown symbol %r' % item)
+
+    def __contains__(self, item):
+        return item in self._name2label or item in self._offset2label
+
+    def merge(self, symbol_pool):
+        """Merge with another @symbol_pool"""
+        self._labels += symbol_pool._labels
+        self._name2label.update(symbol_pool._name2label)
+        self._offset2label.update(symbol_pool._offset2label)
+
+    def gen_label(self):
+        """Generate a new unpinned label"""
+        label = self.add_label("lbl_gen_%.8X" % (self._label_num))
+        self._label_num += 1
+        return label
+
+
+class asm_symbol_pool(AsmSymbolPool):
+
+    def __init__(self):
+        warnings.warn('DEPRECATION WARNING: use "AsmSymbolPool" instead of "asm_symbol_pool"')
+        super(asm_symbol_pool, self).__init__()
+
+
+class AsmCFG(DiGraph):
+
+    """Directed graph standing for a ASM Control Flow Graph with:
+     - nodes: AsmBlock
+     - edges: constraints between blocks, synchronized with AsmBlock's "bto"
+
+    Specialized the .dot export and force the relation between block to be uniq,
+    and associated with a constraint.
+
+    Offer helpers on AsmCFG management, such as research by label, sanity
+    checking and mnemonic size guessing.
+    """
+
+    # Internal structure for pending management
+    AsmCFGPending = namedtuple("AsmCFGPending",
+                               ["waiter", "constraint"])
+
+    def __init__(self, *args, **kwargs):
+        super(AsmCFG, self).__init__(*args, **kwargs)
+        # Edges -> constraint
+        self.edges2constraint = {}
+        # Expected AsmLabel -> set( (src, dst), constraint )
+        self._pendings = {}
+        # Label2block built on the fly
+        self._label2block = {}
+
+    # Compatibility with old list API
+    def append(self, *args, **kwargs):
+        raise DeprecationWarning("AsmCFG is a graph, use add_node")
+
+    def remove(self, *args, **kwargs):
+        raise DeprecationWarning("AsmCFG is a graph, use del_node")
+
+    def __getitem__(self, *args, **kwargs):
+        raise DeprecationWarning("Order of AsmCFG elements is not reliable")
+
+    def __iter__(self):
+        """Iterator on AsmBlock composing the current graph"""
+        return iter(self._nodes)
+
+    def __len__(self):
+        """Return the number of blocks in AsmCFG"""
+        return len(self._nodes)
+
+    # Manage graph with associated constraints
+    def add_edge(self, src, dst, constraint):
+        """Add an edge to the graph
+        @src: AsmBlock instance, source
+        @dst: AsmBlock instance, destination
+        @constraint: constraint associated to this edge
+        """
+        # Sanity check
+        assert (src, dst) not in self.edges2constraint
+
+        # Add the edge to src.bto if needed
+        if dst.label not in [cons.label for cons in src.bto]:
+            src.bto.add(AsmConstraint(dst.label, constraint))
+
+        # Add edge
+        self.edges2constraint[(src, dst)] = constraint
+        super(AsmCFG, self).add_edge(src, dst)
+
+    def add_uniq_edge(self, src, dst, constraint):
+        """Add an edge from @src to @dst if it doesn't already exist"""
+        if (src not in self._nodes_succ or
+                dst not in self._nodes_succ[src]):
+            self.add_edge(src, dst, constraint)
+
+    def del_edge(self, src, dst):
+        """Delete the edge @src->@dst and its associated constraint"""
+        # Delete from src.bto
+        to_remove = [cons for cons in src.bto if cons.label == dst.label]
+        if to_remove:
+            assert len(to_remove) == 1
+            src.bto.remove(to_remove[0])
+
+        # Del edge
+        del self.edges2constraint[(src, dst)]
+        super(AsmCFG, self).del_edge(src, dst)
+
+    def add_node(self, block):
+        """Add the block @block to the current instance, if it is not already in
+        @block: AsmBlock instance
+
+        Edges will be created for @block.bto, if destinations are already in
+        this instance. If not, they will be resolved when adding these
+        aforementionned destinations.
+        `self.pendings` indicates which blocks are not yet resolved.
+        """
+        status = super(AsmCFG, self).add_node(block)
+        if not status:
+            return status
+
+        # Update waiters
+        if block.label in self._pendings:
+            for bblpend in self._pendings[block.label]:
+                self.add_edge(bblpend.waiter, block, bblpend.constraint)
+            del self._pendings[block.label]
+
+        # Synchronize edges with block destinations
+        self._label2block[block.label] = block
+        for constraint in block.bto:
+            dst = self._label2block.get(constraint.label,
+                                        None)
+            if dst is None:
+                # Block is yet unknown, add it to pendings
+                to_add = self.AsmCFGPending(waiter=block,
+                                            constraint=constraint.c_t)
+                self._pendings.setdefault(constraint.label,
+                                          set()).add(to_add)
+            else:
+                # Block is already in known nodes
+                self.add_edge(block, dst, constraint.c_t)
+
+        return status
+
+    def del_node(self, block):
+        super(AsmCFG, self).del_node(block)
+        del self._label2block[block.label]
+
+    def merge(self, graph):
+        """Merge with @graph, taking in account constraints"""
+        # -> add_edge(x, y, constraint)
+        for node in graph._nodes:
+            self.add_node(node)
+        for edge in graph._edges:
+            # Use "_uniq_" beacause the edge can already exist due to add_node
+            self.add_uniq_edge(*edge, constraint=graph.edges2constraint[edge])
+
+    def node2lines(self, node):
+        yield self.DotCellDescription(text=str(node.label.name),
+                                      attr={'align': 'center',
+                                            'colspan': 2,
+                                            'bgcolor': 'grey'})
+
+        if isinstance(node, AsmBlockBad):
+            yield [self.DotCellDescription(
+                text=node.ERROR_TYPES.get(node._errno,
+                                          node._errno),
+                                           attr={})]
+            raise StopIteration
+        for line in node.lines:
+            if self._dot_offset:
+                yield [self.DotCellDescription(text="%.8X" % line.offset,
+                                               attr={}),
+                       self.DotCellDescription(text=str(line), attr={})]
+            else:
+                yield self.DotCellDescription(text=str(line), attr={})
+
+    def node_attr(self, node):
+        if isinstance(node, AsmBlockBad):
+            return {'style': 'filled', 'fillcolor': 'red'}
+        return {}
+
+    def edge_attr(self, src, dst):
+        cst = self.edges2constraint.get((src, dst), None)
+        edge_color = "blue"
+
+        if len(self.successors(src)) > 1:
+            if cst == AsmConstraint.c_next:
+                edge_color = "red"
+            else:
+                edge_color = "limegreen"
+
+        return {"color": edge_color}
+
+    def dot(self, offset=False):
+        """
+        @offset: (optional) if set, add the corresponding offsets in each node
+        """
+        self._dot_offset = offset
+        return super(AsmCFG, self).dot()
+
+    # Helpers
+    @property
+    def pendings(self):
+        """Dictionary of label -> set(AsmCFGPending instance) indicating
+        which label are missing in the current instance.
+        A label is missing if a block which is already in nodes has constraints
+        with him (thanks to its .bto) and the corresponding block is not yet in
+        nodes
+        """
+        return self._pendings
+
+    def _build_label2block(self):
+        self._label2block = {block.label: block
+                             for block in self._nodes}
+
+    def label2block(self, label):
+        """Return the block corresponding to label @label
+        @label: AsmLabel instance or ExprId(AsmLabel) instance"""
+        return self._label2block[label]
+
+    def rebuild_edges(self):
+        """Consider blocks '.bto' and rebuild edges according to them, ie:
+        - update constraint type
+        - add missing edge
+        - remove no more used edge
+
+        This method should be called if a block's '.bto' in nodes have been
+        modified without notifying this instance to resynchronize edges.
+        """
+        self._build_label2block()
+        for block in self._nodes:
+            edges = []
+            # Rebuild edges from bto
+            for constraint in block.bto:
+                dst = self._label2block.get(constraint.label,
+                                            None)
+                if dst is None:
+                    # Missing destination, add to pendings
+                    self._pendings.setdefault(constraint.label,
+                                              set()).add(self.AsmCFGPending(block,
+                                                                            constraint.c_t))
+                    continue
+                edge = (block, dst)
+                edges.append(edge)
+                if edge in self._edges:
+                    # Already known edge, constraint may have changed
+                    self.edges2constraint[edge] = constraint.c_t
+                else:
+                    # An edge is missing
+                    self.add_edge(edge[0], edge[1], constraint.c_t)
+
+            # Remove useless edges
+            for succ in self.successors(block):
+                edge = (block, succ)
+                if edge not in edges:
+                    self.del_edge(*edge)
+
+    def get_bad_blocks(self):
+        """Iterator on AsmBlockBad elements"""
+        # A bad asm block is always a leaf
+        for block in self.leaves():
+            if isinstance(block, AsmBlockBad):
+                yield block
+
+    def get_bad_blocks_predecessors(self, strict=False):
+        """Iterator on block with an AsmBlockBad destination
+        @strict: (optional) if set, return block with only bad
+        successors
+        """
+        # Avoid returning the same block
+        done = set()
+        for badblock in self.get_bad_blocks():
+            for predecessor in self.predecessors_iter(badblock):
+                if predecessor not in done:
+                    if (strict and
+                        not all(isinstance(block, AsmBlockBad)
+                                for block in self.successors_iter(predecessor))):
+                        continue
+                    yield predecessor
+                    done.add(predecessor)
+
+    def sanity_check(self):
+        """Do sanity checks on blocks' constraints:
+        * no pendings
+        * no multiple next constraint to same block
+        * no next constraint to self
+        """
+
+        if len(self._pendings) != 0:
+            raise RuntimeError("Some blocks are missing: %s" % map(str,
+                                                                   self._pendings.keys()))
+
+        next_edges = {edge: constraint
+                      for edge, constraint in self.edges2constraint.iteritems()
+                      if constraint == AsmConstraint.c_next}
+
+        for block in self._nodes:
+            # No next constraint to self
+            if (block, block) in next_edges:
+                raise RuntimeError('Bad constraint: self in next')
+
+            # No multiple next constraint to same block
+            pred_next = list(pblock
+                             for (pblock, dblock) in next_edges
+                             if dblock == block)
+
+            if len(pred_next) > 1:
+                raise RuntimeError("Too many next constraints for bloc %r"
+                                   "(%s)" % (block.label,
+                                             map(lambda x: x.label, pred_next)))
+
+    def guess_blocks_size(self, mnemo):
+        """Asm and compute max block size
+        Add a 'size' and 'max_size' attribute on each block
+        @mnemo: metamn instance"""
+        for block in self._nodes:
+            size = 0
+            for instr in block.lines:
+                if isinstance(instr, AsmRaw):
+                    # for special AsmRaw, only extract len
+                    if isinstance(instr.raw, list):
+                        data = None
+                        if len(instr.raw) == 0:
+                            l = 0
+                        else:
+                            l = instr.raw[0].size / 8 * len(instr.raw)
+                    elif isinstance(instr.raw, str):
+                        data = instr.raw
+                        l = len(data)
+                    else:
+                        raise NotImplementedError('asm raw')
+                else:
+                    # Assemble the instruction to retrieve its len.
+                    # If the instruction uses symbol it will fail
+                    # In this case, the max_instruction_len is used
+                    try:
+                        candidates = mnemo.asm(instr)
+                        l = len(candidates[-1])
+                    except:
+                        l = mnemo.max_instruction_len
+                    data = None
+                instr.data = data
+                instr.l = l
+                size += l
+
+            block.size = size
+            block.max_size = size
+            log_asmblock.info("size: %d max: %d", block.size, block.max_size)
+
+    def apply_splitting(self, symbol_pool, dis_block_callback=None, **kwargs):
+        """Consider @self' bto destinations and split block in @self if one of
+        these destinations jumps in the middle of this block.
+        In order to work, they must be only one block in @self per label in
+        @symbol_pool (which is true if @self come from the same disasmEngine).
+
+        @symbol_pool: AsmSymbolPool instance associated with @self'labels
+        @dis_block_callback: (optional) if set, this callback will be called on
+        new block destinations
+        @kwargs: (optional) named arguments to pass to dis_block_callback
+        """
+        # Get all possible destinations not yet resolved, with a resolved
+        # offset
+        block_dst = [label.offset
+                     for label in self.pendings
+                     if label.offset is not None]
+
+        todo = self.nodes().copy()
+        rebuild_needed = False
+
+        while todo:
+            # Find a block with a destination inside another one
+            cur_block = todo.pop()
+            range_start, range_stop = cur_block.get_range()
+
+            for off in block_dst:
+                if not (off > range_start and off < range_stop):
+                    continue
+
+                # `cur_block` must be splitted at offset `off`
+                label = symbol_pool.getby_offset_create(off)
+                new_b = cur_block.split(off, label)
+                log_asmblock.debug("Split block %x", off)
+                if new_b is None:
+                    log_asmblock.error("Cannot split %x!!", off)
+                    continue
+
+                # Remove pending from cur_block
+                # Links from new_b will be generated in rebuild_edges
+                for dst in new_b.bto:
+                    if dst.label not in self.pendings:
+                        continue
+                    self.pendings[dst.label] = set(pending for pending in self.pendings[dst.label]
+                                                   if pending.waiter != cur_block)
+
+                # The new block destinations may need to be disassembled
+                if dis_block_callback:
+                    offsets_to_dis = set(constraint.label.offset
+                                         for constraint in new_b.bto)
+                    dis_block_callback(cur_bloc=new_b,
+                                       offsets_to_dis=offsets_to_dis,
+                                       symbol_pool=symbol_pool, **kwargs)
+
+                # Update structure
+                rebuild_needed = True
+                self.add_node(new_b)
+
+                # The new block must be considered
+                todo.add(new_b)
+                range_start, range_stop = cur_block.get_range()
+
+        # Rebuild edges to match new blocks'bto
+        if rebuild_needed:
+            self.rebuild_edges()
+
+    def __str__(self):
+        out = []
+        for node in self.nodes():
+            out.append(str(node))
+        for nodeA, nodeB in self.edges():
+            out.append("%s -> %s" % (nodeA.label, nodeB.label))
+        return '\n'.join(out)
+
+    def __repr__(self):
+        return "<%s %s>" % (self.__class__.__name__, hex(id(self)))
+
+# Out of _merge_blocks to be computed only once
+_acceptable_block = lambda block: (not isinstance(block, AsmBlockBad) and
+                                   len(block.lines) > 0)
+_parent = MatchGraphJoker(restrict_in=False, filt=_acceptable_block)
+_son = MatchGraphJoker(restrict_out=False, filt=_acceptable_block)
+_expgraph = _parent >> _son
+
+
+def _merge_blocks(dg, graph):
+    """Graph simplification merging AsmBlock with one and only one son with this
+    son if this son has one and only one parent"""
+
+    # Blocks to ignore, because they have been removed from the graph
+    to_ignore = set()
+
+    for match in _expgraph.match(graph):
+
+        # Get matching blocks
+        block, succ = match[_parent], match[_son]
+
+        # Ignore already deleted blocks
+        if (block in to_ignore or
+            succ in to_ignore):
+            continue
+
+        # Remove block last instruction if needed
+        last_instr = block.lines[-1]
+        if last_instr.delayslot > 0:
+            # TODO: delayslot
+            raise RuntimeError("Not implemented yet")
+
+        if last_instr.is_subcall():
+            continue
+        if last_instr.breakflow() and last_instr.dstflow():
+            block.lines.pop()
+
+        # Merge block
+        block.lines += succ.lines
+        for nextb in graph.successors_iter(succ):
+            graph.add_edge(block, nextb, graph.edges2constraint[(succ, nextb)])
+
+        graph.del_node(succ)
+        to_ignore.add(succ)
+
+
+bbl_simplifier = DiGraphSimplifier()
+bbl_simplifier.enable_passes([_merge_blocks])
+
+
+def conservative_asm(mnemo, instr, symbols, conservative):
+    """
+    Asm instruction;
+    Try to keep original instruction bytes if it exists
+    """
+    candidates = mnemo.asm(instr, symbols)
+    if not candidates:
+        raise ValueError('cannot asm:%s' % str(instr))
+    if not hasattr(instr, "b"):
+        return candidates[0], candidates
+    if instr.b in candidates:
+        return instr.b, candidates
+    if conservative:
+        for c in candidates:
+            if len(c) == len(instr.b):
+                return c, candidates
+    return candidates[0], candidates
+
+
+def fix_expr_val(expr, symbols):
+    """Resolve an expression @expr using @symbols"""
+    def expr_calc(e):
+        if isinstance(e, m2_expr.ExprId):
+            s = symbols._name2label[e.name]
+            e = m2_expr.ExprInt(s.offset, e.size)
+        return e
+    result = expr.visit(expr_calc)
+    result = expr_simp(result)
+    if not isinstance(result, m2_expr.ExprInt):
+        raise RuntimeError('Cannot resolve symbol %s' % expr)
+    return result
+
+
+def fix_label_offset(symbol_pool, label, offset, modified):
+    """Fix the @label offset to @offset. If the @offset has changed, add @label
+    to @modified
+    @symbol_pool: current symbol_pool
+    """
+    if label.offset == offset:
+        return
+    symbol_pool.set_offset(label, offset)
+    modified.add(label)
+
+
+class BlockChain(object):
+
+    """Manage blocks linked with an asm_constraint_next"""
+
+    def __init__(self, symbol_pool, blocks):
+        self.symbol_pool = symbol_pool
+        self.blocks = blocks
+        self.place()
+
+    @property
+    def pinned(self):
+        """Return True iff at least one block is pinned"""
+        return self.pinned_block_idx is not None
+
+    def _set_pinned_block_idx(self):
+        self.pinned_block_idx = None
+        for i, block in enumerate(self.blocks):
+            if is_int(block.label.offset):
+                if self.pinned_block_idx is not None:
+                    raise ValueError("Multiples pinned block detected")
+                self.pinned_block_idx = i
+
+    def place(self):
+        """Compute BlockChain min_offset and max_offset using pinned block and
+        blocks' size
+        """
+        self._set_pinned_block_idx()
+        self.max_size = 0
+        for block in self.blocks:
+            self.max_size += block.max_size + block.alignment - 1
+
+        # Check if chain has one block pinned
+        if not self.pinned:
+            return
+
+        offset_base = self.blocks[self.pinned_block_idx].label.offset
+        assert(offset_base % self.blocks[self.pinned_block_idx].alignment == 0)
+
+        self.offset_min = offset_base
+        for block in self.blocks[:self.pinned_block_idx - 1:-1]:
+            self.offset_min -= block.max_size + \
+                (block.alignment - block.max_size) % block.alignment
+
+        self.offset_max = offset_base
+        for block in self.blocks[self.pinned_block_idx:]:
+            self.offset_max += block.max_size + \
+                (block.alignment - block.max_size) % block.alignment
+
+    def merge(self, chain):
+        """Best effort merge two block chains
+        Return the list of resulting blockchains"""
+        self.blocks += chain.blocks
+        self.place()
+        return [self]
+
+    def fix_blocks(self, modified_labels):
+        """Propagate a pinned to its blocks' neighbour
+        @modified_labels: store new pinned labels"""
+
+        if not self.pinned:
+            raise ValueError('Trying to fix unpinned block')
+
+        # Propagate offset to blocks before pinned block
+        pinned_block = self.blocks[self.pinned_block_idx]
+        offset = pinned_block.label.offset
+        if offset % pinned_block.alignment != 0:
+            raise RuntimeError('Bad alignment')
+
+        for block in self.blocks[:self.pinned_block_idx - 1:-1]:
+            new_offset = offset - block.size
+            new_offset = new_offset - new_offset % pinned_block.alignment
+            fix_label_offset(self.symbol_pool,
+                             block.label,
+                             new_offset,
+                             modified_labels)
+
+        # Propagate offset to blocks after pinned block
+        offset = pinned_block.label.offset + pinned_block.size
+
+        last_block = pinned_block
+        for block in self.blocks[self.pinned_block_idx + 1:]:
+            offset += (- offset) % last_block.alignment
+            fix_label_offset(self.symbol_pool,
+                             block.label,
+                             offset,
+                             modified_labels)
+            offset += block.size
+            last_block = block
+        return modified_labels
+
+
+class BlockChainWedge(object):
+
+    """Stand for wedges between blocks"""
+
+    def __init__(self, symbol_pool, offset, size):
+        self.symbol_pool = symbol_pool
+        self.offset = offset
+        self.max_size = size
+        self.offset_min = offset
+        self.offset_max = offset + size
+
+    def merge(self, chain):
+        """Best effort merge two block chains
+        Return the list of resulting blockchains"""
+        self.symbol_pool.set_offset(chain.blocks[0].label, self.offset_max)
+        chain.place()
+        return [self, chain]
+
+
+def group_constrained_blocks(symbol_pool, blocks):
+    """
+    Return the BlockChains list built from grouped asm blocks linked by
+    asm_constraint_next
+    @blocks: a list of asm block
+    """
+    log_asmblock.info('group_constrained_blocks')
+
+    # Group adjacent blocks
+    remaining_blocks = list(blocks)
+    known_block_chains = {}
+    lbl2block = {block.label: block for block in blocks}
+
+    while remaining_blocks:
+        # Create a new block chain
+        block_list = [remaining_blocks.pop()]
+
+        # Find sons in remainings blocks linked with a next constraint
+        while True:
+            # Get next block
+            next_label = block_list[-1].get_next()
+            if next_label is None or next_label not in lbl2block:
+                break
+            next_block = lbl2block[next_label]
+
+            # Add the block at the end of the current chain
+            if next_block not in remaining_blocks:
+                break
+            block_list.append(next_block)
+            remaining_blocks.remove(next_block)
+
+        # Check if son is in a known block group
+        if next_label is not None and next_label in known_block_chains:
+            block_list += known_block_chains[next_label]
+            del known_block_chains[next_label]
+
+        known_block_chains[block_list[0].label] = block_list
+
+    out_block_chains = []
+    for label in known_block_chains:
+        chain = BlockChain(symbol_pool, known_block_chains[label])
+        out_block_chains.append(chain)
+    return out_block_chains
+
+
+def get_blockchains_address_interval(blockChains, dst_interval):
+    """Compute the interval used by the pinned @blockChains
+    Check if the placed chains are in the @dst_interval"""
+
+    allocated_interval = interval()
+    for chain in blockChains:
+        if not chain.pinned:
+            continue
+        chain_interval = interval([(chain.offset_min, chain.offset_max - 1)])
+        if chain_interval not in dst_interval:
+            raise ValueError('Chain placed out of destination interval')
+        allocated_interval += chain_interval
+    return allocated_interval
+
+
+def resolve_symbol(blockChains, symbol_pool, dst_interval=None):
+    """Place @blockChains in the @dst_interval"""
+
+    log_asmblock.info('resolve_symbol')
+    if dst_interval is None:
+        dst_interval = interval([(0, 0xFFFFFFFFFFFFFFFF)])
+
+    forbidden_interval = interval(
+        [(-1, 0xFFFFFFFFFFFFFFFF + 1)]) - dst_interval
+    allocated_interval = get_blockchains_address_interval(blockChains,
+                                                          dst_interval)
+    log_asmblock.debug('allocated interval: %s', allocated_interval)
+
+    pinned_chains = [chain for chain in blockChains if chain.pinned]
+
+    # Add wedge in forbidden intervals
+    for start, stop in forbidden_interval.intervals:
+        wedge = BlockChainWedge(
+            symbol_pool, offset=start, size=stop + 1 - start)
+        pinned_chains.append(wedge)
+
+    # Try to place bigger blockChains first
+    pinned_chains.sort(key=lambda x: x.offset_min)
+    blockChains.sort(key=lambda x: -x.max_size)
+
+    fixed_chains = list(pinned_chains)
+
+    log_asmblock.debug("place chains")
+    for chain in blockChains:
+        if chain.pinned:
+            continue
+        fixed = False
+        for i in xrange(1, len(fixed_chains)):
+            prev_chain = fixed_chains[i - 1]
+            next_chain = fixed_chains[i]
+
+            if prev_chain.offset_max + chain.max_size < next_chain.offset_min:
+                new_chains = prev_chain.merge(chain)
+                fixed_chains[i - 1:i] = new_chains
+                fixed = True
+                break
+        if not fixed:
+            raise RuntimeError('Cannot find enough space to place blocks')
+
+    return [chain for chain in fixed_chains if isinstance(chain, BlockChain)]
+
+
+def filter_exprid_label(exprs):
+    """Extract labels from list of ExprId @exprs"""
+    return set(expr.name for expr in exprs if isinstance(expr.name, AsmLabel))
+
+
+def get_block_labels(block):
+    """Extract labels used by @block"""
+    symbols = set()
+    for instr in block.lines:
+        if isinstance(instr, AsmRaw):
+            if isinstance(instr.raw, list):
+                for expr in instr.raw:
+                    symbols.update(m2_expr.get_expr_ids(expr))
+        else:
+            for arg in instr.args:
+                symbols.update(m2_expr.get_expr_ids(arg))
+    labels = filter_exprid_label(symbols)
+    return labels
+
+
+def assemble_block(mnemo, block, symbol_pool, conservative=False):
+    """Assemble a @block using @symbol_pool
+    @conservative: (optional) use original bytes when possible
+    """
+    offset_i = 0
+
+    for instr in block.lines:
+        if isinstance(instr, AsmRaw):
+            if isinstance(instr.raw, list):
+                # Fix special AsmRaw
+                data = ""
+                for expr in instr.raw:
+                    expr_int = fix_expr_val(expr, symbol_pool)
+                    data += pck[expr_int.size](expr_int.arg)
+                instr.data = data
+
+            instr.offset = offset_i
+            offset_i += instr.l
+            continue
+
+        # Assemble an instruction
+        saved_args = list(instr.args)
+        instr.offset = block.label.offset + offset_i
+
+        # Replace instruction's arguments by resolved ones
+        instr.args = instr.resolve_args_with_symbols(symbol_pool)
+
+        if instr.dstflow():
+            instr.fixDstOffset()
+
+        old_l = instr.l
+        cached_candidate, _ = conservative_asm(mnemo, instr, symbol_pool,
+                                               conservative)
+
+        # Restore original arguments
+        instr.args = saved_args
+
+        # We need to update the block size
+        block.size = block.size - old_l + len(cached_candidate)
+        instr.data = cached_candidate
+        instr.l = len(cached_candidate)
+
+        offset_i += instr.l
+
+
+def asmbloc_final(mnemo, blocks, blockChains, symbol_pool, conservative=False):
+    """Resolve and assemble @blockChains using @symbol_pool until fixed point is
+    reached"""
+
+    log_asmblock.debug("asmbloc_final")
+
+    # Init structures
+    lbl2block = {block.label: block for block in blocks}
+    blocks_using_label = {}
+    for block in blocks:
+        labels = get_block_labels(block)
+        for label in labels:
+            blocks_using_label.setdefault(label, set()).add(block)
+
+    block2chain = {}
+    for chain in blockChains:
+        for block in chain.blocks:
+            block2chain[block] = chain
+
+    # Init worklist
+    blocks_to_rework = set(blocks)
+
+    # Fix and re-assemble blocks until fixed point is reached
+    while True:
+
+        # Propagate pinned blocks into chains
+        modified_labels = set()
+        for chain in blockChains:
+            chain.fix_blocks(modified_labels)
+
+        for label in modified_labels:
+            # Retrive block with modified reference
+            if label in lbl2block:
+                blocks_to_rework.add(lbl2block[label])
+
+            # Enqueue blocks referencing a modified label
+            if label not in blocks_using_label:
+                continue
+            for block in blocks_using_label[label]:
+                blocks_to_rework.add(block)
+
+        # No more work
+        if not blocks_to_rework:
+            break
+
+        while blocks_to_rework:
+            block = blocks_to_rework.pop()
+            assemble_block(mnemo, block, symbol_pool, conservative)
+
+
+def asm_resolve_final(mnemo, blocks, symbol_pool, dst_interval=None):
+    """Resolve and assemble @blocks using @symbol_pool into interval
+    @dst_interval"""
+
+    blocks.sanity_check()
+
+    blocks.guess_blocks_size(mnemo)
+    blockChains = group_constrained_blocks(symbol_pool, blocks)
+    resolved_blockChains = resolve_symbol(
+        blockChains, symbol_pool, dst_interval)
+
+    asmbloc_final(mnemo, blocks, resolved_blockChains, symbol_pool)
+    patches = {}
+    output_interval = interval()
+
+    for block in blocks:
+        offset = block.label.offset
+        for instr in block.lines:
+            if not instr.data:
+                # Empty line
+                continue
+            assert len(instr.data) == instr.l
+            patches[offset] = instr.data
+            instruction_interval = interval([(offset, offset + instr.l - 1)])
+            if not (instruction_interval & output_interval).empty:
+                raise RuntimeError("overlapping bytes %X" % int(offset))
+            instr.offset = offset
+            offset += instr.l
+    return patches
+
+
+class disasmEngine(object):
+
+    """Disassembly engine, taking care of disassembler options and mutli-block
+    strategy.
+
+    Engine options:
+
+    + Object supporting membership test (offset in ..)
+     - dont_dis: stop the current disassembly branch if reached
+     - split_dis: force a basic block end if reached,
+                  with a next constraint on its successor
+     - dont_dis_retcall_funcs: stop disassembly after a call to one
+                               of the given functions
+
+    + On/Off
+     - follow_call: recursively disassemble CALL destinations
+     - dontdis_retcall: stop on CALL return addresses
+     - dont_dis_nulstart_bloc: stop if a block begin with a few \x00
+
+    + Number
+     - lines_wd: maximum block's size (in number of instruction)
+     - blocs_wd: maximum number of distinct disassembled block
+
+    + callback(arch, attrib, pool_bin, cur_bloc, offsets_to_dis,
+               symbol_pool)
+     - dis_bloc_callback: callback after each new disassembled block
+
+    The engine also tracks already handled block, for performance and to avoid
+    infinite cycling.
+    Addresses of disassembled block is in the attribute `job_done`.
+    To force a new disassembly, the targeted offset must first be removed from
+    this structure.
+    """
+
+    def __init__(self, arch, attrib, bin_stream, **kwargs):
+        """Instanciate a new disassembly engine
+        @arch: targeted architecture
+        @attrib: architecture attribute
+        @bin_stream: bytes source
+        @kwargs: (optional) custom options
+        """
+        self.arch = arch
+        self.attrib = attrib
+        self.bin_stream = bin_stream
+        self.symbol_pool = AsmSymbolPool()
+        self.job_done = set()
+
+        # Setup options
+        self.dont_dis = []
+        self.split_dis = []
+        self.follow_call = False
+        self.dontdis_retcall = False
+        self.lines_wd = None
+        self.blocs_wd = None
+        self.dis_bloc_callback = None
+        self.dont_dis_nulstart_bloc = False
+        self.dont_dis_retcall_funcs = set()
+
+        # Override options if needed
+        self.__dict__.update(kwargs)
+
+    def _dis_bloc(self, offset):
+        """Disassemble the block at offset @offset
+        Return the created AsmBlock and future offsets to disassemble
+        """
+
+        lines_cpt = 0
+        in_delayslot = False
+        delayslot_count = self.arch.delayslot
+        offsets_to_dis = set()
+        add_next_offset = False
+        label = self.symbol_pool.getby_offset_create(offset)
+        cur_block = AsmBlock(label)
+        log_asmblock.debug("dis at %X", int(offset))
+        while not in_delayslot or delayslot_count > 0:
+            if in_delayslot:
+                delayslot_count -= 1
+
+            if offset in self.dont_dis:
+                if not cur_block.lines:
+                    self.job_done.add(offset)
+                    # Block is empty -> bad block
+                    cur_block = AsmBlockBad(label, errno=2)
+                else:
+                    # Block is not empty, stop the desassembly pass and add a
+                    # constraint to the next block
+                    cur_block.add_cst(offset, AsmConstraint.c_next,
+                                      self.symbol_pool)
+                break
+
+            if lines_cpt > 0 and offset in self.split_dis:
+                cur_block.add_cst(offset, AsmConstraint.c_next,
+                                  self.symbol_pool)
+                offsets_to_dis.add(offset)
+                break
+
+            lines_cpt += 1
+            if self.lines_wd is not None and lines_cpt > self.lines_wd:
+                log_asmblock.debug("lines watchdog reached at %X", int(offset))
+                break
+
+            if offset in self.job_done:
+                cur_block.add_cst(offset, AsmConstraint.c_next,
+                                  self.symbol_pool)
+                break
+
+            off_i = offset
+            try:
+                instr = self.arch.dis(self.bin_stream, self.attrib, offset)
+            except (Disasm_Exception, IOError), e:
+                log_asmblock.warning(e)
+                instr = None
+
+            if instr is None:
+                log_asmblock.warning("cannot disasm at %X", int(off_i))
+                if not cur_block.lines:
+                    self.job_done.add(offset)
+                    # Block is empty -> bad block
+                    cur_block = AsmBlockBad(label, errno=0)
+                else:
+                    # Block is not empty, stop the desassembly pass and add a
+                    # constraint to the next block
+                    cur_block.add_cst(off_i, AsmConstraint.c_next,
+                                      self.symbol_pool)
+                break
+
+            # XXX TODO nul start block option
+            if self.dont_dis_nulstart_bloc and instr.b.count('\x00') == instr.l:
+                log_asmblock.warning("reach nul instr at %X", int(off_i))
+                if not cur_block.lines:
+                    # Block is empty -> bad block
+                    cur_block = AsmBlockBad(label, errno=1)
+                else:
+                    # Block is not empty, stop the desassembly pass and add a
+                    # constraint to the next block
+                    cur_block.add_cst(off_i, AsmConstraint.c_next,
+                                      self.symbol_pool)
+                break
+
+            # special case: flow graph modificator in delayslot
+            if in_delayslot and instr and (instr.splitflow() or instr.breakflow()):
+                add_next_offset = True
+                break
+
+            self.job_done.add(offset)
+            log_asmblock.debug("dis at %X", int(offset))
+
+            offset += instr.l
+            log_asmblock.debug(instr)
+            log_asmblock.debug(instr.args)
+
+            cur_block.addline(instr)
+            if not instr.breakflow():
+                continue
+            # test split
+            if instr.splitflow() and not (instr.is_subcall() and self.dontdis_retcall):
+                add_next_offset = True
+                pass
+            if instr.dstflow():
+                instr.dstflow2label(self.symbol_pool)
+                dst = instr.getdstflow(self.symbol_pool)
+                dstn = []
+                for d in dst:
+                    if isinstance(d, m2_expr.ExprId) and \
+                            isinstance(d.name, AsmLabel):
+                        dstn.append(d.name)
+                        if d.name.offset in self.dont_dis_retcall_funcs:
+                            add_next_offset = False
+                dst = dstn
+                if (not instr.is_subcall()) or self.follow_call:
+                    cur_block.bto.update(
+                        [AsmConstraint(x, AsmConstraint.c_to) for x in dst])
+
+            # get in delayslot mode
+            in_delayslot = True
+            delayslot_count = instr.delayslot
+
+        for c in cur_block.bto:
+            offsets_to_dis.add(c.label.offset)
+
+        if add_next_offset:
+            cur_block.add_cst(offset, AsmConstraint.c_next, self.symbol_pool)
+            offsets_to_dis.add(offset)
+
+        # Fix multiple constraints
+        cur_block.fix_constraints()
+
+        if self.dis_bloc_callback is not None:
+            self.dis_bloc_callback(mn=self.arch, attrib=self.attrib,
+                                   pool_bin=self.bin_stream, cur_bloc=cur_block,
+                                   offsets_to_dis=offsets_to_dis,
+                                   symbol_pool=self.symbol_pool)
+        return cur_block, offsets_to_dis
+
+    def dis_bloc(self, offset):
+        """Disassemble the block at offset @offset and return the created
+        AsmBlock
+        @offset: targeted offset to disassemble
+        """
+        current_block, _ = self._dis_bloc(offset)
+        return current_block
+
+    def dis_multibloc(self, offset, blocs=None):
+        """Disassemble every block reachable from @offset regarding
+        specific disasmEngine conditions
+        Return an AsmCFG instance containing disassembled blocks
+        @offset: starting offset
+        @blocs: (optional) AsmCFG instance of already disassembled blocks to
+                merge with
+        """
+        log_asmblock.info("dis bloc all")
+        if blocs is None:
+            blocs = AsmCFG()
+        todo = [offset]
+
+        bloc_cpt = 0
+        while len(todo):
+            bloc_cpt += 1
+            if self.blocs_wd is not None and bloc_cpt > self.blocs_wd:
+                log_asmblock.debug("blocs watchdog reached at %X", int(offset))
+                break
+
+            target_offset = int(todo.pop(0))
+            if (target_offset is None or
+                    target_offset in self.job_done):
+                continue
+            cur_block, nexts = self._dis_bloc(target_offset)
+            todo += nexts
+            blocs.add_node(cur_block)
+
+        blocs.apply_splitting(self.symbol_pool,
+                              dis_block_callback=self.dis_bloc_callback,
+                              mn=self.arch, attrib=self.attrib,
+                              pool_bin=self.bin_stream)
+        return blocs
diff --git a/miasm2/core/cpu.py b/miasm2/core/cpu.py
index 41ae822d..8b906027 100644
--- a/miasm2/core/cpu.py
+++ b/miasm2/core/cpu.py
@@ -8,7 +8,7 @@ from collections import defaultdict
 import pyparsing
 
 import miasm2.expression.expression as m2_expr
-from miasm2.core import asmbloc
+from miasm2.core import asmblock
 from miasm2.core.bin_stream import bin_stream, bin_stream_str
 from miasm2.core.utils import Disasm_Exception
 from miasm2.expression.simplifications import expr_simp
@@ -232,7 +232,7 @@ class ParseAst(object):
         if size is None:
             size = self.default_size
         assert value is not None
-        return m2_expr.ExprId(asmbloc.AsmLabel(value), size)
+        return m2_expr.ExprId(asmblock.AsmLabel(value), size)
 
     def ast_to_expr(self, size, ast):
         """Transform a typed ast into a Miasm expression
@@ -974,7 +974,7 @@ class instruction(object):
             ids = m2_expr.get_expr_ids(e)
             fixed_ids = {}
             for x in ids:
-                if isinstance(x.name, asmbloc.AsmLabel):
+                if isinstance(x.name, asmblock.AsmLabel):
                     name = x.name.name
                     # special symbol $
                     if name == '$':
diff --git a/miasm2/core/parse_asm.py b/miasm2/core/parse_asm.py
index 514fee3b..8ea0f6b1 100644
--- a/miasm2/core/parse_asm.py
+++ b/miasm2/core/parse_asm.py
@@ -2,7 +2,7 @@
 import re
 
 import miasm2.expression.expression as m2_expr
-import miasm2.core.asmbloc as asmbloc
+import miasm2.core.asmblock as asmblock
 from miasm2.core.cpu import gen_base_expr, ParseAst
 from miasm2.core.cpu import instruction
 
@@ -77,7 +77,7 @@ def replace_expr_labels(expr, symbol_pool, replace_id):
     Update @replace_id"""
 
     if not (isinstance(expr, m2_expr.ExprId) and
-            isinstance(expr.name, asmbloc.AsmLabel)):
+            isinstance(expr.name, asmblock.AsmLabel)):
         return expr
 
     old_lbl = expr.name
@@ -114,10 +114,10 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None):
     """
 
     if symbol_pool is None:
-        symbol_pool = asmbloc.AsmSymbolPool()
+        symbol_pool = asmblock.AsmSymbolPool()
 
-    C_NEXT = asmbloc.AsmConstraint.c_next
-    C_TO = asmbloc.AsmConstraint.c_to
+    C_NEXT = asmblock.AsmConstraint.c_next
+    C_TO = asmblock.AsmConstraint.c_to
 
     lines = []
     # parse each line
@@ -151,7 +151,7 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None):
                 raw = raw.decode('string_escape')
                 if directive == 'string':
                     raw += "\x00"
-                lines.append(asmbloc.AsmRaw(raw))
+                lines.append(asmblock.AsmRaw(raw))
                 continue
             if directive == 'ustring':
                 # XXX HACK
@@ -159,7 +159,7 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None):
                 raw = line[line.find(r'"') + 1:line.rfind(r'"')] + "\x00"
                 raw = raw.decode('string_escape')
                 raw = "".join([string + '\x00' for string in raw])
-                lines.append(asmbloc.AsmRaw(raw))
+                lines.append(asmblock.AsmRaw(raw))
                 continue
             if directive in declarator:
                 data_raw = line[match_re.end():].split(' ', 1)[1]
@@ -179,7 +179,7 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None):
                     element_expr = base_expr.parseString(element)[0]
                     expr_list.append(element_expr.canonize())
 
-                raw_data = asmbloc.AsmRaw(expr_list)
+                raw_data = asmblock.AsmRaw(expr_list)
                 raw_data.element_size = size
                 lines.append(raw_data)
                 continue
@@ -225,13 +225,13 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None):
             instr.dstflow2label(symbol_pool)
         lines.append(instr)
 
-    asmbloc.log_asmbloc.info("___pre asm oki___")
+    asmblock.log_asmblock.info("___pre asm oki___")
     # make blocks
 
     cur_block = None
     state = STATE_NO_BLOC
     i = 0
-    blocks = asmbloc.AsmCFG()
+    blocks = asmblock.AsmCFG()
     block_to_nlink = None
     delayslot = 0
     while i < len(lines):
@@ -250,21 +250,21 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None):
                 block_to_nlink = None
                 i += 1
                 continue
-            elif not isinstance(line, asmbloc.AsmLabel):
+            elif not isinstance(line, asmblock.AsmLabel):
                 # First line must be a label. If it's not the case, generate
                 # it.
                 label = guess_next_new_label(symbol_pool)
-                cur_block = asmbloc.AsmBlock(label, alignment=mnemo.alignment)
+                cur_block = asmblock.AsmBlock(label, alignment=mnemo.alignment)
             else:
-                cur_block = asmbloc.AsmBlock(line, alignment=mnemo.alignment)
+                cur_block = asmblock.AsmBlock(line, alignment=mnemo.alignment)
                 i += 1
             # Generate the current bloc
             blocks.add_node(cur_block)
             state = STATE_IN_BLOC
             if block_to_nlink:
                 block_to_nlink.addto(
-                    asmbloc.AsmConstraint(cur_block.label,
-                                          C_NEXT))
+                    asmblock.AsmConstraint(cur_block.label,
+                                           C_NEXT))
             block_to_nlink = None
             continue
 
@@ -278,13 +278,13 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None):
                 block_to_nlink = cur_block
             elif isinstance(line, DirectiveAlign):
                 cur_block.alignment = line.alignment
-            elif isinstance(line, asmbloc.AsmRaw):
+            elif isinstance(line, asmblock.AsmRaw):
                 cur_block.addline(line)
                 block_to_nlink = cur_block
-            elif isinstance(line, asmbloc.AsmLabel):
+            elif isinstance(line, asmblock.AsmLabel):
                 if block_to_nlink:
                     cur_block.addto(
-                        asmbloc.AsmConstraint(line, C_NEXT))
+                        asmblock.AsmConstraint(line, C_NEXT))
                     block_to_nlink = None
                 state = STATE_NO_BLOC
                 continue
@@ -303,7 +303,7 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None):
                             continue
                         if dst in mnemo.regs.all_regs_ids:
                             continue
-                        cur_block.addto(asmbloc.AsmConstraint(dst.name, C_TO))
+                        cur_block.addto(asmblock.AsmConstraint(dst.name, C_TO))
 
                 if not line.splitflow():
                     block_to_nlink = None
@@ -318,5 +318,5 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None):
         block.fix_constraints()
 
         # Log block
-        asmbloc.log_asmbloc.info(block)
+        asmblock.log_asmblock.info(block)
     return blocks, symbol_pool
diff --git a/miasm2/ir/ir.py b/miasm2/ir/ir.py
index 1d7bb434..5ebb51ec 100644
--- a/miasm2/ir/ir.py
+++ b/miasm2/ir/ir.py
@@ -24,7 +24,7 @@ from itertools import chain
 import miasm2.expression.expression as m2_expr
 from miasm2.expression.expression_helper import get_missing_interval
 from miasm2.expression.simplifications import expr_simp
-from miasm2.core.asmbloc import AsmSymbolPool, expr_is_label, AsmLabel, \
+from miasm2.core.asmblock import AsmSymbolPool, expr_is_label, AsmLabel, \
     AsmBlock
 from miasm2.core.graph import DiGraph
 
diff --git a/miasm2/ir/symbexec.py b/miasm2/ir/symbexec.py
index b5c43a4e..ab873cfd 100644
--- a/miasm2/ir/symbexec.py
+++ b/miasm2/ir/symbexec.py
@@ -4,7 +4,7 @@ import logging
 import miasm2.expression.expression as m2_expr
 from miasm2.expression.modint import int32
 from miasm2.expression.simplifications import expr_simp
-from miasm2.core import asmbloc
+from miasm2.core import asmblock
 from miasm2.ir.ir import AssignBlock
 from miasm2.core.interval import interval
 
@@ -205,7 +205,7 @@ class SymbolicExecutionEngine(object):
         elif isinstance(expr, m2_expr.ExprInt):
             return expr
         elif isinstance(expr, m2_expr.ExprId):
-            if isinstance(expr.name, asmbloc.AsmLabel) and expr.name.offset is not None:
+            if isinstance(expr.name, asmblock.AsmLabel) and expr.name.offset is not None:
                 ret = m2_expr.ExprInt(expr.name.offset, expr.size)
             else:
                 ret = state.get(expr, expr)
diff --git a/miasm2/ir/translators/C.py b/miasm2/ir/translators/C.py
index 4a6bbb37..1dfdbb00 100644
--- a/miasm2/ir/translators/C.py
+++ b/miasm2/ir/translators/C.py
@@ -1,5 +1,5 @@
 from miasm2.ir.translators.translator import Translator
-from miasm2.core import asmbloc
+from miasm2.core import asmblock
 from miasm2.expression.modint import size2mask
 
 
@@ -23,7 +23,7 @@ class TranslatorC(Translator):
 
 
     def from_ExprId(self, expr):
-        if isinstance(expr.name, asmbloc.AsmLabel):
+        if isinstance(expr.name, asmblock.AsmLabel):
             return "0x%x" % expr.name.offset
         return str(expr)
 
diff --git a/miasm2/ir/translators/smt2.py b/miasm2/ir/translators/smt2.py
index 7a3e342e..26ff9127 100644
--- a/miasm2/ir/translators/smt2.py
+++ b/miasm2/ir/translators/smt2.py
@@ -1,7 +1,7 @@
 import logging
 import operator
 
-from miasm2.core.asmbloc import AsmLabel
+from miasm2.core.asmblock import AsmLabel
 from miasm2.ir.translators.translator import Translator
 from miasm2.expression.smt2_helper import *
 
diff --git a/miasm2/ir/translators/z3_ir.py b/miasm2/ir/translators/z3_ir.py
index 32c7637a..d8b550d9 100644
--- a/miasm2/ir/translators/z3_ir.py
+++ b/miasm2/ir/translators/z3_ir.py
@@ -3,7 +3,7 @@ import operator
 
 import z3
 
-from miasm2.core.asmbloc import AsmLabel
+from miasm2.core.asmblock import AsmLabel
 from miasm2.ir.translators.translator import Translator
 
 log = logging.getLogger("translator_z3")
diff --git a/miasm2/jitter/codegen.py b/miasm2/jitter/codegen.py
index 09383f54..9d005451 100644
--- a/miasm2/jitter/codegen.py
+++ b/miasm2/jitter/codegen.py
@@ -1,7 +1,7 @@
 import miasm2.expression.expression as m2_expr
 from miasm2.ir.ir import IRBlock
 from miasm2.ir.translators import Translator
-from miasm2.core.asmbloc import expr_is_label, AsmBlockBad, AsmLabel
+from miasm2.core.asmblock import expr_is_label, AsmBlockBad, AsmLabel
 
 # Miasm to C translator
 translator = Translator.to_language("C")
diff --git a/miasm2/jitter/jitcore.py b/miasm2/jitter/jitcore.py
index b0f911eb..0ccbfcd7 100644
--- a/miasm2/jitter/jitcore.py
+++ b/miasm2/jitter/jitcore.py
@@ -15,7 +15,7 @@
 # with this program; if not, write to the Free Software Foundation, Inc.,
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 #
-from miasm2.core import asmbloc
+from miasm2.core import asmblock
 from miasm2.core.interval import interval
 from miasm2.core.utils import BoundedDict
 from miasm2.jitter.csts import *
@@ -55,13 +55,13 @@ class JitCore(object):
                         "max_exec_per_call": 0 # 0 means no limit
                         }
 
-        self.mdis = asmbloc.disasmEngine(ir_arch.arch, ir_arch.attrib, bs,
-                                         lines_wd=self.options["jit_maxline"],
-                                         symbol_pool=ir_arch.symbol_pool,
-                                         follow_call=False,
-                                         dontdis_retcall=False,
-                                         split_dis=self.split_dis,
-                                         dis_bloc_callback=self.disasm_cb)
+        self.mdis = asmblock.disasmEngine(ir_arch.arch, ir_arch.attrib, bs,
+                                          lines_wd=self.options["jit_maxline"],
+                                          symbol_pool=ir_arch.symbol_pool,
+                                          follow_call=False,
+                                          dontdis_retcall=False,
+                                          split_dis=self.split_dis,
+                                          dis_bloc_callback=self.disasm_cb)
 
 
     def set_options(self, **kwargs):
@@ -133,7 +133,7 @@ class JitCore(object):
         """
 
         # Get the block
-        if isinstance(addr, asmbloc.AsmLabel):
+        if isinstance(addr, asmblock.AsmLabel):
             addr = addr.offset
 
         # Prepare disassembler
@@ -147,7 +147,7 @@ class JitCore(object):
         except IOError:
             # vm_exception_flag is set
             label = self.ir_arch.symbol_pool.getby_offset_create(addr)
-            cur_block = asmbloc.AsmBlockBad(label)
+            cur_block = asmblock.AsmBlockBad(label)
 
         # Logging
         if self.log_newbloc:
diff --git a/miasm2/jitter/jitcore_cc_base.py b/miasm2/jitter/jitcore_cc_base.py
index 9d41d06c..ae8a5dc2 100644
--- a/miasm2/jitter/jitcore_cc_base.py
+++ b/miasm2/jitter/jitcore_cc_base.py
@@ -113,7 +113,7 @@ class JitCore_Cc_Base(JitCore):
     def hash_block(self, block):
         """
         Build a hash of the block @block
-        @block: asmbloc
+        @block: asmblock
         """
         block_raw = "".join(line.b for line in block.lines)
         block_hash = md5("%X_%s_%s_%s" % (block.label.offset,
diff --git a/miasm2/jitter/jitcore_llvm.py b/miasm2/jitter/jitcore_llvm.py
index 8f58f1da..d082dd79 100644
--- a/miasm2/jitter/jitcore_llvm.py
+++ b/miasm2/jitter/jitcore_llvm.py
@@ -121,7 +121,7 @@ class JitCore_LLVM(jitcore.JitCore):
     def hash_block(self, block):
         """
         Build a hash of the block @block
-        @block: asmbloc
+        @block: asmblock
         """
         block_raw = "".join(line.b for line in block.lines)
         block_hash = md5("%X_%s_%s_%s" % (block.label.offset,
diff --git a/miasm2/jitter/llvmconvert.py b/miasm2/jitter/llvmconvert.py
index e98d2133..226a1b8e 100644
--- a/miasm2/jitter/llvmconvert.py
+++ b/miasm2/jitter/llvmconvert.py
@@ -16,7 +16,7 @@ from llvmlite import binding as llvm
 from llvmlite import ir as llvm_ir
 import miasm2.expression.expression as m2_expr
 import miasm2.jitter.csts as m2_csts
-import miasm2.core.asmbloc as m2_asmbloc
+import miasm2.core.asmblock as m2_asmblock
 from miasm2.jitter.codegen import CGen
 from miasm2.expression.expression_helper import possible_values
 
@@ -508,9 +508,9 @@ class LLVMFunction():
         @label: str or asmlabel instance"""
         if isinstance(label, str):
             return label
-        elif isinstance(label, m2_asmbloc.AsmLabel):
+        elif isinstance(label, m2_asmblock.AsmLabel):
             return "label_%s" % label.name
-        elif m2_asmbloc.expr_is_label(label):
+        elif m2_asmblock.expr_is_label(label):
             return "label_%s" % label.name.name
         else:
             raise ValueError("label must either be str or asmlabel")
@@ -1038,7 +1038,7 @@ class LLVMFunction():
             index = dst2case.get(value, i)
             to_eval = to_eval.replace_expr({value: m2_expr.ExprInt(index, value.size)})
             dst2case[value] = index
-            if m2_asmbloc.expr_is_int_or_label(value):
+            if m2_asmblock.expr_is_int_or_label(value):
                 case2dst[i] = value
             else:
                 case2dst[i] = self.add_ir(value)
@@ -1068,7 +1068,7 @@ class LLVMFunction():
             dst = m2_expr.ExprId(self.llvm_context.ir_arch.symbol_pool.getby_offset_create(int(dst)),
                                  dst.size)
 
-        if m2_asmbloc.expr_is_label(dst):
+        if m2_asmblock.expr_is_label(dst):
             bbl = self.get_basic_bloc_by_label(dst)
             offset = dst.name.offset
             if bbl is not None:
@@ -1276,7 +1276,7 @@ class LLVMFunction():
         self.init_fc()
         self.local_vars_pointers["status"] = self.local_vars["status"]
 
-        if isinstance(asmblock, m2_asmbloc.AsmBlockBad):
+        if isinstance(asmblock, m2_asmblock.AsmBlockBad):
             self.gen_bad_block(asmblock)
             return
 
diff --git a/test/analysis/depgraph.py b/test/analysis/depgraph.py
index f84f19cc..24095c7b 100644
--- a/test/analysis/depgraph.py
+++ b/test/analysis/depgraph.py
@@ -1,7 +1,7 @@
 """Regression test module for DependencyGraph"""
 from miasm2.expression.expression import ExprId, ExprInt32, ExprAff, ExprCond, \
     ExprInt
-from miasm2.core.asmbloc import AsmLabel
+from miasm2.core.asmblock import AsmLabel
 from miasm2.ir.analysis import ira
 from miasm2.ir.ir import IRBlock, AssignBlock
 from miasm2.core.graph import DiGraph
diff --git a/test/arch/aarch64/unit/asm_test.py b/test/arch/aarch64/unit/asm_test.py
index d8639ce7..ddb8a08c 100644
--- a/test/arch/aarch64/unit/asm_test.py
+++ b/test/arch/aarch64/unit/asm_test.py
@@ -5,7 +5,7 @@ from miasm2.core.cpu import ParseAst
 from miasm2.arch.aarch64.arch import mn_aarch64, base_expr, variable
 from miasm2.core import parse_asm
 from miasm2.expression.expression import *
-from miasm2.core import asmbloc
+from miasm2.core import asmblock
 from elfesteem.strpatchwork import StrPatchwork
 from miasm2.analysis.machine import Machine
 from miasm2.jitter.csts import *
@@ -33,7 +33,7 @@ class Asm_Test(object):
         # fix shellcode addr
         symbol_pool.set_offset(symbol_pool.getby_name("main"), 0x0)
         s = StrPatchwork()
-        patches = asmbloc.asm_resolve_final(mn_aarch64, blocks, symbol_pool)
+        patches = asmblock.asm_resolve_final(mn_aarch64, blocks, symbol_pool)
         for offset, raw in patches.items():
             s[offset] = raw
 
diff --git a/test/arch/mips32/unit/asm_test.py b/test/arch/mips32/unit/asm_test.py
index 4edcaf84..9281f1b6 100644
--- a/test/arch/mips32/unit/asm_test.py
+++ b/test/arch/mips32/unit/asm_test.py
@@ -5,7 +5,7 @@ from miasm2.core.cpu import ParseAst
 from miasm2.arch.mips32.arch import mn_mips32, base_expr, variable
 from miasm2.core import parse_asm
 from miasm2.expression.expression import *
-from miasm2.core import asmbloc
+from miasm2.core import asmblock
 from elfesteem.strpatchwork import StrPatchwork
 from miasm2.analysis.machine import Machine
 from miasm2.jitter.csts import *
@@ -33,7 +33,7 @@ class Asm_Test(object):
         # fix shellcode addr
         symbol_pool.set_offset(symbol_pool.getby_name("main"), 0x0)
         s = StrPatchwork()
-        patches = asmbloc.asm_resolve_final(mn_mips32, blocks, symbol_pool)
+        patches = asmblock.asm_resolve_final(mn_mips32, blocks, symbol_pool)
         for offset, raw in patches.items():
             s[offset] = raw
 
diff --git a/test/arch/x86/sem.py b/test/arch/x86/sem.py
index 40988e61..7b6a20b7 100755
--- a/test/arch/x86/sem.py
+++ b/test/arch/x86/sem.py
@@ -13,7 +13,7 @@ from miasm2.arch.x86.sem import ir_x86_32 as ir_32, ir_x86_64 as ir_64
 from miasm2.arch.x86.regs import *
 from miasm2.expression.expression import *
 from miasm2.expression.simplifications      import expr_simp
-from miasm2.core import parse_asm, asmbloc
+from miasm2.core import parse_asm, asmblock
 
 
 logging.getLogger('cpuhelper').setLevel(logging.ERROR)
@@ -47,7 +47,7 @@ def compute(ir, mode, asm, inputstate={}, debug=False):
 def compute_txt(ir, mode, txt, inputstate={}, debug=False):
     blocks, symbol_pool = parse_asm.parse_txt(mn, mode, txt)
     symbol_pool.set_offset(symbol_pool.getby_name("main"), 0x0)
-    patches = asmbloc.asm_resolve_final(mn, blocks, symbol_pool)
+    patches = asmblock.asm_resolve_final(mn, blocks, symbol_pool)
     interm = ir(symbol_pool)
     for bbl in blocks:
         interm.add_bloc(bbl)
diff --git a/test/arch/x86/unit/asm_test.py b/test/arch/x86/unit/asm_test.py
index ebe7612d..aba47df1 100644
--- a/test/arch/x86/unit/asm_test.py
+++ b/test/arch/x86/unit/asm_test.py
@@ -5,7 +5,7 @@ from miasm2.core.cpu import ParseAst
 from miasm2.arch.x86.arch import mn_x86, base_expr, variable
 from miasm2.core import parse_asm
 from miasm2.expression.expression import *
-from miasm2.core import asmbloc
+from miasm2.core import asmblock
 from elfesteem.strpatchwork import StrPatchwork
 from miasm2.analysis.machine import Machine
 from miasm2.jitter.csts import *
@@ -49,7 +49,7 @@ class Asm_Test(object):
         # fix shellcode addr
         symbol_pool.set_offset(symbol_pool.getby_name("main"), 0x0)
         s = StrPatchwork()
-        patches = asmbloc.asm_resolve_final(mn_x86, blocks, symbol_pool)
+        patches = asmblock.asm_resolve_final(mn_x86, blocks, symbol_pool)
         for offset, raw in patches.items():
             s[offset] = raw
 
diff --git a/test/core/asmbloc.py b/test/core/asmblock.py
index 67c8e813..79bf47be 100644
--- a/test/core/asmbloc.py
+++ b/test/core/asmblock.py
@@ -2,7 +2,7 @@ from pdb import pm
 
 from miasm2.arch.x86.disasm import dis_x86_32
 from miasm2.analysis.binary import Container
-from miasm2.core.asmbloc import AsmCFG, AsmConstraint, AsmBlock, \
+from miasm2.core.asmblock import AsmCFG, AsmConstraint, AsmBlock, \
     AsmLabel, AsmBlockBad, AsmConstraintTo, AsmConstraintNext, \
     bbl_simplifier
 from miasm2.core.graph import DiGraphSimplifier, MatchGraphJoker
diff --git a/test/core/parse_asm.py b/test/core/parse_asm.py
index e91c8c8c..54f3be1d 100755
--- a/test/core/parse_asm.py
+++ b/test/core/parse_asm.py
@@ -38,7 +38,7 @@ class TestParseAsm(unittest.TestCase):
     def test_DirectiveDontSplit(self):
         from miasm2.arch.x86.arch import mn_x86
         from miasm2.core.parse_asm import parse_txt
-        from miasm2.core.asmbloc import asm_resolve_final
+        from miasm2.core.asmblock import asm_resolve_final
 
         ASM0 = '''
         lbl0:
diff --git a/test/core/sembuilder.py b/test/core/sembuilder.py
index d0109092..d8fdb6c4 100644
--- a/test/core/sembuilder.py
+++ b/test/core/sembuilder.py
@@ -3,7 +3,7 @@ from pdb import pm
 
 from miasm2.core.sembuilder import SemBuilder
 import miasm2.expression.expression as m2_expr
-from miasm2.core.asmbloc import AsmLabel
+from miasm2.core.asmblock import AsmLabel
 
 # Test classes
 class IR(object):
diff --git a/test/ir/analysis.py b/test/ir/analysis.py
index 0350fb23..6209b36b 100644
--- a/test/ir/analysis.py
+++ b/test/ir/analysis.py
@@ -1,6 +1,6 @@
 """ Test cases for dead code elimination"""
 from miasm2.expression.expression import ExprId, ExprInt32, ExprAff, ExprMem
-from miasm2.core.asmbloc import AsmLabel
+from miasm2.core.asmblock import AsmLabel
 from miasm2.ir.analysis import ira
 from miasm2.ir.ir import IRBlock, AssignBlock
 
diff --git a/test/ir/translators/z3_ir.py b/test/ir/translators/z3_ir.py
index 9a75a320..0251c2fe 100644
--- a/test/ir/translators/z3_ir.py
+++ b/test/ir/translators/z3_ir.py
@@ -1,6 +1,6 @@
 import z3
 
-from miasm2.core.asmbloc import AsmLabel
+from miasm2.core.asmblock import AsmLabel
 from miasm2.expression.expression import *
 from miasm2.ir.translators.translator import Translator
 from miasm2.ir.translators.z3_ir import Z3Mem
diff --git a/test/test_all.py b/test/test_all.py
index 0c9a0c08..4f3ea760 100755
--- a/test/test_all.py
+++ b/test/test_all.py
@@ -230,7 +230,7 @@ for script in ["interval.py",
                "test_types.py",
                ]:
     testset += RegressionTest([script], base_dir="core")
-testset += RegressionTest(["asmbloc.py"], base_dir="core",
+testset += RegressionTest(["asmblock.py"], base_dir="core",
                           products=["graph.dot", "graph2.dot",
                                     "graph3.dot", "graph4.dot"])
 ## Expression