about summary refs log tree commit diff stats
path: root/miasm2/jitter
diff options
context:
space:
mode:
Diffstat (limited to 'miasm2/jitter')
-rw-r--r--miasm2/jitter/codegen.py130
-rw-r--r--miasm2/jitter/jitcore.py44
-rw-r--r--miasm2/jitter/jitcore_cc_base.py14
-rw-r--r--miasm2/jitter/jitcore_gcc.py11
-rw-r--r--miasm2/jitter/jitcore_llvm.py8
-rw-r--r--miasm2/jitter/jitcore_python.py31
-rw-r--r--miasm2/jitter/llvmconvert.py154
-rw-r--r--miasm2/jitter/loader/pe.py4
8 files changed, 199 insertions, 197 deletions
diff --git a/miasm2/jitter/codegen.py b/miasm2/jitter/codegen.py
index 519664e3..c6232642 100644
--- a/miasm2/jitter/codegen.py
+++ b/miasm2/jitter/codegen.py
@@ -2,7 +2,8 @@
 Module to generate C code for a given native @block
 """
 
-import miasm2.expression.expression as m2_expr
+from miasm2.expression.expression import Expr, ExprId, ExprLoc, ExprInt, \
+    ExprMem, ExprCond, LocKey
 from miasm2.ir.ir import IRBlock, AssignBlock
 
 from miasm2.ir.translators.C import TranslatorC
@@ -108,20 +109,20 @@ class CGen(object):
         """Iinitialize jitter internals"""
         self.id_to_c_id = {}
         for reg in self.ir_arch.arch.regs.all_regs_ids:
-            self.id_to_c_id[reg] = m2_expr.ExprId('mycpu->%s' % reg, reg.size)
+            self.id_to_c_id[reg] = ExprId('mycpu->%s' % reg, reg.size)
 
         self.C_PC = self.id_to_c(self.PC)
 
-    @staticmethod
-    def label_to_jitlabel(lbl):
-        """Convert AsmLabel to a jitter label name"""
-        assert lbl.offset is not None
-        return "jitblock_%X" % lbl.offset
+    def loc_key_to_jitlabel(self, lbl):
+        """Convert LocKey to a jitter label name"""
+        offset = self.ir_arch.symbol_pool.loc_key_to_offset(lbl)
+        assert offset is not None
+        return "jitblock_%X" % offset
 
     def dst_to_c(self, src):
         """Translate Expr @src into C code"""
-        if not isinstance(src, m2_expr.Expr):
-            src = m2_expr.ExprInt(src, self.PC.size)
+        if not isinstance(src, Expr):
+            src = ExprInt(src, self.PC.size)
         return self.id_to_c(src)
 
     def patch_c_id(self, expr):
@@ -132,12 +133,12 @@ class CGen(object):
         """Translate Expr @expr into corresponding C code"""
         return self.translator.from_expr(self.patch_c_id(expr))
 
-    def add_label_index(self, dst2index, lbl):
+    def add_label_index(self, dst2index, loc_key):
         """Insert @lbl to the dictionnary @dst2index with a uniq value
-        @dst2index: AsmLabel -> uniq value
-        @lbl: AsmLabel istance"""
+        @dst2index: LocKey -> uniq value
+        @loc_key: LocKey istance"""
 
-        dst2index[lbl] = len(dst2index)
+        dst2index[loc_key] = len(dst2index)
 
     def assignblk_to_irbloc(self, instr, assignblk):
         """
@@ -148,10 +149,11 @@ class CGen(object):
         new_assignblk = dict(assignblk)
         if self.ir_arch.IRDst not in assignblk:
             offset = instr.offset + instr.l
-            dst = m2_expr.ExprInt(offset, self.ir_arch.IRDst.size)
+            loc_key = self.ir_arch.symbol_pool.getby_offset_create(offset)
+            dst = ExprLoc(loc_key, self.ir_arch.IRDst.size)
             new_assignblk[self.ir_arch.IRDst] = dst
         irs = [AssignBlock(new_assignblk, instr)]
-        return IRBlock(self.ir_arch.get_instr_label(instr).loc_key, irs)
+        return IRBlock(self.ir_arch.get_loc_key_for_instr(instr), irs)
 
     def block2assignblks(self, block):
         """
@@ -169,6 +171,7 @@ class CGen(object):
             for irblock in irblocks:
                 assert irblock.dst is not None
             irblocks_list.append(irblocks)
+
         return irblocks_list
 
     def add_local_var(self, dst_var, dst_index, expr):
@@ -184,7 +187,7 @@ class CGen(object):
         if size not in dst_index:
             raise RuntimeError("Unsupported operand size %s", size)
         var_num = dst_index[size]
-        dst = m2_expr.ExprId("var_%.2d_%.2d" % (size, var_num), size)
+        dst = ExprId("var_%.2d_%.2d" % (size, var_num), size)
         dst_index[size] += 1
         dst_var[expr] = dst
         return dst
@@ -200,12 +203,13 @@ class CGen(object):
 
         # Prefetch memory read
         for expr in assignblk.get_r(mem_read=True):
-            if not isinstance(expr, m2_expr.ExprMem):
+            if not isinstance(expr, ExprMem):
                 continue
             var_num = mem_index[expr.size]
             mem_index[expr.size] += 1
-            var = m2_expr.ExprId(
-                "prefetch_%.2d_%.2d" % (expr.size, var_num), expr.size)
+            var = ExprId(
+                "prefetch_%.2d_%.2d" % (expr.size, var_num), expr.size
+            )
             mem_var[expr] = var
 
         # Generate memory prefetch
@@ -239,7 +243,7 @@ class CGen(object):
             src = src.replace_expr(prefetchers)
             if dst is self.ir_arch.IRDst:
                 pass
-            elif isinstance(dst, m2_expr.ExprId):
+            elif isinstance(dst, ExprId):
                 new_dst = self.add_local_var(dst_var, dst_index, dst)
                 if dst in self.ir_arch.arch.regs.regs_flt_expr:
                     # Dont mask float affectation
@@ -250,9 +254,9 @@ class CGen(object):
                         '%s = (%s)&%s;' % (self.id_to_c(new_dst),
                                            self.id_to_c(src),
                                            SIZE_TO_MASK[src.size]))
-            elif isinstance(dst, m2_expr.ExprMem):
+            elif isinstance(dst, ExprMem):
                 ptr = dst.arg.replace_expr(prefetchers)
-                new_dst = m2_expr.ExprMem(ptr, dst.size)
+                new_dst = ExprMem(ptr, dst.size)
                 str_dst = self.id_to_c(new_dst).replace('MEM_LOOKUP', 'MEM_WRITE')
                 c_mem.append('%s, %s);' % (str_dst[:-1], self.id_to_c(src)))
             else:
@@ -284,25 +288,25 @@ class CGen(object):
         @dst2index: dictionnary to link label to its index
         """
 
-        if isinstance(expr, m2_expr.ExprCond):
+        if isinstance(expr, ExprCond):
             cond = self.id_to_c(expr.cond)
             src1, src1b = self.traverse_expr_dst(expr.src1, dst2index)
             src2, src2b = self.traverse_expr_dst(expr.src2, dst2index)
             return ("((%s)?(%s):(%s))" % (cond, src1, src2),
                     "((%s)?(%s):(%s))" % (cond, src1b, src2b))
-        if isinstance(expr, m2_expr.ExprInt):
+        if isinstance(expr, ExprInt):
             offset = int(expr)
-            self.add_label_index(dst2index, offset)
-            return ("%s" % dst2index[offset], hex(offset))
-        if expr.is_label():
-            label = self.ir_arch.symbol_pool.loc_key_to_label(expr.loc_key)
-            if label.offset != None:
-                offset = label.offset
-                self.add_label_index(dst2index, offset)
-                return ("%s" % dst2index[offset], hex(offset))
-            self.add_label_index(dst2index, label)
-            return ("%s" % dst2index[label], "0")
-
+            loc_key = self.ir_arch.symbol_pool.getby_offset_create(offset)
+            self.add_label_index(dst2index, loc_key)
+            return ("%s" % dst2index[loc_key], hex(offset))
+        if expr.is_loc():
+            loc_key = expr.loc_key
+            offset = self.ir_arch.symbol_pool.loc_key_to_offset(expr.loc_key)
+            if offset is not None:
+                self.add_label_index(dst2index, loc_key)
+                return ("%s" % dst2index[loc_key], hex(offset))
+            self.add_label_index(dst2index, loc_key)
+            return ("%s" % dst2index[loc_key], "0")
         dst2index[expr] = -1
         return ("-1", self.id_to_c(expr))
 
@@ -355,24 +359,28 @@ class CGen(object):
         @attrib: instruction Attributes
         @instr_offsets: instructions offsets list
         @dst: potential instruction destination"""
-        if isinstance(dst, AsmLabel) and dst.offset is None:
-            # Generate goto for local labels
-            return ['goto %s;' % dst.name]
-        offset = None
-        if isinstance(dst, AsmLabel) and dst.offset is not None:
-            offset = dst.offset
-        elif isinstance(dst, (int, long)):
-            offset = dst
+
         out = []
-        if (offset is not None and
-            offset > attrib.instr.offset and
+        if isinstance(dst, Expr):
+            out += self.gen_post_code(attrib)
+            out.append('BlockDst->address = DST_value;')
+            out += self.gen_post_instr_checks(attrib)
+            out.append('\t\treturn JIT_RET_NO_EXCEPTION;')
+            return out
+
+        assert isinstance(dst, LocKey)
+        offset = self.ir_arch.symbol_pool.loc_key_to_offset(dst)
+        if offset is None:
+            # Generate goto for local labels
+            name = self.ir_arch.symbol_pool.loc_key_to_name(dst)
+            return ['goto %s;' % name]
+        if (offset > attrib.instr.offset and
             offset in instr_offsets):
             # Only generate goto for next instructions.
             # (consecutive instructions)
-            lbl = self.ir_arch.symbol_pool.getby_offset_create(dst)
             out += self.gen_post_code(attrib)
             out += self.gen_post_instr_checks(attrib)
-            out.append('goto %s;' % self.label_to_jitlabel(lbl))
+            out.append('goto %s;' % self.loc_key_to_jitlabel(dst))
         else:
             out += self.gen_post_code(attrib)
             out.append('BlockDst->address = DST_value;')
@@ -468,10 +476,10 @@ class CGen(object):
 
         element_read = assignblk.get_r(mem_read=True)
         # Check mem read
-        attrib.mem_read = any(isinstance(expr, m2_expr.ExprMem)
+        attrib.mem_read = any(isinstance(expr, ExprMem)
                               for expr in element_read)
         # Check mem write
-        attrib.mem_write = any(isinstance(dst, m2_expr.ExprMem)
+        attrib.mem_write = any(isinstance(dst, ExprMem)
                                for dst in assignblk)
 
     def get_attributes(self, instr, irblocks, log_mn=False, log_regs=False):
@@ -522,9 +530,11 @@ class CGen(object):
         """
 
         instr_offsets = [line.offset for line in block.lines]
-        instr_offsets.append(self.get_block_post_label(block).offset)
+        post_label = self.get_block_post_label(block)
+        post_offset = self.ir_arch.symbol_pool.loc_key_to_offset(post_label)
+        instr_offsets.append(post_offset)
         lbl_start = self.ir_arch.symbol_pool.getby_offset_create(instr_offsets[0])
-        return (self.CODE_INIT % self.label_to_jitlabel(lbl_start)).split("\n"), instr_offsets
+        return (self.CODE_INIT % self.loc_key_to_jitlabel(lbl_start)).split("\n"), instr_offsets
 
     def gen_irblock(self, instr_attrib, attributes, instr_offsets, irblock):
         """
@@ -557,8 +567,9 @@ class CGen(object):
         """
 
         lbl = self.get_block_post_label(block)
-        dst = self.dst_to_c(lbl.offset)
-        code = self.CODE_RETURN_NO_EXCEPTION % (self.label_to_jitlabel(lbl), self.C_PC, dst, dst)
+        offset = self.ir_arch.symbol_pool.loc_key_to_offset(lbl)
+        dst = self.dst_to_c(offset)
+        code = self.CODE_RETURN_NO_EXCEPTION % (self.loc_key_to_jitlabel(lbl), self.C_PC, dst, dst)
         return code.split('\n')
 
     def gen_c(self, block, log_mn=False, log_regs=False):
@@ -571,24 +582,25 @@ class CGen(object):
         if isinstance(block, AsmBlockBad):
             return self.gen_bad_block()
         irblocks_list = self.block2assignblks(block)
-
         out, instr_offsets = self.gen_init(block)
         assert len(block.lines) == len(irblocks_list)
         for instr, irblocks in zip(block.lines, irblocks_list):
             instr_attrib, irblocks_attributes = self.get_attributes(instr, irblocks, log_mn, log_regs)
-
             for index, irblock in enumerate(irblocks):
                 new_irblock = self.ir_arch.irbloc_fix_regs_for_mode(irblock, self.ir_arch.attrib)
-                label = self.ir_arch.symbol_pool.loc_key_to_label(new_irblock.label)
-                if label.offset is None:
+                label = new_irblock.loc_key
+                offset = self.ir_arch.symbol_pool.loc_key_to_offset(label)
+                if offset is None:
+                    name = self.ir_arch.symbol_pool.loc_key_to_name(label)
                     out.append("%-40s // %.16X %s" %
-                               (str(label.name) + ":", instr.offset, instr))
+                               (str(name) + ":", instr.offset, instr))
                 else:
                     out.append("%-40s // %.16X %s" %
-                               (self.label_to_jitlabel(label) + ":", instr.offset, instr))
+                               (self.loc_key_to_jitlabel(label) + ":", instr.offset, instr))
                 if index == 0:
                     out += self.gen_pre_code(instr_attrib)
                 out += self.gen_irblock(instr_attrib, irblocks_attributes[index], instr_offsets, new_irblock)
 
         out += self.gen_finalize(block)
+
         return ['\t' + line for line in out]
diff --git a/miasm2/jitter/jitcore.py b/miasm2/jitter/jitcore.py
index 4402ef49..8fd3453e 100644
--- a/miasm2/jitter/jitcore.py
+++ b/miasm2/jitter/jitcore.py
@@ -17,9 +17,10 @@
 #
 from hashlib import md5
 
-from miasm2.core.asmblock import disasmEngine, AsmLabel, AsmBlockBad
+from miasm2.core.asmblock import disasmEngine, AsmBlockBad
 from miasm2.core.interval import interval
 from miasm2.core.utils import BoundedDict
+from miasm2.expression.expression import LocKey
 from miasm2.jitter.csts import *
 
 
@@ -40,7 +41,7 @@ class JitCore(object):
         self.arch_name = "%s%s" % (self.ir_arch.arch.name, self.ir_arch.attrib)
         self.bs = bs
         self.known_blocs = {}
-        self.lbl2jitbloc = BoundedDict(self.jitted_block_max_size,
+        self.loc_key_to_jit_block = BoundedDict(self.jitted_block_max_size,
                                        delete_cb=self.jitted_block_delete_cb)
         self.lbl2bloc = {}
         self.log_mn = False
@@ -75,7 +76,7 @@ class JitCore(object):
 
     def clear_jitted_blocks(self):
         "Reset all jitted blocks"
-        self.lbl2jitbloc.clear()
+        self.loc_key_to_jit_block.clear()
         self.lbl2bloc.clear()
         self.blocs_mem_interval = interval()
 
@@ -100,8 +101,9 @@ class JitCore(object):
             cur_block.ad_max = cur_block.lines[-1].offset + cur_block.lines[-1].l
         else:
             # 1 byte block for unknown mnemonic
-            cur_block.ad_min = cur_block.label.offset
-            cur_block.ad_max = cur_block.label.offset+1
+            offset = ir_arch.symbol_pool.loc_key_to_offset(cur_block.loc_key)
+            cur_block.ad_min = offset
+            cur_block.ad_max = offset+1
 
 
     def add_bloc_to_mem_interval(self, vm, block):
@@ -125,20 +127,21 @@ class JitCore(object):
         """Add a block to JiT and JiT it.
         @block: asm_bloc to add
         """
-
         irblocks = self.ir_arch.add_block(block, gen_pc_updt = True)
         block.blocks = irblocks
-        self.jitirblocs(block.label, irblocks)
+        self.jitirblocs(block.loc_key, irblocks)
 
     def disbloc(self, addr, vm):
         """Disassemble a new block and JiT it
-        @addr: address of the block to disassemble (AsmLabel or int)
+        @addr: address of the block to disassemble (LocKey or int)
         @vm: VmMngr instance
         """
 
         # Get the block
-        if isinstance(addr, AsmLabel):
-            addr = addr.offset
+        if isinstance(addr, LocKey):
+            addr = self.ir_arch.symbol_pool.loc_key_to_offset(addr)
+            if addr is None:
+                raise RuntimeError("Unknown offset for LocKey")
 
         # Prepare disassembler
         self.mdis.lines_wd = self.options["jit_maxline"]
@@ -153,7 +156,7 @@ class JitCore(object):
             print cur_block
 
         # Update label -> block
-        self.lbl2bloc[cur_block.label] = cur_block
+        self.lbl2bloc[cur_block.loc_key] = cur_block
 
         # Store min/max block address needed in jit automod code
         self.get_bloc_min_max(cur_block)
@@ -174,7 +177,7 @@ class JitCore(object):
         if lbl is None:
             lbl = getattr(cpu, self.ir_arch.pc.name)
 
-        if not lbl in self.lbl2jitbloc:
+        if not lbl in self.loc_key_to_jit_block:
             # Need to JiT the block
             cur_block = self.disbloc(lbl, cpu.vmmngr)
             if isinstance(cur_block, AsmBlockBad):
@@ -188,7 +191,7 @@ class JitCore(object):
                 return lbl
 
         # Run the block and update cpu/vmmngr state
-        return self.exec_wrapper(lbl, cpu, self.lbl2jitbloc.data, breakpoints,
+        return self.exec_wrapper(lbl, cpu, self.loc_key_to_jit_block.data, breakpoints,
                                  self.options["max_exec_per_call"])
 
     def blocs2memrange(self, blocks):
@@ -245,16 +248,18 @@ class JitCore(object):
             try:
                 for irblock in block.blocks:
                     # Remove offset -> jitted block link
-                    if irblock.label.offset in self.lbl2jitbloc:
-                        del(self.lbl2jitbloc[irblock.label.offset])
+                    offset = self.ir_arch.symbol_pool.loc_key_to_offset(irblock.loc_key)
+                    if offset in self.loc_key_to_jit_block:
+                        del(self.loc_key_to_jit_block[offset])
 
             except AttributeError:
                 # The block has never been translated in IR
-                if block.label.offset in self.lbl2jitbloc:
-                    del(self.lbl2jitbloc[block.label.offset])
+                offset = self.ir_arch.symbol_pool.loc_key_to_offset(block.loc_key)
+                if offset in self.loc_key_to_jit_block:
+                    del(self.loc_key_to_jit_block[offset])
 
             # Remove label -> block link
-            del(self.lbl2bloc[block.label])
+            del(self.lbl2bloc[block.loc_key])
 
         return modified_blocks
 
@@ -283,7 +288,8 @@ class JitCore(object):
         @block: asmblock
         """
         block_raw = "".join(line.b for line in block.lines)
-        block_hash = md5("%X_%s_%s_%s_%s" % (block.label.offset,
+        offset = self.ir_arch.symbol_pool.loc_key_to_offset(block.loc_key)
+        block_hash = md5("%X_%s_%s_%s_%s" % (offset,
                                              self.arch_name,
                                              self.log_mn,
                                              self.log_regs,
diff --git a/miasm2/jitter/jitcore_cc_base.py b/miasm2/jitter/jitcore_cc_base.py
index 4dd8825a..f0a75cf4 100644
--- a/miasm2/jitter/jitcore_cc_base.py
+++ b/miasm2/jitter/jitcore_cc_base.py
@@ -85,20 +85,20 @@ class JitCore_Cc_Base(JitCore):
         """
         self.codegen = codegen
 
-    def label2fname(self, label):
+    def loc_key_to_filename(self, loc_key):
         """
-        Generate function name from @label
-        @label: AsmLabel instance
+        Generate function name from @loc_key
+        @loc_key: LocKey instance
         """
-        return "block_%s" % self.codegen.label_to_jitlabel(label)
+        return "block_%s" % self.codegen.loc_key_to_jitlabel(loc_key)
 
-    def gen_c_code(self, label, block):
+    def gen_c_code(self, loc_key, block):
         """
         Return the C code corresponding to the @irblocks
-        @label: AsmLabel of the block to jit
+        @loc_key: LocKey of the block to jit
         @irblocks: list of irblocks
         """
-        f_name = self.label2fname(label)
+        f_name = self.loc_key_to_filename(loc_key)
         f_declaration = 'int %s(block_id * BlockDst, JitCpu* jitcpu)' % f_name
         out = self.codegen.gen_c(block, log_mn=self.log_mn, log_regs=self.log_regs)
         out = [f_declaration + '{'] + out + ['}\n']
diff --git a/miasm2/jitter/jitcore_gcc.py b/miasm2/jitter/jitcore_gcc.py
index ccccc37a..d9da3160 100644
--- a/miasm2/jitter/jitcore_gcc.py
+++ b/miasm2/jitter/jitcore_gcc.py
@@ -25,12 +25,13 @@ class JitCore_Gcc(JitCore_Cc_Base):
         del self.states[offset]
 
     def load_code(self, label, fname_so):
-        f_name = self.label2fname(label)
+        f_name = self.loc_key_to_filename(label)
         lib = ctypes.cdll.LoadLibrary(fname_so)
         func = getattr(lib, f_name)
         addr = ctypes.cast(func, ctypes.c_void_p).value
-        self.lbl2jitbloc[label.offset] = addr
-        self.states[label.offset] = lib
+        offset = self.ir_arch.symbol_pool.loc_key_to_offset(label)
+        self.loc_key_to_jit_block[offset] = addr
+        self.states[offset] = lib
 
     def add_bloc(self, block):
         """Add a bloc to JiT and JiT it.
@@ -40,7 +41,7 @@ class JitCore_Gcc(JitCore_Cc_Base):
         fname_out = os.path.join(self.tempdir, "%s.so" % block_hash)
 
         if not os.access(fname_out, os.R_OK | os.X_OK):
-            func_code = self.gen_c_code(block.label, block)
+            func_code = self.gen_c_code(block.loc_key, block)
 
             # Create unique C file
             fdesc, fname_in = tempfile.mkstemp(suffix=".c")
@@ -60,7 +61,7 @@ class JitCore_Gcc(JitCore_Cc_Base):
             os.rename(fname_tmp, fname_out)
             os.remove(fname_in)
 
-        self.load_code(block.label, fname_out)
+        self.load_code(block.loc_key, fname_out)
 
     @staticmethod
     def gen_C_source(ir_arch, func_code):
diff --git a/miasm2/jitter/jitcore_llvm.py b/miasm2/jitter/jitcore_llvm.py
index a8d30f46..5152cf9e 100644
--- a/miasm2/jitter/jitcore_llvm.py
+++ b/miasm2/jitter/jitcore_llvm.py
@@ -84,7 +84,7 @@ class JitCore_LLVM(jitcore.JitCore):
 
         if not os.access(fname_out, os.R_OK):
             # Build a function in the context
-            func = LLVMFunction(self.context, block.label)
+            func = LLVMFunction(self.context, block.loc_key)
 
             # Set log level
             func.log_regs = self.log_regs
@@ -115,7 +115,9 @@ class JitCore_LLVM(jitcore.JitCore):
 
         else:
             # The cache file exists: function can be loaded from cache
-            ptr = self.context.get_ptr_from_cache(fname_out, block.label)
+            ptr = self.context.get_ptr_from_cache(fname_out, block.loc_key)
 
         # Store a pointer on the function jitted code
-        self.lbl2jitbloc[block.label.offset] = ptr
+        loc_key = block.loc_key
+        offset = self.ir_arch.symbol_pool.loc_key_to_offset(loc_key)
+        self.loc_key_to_jit_block[offset] = ptr
diff --git a/miasm2/jitter/jitcore_python.py b/miasm2/jitter/jitcore_python.py
index af9f09e6..785e3fa1 100644
--- a/miasm2/jitter/jitcore_python.py
+++ b/miasm2/jitter/jitcore_python.py
@@ -34,9 +34,9 @@ class JitCore_Python(jitcore.JitCore):
         "Preload symbols according to current architecture"
         self.symbexec.reset_regs()
 
-    def jitirblocs(self, label, irblocks):
+    def jitirblocs(self, loc_key, irblocks):
         """Create a python function corresponding to an irblocks' group.
-        @label: the label of the irblocks
+        @loc_key: the loc_key of the irblocks
         @irblocks: a gorup of irblocks
         """
 
@@ -48,7 +48,7 @@ class JitCore_Python(jitcore.JitCore):
             vmmngr = cpu.vmmngr
 
             # Keep current location in irblocks
-            cur_label = label.loc_key
+            cur_loc_key = loc_key
 
             # Required to detect new instructions
             offsets_jitted = set()
@@ -57,13 +57,12 @@ class JitCore_Python(jitcore.JitCore):
             exec_engine = self.symbexec
             expr_simp = exec_engine.expr_simp
 
-            known_loc_keys = set(irb.label for irb in irblocks)
+            known_loc_keys = set(irb.loc_key for irb in irblocks)
             # For each irbloc inside irblocks
             while True:
-
                 # Get the current bloc
                 for irb in irblocks:
-                    if irb.label == cur_label:
+                    if irb.loc_key == cur_loc_key:
                         break
 
                 else:
@@ -123,24 +122,24 @@ class JitCore_Python(jitcore.JitCore):
                 if isinstance(ad, m2_expr.ExprInt):
                     return ad.arg.arg
                 elif isinstance(ad, m2_expr.ExprLoc):
-                    cur_label = ad.loc_key
-                    if cur_label not in known_loc_keys:
-                        return cur_label
+                    cur_loc_key = ad.loc_key
                 else:
                     raise NotImplementedError("Type not handled: %s" % ad)
 
-        # Associate myfunc with current label
-        self.lbl2jitbloc[label.offset] = myfunc
+        # Associate myfunc with current loc_key
+        offset = self.ir_arch.symbol_pool.loc_key_to_offset(loc_key)
+        assert offset is not None
+        self.loc_key_to_jit_block[offset] = myfunc
 
-    def exec_wrapper(self, label, cpu, _lbl2jitbloc, _breakpoints,
+    def exec_wrapper(self, loc_key, cpu, _loc_key_to_jit_block, _breakpoints,
                      _max_exec_per_call):
-        """Call the function @label with @cpu
-        @label: function's label
+        """Call the function @loc_key with @cpu
+        @loc_key: function's loc_key
         @cpu: JitCpu instance
         """
 
-        # Get Python function corresponding to @label
-        fc_ptr = self.lbl2jitbloc[label]
+        # Get Python function corresponding to @loc_key
+        fc_ptr = self.loc_key_to_jit_block[loc_key]
 
         # Execute the function
         return fc_ptr(cpu)
diff --git a/miasm2/jitter/llvmconvert.py b/miasm2/jitter/llvmconvert.py
index 3f7d0c6d..2045f083 100644
--- a/miasm2/jitter/llvmconvert.py
+++ b/miasm2/jitter/llvmconvert.py
@@ -14,7 +14,8 @@
 import os
 from llvmlite import binding as llvm
 from llvmlite import ir as llvm_ir
-import miasm2.expression.expression as m2_expr
+from miasm2.expression.expression import ExprId, ExprInt, ExprMem, ExprSlice, \
+    ExprCond, ExprLoc, ExprOp, ExprCompose, LocKey
 import miasm2.jitter.csts as m2_csts
 import miasm2.core.asmblock as m2_asmblock
 from miasm2.jitter.codegen import CGen
@@ -43,7 +44,7 @@ class LLVMType(llvm_ir.Type):
     @classmethod
     def generic(cls, e):
         "Generic value for execution"
-        if isinstance(e, m2_expr.ExprInt):
+        if isinstance(e, ExprInt):
             return llvm_e.GenericValue.int(LLVMType.IntType(e.size), int(e.arg))
         elif isinstance(e, llvm_e.GenericValue):
             return e
@@ -69,25 +70,21 @@ class LLVMContext():
         self.target_machine = target.create_target_machine()
         self.init_exec_engine()
 
-
     def canonize_label_name(self, label):
         """Canonize @label names to a common form.
         @label: str or asmlabel instance"""
         if isinstance(label, str):
             return label
-        if isinstance(label, m2_expr.Expr) and expr.is_label():
-            label = self.llvm_context.ir_arch.symbol_pool.loc_key_to_label(label.index)
-        if isinstance(label, (int, long)):
-            fds
-            label = self.llvm_context.ir_arch.symbol_pool.loc_key_to_label(label)
-
-        if isinstance(label, m2_asmblock.AsmLabel):
-            if label.offset is None:
-                return "label_%s" % label.name
-            else:
-                return "label_%X" % label.offset
+        if not isinstance(label, LocKey):
+            raise ValueError("label must either be str or LocKey")
+
+        offset = self.ir_arch.symbol_pool.loc_key_to_offset(label)
+
+        if offset is None:
+            name = self.ir_arch.symbol_pool.loc_key_to_name(label)
+            return "%s" % name
         else:
-            raise ValueError("label must either be str or asmlabel")
+            return "label_off_%X" % offset
 
     def optimise_level(self, level=2):
         """Set the optimisation level to @level from 0 to 2
@@ -400,8 +397,8 @@ class LLVMFunction():
 
     def __init__(self, llvm_context, name="fc", new_module=True):
         "Create a new function with name @name"
-        name = self.canonize_label_name(name)
         self.llvm_context = llvm_context
+        name = self.llvm_context.canonize_label_name(name)
         if new_module:
             self.llvm_context.new_module()
         self.mod = self.llvm_context.get_module()
@@ -427,7 +424,7 @@ class LLVMFunction():
         @label: str or asmlabel
         @overwrite: if False, do nothing if a bbl with the same name already exists
         Return the corresponding LLVM Basic Block"""
-        name = self.canonize_label_name(label)
+        name = self.llvm_context.canonize_label_name(label)
         bbl = self.name2bbl.get(name, None)
         if not overwrite and bbl is not None:
             return bbl
@@ -505,27 +502,9 @@ class LLVMFunction():
             var_casted = var
         self.builder.ret(var_casted)
 
-    def canonize_label_name(self, label):
-        """Canonize @label names to a common form.
-        @label: str or asmlabel instance"""
-        if isinstance(label, str):
-            return label
-        if isinstance(label, m2_expr.Expr) and expr.is_label():
-            label = self.llvm_context.ir_arch.symbol_pool.loc_key_to_label(label.index)
-        if isinstance(label, m2_expr.LocKey):
-            label = self.llvm_context.ir_arch.symbol_pool.loc_key_to_label(label)
-
-        if isinstance(label, m2_asmblock.AsmLabel):
-            if label.offset is None:
-                return "label_%s" % label.name
-            else:
-                return "label_%X" % label.offset
-        else:
-            raise ValueError("label must either be str or asmlabel")
-
-    def get_basic_bloc_by_label(self, label):
+    def get_basic_block_by_loc_key(self, loc_key):
         "Return the bbl corresponding to label, None otherwise"
-        return self.name2bbl.get(self.canonize_label_name(label), None)
+        return self.name2bbl.get(self.llvm_context.canonize_label_name(loc_key), None)
 
     def global_constant(self, name, value):
         """
@@ -591,11 +570,11 @@ class LLVMFunction():
         # Destination
         builder = self.builder
 
-        if isinstance(dst, m2_expr.ExprId):
+        if isinstance(dst, ExprId):
             ptr_casted = self.get_ptr_by_expr(dst)
             builder.store(src, ptr_casted)
 
-        elif isinstance(dst, m2_expr.ExprMem):
+        elif isinstance(dst, ExprMem):
             addr = self.add_ir(dst.arg)
             self.llvm_context.memory_write(self, addr, dst.size, src)
         else:
@@ -648,19 +627,18 @@ class LLVMFunction():
 
         builder = self.builder
 
-        if isinstance(expr, m2_expr.ExprInt):
+        if isinstance(expr, ExprInt):
             ret = llvm_ir.Constant(LLVMType.IntType(expr.size), int(expr.arg))
             self.update_cache(expr, ret)
             return ret
 
-        if expr.is_label():
-            label = self.llvm_context.ir_arch.symbol_pool.loc_key_to_label(expr.loc_key)
-            offset = label.offset
+        if expr.is_loc():
+            offset = self.llvm_context.ir_arch.symbol_pool.loc_key_to_offset(expr.loc_key)
             ret = llvm_ir.Constant(LLVMType.IntType(expr.size), offset)
             self.update_cache(expr, ret)
             return ret
 
-        if isinstance(expr, m2_expr.ExprId):
+        if isinstance(expr, ExprId):
             name = expr.name
             try:
                 # If expr.name is already known (args)
@@ -674,7 +652,7 @@ class LLVMFunction():
             self.update_cache(expr, var)
             return var
 
-        if isinstance(expr, m2_expr.ExprOp):
+        if isinstance(expr, ExprOp):
             op = expr.op
 
             if (op in self.op_translate or
@@ -881,12 +859,12 @@ class LLVMFunction():
 
             raise NotImplementedError()
 
-        if isinstance(expr, m2_expr.ExprMem):
+        if isinstance(expr, ExprMem):
 
             addr = self.add_ir(expr.arg)
             return self.llvm_context.memory_lookup(self, addr, expr.size)
 
-        if isinstance(expr, m2_expr.ExprCond):
+        if isinstance(expr, ExprCond):
             # Compute cond
             cond = self.add_ir(expr.cond)
             zero_casted = LLVMType.IntType(expr.cond.size)(0)
@@ -899,7 +877,7 @@ class LLVMFunction():
             self.update_cache(expr, ret)
             return ret
 
-        if isinstance(expr, m2_expr.ExprSlice):
+        if isinstance(expr, ExprSlice):
 
             src = self.add_ir(expr.arg)
 
@@ -925,7 +903,7 @@ class LLVMFunction():
             self.update_cache(expr, ret)
             return ret
 
-        if isinstance(expr, m2_expr.ExprCompose):
+        if isinstance(expr, ExprCompose):
 
             args = []
 
@@ -1006,9 +984,9 @@ class LLVMFunction():
         builder.position_at_end(then_block)
         PC = self.llvm_context.PC
         if isinstance(offset, (int, long)):
-            offset = self.add_ir(m2_expr.ExprInt(offset, PC.size))
+            offset = self.add_ir(ExprInt(offset, PC.size))
         self.affect(offset, PC)
-        self.affect(self.add_ir(m2_expr.ExprInt(1, 8)), m2_expr.ExprId("status", 32))
+        self.affect(self.add_ir(ExprInt(1, 8)), ExprId("status", 32))
         self.set_ret(offset)
 
         builder.position_at_end(merge_block)
@@ -1053,9 +1031,9 @@ class LLVMFunction():
         builder.position_at_end(then_block)
         PC = self.llvm_context.PC
         if isinstance(offset, (int, long)):
-            offset = self.add_ir(m2_expr.ExprInt(offset, PC.size))
+            offset = self.add_ir(ExprInt(offset, PC.size))
         self.affect(offset, PC)
-        self.affect(self.add_ir(m2_expr.ExprInt(1, 8)), m2_expr.ExprId("status", 32))
+        self.affect(self.add_ir(ExprInt(1, 8)), ExprId("status", 32))
         self.set_ret(offset)
 
         builder.position_at_end(merge_block)
@@ -1100,9 +1078,9 @@ class LLVMFunction():
         for i, solution in enumerate(possible_values(expr)):
             value = solution.value
             index = dst2case.get(value, i)
-            to_eval = to_eval.replace_expr({value: m2_expr.ExprInt(index, value.size)})
+            to_eval = to_eval.replace_expr({value: ExprInt(index, value.size)})
             dst2case[value] = index
-            if value.is_int() or value.is_label():
+            if value.is_int() or value.is_loc():
                 case2dst[i] = value
             else:
                 case2dst[i] = self.add_ir(value)
@@ -1128,14 +1106,14 @@ class LLVMFunction():
         # We are no longer in the main stream, deactivate cache
         self.main_stream = False
 
-        if isinstance(dst, m2_expr.ExprInt):
-            label = self.llvm_context.ir_arch.symbol_pool.getby_offset_create(int(dst))
-            dst = m2_expr.ExprLoc(label.loc_key, dst.size)
+        if isinstance(dst, ExprInt):
+            loc_key = self.llvm_context.ir_arch.symbol_pool.getby_offset_create(int(dst))
+            dst = ExprLoc(loc_key, dst.size)
 
-        if isinstance(dst, m2_expr.ExprLoc):
-            label = self.llvm_context.ir_arch.symbol_pool.loc_key_to_label(dst.loc_key)
-            bbl = self.get_basic_bloc_by_label(label)
-            offset = label.offset
+        if isinstance(dst, ExprLoc):
+            loc_key = dst.loc_key
+            bbl = self.get_basic_block_by_loc_key(loc_key)
+            offset = self.llvm_context.ir_arch.symbol_pool.loc_key_to_offset(loc_key)
             if bbl is not None:
                 # "local" jump, inside this function
                 if offset is None:
@@ -1155,7 +1133,7 @@ class LLVMFunction():
                 # extern
 
             # "extern" jump on a defined offset, return to the caller
-            dst = self.add_ir(m2_expr.ExprInt(offset, PC.size))
+            dst = self.add_ir(ExprInt(offset, PC.size))
 
         # "extern" jump with a computed value, return to the caller
         assert isinstance(dst, (llvm_ir.Instruction, llvm_ir.Value))
@@ -1167,7 +1145,7 @@ class LLVMFunction():
         self.gen_post_code(attrib)
         self.affect(dst, PC)
         self.gen_post_instr_checks(attrib, dst)
-        self.affect(self.add_ir(m2_expr.ExprInt(0, 8)), m2_expr.ExprId("status", 32))
+        self.affect(self.add_ir(ExprInt(0, 8)), ExprId("status", 32))
         self.set_ret(dst)
 
 
@@ -1191,7 +1169,7 @@ class LLVMFunction():
 
             # Prefetch memory
             for element in assignblk.get_r(mem_read=True):
-                if isinstance(element, m2_expr.ExprMem):
+                if isinstance(element, ExprMem):
                     self.add_ir(element)
 
             # Evaluate expressions
@@ -1209,7 +1187,7 @@ class LLVMFunction():
 
             # Update the memory
             for dst, src in values.iteritems():
-                if isinstance(dst, m2_expr.ExprMem):
+                if isinstance(dst, ExprMem):
                     self.affect(src, dst)
 
             # Check memory write exception
@@ -1219,7 +1197,7 @@ class LLVMFunction():
 
             # Update registers values
             for dst, src in values.iteritems():
-                if not isinstance(dst, m2_expr.ExprMem):
+                if not isinstance(dst, ExprMem):
                     self.affect(src, dst)
 
             # Check post assignblk exception flags
@@ -1260,11 +1238,12 @@ class LLVMFunction():
         builder = self.builder
         m2_exception_flag = self.llvm_context.ir_arch.arch.regs.exception_flags
         t_size = LLVMType.IntType(m2_exception_flag.size)
-        self.affect(self.add_ir(m2_expr.ExprInt(1, 8)),
-                    m2_expr.ExprId("status", 32))
+        self.affect(self.add_ir(ExprInt(1, 8)),
+                    ExprId("status", 32))
         self.affect(t_size(m2_csts.EXCEPT_UNK_MNEMO),
                     m2_exception_flag)
-        self.set_ret(LLVMType.IntType(64)(asmblock.label.offset))
+        offset = self.llvm_context.ir_arch.symbol_pool.loc_key_to_offset(asmblock.loc_key)
+        self.set_ret(LLVMType.IntType(64)(offset))
 
     def gen_finalize(self, asmblock, codegen):
         """
@@ -1275,11 +1254,11 @@ class LLVMFunction():
             next_label = codegen.get_block_post_label(asmblock)
             builder = self.builder
 
-            builder.position_at_end(self.get_basic_bloc_by_label(next_label))
+            builder.position_at_end(self.get_basic_block_by_loc_key(next_label))
 
             # Common code
-            self.affect(self.add_ir(m2_expr.ExprInt(0, 8)),
-                        m2_expr.ExprId("status", 32))
+            self.affect(self.add_ir(ExprInt(0, 8)),
+                        ExprId("status", 32))
 
             # Check if IRDst has been set
             zero_casted = LLVMType.IntType(codegen.delay_slot_set.size)(0)
@@ -1302,14 +1281,15 @@ class LLVMFunction():
             PC = self.llvm_context.PC
             to_ret = self.add_ir(codegen.delay_slot_dst)
             self.affect(to_ret, PC)
-            self.affect(self.add_ir(m2_expr.ExprInt(0, 8)),
-                        m2_expr.ExprId("status", 32))
+            self.affect(self.add_ir(ExprInt(0, 8)),
+                        ExprId("status", 32))
             self.set_ret(to_ret)
 
             # Else Block
             builder.position_at_end(else_block)
             PC = self.llvm_context.PC
-            to_ret = LLVMType.IntType(PC.size)(next_label.offset)
+            next_label_offset = self.llvm_context.ir_arch.symbol_pool.loc_key_to_offset(next_label)
+            to_ret = LLVMType.IntType(PC.size)(next_label_offset)
             self.affect(to_ret, PC)
             self.set_ret(to_ret)
 
@@ -1318,16 +1298,16 @@ class LLVMFunction():
         Prototype : f(i8* jitcpu, i8* vmcpu, i8* vmmngr, i8* status)"""
 
         # Build function signature
-        self.my_args.append((m2_expr.ExprId("jitcpu", 32),
+        self.my_args.append((ExprId("jitcpu", 32),
                              llvm_ir.PointerType(LLVMType.IntType(8)),
                              "jitcpu"))
-        self.my_args.append((m2_expr.ExprId("vmcpu", 32),
+        self.my_args.append((ExprId("vmcpu", 32),
                              llvm_ir.PointerType(LLVMType.IntType(8)),
                              "vmcpu"))
-        self.my_args.append((m2_expr.ExprId("vmmngr", 32),
+        self.my_args.append((ExprId("vmmngr", 32),
                              llvm_ir.PointerType(LLVMType.IntType(8)),
                              "vmmngr"))
-        self.my_args.append((m2_expr.ExprId("status", 32),
+        self.my_args.append((ExprId("status", 32),
                              llvm_ir.PointerType(LLVMType.IntType(8)),
                              "status"))
         ret_size = 64
@@ -1360,9 +1340,10 @@ class LLVMFunction():
                 ptr = self.CreateEntryBlockAlloca(eltype,
                                                   default_value=eltype(0))
                 self.local_vars_pointers[element.name] = ptr
-            lbl = codegen.get_block_post_label(asmblock)
-            instr_offsets.append(lbl.offset)
-            self.append_basic_block(lbl)
+            loc_key = codegen.get_block_post_label(asmblock)
+            offset = self.llvm_context.ir_arch.symbol_pool.loc_key_to_offset(loc_key)
+            instr_offsets.append(offset)
+            self.append_basic_block(loc_key)
 
         # Add content
         builder.position_at_end(entry_bbl)
@@ -1375,7 +1356,7 @@ class LLVMFunction():
 
             # Pre-create basic blocks
             for irblock in irblocks:
-                self.append_basic_block(irblock.label, overwrite=False)
+                self.append_basic_block(irblock.loc_key, overwrite=False)
 
             # Generate the corresponding code
             for index, irblock in enumerate(irblocks):
@@ -1383,8 +1364,7 @@ class LLVMFunction():
                     irblock, self.llvm_context.ir_arch.attrib)
 
                 # Set the builder at the begining of the correct bbl
-                name = self.canonize_label_name(new_irblock.label)
-                self.builder.position_at_end(self.get_basic_bloc_by_label(name))
+                self.builder.position_at_end(self.get_basic_block_by_loc_key(new_irblock.loc_key))
 
                 if index == 0:
                     self.gen_pre_code(instr_attrib)
@@ -1395,7 +1375,7 @@ class LLVMFunction():
 
         # Branch entry_bbl on first label
         builder.position_at_end(entry_bbl)
-        first_label_bbl = self.get_basic_bloc_by_label(asmblock.label)
+        first_label_bbl = self.get_basic_block_by_loc_key(asmblock.loc_key)
         builder.branch(first_label_bbl)
 
 
diff --git a/miasm2/jitter/loader/pe.py b/miasm2/jitter/loader/pe.py
index ea6c2c98..9bc0ef8b 100644
--- a/miasm2/jitter/loader/pe.py
+++ b/miasm2/jitter/loader/pe.py
@@ -162,7 +162,9 @@ def vm_load_pe(vm, fdata, align_s=True, load_hdr=True, name="", **kargs):
                 new_size = pe.SHList[i + 1].addr - section.addr
                 section.size = new_size
                 section.rawsize = new_size
-                section.data = section.data[:new_size]
+                section.data = strpatchwork.StrPatchwork(
+                    section.data[:new_size]
+                )
                 section.offset = section.addr
 
             # Last section alignement