def get_caracteristics(self, assignblk, attrib): """ Set the carateristics in @attrib according to the @assignblk @assignblk: an AssignBlock instance @attrib: an Attributes instance """ # Check explicit exception raising attrib.set_exception = self.ir_arch.arch.regs.exception_flags in assignblk element_read = assignblk.get_r(mem_read=True) # Check implicit exception raising attrib.op_set_exception = any( self.is_exception_operator(operator) for elem in assignblk.values() for operator in m2_expr.get_expr_ops(elem)) # Check mem read attrib.mem_read = any( isinstance(expr, m2_expr.ExprMem) for expr in element_read) # Check mem write attrib.mem_write = any( isinstance(dst, m2_expr.ExprMem) for dst in assignblk)
def get_caracteristics(self, irblock): """ Get the carateristics of each assignblk in the @irblock @irblock: an irbloc instance """ for assignblk in irblock.irs: assignblk.mem_read, assignblk.mem_write = False, False assignblk.op_set_exception = False # Check explicit exception raising assignblk.set_exception = self.ir_arch.arch.regs.exception_flags in assignblk element_read = assignblk.get_r(mem_read=True) # Check implicit exception raising assignblk.op_set_exception = any(self.is_exception_operator(operator) for elem in assignblk.values() for operator in m2_expr.get_expr_ops(elem)) # Check mem read assignblk.mem_read = any(isinstance(expr, m2_expr.ExprMem) for expr in element_read) # Check mem write assignblk.mem_write = any(isinstance(dst, m2_expr.ExprMem) for dst in assignblk)
def Expr2C(ir_arch, l, exprs, gen_exception_code=False): id_to_update = [] out = ["// %s" % (l)] out_pc = [] dst_dict = {} src_mem = {} prefect_index = {8: 0, 16: 0, 32: 0, 64: 0} new_expr = [] e = set_pc(ir_arch, l.offset & mask_int) #out.append("%s;" % patch_c_id(ir_arch.arch, e))) pc_is_dst = False fetch_mem = False set_exception_flags = False for e in exprs: assert isinstance(e, m2_expr.ExprAff) assert not isinstance(e.dst, m2_expr.ExprOp) if isinstance(e.dst, m2_expr.ExprId): if not e.dst in dst_dict: dst_dict[e.dst] = [] dst_dict[e.dst].append(e) else: new_expr.append(e) # test exception flags ops = m2_expr.get_expr_ops(e) if set(['umod', 'udiv']).intersection(ops): set_exception_flags = True if e.dst == exception_flags: set_exception_flags = True # TODO XXX test function whose set exception_flags # search mem lookup for generate mem read prefetch rs = e.src.get_r(mem_read=True) for r in rs: if (not isinstance(r, m2_expr.ExprMem)) or r in src_mem: continue fetch_mem = True index = prefect_index[r.size] prefect_index[r.size] += 1 pfmem = prefetch_id_size[r.size][index] src_mem[r] = pfmem for dst, exs in dst_dict.items(): if len(exs) == 1: new_expr += exs continue exs = [expr_simp(x) for x in exs] log_to_c_h.debug('warning: detected multi dst to same id') log_to_c_h.debug('\t'.join([str(x) for x in exs])) new_expr += exs out_mem = [] # first, generate mem prefetch mem_k = src_mem.keys() mem_k.sort() for k in mem_k: str_src = TranslatorC.from_expr(patch_c_id(ir_arch.arch, k)) str_dst = TranslatorC.from_expr(patch_c_id(ir_arch.arch, src_mem[k])) out.append('%s = %s;' % (str_dst, str_src)) src_w_len = {} for k, v in src_mem.items(): src_w_len[k] = v for e in new_expr: src, dst = e.src, e.dst # reload src using prefetch src = src.replace_expr(src_w_len) if dst is ir_arch.IRDst: out += gen_irdst(ir_arch, src) continue str_src = TranslatorC.from_expr(patch_c_id(ir_arch.arch, src)) str_dst = TranslatorC.from_expr(patch_c_id(ir_arch.arch, dst)) if isinstance(dst, m2_expr.ExprId): id_to_update.append(dst) str_dst = patch_c_new_id(ir_arch.arch, dst) if dst in ir_arch.arch.regs.regs_flt_expr: # dont mask float affectation out.append('%s = (%s);' % (str_dst, str_src)) else: out.append('%s = (%s)&0x%X;' % (str_dst, str_src, my_size_mask[src.size])) elif isinstance(dst, m2_expr.ExprMem): fetch_mem = True str_dst = str_dst.replace('MEM_LOOKUP', 'MEM_WRITE') out_mem.append('%s, %s);' % (str_dst[:-1], str_src)) if e.dst == ir_arch.arch.pc[ir_arch.attrib]: pc_is_dst = True out_pc += ["return;"] # if len(id_to_update) != len(set(id_to_update)): # raise ValueError('Not implemented: multi dst to same id!', str([str(x) # for x in exprs])) out += out_mem if gen_exception_code: if fetch_mem: e = set_pc(ir_arch, l.offset & mask_int) s1 = "%s" % TranslatorC.from_expr(patch_c_id(ir_arch.arch, e)) s1 += ';\n Resolve_dst(BlockDst, 0x%X, 0)' % (l.offset & mask_int) out.append(code_exception_fetch_mem_at_instr_noautomod % s1) if set_exception_flags: e = set_pc(ir_arch, l.offset & mask_int) s1 = "%s" % TranslatorC.from_expr(patch_c_id(ir_arch.arch, e)) s1 += ';\n Resolve_dst(BlockDst, 0x%X, 0)' % (l.offset & mask_int) out.append(code_exception_at_instr_noautomod % s1) for i in id_to_update: if i is ir_arch.IRDst: continue out.append( '%s = %s;' % (patch_c_id(ir_arch.arch, i), patch_c_new_id(ir_arch.arch, i))) post_instr = [] # test stop exec #### if gen_exception_code: if set_exception_flags: if pc_is_dst: post_instr.append("if (vm_mngr->exception_flags) { " + "/*pc = 0x%X; */return; }" % (l.offset)) else: e = set_pc(ir_arch, l.offset & mask_int) s1 = "%s" % TranslatorC.from_expr(patch_c_id(ir_arch.arch, e)) s1 += ';\n Resolve_dst(BlockDst, 0x%X, 0)' % (l.offset & mask_int) e = set_pc(ir_arch, (l.offset + l.l) & mask_int) s2 = "%s" % TranslatorC.from_expr(patch_c_id(ir_arch.arch, e)) s2 += ';\n Resolve_dst(BlockDst, 0x%X, 0)' % ( (l.offset + l.l) & mask_int) post_instr.append(code_exception_post_instr_noautomod % (s1, s2)) if fetch_mem: if l.additional_info.except_on_instr: offset = l.offset else: offset = l.offset + l.l e = set_pc(ir_arch, offset & mask_int) s1 = "%s" % TranslatorC.from_expr(patch_c_id(ir_arch.arch, e)) s1 += ';\n Resolve_dst(BlockDst, 0x%X, 0)' % (offset & mask_int) post_instr.append(code_exception_fetch_mem_post_instr_noautomod % (s1)) # pc manip after all modifications return out, post_instr, post_instr + out_pc
def Expr2C(ir_arch, l, exprs, gen_exception_code=False): id_to_update = [] out = ["// %s" % (l)] out_pc = [] dst_dict = {} src_mem = {} prefect_index = {8: 0, 16: 0, 32: 0, 64: 0} new_expr = [] e = set_pc(ir_arch, l.offset & mask_int) #out.append("%s;" % patch_c_id(ir_arch.arch, e))) pc_is_dst = False fetch_mem = False set_exception_flags = False for e in exprs: assert isinstance(e, m2_expr.ExprAff) assert not isinstance(e.dst, m2_expr.ExprOp) if isinstance(e.dst, m2_expr.ExprId): if not e.dst in dst_dict: dst_dict[e.dst] = [] dst_dict[e.dst].append(e) else: new_expr.append(e) # test exception flags ops = m2_expr.get_expr_ops(e) if set(['umod', 'udiv']).intersection(ops): set_exception_flags = True if e.dst == exception_flags: set_exception_flags = True # TODO XXX test function whose set exception_flags # search mem lookup for generate mem read prefetch rs = e.src.get_r(mem_read=True) for r in rs: if (not isinstance(r, m2_expr.ExprMem)) or r in src_mem: continue fetch_mem = True index = prefect_index[r.size] prefect_index[r.size] += 1 pfmem = prefetch_id_size[r.size][index] src_mem[r] = pfmem for dst, exs in dst_dict.items(): if len(exs) == 1: new_expr += exs continue exs = [expr_simp(x) for x in exs] log_to_c_h.debug('warning: detected multi dst to same id') log_to_c_h.debug('\t'.join([str(x) for x in exs])) new_expr += exs out_mem = [] # first, generate mem prefetch mem_k = src_mem.keys() mem_k.sort() for k in mem_k: str_src = translator.from_expr(patch_c_id(ir_arch.arch, k)) str_dst = translator.from_expr(patch_c_id(ir_arch.arch, src_mem[k])) out.append('%s = %s;' % (str_dst, str_src)) src_w_len = {} for k, v in src_mem.items(): src_w_len[k] = v for e in new_expr: src, dst = e.src, e.dst # reload src using prefetch src = src.replace_expr(src_w_len) if dst is ir_arch.IRDst: out += gen_irdst(ir_arch, src) continue str_src = translator.from_expr(patch_c_id(ir_arch.arch, src)) str_dst = translator.from_expr(patch_c_id(ir_arch.arch, dst)) if isinstance(dst, m2_expr.ExprId): id_to_update.append(dst) str_dst = patch_c_new_id(ir_arch.arch, dst) if dst in ir_arch.arch.regs.regs_flt_expr: # dont mask float affectation out.append('%s = (%s);' % (str_dst, str_src)) else: out.append('%s = (%s)&0x%X;' % (str_dst, str_src, my_size_mask[src.size])) elif isinstance(dst, m2_expr.ExprMem): fetch_mem = True str_dst = str_dst.replace('MEM_LOOKUP', 'MEM_WRITE') out_mem.append('%s, %s);' % (str_dst[:-1], str_src)) if e.dst == ir_arch.arch.pc[ir_arch.attrib]: pc_is_dst = True out_pc += ["return JIT_RET_NO_EXCEPTION;"] # if len(id_to_update) != len(set(id_to_update)): # raise ValueError('Not implemented: multi dst to same id!', str([str(x) # for x in exprs])) out += out_mem if gen_exception_code: if fetch_mem: e = set_pc(ir_arch, l.offset & mask_int) s1 = "%s" % translator.from_expr(patch_c_id(ir_arch.arch, e)) s1 += ';\n Resolve_dst(BlockDst, 0x%X, 0)'%(l.offset & mask_int) out.append(code_exception_fetch_mem_at_instr_noautomod % s1) if set_exception_flags: e = set_pc(ir_arch, l.offset & mask_int) s1 = "%s" % translator.from_expr(patch_c_id(ir_arch.arch, e)) s1 += ';\n Resolve_dst(BlockDst, 0x%X, 0)'%(l.offset & mask_int) out.append(code_exception_at_instr_noautomod % s1) for i in id_to_update: if i is ir_arch.IRDst: continue out.append('%s = %s;' % (patch_c_id(ir_arch.arch, i), patch_c_new_id(ir_arch.arch, i))) post_instr = [] # test stop exec #### if gen_exception_code: if set_exception_flags: if pc_is_dst: post_instr.append("if (VM_exception_flag) { " + "/*pc = 0x%X; */return JIT_RET_EXCEPTION; }" % (l.offset)) else: e = set_pc(ir_arch, l.offset & mask_int) s1 = "%s" % translator.from_expr(patch_c_id(ir_arch.arch, e)) s1 += ';\n Resolve_dst(BlockDst, 0x%X, 0)'%(l.offset & mask_int) e = set_pc(ir_arch, (l.offset + l.l) & mask_int) s2 = "%s" % translator.from_expr(patch_c_id(ir_arch.arch, e)) s2 += ';\n Resolve_dst(BlockDst, 0x%X, 0)'%((l.offset + l.l) & mask_int) post_instr.append( code_exception_post_instr_noautomod % (s1, s2)) if fetch_mem: if l.additional_info.except_on_instr: offset = l.offset else: offset = l.offset + l.l e = set_pc(ir_arch, offset & mask_int) s1 = "%s" % translator.from_expr(patch_c_id(ir_arch.arch, e)) s1 += ';\n Resolve_dst(BlockDst, 0x%X, 0)'%(offset & mask_int) post_instr.append( code_exception_fetch_mem_post_instr_noautomod % (s1)) # pc manip after all modifications return out, post_instr, post_instr + out_pc