diff options
Diffstat (limited to 'miasm2/jitter')
| -rw-r--r-- | miasm2/jitter/codegen.py | 27 | ||||
| -rw-r--r-- | miasm2/jitter/jitcore_llvm.py | 5 | ||||
| -rw-r--r-- | miasm2/jitter/jitcore_python.py | 12 | ||||
| -rw-r--r-- | miasm2/jitter/jitload.py | 1 | ||||
| -rw-r--r-- | miasm2/jitter/llvmconvert.py | 59 | ||||
| -rw-r--r-- | miasm2/jitter/loader/pe.py | 3 |
6 files changed, 69 insertions, 38 deletions
diff --git a/miasm2/jitter/codegen.py b/miasm2/jitter/codegen.py index b10a9257..519664e3 100644 --- a/miasm2/jitter/codegen.py +++ b/miasm2/jitter/codegen.py @@ -4,16 +4,17 @@ Module to generate C code for a given native @block import miasm2.expression.expression as m2_expr from miasm2.ir.ir import IRBlock, AssignBlock -from miasm2.ir.translators import Translator -from miasm2.core.asmblock import expr_is_label, AsmBlockBad, AsmLabel -# Miasm to C translator -TRANSLATOR = Translator.to_language("C") +from miasm2.ir.translators.C import TranslatorC +from miasm2.core.asmblock import AsmBlockBad -SIZE_TO_MASK = {size: TRANSLATOR.from_expr(m2_expr.ExprInt(0, size).mask) +TRANSLATOR_NO_SYMBOL = TranslatorC(symbol_pool=None) + +SIZE_TO_MASK = {size: TRANSLATOR_NO_SYMBOL.from_expr(ExprInt(0, size).mask) for size in (1, 2, 3, 7, 8, 16, 32, 64, 128)} + class Attributes(object): """ @@ -100,6 +101,7 @@ class CGen(object): def __init__(self, ir_arch): self.ir_arch = ir_arch self.PC = self.ir_arch.pc + self.translator = TranslatorC(self.ir_arch.symbol_pool) self.init_arch_C() def init_arch_C(self): @@ -128,7 +130,7 @@ class CGen(object): def id_to_c(self, expr): """Translate Expr @expr into corresponding C code""" - return TRANSLATOR.from_expr(self.patch_c_id(expr)) + return self.translator.from_expr(self.patch_c_id(expr)) def add_label_index(self, dst2index, lbl): """Insert @lbl to the dictionnary @dst2index with a uniq value @@ -149,7 +151,7 @@ class CGen(object): dst = m2_expr.ExprInt(offset, 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), irs) + return IRBlock(self.ir_arch.get_instr_label(instr).loc_key, irs) def block2assignblks(self, block): """ @@ -292,8 +294,8 @@ class CGen(object): offset = int(expr) self.add_label_index(dst2index, offset) return ("%s" % dst2index[offset], hex(offset)) - if expr_is_label(expr): - label = expr.name + 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) @@ -577,12 +579,13 @@ class CGen(object): for index, irblock in enumerate(irblocks): new_irblock = self.ir_arch.irbloc_fix_regs_for_mode(irblock, self.ir_arch.attrib) - if new_irblock.label.offset is None: + label = self.ir_arch.symbol_pool.loc_key_to_label(new_irblock.label) + if label.offset is None: out.append("%-40s // %.16X %s" % - (str(new_irblock.label.name) + ":", instr.offset, instr)) + (str(label.name) + ":", instr.offset, instr)) else: out.append("%-40s // %.16X %s" % - (self.label_to_jitlabel(new_irblock.label) + ":", instr.offset, instr)) + (self.label_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) diff --git a/miasm2/jitter/jitcore_llvm.py b/miasm2/jitter/jitcore_llvm.py index 452b6d84..a8d30f46 100644 --- a/miasm2/jitter/jitcore_llvm.py +++ b/miasm2/jitter/jitcore_llvm.py @@ -78,12 +78,13 @@ class JitCore_LLVM(jitcore.JitCore): """Add a block to JiT and JiT it. @block: the block to add """ + block_hash = self.hash_block(block) fname_out = os.path.join(self.tempdir, "%s.bc" % block_hash) if not os.access(fname_out, os.R_OK): # Build a function in the context - func = LLVMFunction(self.context, LLVMFunction.canonize_label_name(block.label)) + func = LLVMFunction(self.context, block.label) # Set log level func.log_regs = self.log_regs @@ -114,7 +115,7 @@ 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, LLVMFunction.canonize_label_name(block.label)) + ptr = self.context.get_ptr_from_cache(fname_out, block.label) # Store a pointer on the function jitted code self.lbl2jitbloc[block.label.offset] = ptr diff --git a/miasm2/jitter/jitcore_python.py b/miasm2/jitter/jitcore_python.py index 799848ab..af9f09e6 100644 --- a/miasm2/jitter/jitcore_python.py +++ b/miasm2/jitter/jitcore_python.py @@ -48,7 +48,7 @@ class JitCore_Python(jitcore.JitCore): vmmngr = cpu.vmmngr # Keep current location in irblocks - cur_label = label + cur_label = label.loc_key # Required to detect new instructions offsets_jitted = set() @@ -57,6 +57,7 @@ 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) # For each irbloc inside irblocks while True: @@ -64,6 +65,7 @@ class JitCore_Python(jitcore.JitCore): for irb in irblocks: if irb.label == cur_label: break + else: raise RuntimeError("Irblocks must end with returning an " "ExprInt instance") @@ -75,7 +77,7 @@ class JitCore_Python(jitcore.JitCore): for assignblk in irb: instr = assignblk.instr # For each new instruction (in assembly) - if instr.offset not in offsets_jitted: + if instr is not None and instr.offset not in offsets_jitted: # Test exceptions vmmngr.check_invalid_code_blocs() vmmngr.check_memory_breakpoint() @@ -120,8 +122,10 @@ class JitCore_Python(jitcore.JitCore): # Manage resulting address if isinstance(ad, m2_expr.ExprInt): return ad.arg.arg - elif isinstance(ad, m2_expr.ExprId): - cur_label = ad.name + elif isinstance(ad, m2_expr.ExprLoc): + cur_label = ad.loc_key + if cur_label not in known_loc_keys: + return cur_label else: raise NotImplementedError("Type not handled: %s" % ad) diff --git a/miasm2/jitter/jitload.py b/miasm2/jitter/jitload.py index db486b4f..28200997 100644 --- a/miasm2/jitter/jitload.py +++ b/miasm2/jitter/jitload.py @@ -313,7 +313,6 @@ class jitter(object): Check exceptions before breakpoints.""" self.pc = pc - # Callback called before exec if self.exec_cb is not None: res = self.exec_cb(self) diff --git a/miasm2/jitter/llvmconvert.py b/miasm2/jitter/llvmconvert.py index dd3afed6..3f7d0c6d 100644 --- a/miasm2/jitter/llvmconvert.py +++ b/miasm2/jitter/llvmconvert.py @@ -69,6 +69,26 @@ 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 + else: + raise ValueError("label must either be str or asmlabel") + def optimise_level(self, level=2): """Set the optimisation level to @level from 0 to 2 0: non-optimized @@ -324,6 +344,7 @@ class LLVMContext_JIT(LLVMContext): def get_ptr_from_cache(self, file_name, func_name): "Load @file_name and return a pointer on the jitter @func_name" # We use an empty module to avoid loosing time on function building + func_name = self.canonize_label_name(func_name) empty_module = llvm.parse_assembly("") empty_module.fname_out = file_name @@ -379,6 +400,7 @@ 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 if new_module: self.llvm_context.new_module() @@ -483,14 +505,16 @@ class LLVMFunction(): var_casted = var self.builder.ret(var_casted) - @staticmethod - def canonize_label_name(label): + 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 m2_asmblock.expr_is_label(label): - label = label.name + 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 @@ -629,15 +653,15 @@ class LLVMFunction(): 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 + ret = llvm_ir.Constant(LLVMType.IntType(expr.size), offset) + self.update_cache(expr, ret) + return ret + if isinstance(expr, m2_expr.ExprId): name = expr.name - if not isinstance(name, str): - # Resolve label - offset = name.offset - ret = llvm_ir.Constant(LLVMType.IntType(expr.size), offset) - self.update_cache(expr, ret) - return ret - try: # If expr.name is already known (args) return self.local_vars[name] @@ -1078,7 +1102,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_asmblock.expr_is_int_or_label(value): + if value.is_int() or value.is_label(): case2dst[i] = value else: case2dst[i] = self.add_ir(value) @@ -1105,12 +1129,13 @@ class LLVMFunction(): self.main_stream = False if isinstance(dst, m2_expr.ExprInt): - dst = m2_expr.ExprId(self.llvm_context.ir_arch.symbol_pool.getby_offset_create(int(dst)), - dst.size) + label = self.llvm_context.ir_arch.symbol_pool.getby_offset_create(int(dst)) + dst = m2_expr.ExprLoc(label.loc_key, dst.size) - if m2_asmblock.expr_is_label(dst): - bbl = self.get_basic_bloc_by_label(dst) - offset = dst.name.offset + 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 bbl is not None: # "local" jump, inside this function if offset is None: diff --git a/miasm2/jitter/loader/pe.py b/miasm2/jitter/loader/pe.py index 2fe4cd3f..ea6c2c98 100644 --- a/miasm2/jitter/loader/pe.py +++ b/miasm2/jitter/loader/pe.py @@ -162,8 +162,7 @@ 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 = strpatchwork.StrPatchwork( - section.data[:new_size]) + section.data = section.data[:new_size] section.offset = section.addr # Last section alignement |