def sdiv(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b loc_div = ExprLoc(ir.loc_db.add_location(), ir.IRDst.size) loc_except = ExprId(ir.loc_db.add_location(), ir.IRDst.size) loc_next = ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size) e.append(ExprAff(ir.IRDst, ExprCond(c, loc_div, loc_except))) do_except = [] do_except.append( ExprAff(exception_flags, ExprInt(EXCEPT_DIV_BY_ZERO, exception_flags.size))) do_except.append(ExprAff(ir.IRDst, loc_next)) blk_except = IRBlock(loc_except.loc_key, [AssignBlock(do_except, instr)]) r = ExprOp("idiv", b, c) do_div = [] do_div.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: do_div.append(ExprAff(ir.IRDst, r)) do_div.append(ExprAff(ir.IRDst, loc_next)) blk_div = IRBlock(loc_div.loc_key, [AssignBlock(do_div, instr)]) return e, [blk_div, blk_except]
def post_add_bloc(self, block, ir_blocks): IntermediateRepresentation.post_add_bloc(self, block, ir_blocks) for irb in ir_blocks: pc_val = None lr_val = None for assignblk in irb.irs: pc_val = assignblk.get(self.arch.regs.PC, pc_val) lr_val = assignblk.get(self.arch.regs.RA, lr_val) if pc_val is None or lr_val is None: continue if not expr_is_int_or_label(lr_val): continue if expr_is_label(lr_val): lr_val = ExprInt32(lr_val.name.offset) line = block.lines[-2] if lr_val.arg != line.offset + 8: raise ValueError("Wrong arg") # CALL lbl = block.get_next() new_lbl = self.gen_label() irs = self.call_effects(pc_val, line) irs.append(AssignBlock([ExprAff(self.IRDst, ExprId(lbl, size=self.pc.size))])) nblock = IRBlock(new_lbl, irs) nblock.lines = [line] * len(irs) self.blocks[new_lbl] = nblock irb.dst = ExprId(new_lbl, size=self.pc.size)
def udiv(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b lbl_div = ExprId(ir.gen_label(), ir.IRDst.size) lbl_except = ExprId(ir.gen_label(), ir.IRDst.size) lbl_next = ExprId(ir.get_next_label(instr), ir.IRDst.size) e.append(ExprAff(ir.IRDst, ExprCond(c, lbl_div, lbl_except))) do_except = [] do_except.append( ExprAff(exception_flags, ExprInt(EXCEPT_DIV_BY_ZERO, exception_flags.size))) do_except.append(ExprAff(ir.IRDst, lbl_next)) blk_except = IRBlock(lbl_except.name, [AssignBlock(do_except, instr)]) r = ExprOp("udiv", b, c) do_div = [] do_div.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: do_div.append(ExprAff(ir.IRDst, r)) do_div.append(ExprAff(ir.IRDst, lbl_next)) blk_div = IRBlock(lbl_div.name, [AssignBlock(do_div, instr)]) return e, [blk_div, blk_except]
def do_it_block(self, label, index, block, assignments, gen_pc_updt): instr = block.lines[index] it_hints, it_cond = self.parse_itt(instr) cond_num = cond_dct_inv[it_cond.name] cond_eq = tab_cond[cond_num] # if not index + len(it_hints) <= len(block.lines): # raise NotImplementedError("Splitted IT block non supported yet") ir_blocks_all = [] # Gen dummy irblock for IT instr label_next = self.get_next_label(instr) dst = ExprAff(self.IRDst, ExprId(label_next, 32)) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) irblock = IRBlock(label, assignments) ir_blocks_all.append([irblock]) label = label_next assignments = [] if isinstance(it_hints, Iterable): for hint in it_hints: irblocks = [] index += 1 instr = block.lines[index] # Add conditionnal jump to current irblock label_do = self.symbol_pool.gen_label() label_next = self.get_next_label(instr) if hint: local_cond = ~cond_eq else: local_cond = cond_eq dst = ExprAff(self.IRDst, ExprCond(local_cond, ExprId(label_do, 32), ExprId(label_next, 32))) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) irblock = IRBlock(label, assignments) irblocks.append(irblock) assignments = [] label = label_do split = self.add_instr_to_irblock(block, instr, assignments, irblocks, gen_pc_updt) # if split: # raise NotImplementedError("Unsupported instr in IT block (%s)" % instr) dst = ExprAff(self.IRDst, ExprId(label_next, 32)) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) irblock = IRBlock(label, assignments) irblocks.append(irblock) label = label_next assignments = [] ir_blocks_all.append(irblocks) return index, ir_blocks_all
def do_it_block(self, loc, index, block, assignments, gen_pc_updt): instr = block.lines[index] it_hints, it_cond = self.parse_itt(instr) cond_num = cond_dct_inv[it_cond.name] cond_eq = tab_cond[cond_num] if not index + len(it_hints) <= len(block.lines): raise NotImplementedError("Splitted IT block non supported yet") ir_blocks_all = [] # Gen dummy irblock for IT instr loc_next = self.get_next_loc_key(instr) dst = ExprAff(self.IRDst, ExprId(loc_next, 32)) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) irblock = IRBlock(loc, assignments) ir_blocks_all.append([irblock]) loc = loc_next assignments = [] for hint in it_hints: irblocks = [] index += 1 instr = block.lines[index] # Add conditionnal jump to current irblock loc_do = self.loc_db.add_location() loc_next = self.get_next_loc_key(instr) if hint: local_cond = ~cond_eq else: local_cond = cond_eq dst = ExprAff(self.IRDst, ExprCond(local_cond, ExprLoc(loc_do, 32), ExprLoc(loc_next, 32))) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) irblock = IRBlock(loc, assignments) irblocks.append(irblock) assignments = [] loc = loc_do split = self.add_instr_to_current_state( instr, block, assignments, irblocks, gen_pc_updt ) if split: raise NotImplementedError("Unsupported instr in IT block (%s)" % instr) dst = ExprAff(self.IRDst, ExprId(loc_next, 32)) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) irblock = IRBlock(loc, assignments) irblocks.append(irblock) loc = loc_next assignments = [] ir_blocks_all.append(irblocks) return index, ir_blocks_all
def block2assignblks(self, block): irblocks_list = super(mipsCGen, self).block2assignblks(block) for irblocks in irblocks_list: for blk_idx, irblock in enumerate(irblocks): has_breakflow = any(assignblock.instr.breakflow() for assignblock in irblock) if not has_breakflow: continue irs = [] for assignblock in irblock: if self.ir_arch.pc not in assignblock: irs.append(AssignBlock(assignments, assignblock.instr)) continue assignments = dict(assignblock) # Add internal branch destination assignments[self.delay_slot_dst] = assignblock[ self.ir_arch.pc] assignments[self.delay_slot_set] = m2_expr.ExprInt(1, 32) # Replace IRDst with next instruction assignments[self.ir_arch.IRDst] = m2_expr.ExprId( self.ir_arch.get_next_instr(assignblock.instr), 32) irs.append(AssignBlock(assignments, assignblock.instr)) irblocks[blk_idx] = IRBlock(irblock.label, irs) return irblocks_list
def post_add_asmblock_to_ircfg(self, block, ircfg, ir_blocks): IntermediateRepresentation.post_add_asmblock_to_ircfg(self, block, ircfg, ir_blocks) new_irblocks = [] for irb in ir_blocks: pc_val = None lr_val = None for assignblk in irb: pc_val = assignblk.get(self.arch.regs.PC, pc_val) lr_val = assignblk.get(self.arch.regs.RA, lr_val) if pc_val is None or lr_val is None: new_irblocks.append(irb) continue if lr_val.is_loc(): offset = self.loc_db.get_location_offset(lr_val.loc_key) if offset is not None: lr_val = ExprInt(offset, 32) if not lr_val.is_int(): continue instr = block.lines[-2] if int(lr_val) != instr.offset + 8: raise ValueError("Wrong arg") # CALL lbl = block.get_next() new_lbl = self.gen_label() call_assignblks, extra_irblocks = self.call_effects(pc_val, instr) ir_blocks += extra_irblocks irs.append(AssignBlock([ExprAff(self.IRDst, ExprId(lbl, size=self.pc.size))], instr)) new_irblocks.append(IRBlock(new_lbl, call_assignblks)) new_irblocks.append(irb.set_dst(ExprId(new_lbl, size=self.pc.size))) return new_irblocks
def emul(self, ir_arch, ctx=None, step=False): """Symbolic execution of relevant nodes according to the history Return the values of inputs nodes' elements @ir_arch: IntermediateRepresentation instance @ctx: (optional) Initial context as dictionnary @step: (optional) Verbose execution Warning: The emulation is not sound if the inputs nodes depend on loop variant. """ # Init ctx_init = {} if ctx is not None: ctx_init.update(ctx) assignblks = [] # Build a single affectation block according to history last_index = len(self.relevant_loc_keys) for index, loc_key in enumerate(reversed(self.relevant_loc_keys), 1): if index == last_index and loc_key == self.initial_state.loc_key: line_nb = self.initial_state.line_nb else: line_nb = None assignblks += self.irblock_slice(self._ircfg.blocks[loc_key], line_nb).assignblks # Eval the block loc_db = LocationDB() temp_loc = loc_db.get_or_create_name_location("Temp") symb_exec = SymbolicExecutionEngine(ir_arch, ctx_init) symb_exec.eval_updt_irblock(IRBlock(temp_loc, assignblks), step=step) # Return only inputs values (others could be wrongs) return {element: symb_exec.symbols[element] for element in self.inputs}
def post_add_block(self, block, ir_blocks): IntermediateRepresentation.post_add_block(self, block, ir_blocks) new_irblocks = [] for irb in ir_blocks: pc_val = None lr_val = None for assignblk in irb.irs: pc_val = assignblk.get(self.arch.regs.PC, pc_val) lr_val = assignblk.get(self.arch.regs.RA, lr_val) if pc_val is None or lr_val is None: new_irblocks.append(irb) continue if not expr_is_int_or_label(lr_val): new_irblocks.append(irb) continue if expr_is_label(lr_val): lr_val = ExprInt(lr_val.name.offset, 32) instr = block.lines[-2] if lr_val.arg != instr.offset + 8: raise ValueError("Wrong arg") # CALL lbl = block.get_next() new_lbl = self.gen_label() irs = self.call_effects(pc_val, instr) irs.append( AssignBlock( [ExprAff(self.IRDst, ExprId(lbl, size=self.pc.size))], instr)) new_irblocks.append(IRBlock(new_lbl, irs)) new_irblocks.append(irb.set_dst(ExprId(new_lbl, size=self.pc.size))) return new_irblocks
def emul(self, ctx=None, step=False): """Symbolic execution of relevant nodes according to the history Return the values of inputs nodes' elements @ctx: (optional) Initial context as dictionnary @step: (optional) Verbose execution Warning: The emulation is not sound if the inputs nodes depend on loop variant. """ # Init ctx_init = self._ira.arch.regs.regs_init if ctx is not None: ctx_init.update(ctx) assignblks = [] # Build a single affectation block according to history last_index = len(self.relevant_labels) for index, label in enumerate(reversed(self.relevant_labels), 1): if index == last_index and label == self.initial_state.label: line_nb = self.initial_state.line_nb else: line_nb = None assignblks += self.irblock_slice(self._ira.blocks[label], line_nb).assignblks # Eval the block temp_label = AsmLabel("Temp") symb_exec = SymbolicExecutionEngine(self._ira, ctx_init) symb_exec.eval_updt_irblock(IRBlock(temp_label, assignblks), step=step) # Return only inputs values (others could be wrongs) return {element: symb_exec.symbols[element] for element in self.inputs}
def emulbloc(self, irb, step=False): """ Symbolic execution of the @irb on the current state @irb: IRBlock instance @step: display intermediate steps """ assignblks = [] for index, assignblk in enumerate(irb.irs): new_assignblk = {} links = {} for dst, src in assignblk.iteritems(): src = self.propag_expr_cst(src) if dst.is_mem(): ptr = dst.arg ptr = self.propag_expr_cst(ptr) dst = ExprMem(ptr, dst.size) new_assignblk[dst] = src for arg in assignblk.instr.args: new_arg = self.propag_expr_cst(arg) links[new_arg] = arg self.cst_propag_link[(irb.label, index)] = links self.eval_ir(assignblk) assignblks.append(AssignBlock(new_assignblk, assignblk.instr)) self.ir_arch.blocks[irb.label] = IRBlock(irb.label, assignblks)
def replace_stack_vars(ir_arch_a, ssa): """ Try to replace stack based memory accesses by variables. WARNING: may fail @ir_arch_a: ira instance @ssa: SSADiGraph instance """ base_to_info = retrieve_stack_accesses(ir_arch_a, ssa) modified = False for block in ssa.graph.blocks.itervalues(): assignblks = [] for assignblk in block: out = {} for dst, src in assignblk.iteritems(): new_dst = dst.visit(lambda expr:replace_mem_stack_vars(expr, base_to_info)) new_src = src.visit(lambda expr:replace_mem_stack_vars(expr, base_to_info)) if new_dst != dst or new_src != src: modified |= True out[new_dst] = new_src out = AssignBlock(out, assignblk.instr) assignblks.append(out) new_block = IRBlock(block.loc_key, assignblks) ssa.graph.blocks[block.loc_key] = new_block return modified
def _do_merge_blocks(ircfg, loc_key, son_loc_key): """ Merge two irblocks at @loc_key and @son_loc_key @ircfg: DiGrpahIR @loc_key: LocKey instance of the parent IRBlock @loc_key: LocKey instance of the son IRBlock """ assignblks = [] for assignblk in ircfg.blocks[loc_key]: if ircfg.IRDst not in assignblk: assignblks.append(assignblk) continue affs = {} for dst, src in assignblk.iteritems(): if dst != ircfg.IRDst: affs[dst] = src if affs: assignblks.append(AssignBlock(affs, assignblk.instr)) assignblks += ircfg.blocks[son_loc_key].assignblks new_block = IRBlock(loc_key, assignblks) ircfg.discard_edge(loc_key, son_loc_key) for son_successor in ircfg.successors(son_loc_key): ircfg.add_uniq_edge(loc_key, son_successor) ircfg.discard_edge(son_loc_key, son_successor) del ircfg.blocks[son_loc_key] ircfg.del_node(son_loc_key) ircfg.blocks[loc_key] = new_block
def dead_simp(irarch, ircfg): """ Remove useless affectations. This function is used to analyse relation of a * complete function * This means the blocks under study represent a solid full function graph. Source : Kennedy, K. (1979). A survey of data flow analysis techniques. IBM Thomas J. Watson Research Division, page 43 @ircfg: IntermediateRepresentation instance """ modified = False reaching_defs = ReachingDefinitions(ircfg) defuse = DiGraphDefUse(reaching_defs, deref_mem=True) useful = set(dead_simp_useful_assignblks(irarch, defuse, reaching_defs)) for block in ircfg.blocks.itervalues(): irs = [] for idx, assignblk in enumerate(block): new_assignblk = dict(assignblk) for lval in assignblk: if AssignblkNode(block.loc_key, idx, lval) not in useful: del new_assignblk[lval] modified = True irs.append(AssignBlock(new_assignblk, assignblk.instr)) ircfg.blocks[block.loc_key] = IRBlock(block.loc_key, irs) return modified
def add_condition_expr(ir, instr, cond, instr_ir, extra_ir): if cond == COND_AL: return instr_ir, extra_ir if not cond in tab_cond: raise ValueError('unknown condition %r' % cond) cond = tab_cond[cond] loc_next = ir.get_next_loc_key(instr) loc_next_expr = ExprLoc(loc_next, 32) loc_do = ir.loc_db.add_location() loc_do_expr = ExprLoc(loc_do, 32) dst_cond = ExprCond(cond, loc_do_expr, loc_next_expr) assert (isinstance(instr_ir, list)) has_irdst = False for e in instr_ir: if e.dst == ir.IRDst: has_irdst = True break if not has_irdst: instr_ir.append(ExprAff(ir.IRDst, loc_next_expr)) e_do = IRBlock(loc_do, [AssignBlock(instr_ir, instr)]) e = [ExprAff(ir.IRDst, dst_cond)] return e, [e_do] + extra_ir
def discard_phi_sources(ircfg, deleted_vars): """ Remove phi sources in @ircfg belonging to @deleted_vars set @ircfg: IRCFG instance in ssa form @deleted_vars: unused phi sources """ for block in ircfg.blocks.values(): if not block.assignblks: continue assignblk = block[0] todo = {} modified = False for dst, src in assignblk.iteritems(): if not src.is_op('Phi'): todo[dst] = src continue srcs = set(expr for expr in src.args if expr not in deleted_vars) assert (srcs) if len(srcs) > 1: todo[dst] = srcs continue todo[dst] = srcs.pop() modified = True if not modified: continue assignblks = list(block) assignblk = dict(assignblk) assignblk.update(todo) assignblk = AssignBlock(assignblk, assignblks[0].instr) assignblks[0] = assignblk new_irblock = IRBlock(block.loc_key, assignblks) ircfg.blocks[block.loc_key] = new_irblock return True
def add_asmblock_to_ircfg(self, block, ircfg, gen_pc_updt=False): """ Add a native block to the current IR @block: native assembly block @ircfg: IRCFG instance @gen_pc_updt: insert PC update effects between instructions """ loc_key = block.loc_key ir_blocks_all = [] assignments = [] for index, instr in enumerate(block.lines): if loc_key is None: assignments = [] loc_key = self.get_loc_key_for_instr(instr) if instr.is_subcall(): assert index == len(block.lines) - 2 # Add last instruction first (before call) split = self.add_instr_to_current_state( block.lines[-1], block, assignments, ir_blocks_all, gen_pc_updt ) assert not split # Add call effects after the delay splot split = self.add_instr_to_current_state( instr, block, assignments, ir_blocks_all, gen_pc_updt ) assert split break split = self.add_instr_to_current_state( instr, block, assignments, ir_blocks_all, gen_pc_updt ) if split: ir_blocks_all.append(IRBlock(loc_key, assignments)) loc_key = None assignments = [] if loc_key is not None: ir_blocks_all.append(IRBlock(loc_key, assignments)) new_ir_blocks_all = self.post_add_asmblock_to_ircfg(block, ircfg, ir_blocks_all) for irblock in new_ir_blocks_all: ircfg.add_irblock(irblock) return new_ir_blocks_all
def _convert_phi(self): """Inserts corresponding phi functions inplace into IRBlock at the beginning""" for loc_key in self._phinodes: irblock = self.get_block(loc_key) assignblk = AssignBlock(self._phinodes[loc_key]) # insert at the beginning new_irs = IRBlock(loc_key, [assignblk] + list(irblock.assignblks)) self.ircfg.blocks[loc_key] = new_irs
def gen_irblock(label, exprs_list): irs = [] for exprs in exprs_list: if isinstance(exprs, AssignBlock): irs.append(exprs) else: irs.append(AssignBlock(exprs)) irbl = IRBlock(label, irs) return irbl
def assignblk_to_irbloc(self, instr, assignblk): """ Ensure IRDst is always set in the head @assignblk of the @instr @assignblk: Assignblk instance @instr: an instruction instance """ if self.ir_arch.IRDst not in assignblk: assignblk[self.ir_arch.IRDst] = m2_expr.ExprInt( instr.offset + instr.l, self.ir_arch.IRDst.size) return IRBlock(self.ir_arch.get_instr_label(instr), [assignblk])
def gen_irblock(label, exprs_list): lines = [None for _ in xrange(len(exprs_list))] irs = [] for exprs in exprs_list: if isinstance(exprs, AssignBlock): irs.append(exprs) else: irs.append(AssignBlock(exprs)) irbl = IRBlock(label, irs, lines) return irbl
def add_asmblock_to_ircfg(self, block, ircfg, gen_pc_updt=False): """ Add a native block to the current IR @block: native assembly block @gen_pc_updt: insert PC update effects between instructions """ it_hints = None it_cond = None label = block.loc_key assignments = [] ir_blocks_all = [] index = -1 while index + 1 < len(block.lines): index += 1 instr = block.lines[index] if label is None: assignments = [] label = self.get_loc_key_for_instr(instr) if instr.name.startswith("IT"): index, irblocks_it = self.do_it_block(label, index, block, assignments, gen_pc_updt) for irblocks in irblocks_it: ir_blocks_all += irblocks label = None continue split = self.add_instr_to_current_state(instr, block, assignments, ir_blocks_all, gen_pc_updt) if split: ir_blocks_all.append(IRBlock(label, assignments)) label = None assignments = [] if label is not None: ir_blocks_all.append(IRBlock(label, assignments)) new_ir_blocks_all = self.post_add_asmblock_to_ircfg( block, ircfg, ir_blocks_all) for irblock in new_ir_blocks_all: ircfg.add_irblock(irblock) return new_ir_blocks_all
def add_block(self, block, gen_pc_updt=False): """ Add a native block to the current IR @block: native assembly block @gen_pc_updt: insert PC update effects between instructions """ it_hints = None it_cond = None label = None ir_blocks_all = [] index = -1 while index + 1 < len(block.lines): index += 1 instr = block.lines[index] if label is None: assignments = [] label = self.get_instr_label(instr) if instr.name.startswith("IT"): index, irblocks_it = self.do_it_block(label, index, block, assignments, gen_pc_updt) if isinstance(irblocks_it, Iterable): for irblocks in irblocks_it: ir_blocks_all += irblocks label = None continue split = self.add_instr_to_irblock(block, instr, assignments, ir_blocks_all, gen_pc_updt) if split: ir_blocks_all.append(IRBlock(label, assignments)) label = None assignments = [] if label is not None: ir_blocks_all.append(IRBlock(label, assignments)) new_ir_blocks_all = self.post_add_block(block, ir_blocks_all) if isinstance(new_ir_blocks_all, Iterable): for irblock in new_ir_blocks_all: self.blocks[irblock.label] = irblock return new_ir_blocks_all
def insert_parallel_copy(self): """ Naive Out-of-SSA from CSSA (without coalescing for now) - Replace Phi - Create room for parallel copies in Phi's parents """ ircfg = self.ssa.graph for irblock in ircfg.blocks.values(): if not irblock_has_phi(irblock): continue # Replace Phi with Phi's dst = new_var parallel_copies = {} for dst in self.phi_destinations[irblock.loc_key]: new_var = self.phi_new_var[dst] parallel_copies[dst] = new_var assignblks = list(irblock) assignblks[0] = AssignBlock(parallel_copies, irblock[0].instr) new_irblock = IRBlock(irblock.loc_key, assignblks) ircfg.blocks[irblock.loc_key] = new_irblock # Insert new_var = src in each Phi's parent, at the end of the block parent_to_parallel_copies = {} parallel_copies = {} for dst in irblock[0]: new_var = self.phi_new_var[dst] for parent, src in self.phi_parent_sources[dst]: parent_to_parallel_copies.setdefault(parent, {})[new_var] = src for parent, parallel_copies in parent_to_parallel_copies.iteritems( ): parent = ircfg.blocks[parent] assignblks = list(parent) assignblks.append( AssignBlock(parallel_copies, parent[-1].instr)) new_irblock = IRBlock(parent.loc_key, assignblks) ircfg.blocks[parent.loc_key] = new_irblock
def casp(ir, instr, arg1, arg2, arg3): # XXX TODO: memory barrier e = [] if arg1.size == 32: regs = gpregs32_expr else: regs = gpregs64_expr index1 = regs.index(arg1) index2 = regs.index(arg2) # TODO endianness comp_value = ExprCompose(regs[index1], regs[index1 + 1]) new_value = ExprCompose(regs[index2], regs[index2 + 1]) assert arg3.is_op('preinc') ptr = arg3.args[0] data = ExprMem(ptr, comp_value.size) loc_store = ExprLoc(ir.loc_db.add_location(), ir.IRDst.size) loc_do = ExprLoc(ir.loc_db.add_location(), ir.IRDst.size) loc_next = ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size) e.append( ExprAssign( ir.IRDst, ExprCond(ExprOp("FLAG_EQ_CMP", data, comp_value), loc_do, loc_store))) e_store = [] e_store.append(ExprAssign(data, new_value)) e_store.append(ExprAssign(ir.IRDst, loc_do)) blk_store = IRBlock(loc_store.loc_key, [AssignBlock(e_store, instr)]) e_do = [] e_do.append(ExprAssign(regs[index1], data[:data.size / 2])) e_do.append(ExprAssign(regs[index1 + 1], data[data.size / 2:])) e_do.append(ExprAssign(ir.IRDst, loc_next)) blk_do = IRBlock(loc_do.loc_key, [AssignBlock(e_do, instr)]) return e, [blk_store, blk_do]
def assignblk_to_irbloc(self, instr, assignblk): """ Ensure IRDst is always set in the head @assignblk of the @instr @instr: an instruction instance @assignblk: Assignblk instance """ 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) new_assignblk[self.ir_arch.IRDst] = dst irs = [AssignBlock(new_assignblk, instr)] return IRBlock(self.ir_arch.get_instr_label(instr), irs)
def gen_irblock(label, exprs_list): """ Returns an IRBlock. Used only for tests purpose """ irs = [] for exprs in exprs_list: if isinstance(exprs, AssignBlock): irs.append(exprs) else: irs.append(AssignBlock(exprs)) irbl = IRBlock(label, irs) return irbl
def assignblk_to_irbloc(self, instr, assignblk): """ Ensure IRDst is always set in the head @assignblk of the @instr @instr: an instruction instance @assignblk: Assignblk instance """ new_assignblk = dict(assignblk) if self.ir_arch.IRDst not in assignblk: offset = instr.offset + instr.l loc_key = self.ir_arch.loc_db.get_or_create_offset_location(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_loc_key_for_instr(instr), irs)
def add_out_reg_end(ir_arch_a, ircfg_a): # Add dummy dependency to uncover out regs affectation for loc in ircfg_a.leaves(): irblock = ircfg_a.blocks.get(loc) if irblock is None: continue regs = {} for reg in ir_arch_a.get_out_regs(irblock): regs[reg] = reg assignblks = list(irblock) new_assiblk = AssignBlock(regs, assignblks[-1].instr) assignblks.append(new_assiblk) new_irblock = IRBlock(irblock.loc_key, assignblks) ircfg_a.blocks[loc] = new_irblock
def remove_assign_eq(self): """ Remove trivial expressions (a=a) in the current graph """ for irblock in self.ssa.graph.blocks.values(): assignblks = list(irblock) for i, assignblk in enumerate(assignblks): out = {} for dst, src in assignblk.iteritems(): if dst == src: continue out[dst] = src assignblks[i] = AssignBlock(out, assignblk.instr) self.ssa.graph.blocks[irblock.loc_key] = IRBlock(irblock.loc_key, assignblks)