diff options
Diffstat (limited to 'miasm2/jitter')
| -rw-r--r-- | miasm2/jitter/codegen.py | 130 | ||||
| -rw-r--r-- | miasm2/jitter/jitcore.py | 44 | ||||
| -rw-r--r-- | miasm2/jitter/jitcore_cc_base.py | 14 | ||||
| -rw-r--r-- | miasm2/jitter/jitcore_gcc.py | 11 | ||||
| -rw-r--r-- | miasm2/jitter/jitcore_llvm.py | 8 | ||||
| -rw-r--r-- | miasm2/jitter/jitcore_python.py | 31 | ||||
| -rw-r--r-- | miasm2/jitter/llvmconvert.py | 154 | ||||
| -rw-r--r-- | miasm2/jitter/loader/pe.py | 4 |
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 |