def set_empty_dst_to_next(self, block, ir_blocks): for index, irblock in enumerate(ir_blocks): if irblock.dst is not None: continue next_loc_key = block.get_next() if next_loc_key is None: loc_key = None if block.lines: line = block.lines[-1] if line.offset is not None: loc_key = self.loc_db.get_or_create_offset_location( line.offset + line.l) if loc_key is None: loc_key = self.loc_db.add_location() block.add_cst(loc_key, AsmConstraint.c_next) else: loc_key = next_loc_key dst = m2_expr.ExprLoc(loc_key, self.pc.size) if irblock.assignblks: instr = irblock.assignblks[-1].instr else: instr = None assignblk = AssignBlock({self.IRDst: dst}, instr) ir_blocks[index] = IRBlock(irblock.loc_key, list(irblock.assignblks) + [assignblk])
def beq(arg1, arg2, arg3): "Branches on @arg3 if the quantities of two registers @arg1, @arg2 are eq" dst = arg3 if m2_expr.ExprOp( m2_expr.TOK_EQUAL, arg1, arg2) else m2_expr.ExprLoc( ir.get_next_break_loc_key(instr), ir.IRDst.size) PC = dst ir.IRDst = dst
def gen_loc_key_and_expr(self, size): """ Return a loc_key and it's corresponding ExprLoc @size: size of expression """ loc_key = self.loc_db.add_location() return loc_key, m2_expr.ExprLoc(loc_key, size)
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 dst_loc_key = self.ir_arch.get_next_instr( assignblock.instr) assignments[self.ir_arch.IRDst] = m2_expr.ExprLoc( dst_loc_key, 32) irs.append(AssignBlock(assignments, assignblock.instr)) irblocks[blk_idx] = IRBlock(irblock.loc_key, irs) return irblocks_list
def bgtzl(arg1, arg2): """Branches on @arg2 if the register @arg1 is greater than zero""" cond = m2_expr.ExprOp(m2_expr.TOK_INF_EQUAL_SIGNED, arg1, m2_expr.ExprInt(0, arg1.size)) dst_o = m2_expr.ExprLoc(ir.get_next_delay_loc_key(instr), ir.IRDst.size) if cond else arg2 PC = dst_o ir.IRDst = dst_o
def blezl(arg1, arg2): """Branches on @arg2 if the register @arg1 is less than or equal to zero""" cond = m2_expr.ExprOp(m2_expr.TOK_INF_EQUAL_SIGNED, arg1, m2_expr.ExprInt(0, arg1.size)) dst_o = arg2 if cond else m2_expr.ExprLoc(ir.get_next_delay_loc_key(instr), ir.IRDst.size) PC = dst_o ir.IRDst = dst_o
def bltzl(arg1, arg2): """Branches on @arg2 if the register @arg1 is less than zero""" dst_o = arg2 if m2_expr.ExprOp( m2_expr.TOK_INF_SIGNED, arg1, m2_expr.ExprInt( 0, arg1.size)) else m2_expr.ExprLoc( ir.get_next_delay_loc_key(instr), ir.IRDst.size) PC = dst_o ir.IRDst = dst_o
def bnel(arg1, arg2, arg3): """Branches on @arg3 if the quantities of two registers @arg1, @arg2 are NOT equal""" dst = m2_expr.ExprLoc(ir.get_next_delay_loc_key(instr), ir.IRDst.size) if m2_expr.ExprOp( m2_expr.TOK_EQUAL, arg1, arg2) else arg3 PC = dst ir.IRDst = dst
def bgezl(arg1, arg2): """Branches on @arg2 if the quantities of register @arg1 is greater than or equal to zero""" dst = m2_expr.ExprLoc(ir.get_next_delay_loc_key(instr), ir.IRDst.size) if m2_expr.ExprOp( m2_expr.TOK_INF_SIGNED, arg1, m2_expr.ExprInt(0, arg1.size)) else arg2 PC = dst ir.IRDst = dst
def add_irblock(self, irblock): """ Add the @irblock to the current IRCFG @irblock: IRBlock instance """ self.blocks[irblock.loc_key] = irblock self.add_node(irblock.loc_key) for dst in self.dst_trackback(irblock): if dst.is_int(): dst_loc_key = self.loc_db.get_or_create_offset_location(int(dst)) dst = m2_expr.ExprLoc(dst_loc_key, irblock.dst.size) if dst.is_loc(): self.add_uniq_edge(irblock.loc_key, dst.loc_key)
def tne(ir, instr, arg1, arg2): e = [] loc_except, loc_except_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) loc_next = ir.get_next_loc_key(instr) loc_next_expr = m2_expr.ExprLoc(loc_next, ir.IRDst.size) do_except = [] do_except.append(m2_expr.ExprAssign(exception_flags, m2_expr.ExprInt( EXCEPT_DIV_BY_ZERO, exception_flags.size))) do_except.append(m2_expr.ExprAssign(ir.IRDst, loc_next_expr)) blk_except = IRBlock(ir.loc_db, loc_except, [AssignBlock(do_except, instr)]) cond = arg1 ^ arg2 e = [] e.append(m2_expr.ExprAssign(ir.IRDst, m2_expr.ExprCond(cond, loc_next_expr, loc_except_expr))) return e, [blk_except]
def bal(arg1): PC = arg1 ir.IRDst = arg1 RA = m2_expr.ExprLoc(ir.get_next_break_loc_key(instr), RA.size)
def bc1fl(arg1, arg2): dst_o = m2_expr.ExprLoc(ir.get_next_delay_loc_key(instr), ir.IRDst.size) if arg1 else arg2 PC = dst_o ir.IRDst = dst_o
def bc1t(arg1, arg2): dst_o = arg2 if arg1 else m2_expr.ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) PC = dst_o ir.IRDst = dst_o
def jalr(arg1, arg2): """Jump to an address stored in a register @arg1, and store the return address in another register @arg2""" PC = arg1 ir.IRDst = arg1 arg2 = m2_expr.ExprLoc(ir.get_next_break_loc_key(instr), arg2.size)
def jal(arg1): "Jumps to the calculated address @arg1 and stores the return address in $RA" PC = arg1 ir.IRDst = arg1 RA = m2_expr.ExprLoc(ir.get_next_break_loc_key(instr), RA.size)