Top

miasm2.arch.ppc.sem module

import miasm2.expression.expression as expr
from miasm2.ir.ir import AssignBlock, IntermediateRepresentation, IRBlock
from miasm2.arch.ppc.arch import mn_ppc
from miasm2.arch.ppc.regs import *
from miasm2.core.sembuilder import SemBuilder
from miasm2.jitter.csts import *

spr_dict = {
    8: LR, 9: CTR, 18: DSISR, 19: DAR,
    22: DEC, 26: SRR0, 27: SRR1,
    272: SPRG0, 273: SPRG0, 274: SPRG1, 275: SPRG2, 276: SPRG3,
    284: TBL, 285: TBU, 287: PVR, 1023: PIR
}

crf_dict = dict((ExprId("CR%d" % i, 4),
                 dict( (bit, ExprId("CR%d_%s" % (i, bit), 1))
                       for bit in ['LT', 'GT', 'EQ', 'SO' ] ))
                for i in xrange(8) )

ctx = { 'crf_dict': crf_dict, 'spr_dict': spr_dict }
ctx.update(all_regs_ids_byname)
sbuild = SemBuilder(ctx)

def mn_compute_flags(rvalue, overflow_expr=None):
    ret = []
    ret.append(ExprAff(CR0_LT, rvalue.msb()))
    ret.append(ExprAff(CR0_GT, (ExprCond(rvalue, ExprInt(1, 1),
                                         ExprInt(0, 1)) & ~rvalue.msb())))
    ret.append(ExprAff(CR0_EQ, ExprCond(rvalue, ExprInt(0, 1),
                                        ExprInt(1, 1))))
    if overflow_expr != None:
        ret.append(ExprAff(CR0_SO, XER_SO | overflow_expr))
    else:
        ret.append(ExprAff(CR0_SO, XER_SO))

    return ret

def mn_do_add(ir, instr, arg1, arg2, arg3):
    assert instr.name[0:3] == 'ADD'

    flags_update = []

    has_dot = False
    has_c = False
    has_e = False
    has_o = False

    for l in instr.name[3:]:
        if l == '.':
            has_dot = True
        elif l == 'C':
            has_c = True
        elif l == 'E':
            has_e = True
        elif l == 'O':
            has_o = True
        elif l == 'I' or l == 'M' or l == 'S' or l == 'Z':
            pass	# Taken care of earlier
        else:
            assert False

    rvalue = arg2 + arg3

    if has_e:
        rvalue = rvalue + XER_CA.zeroExtend(32)

    over_expr = None
    if has_o:
        msb1 = arg2.msb()
        msb2 = arg3.msb()
        msba = rvalue.msb()
        over_expr = ~(msb1 ^ msb2) & (msb1 ^ msba)
        flags_update.append(ExprAff(XER_OV, over_expr))
        flags_update.append(ExprAff(XER_SO, XER_SO | over_expr))

    if has_dot:
        flags_update += mn_compute_flags(rvalue, over_expr)

    if has_c or has_e:
        carry_expr = (((arg2 ^ arg3) ^ rvalue) ^
                      ((arg2 ^ rvalue) & (~(arg2 ^ arg3)))).msb()
        flags_update.append(ExprAff(XER_CA, carry_expr))

    return ([ ExprAff(arg1, rvalue) ] + flags_update), []

def mn_do_and(ir, instr, ra, rs, arg2):
    if len(instr.name) > 3 and instr.name[3] == 'C':
        oarg = ~arg2
    else:
        oarg = arg2

    rvalue = rs & oarg
    ret = [ ExprAff(ra, rvalue) ]

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue)

    return ret, []

def mn_do_cntlzw(ir, instr, ra, rs):
    ret = [ ExprAff(ra, ExprOp('cntleadzeros', rs)) ]

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue)

    return ret, []

def crbit_to_reg(bit):
    bit = bit.arg.arg
    crid = bit / 4
    bitname = [ 'LT', 'GT', 'EQ', 'SO' ][bit % 4]
    return all_regs_ids_byname["CR%d_%s" % (crid, bitname)]

def mn_do_cr(ir, instr, crd, cra, crb):
    a = crbit_to_reg(cra)
    b = crbit_to_reg(crb)
    d = crbit_to_reg(crd)

    op = instr.name[2:]

    if op == 'AND':
        r = a & b
    elif op == 'ANDC':
        r = a & ~b
    elif op == 'EQV':
        r = ~(a ^ b)
    elif op == 'NAND':
        r = ~(a & b)
    elif op == 'NOR':
        r = ~(a | b)
    elif op == 'OR':
        r = a | b
    elif op == 'ORC':
        r = a | ~b
    elif op == 'XOR':
        r = a ^ b
    else:
        raise "Unknown operation on CR"
    return [ ExprAff(d, r) ], []

def mn_do_div(ir, instr, rd, ra, rb):
    assert instr.name[0:4] == 'DIVW'

    flags_update = []

    has_dot = False
    has_c = False
    has_o = False
    has_u = False

    for l in instr.name[3:]:
        if l == '.':
            has_dot = True
        elif l == 'C':
            has_c = True
        elif l == 'O':
            has_o = True
        elif l == 'U':
            has_u = True
        elif l == 'W':
            pass
        else:
            assert False

    if has_u:
        op = 'udiv'
    else:
        op = 'idiv'

    rvalue = ExprOp(op, ra, rb)

    over_expr = None
    if has_o:
        over_expr = ExprCond(rb, ExprInt(0, 1), ExprInt(1, 1))
        if not has_u:
            over_expr = over_expr | (ExprCond(ra ^ 0x80000000, ExprInt(0, 1),
                                              ExprInt(1, 1)) &
                                     ExprCond(rb ^ 0xFFFFFFFF, ExprInt(0, 1),
                                              ExprInt(1, 1)))
        flags_update.append(ExprAff(XER_OV, over_expr))
        flags_update.append(ExprAff(XER_SO, XER_SO | over_expr))

    if has_dot:
        flags_update += mn_compute_flags(rvalue, over_expr)

    return ([ ExprAff(rd, rvalue) ] + flags_update), []
    

def mn_do_eqv(ir, instr, ra, rs, rb):
    rvalue = ~(rs ^ rb)
    ret = [ ExprAff(ra, rvalue) ]

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue)

    return ret, []

def mn_do_exts(ir, instr, ra, rs):
    if instr.name[4] == 'B':
        size = 8
    elif instr.name[4] == 'H':
        size = 16
    else:
        assert False

    rvalue = rs[0:size].signExtend(32)
    ret = [ ExprAff(ra, rvalue) ]

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue)

    return ret, []

def byte_swap(expr):
    nbytes = expr.size / 8
    bytes = [ expr[i*8:i*8+8] for i in xrange(nbytes - 1, -1, -1) ]
    return ExprCompose(bytes)

def mn_do_load(ir, instr, arg1, arg2, arg3=None):
    assert instr.name[0] == 'L'

    ret = []

    if instr.name[1] == 'M':
        return mn_do_lmw(ir, instr, arg1, arg2)
    elif instr.name[1] == 'S':
        raise RuntimeError("LSWI, and LSWX need implementing")
        pass # XXX

    size = {'B': 8, 'H': 16, 'W': 32}[instr.name[1]]

    has_a = False
    has_b = False
    has_u = False
    is_lwarx = False

    for l in instr.name[2:]:
        if l == 'A':
            has_a = True
        elif l == 'B':
            has_b = True
        elif l == 'U':
            has_u = True
        elif l == 'X' or l == 'Z':
            pass	# Taken care of earlier
        elif l == 'R' and not has_b:
            is_lwarx = True
        else:
            assert False

    if arg3 is None:
        assert isinstance(arg2, ExprMem)

        address = arg2.arg
    else:
        address = arg2 + arg3

    src = ExprMem(address, size)

    if has_b:
        src = byte_swap(src)

    if has_a:
        src = src.signExtend(32)
    else:
        src = src.zeroExtend(32)

    ret.append(ExprAff(arg1, src))
    if has_u:
        if arg3 is None:
            ret.append(ExprAff(arg2.arg.args[0], address))
        else:
            ret.append(ExprAff(arg2, address))

    if is_lwarx:
        ret.append(ExprAff(reserve, ExprInt(1, 1)))
        ret.append(ExprAff(reserve_address, address))	# XXX should be the PA

    return ret, []

def mn_do_lmw(ir, instr, rd, src):
    ret = []
    address = src.arg
    ri = int(rd.name[1:],10)
    i = 0
    while ri <= 31:
        ret.append(ExprAff(all_regs_ids_byname["R%d" % ri],
                           ExprMem(address + ExprInt(i, 32), 32)))
        ri += 1
        i += 4

    return ret, []

def mn_do_lswi(ir, instr, rd, ra, nb):
    if nb == 0:
        nb = 32
    i = 32
    raise "%r not implemented" % instr

def mn_do_lswx(ir, instr, rd, ra, nb):
    raise "%r not implemented" % instr

def mn_do_mcrf(ir, instr, crfd, crfs):
    ret = []

    for bit in [ 'LT', 'GT', 'EQ', 'SO' ]:
        d = all_regs_ids_byname["%s_%s" % (crfd, bit)]
        s = all_regs_ids_byname["%s_%s" % (crfs, bit)]
        ret.append(ExprAff(d, s))

    return ret, []

def mn_do_mcrxr(ir, instr, crfd):
    ret = []

    for (bit, val) in [ ('LT', XER_SO), ('GT', XER_OV), ('EQ', XER_CA),
                        ('SO', ExprInt(0, 1)) ]:
        ret.append(ExprAff(all_regs_ids_byname["%s_%s" % (crfd, bit)], val))

    return ret, []

def mn_do_mfcr(ir, instr, rd):
    return ([ ExprAff(rd, ExprCompose(*[ all_regs_ids_byname["CR%d_%s" % (i, b)]
                                        for i in xrange(7, -1, -1)
                                        for b in ['SO', 'EQ', 'GT', 'LT']]))],
            [])

@sbuild.parse
def mn_mfmsr(rd):
    rd = MSR

def mn_mfspr(ir, instr, arg1, arg2):
    sprid = arg2.arg.arg
    gprid = int(arg1.name[1:])
    if sprid in spr_dict:
        return [ ExprAff(arg1, spr_dict[sprid]) ], []
    elif sprid == 1:		# XER
        return [ ExprAff(arg1, ExprCompose(XER_BC, ExprInt(0, 22),
                                           XER_CA, XER_OV, XER_SO)) ], []
    else:
        return [ ExprAff(spr_access,
                         ExprInt(((sprid << SPR_ACCESS_SPR_OFF) |
                                    (gprid << SPR_ACCESS_GPR_OFF)), 32)),
                 ExprAff(exception_flags, ExprInt(EXCEPT_SPR_ACCESS, 32)) ], []

def mn_mtcrf(ir, instr, crm, rs):
    ret = []

    for i in xrange(8):
        if crm.arg.arg & (1 << (7 - i)):
            j = (28 - 4 * i) + 3
            for b in ['LT', 'GT', 'EQ', 'SO']:
                ret.append(ExprAff(all_regs_ids_byname["CR%d_%s" % (i, b)],
                                   rs[j:j+1]))
                j -= 1

    return ret, []

def mn_mtmsr(ir, instr, rs):
    print "%08x: MSR assigned" % instr.offset
    return [ ExprAff(MSR, rs) ], []

def mn_mtspr(ir, instr, arg1, arg2):
    sprid = arg1.arg.arg
    gprid = int(arg2.name[1:])
    if sprid in spr_dict:
        return [ ExprAff(spr_dict[sprid], arg2) ], []
    elif sprid == 1:		# XER
        return [ ExprAff(XER_SO, arg2[31:32]),
                 ExprAff(XER_OV, arg2[30:31]),
                 ExprAff(XER_CA, arg2[29:30]),
                 ExprAff(XER_BC, arg2[0:7]) ], []
    else:
        return [ ExprAff(spr_access,
                         ExprInt(((sprid << SPR_ACCESS_SPR_OFF) |
                                    (gprid << SPR_ACCESS_GPR_OFF) |
                                    SPR_ACCESS_IS_WRITE), 32)),
                 ExprAff(exception_flags, ExprInt(EXCEPT_SPR_ACCESS, 32)) ], []

def mn_do_mul(ir, instr, rd, ra, arg2):
    variant = instr.name[3:]
    if variant[-1] == '.':
        variant = variant[:-2]

    if variant == 'HW':
        v1 = ra.signExtend(64)
        v2 = arg2.signExtend(64)
        shift = 32
    elif variant == 'HWU':
        v1 = ra.zeroExtend(64)
        v2 = arg2.zeroExtend(64)
        shift = 32
    else:
        v1 = ra
        v2 = arg2
        shift = 0

    rvalue = ExprOp('*', v1, v2)
    if shift != 0:
        rvalue = rvalue[shift : shift + 32]

    ret = [ ExprAff(rd, rvalue) ]

    over_expr = None
    if variant[-1] == 'O':
        over_expr = ExprCond((rvalue.signExtend(64) ^
                              ExprOp('*', v1.signExtend(64),
                                     v2.signExtend(64))),
                             ExprInt(1, 1), ExprInt(0, 1))
        ret.append(ExprAff(XER_OV, over_expr))
        ret.append(ExprAff(XER_SO, XER_SO | over_expr))

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue, over_expr)

    return ret, []

def mn_do_nand(ir, instr, ra, rs, rb):
    rvalue = ~(rs & rb)
    ret = [ ExprAff(ra, rvalue) ]

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue)

    return ret, []

def mn_do_neg(ir, instr, rd, ra):
    rvalue = -ra
    ret = [ ExprAff(rd, rvalue) ]
    has_o = False

    over_expr = None
    if instr.name[-1] == 'O' or instr.name[-2] == 'O':
        has_o = True
        over_expr = ExprCond(ra ^ ExprInt(0x80000000, 32),
                             ExprInt(0, 1), ExprInt(1, 1))
        ret.append(ExprAff(XER_OV, over_expr))
        ret.append(ExprAff(XER_SO, XER_SO | over_expr))

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue, over_expr)

    return ret, []

def mn_do_nor(ir, instr, ra, rs, rb):

    rvalue = ~(rs | rb)
    ret = [ ExprAff(ra, rvalue) ]

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue)

    return ret, []

def mn_do_or(ir, instr, ra, rs, arg2):
    if len(instr.name) > 2 and instr.name[2] == 'C':
        oarg = ~arg2
    else:
        oarg = arg2

    rvalue = rs | oarg
    ret = [ ExprAff(ra, rvalue) ]

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue)

    return ret, []

def mn_do_rfi(ir, instr):
    dest = ExprCompose(ExprInt(0, 2), SRR0[2:32])
    ret = [ ExprAff(MSR, (MSR &
                          ~ExprInt(0b1111111101110011, 32) |
                          ExprCompose(SRR1[0:2], ExprInt(0, 2),
                                      SRR1[4:7], ExprInt(0, 1), 
                                      SRR1[8:16], ExprInt(0, 16)))),
            ExprAff(PC, dest),
            ExprAff(ir.IRDst, dest) ]
    return ret, []

def mn_do_rotate(ir, instr, ra, rs, shift, mb, me):
    r = ExprOp('<<<', rs, shift)
    if mb <= me:
        m = ExprInt(((1 << (32 - mb)) - 1) & ~((1 << (32 - me - 1)) - 1), 32)
    else:
        m = ExprInt(((1 << (32 - mb)) - 1) | ~((1 << (32 - me - 1)) - 1), 32)
    rvalue = r & m
    if instr.name[0:6] == 'RLWIMI':
        rvalue = rvalue | (ra & ~m)

    ret = [ ExprAff(ra, rvalue) ]

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue)

    return ret, []

def mn_do_slw(ir, instr, ra, rs, rb):

    rvalue = ExprCond(rb[5:6], ExprInt(0, 32),
                      ExprOp('<<', rs, rb & ExprInt(0b11111, 32)))
    ret = [ ExprAff(ra, rvalue) ]

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue)

    return ret, []

def mn_do_sraw(ir, instr, ra, rs, rb):
    rvalue = ExprCond(rb[5:6], ExprInt(0xFFFFFFFF, 32),
                      ExprOp('a>>', rs, rb & ExprInt(0b11111, 32)))
    ret = [ ExprAff(ra, rvalue) ]

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue)

    mask = ExprCond(rb[5:6], ExprInt(0xFFFFFFFF, 32),
                    (ExprInt(0xFFFFFFFF, 32) >>
                     (ExprInt(32, 32) - (rb & ExprInt(0b11111, 32)))))
    ret.append(ExprAff(XER_CA, rs.msb() &
                       ExprCond(rs & mask, ExprInt(1, 1), ExprInt(0, 1))))

    return ret, []

def mn_do_srawi(ir, instr, ra, rs, imm):
    rvalue = ExprOp('a>>', rs, imm)
    ret = [ ExprAff(ra, rvalue) ]

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue)

    mask = ExprInt(0xFFFFFFFF >> (32 - imm.arg.arg), 32)

    ret.append(ExprAff(XER_CA, rs.msb() &
                       ExprCond(rs & mask, ExprInt(1, 1), ExprInt(0, 1))))

    return ret, []

def mn_do_srw(ir, instr, ra, rs, rb):
    rvalue = rs >> (rb & ExprInt(0b11111, 32))
    ret = [ ExprAff(ra, rvalue) ]

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue)

    return ret, []

def mn_do_stmw(ir, instr, rs, dest):
    ret = []
    address = dest.arg
    ri = int(rs.name[1:],10)
    i = 0
    while ri <= 31:
        ret.append(ExprAff(ExprMem(address + ExprInt(i,32), 32),
                           all_regs_ids_byname["R%d" % ri]))
        ri += 1
        i += 4

    return ret, []

def mn_do_store(ir, instr, arg1, arg2, arg3=None):
    assert instr.name[0:2] == 'ST'

    ret = []
    additional_ir = []

    if instr.name[2] == 'S':
        raise RuntimeError("STSWI, and STSWX need implementing")
        pass # XXX

    size = {'B': 8, 'H': 16, 'W': 32}[instr.name[2]]

    has_b = False
    has_u = False
    is_stwcx = False

    for l in instr.name[3:]:
        if l == 'B' or l == 'R':
            has_b = True
        elif l == 'U':
            has_u = True
        elif l == 'X' or l == 'Z':
            pass	# Taken care of earlier
        elif l == 'C' or l == '.':
            is_stwcx = True
        else:
            assert False

    if arg3 is None:
        assert isinstance(arg2, ExprMem)

        address = arg2.arg
    else:
        address = arg2 + arg3

    dest = ExprMem(address, size)

    src = arg1[0:size]
    if has_b:
        src = byte_swap(src)

    ret.append(ExprAff(dest, src))
    if has_u:
        if arg3 is None:
            ret.append(ExprAff(arg2.arg.args[0], address))
        else:
            ret.append(ExprAff(arg2, address))

    if is_stwcx:
        loc_do = ExprLoc(ir.loc_db.add_location(), ir.IRDst.size)
        loc_dont = ExprLoc(ir.loc_db.add_location(), ir.IRDst.size)
        loc_next = ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size)
        flags = [ ExprAff(CR0_LT, ExprInt(0,1)),
                  ExprAff(CR0_GT, ExprInt(0,1)),
                  ExprAff(CR0_SO, XER_SO)]
        ret += flags
        ret.append(ExprAff(CR0_EQ, ExprInt(1,1)))
        ret.append(ExprAff(ir.IRDst, loc_next))
        dont = flags + [ ExprAff(CR0_EQ, ExprInt(0,1)),
                         ExprAff(ir.IRDst, loc_next) ]
        additional_ir = [ IRBlock(loc_do, [ AssignBlock(ret) ]),
                          IRBlock(loc_dont, [ AssignBlock(dont) ]) ]
        ret = [ ExprAff(reserve, ExprInt(0, 1)),
                ExprAff(ir.IRDst, ExprCond(reserve, loc_do, loc_dont)) ]

    return ret, additional_ir

def mn_do_sub(ir, instr, arg1, arg2, arg3):
    assert instr.name[0:4] == 'SUBF'

    flags_update = []

    has_dot = False
    has_c = False
    has_e = False
    has_o = False

    for l in instr.name[4:]:
        if l == '.':
            has_dot = True
        elif l == 'C':
            has_c = True
        elif l == 'E':
            has_e = True
        elif l == 'O':
            has_o = True
        elif l == 'I' or l == 'M' or l == 'S' or l == 'Z':
            pass	# Taken care of earlier
        else:
            assert False

    if has_e:
        arg3 = arg3 + XER_CA.zeroExtend(32)
        arg2 = arg2 + ExprInt(1, 32)

    rvalue = arg3 - arg2

    over_expr = None
    if has_o:
        msb1 = arg2.msb()
        msb2 = arg3.msb()
        msba = rvalue.msb()
        over_expr = (msb1 ^ msb2) & (msb1 ^ msba)
        flags_update.append(ExprAff(XER_OV, over_expr))
        flags_update.append(ExprAff(XER_SO, XER_SO | over_expr))

    if has_dot:
        flags_update += mn_compute_flags(rvalue, over_expr)

    if has_c or has_e:
        carry_expr = ((((arg3 ^ arg2) ^ rvalue) ^
                       ((arg3 ^ rvalue) & (arg3 ^ arg2))).msb())
        flags_update.append(ExprAff(XER_CA, ~carry_expr))

    return ([ ExprAff(arg1, rvalue) ] + flags_update), []

def mn_do_xor(ir, instr, ra, rs, rb):
    rvalue = rs ^ rb
    ret = [ ExprAff(ra, rvalue) ]

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue)

    return ret, []

def mn_b(ir, instr, arg1, arg2 = None):
    if arg2 is not None:
        arg1 = arg2
    return [ ExprAff(PC, arg1), ExprAff(ir.IRDst, arg1) ], []

def mn_bl(ir, instr, arg1, arg2 = None):
    if arg2 is not None:
        arg1 = arg2
    dst = ir.get_next_instr(instr)
    return [ ExprAff(LR, ExprLoc(dst, 32)),
             ExprAff(PC, arg1),
             ExprAff(ir.IRDst, arg1) ], []

def mn_get_condition(instr):
    bit = instr.additional_info.bi & 0b11
    cr = instr.args[0].name
    return all_regs_ids_byname[cr + '_' + ['LT', 'GT', 'EQ', 'SO'][bit]]

def mn_do_cond_branch(ir, instr, dest):
    bo = instr.additional_info.bo
    bi = instr.additional_info.bi
    ret = []

    if bo & 0b00100:
        ctr_cond = True
    else:
        ret.append(ExprAff(CTR, CTR - ExprInt(1, 32)))
        ctr_cond = ExprCond(CTR ^ ExprInt(1, 32), ExprInt(1, 1), ExprInt(0, 1))
        if bo & 0b00010:
            ctr_cond = ~ctr_cond

    if (bo & 0b10000):
        cond_cond = True
    else:
        cond_cond = mn_get_condition(instr)
        if not (bo & 0b01000):
            cond_cond = ~cond_cond

    if ctr_cond != True or cond_cond != True:
        if ctr_cond != True:
            condition = ctr_cond
            if cond_cond != True:
                condition = condition & cond_cond
        else:
            condition = cond_cond
        dst = ir.get_next_instr(instr)
        dest_expr = ExprCond(condition, dest,
                             ExprLoc(dst, 32))
    else:
        dest_expr = dest

    if instr.name[-1] == 'L' or instr.name[-2:-1] == 'LA':
        dst = ir.get_next_instr(instr)
        ret.append(ExprAff(LR, ExprLoc(dst, 32)))

    ret.append(ExprAff(PC, dest_expr))
    ret.append(ExprAff(ir.IRDst, dest_expr))

    return ret, []

def mn_do_nop_warn(ir, instr, *args):
    print "Warning, instruction %s implemented as NOP" % instr
    return [], []

@sbuild.parse
def mn_cmp_signed(arg1, arg2, arg3):
    crf_dict[arg1]['LT'] = ((arg2 - arg3) ^
                            ((arg2 ^ arg3) & ((arg2 - arg3) ^ arg2))).msb()
    crf_dict[arg1]['GT'] = ((arg3 - arg2) ^
                            ((arg3 ^ arg2) & ((arg3 - arg2) ^ arg3))).msb()
    crf_dict[arg1]['EQ'] = i1(0) if arg2 - arg3 else i1(1)
    crf_dict[arg1]['SO'] = XER_SO

@sbuild.parse
def mn_cmp_unsigned(arg1, arg2, arg3):
    crf_dict[arg1]['LT'] = (((arg2 - arg3) ^
                             ((arg2 ^ arg3) & ((arg2 - arg3) ^ arg2))) ^
                            arg2 ^ arg3).msb()
    crf_dict[arg1]['GT'] = (((arg3 - arg2) ^
                             ((arg3 ^ arg2) & ((arg3 - arg2) ^ arg3))) ^
                            arg2 ^ arg3).msb()
    crf_dict[arg1]['EQ'] = i1(0) if arg2 - arg3 else i1(1)
    crf_dict[arg1]['SO'] = XER_SO

def mn_nop(ir, instr, *args):
    return [], []

@sbuild.parse
def mn_or(arg1, arg2, arg3):
    arg1 = arg2 | arg3

@sbuild.parse
def mn_assign(arg1, arg2):
    arg2 = arg1

def mn_stb(ir, instr, arg1, arg2):
    dest = ExprMem(arg2.arg, 8)
    return [ExprAff(dest, ExprSlice(arg1, 0, 8))], []

@sbuild.parse
def mn_stwu(arg1, arg2):
    arg2 = arg1
    arg1 = arg2.arg

sem_dir = {
    'B': mn_b,
    'BA': mn_b,
    'BL': mn_bl,
    'BLA': mn_bl,
    'CMPLW': mn_cmp_unsigned,
    'CMPLWI': mn_cmp_unsigned,
    'CMPW': mn_cmp_signed,
    'CMPWI': mn_cmp_signed,
    'CNTLZW': mn_do_cntlzw,
    'CNTLZW.': mn_do_cntlzw,
    'ECIWX': mn_do_nop_warn,
    'ECOWX': mn_do_nop_warn,
    'EIEIO': mn_do_nop_warn,
    'EQV': mn_do_eqv,
    'EQV.': mn_do_eqv,
    'ICBI': mn_do_nop_warn,
    'ISYNC': mn_do_nop_warn,
    'MCRF': mn_do_mcrf,
    'MCRXR': mn_do_mcrxr,
    'MFCR': mn_do_mfcr,
    'MFMSR': mn_mfmsr,
    'MFSPR': mn_mfspr,
    'MFSR': mn_do_nop_warn,
    'MFSRIN': mn_do_nop_warn,
    'MFTB': mn_mfmsr,
    'MTCRF': mn_mtcrf,
    'MTMSR': mn_mtmsr,
    'MTSPR': mn_mtspr,
    'MTSR': mn_do_nop_warn,
    'MTSRIN': mn_do_nop_warn,
    'NAND': mn_do_nand,
    'NAND.': mn_do_nand,
    'NOR': mn_do_nor,
    'NOR.': mn_do_nor,
    'RFI': mn_do_rfi,
    'SC': mn_do_nop_warn,
    'SLW': mn_do_slw,
    'SLW.': mn_do_slw,
    'SRAW': mn_do_sraw,
    'SRAW.': mn_do_sraw,
    'SRAWI': mn_do_srawi,
    'SRAWI.': mn_do_srawi,
    'SRW': mn_do_srw,
    'SRW.': mn_do_srw,
    'SYNC': mn_do_nop_warn,
    'TLBIA': mn_do_nop_warn,
    'TLBIE': mn_do_nop_warn,
    'TLBSYNC': mn_do_nop_warn,
    'TW': mn_do_nop_warn,
    'TWI': mn_do_nop_warn,
}


class ir_ppc32b(IntermediateRepresentation):

    def __init__(self, loc_db=None):
        super(ir_ppc32b, self).__init__(mn_ppc, 'b', loc_db)
        self.pc = mn_ppc.getpc()
        self.sp = mn_ppc.getsp()
        self.IRDst = expr.ExprId('IRDst', 32)
        self.addrsize = 32

    def get_ir(self, instr):
        args = instr.args[:]
        if instr.name[0:5] in [ 'ADDIS', 'ORIS', 'XORIS', 'ANDIS' ]:
            args[2] = ExprInt(args[2].arg << 16, 32)
        if instr.name[0:3] == 'ADD':
            if instr.name[0:4] == 'ADDZ':
                last_arg = ExprInt(0, 32)
            elif instr.name[0:4] == 'ADDM':
                last_arg = ExprInt(0xFFFFFFFF, 32)
            else:
                last_arg = args[2]
            instr_ir, extra_ir = mn_do_add(self, instr, args[0], args[1],
                                           last_arg)
        elif instr.name[0:3] == 'AND':
            instr_ir, extra_ir = mn_do_and(self, instr, *args)
        elif instr.additional_info.bo_bi_are_defined:
            name = instr.name
            if name[-1] == '+' or name[-1] == '-':
                name = name[0:-1]
            if name[-3:] == 'CTR' or name[-4:] == 'CTRL':
                arg1 = ExprCompose(ExprInt(0, 2), CTR[2:32])
            elif name[-2:] == 'LR' or name[-3:] == 'LRL':
                arg1 = ExprCompose(ExprInt(0, 2), LR[2:32])
            else:
                arg1 = args[1]
            instr_ir, extra_ir = mn_do_cond_branch(self, instr, arg1)
        elif instr.name[0:2] == 'CR':
            instr_ir, extra_ir = mn_do_cr(self, instr, *args)
        elif instr.name[0:3] == 'DCB':
            instr_ir, extra_ir = mn_do_nop_warn(self, instr, *args)
        elif instr.name[0:3] == 'DIV':
            instr_ir, extra_ir = mn_do_div(self, instr, *args)
        elif instr.name[0:4] == 'EXTS':
            instr_ir, extra_ir = mn_do_exts(self, instr, *args)
        elif instr.name[0] == 'L':
            instr_ir, extra_ir = mn_do_load(self, instr, *args)
        elif instr.name[0:3] == 'MUL':
            instr_ir, extra_ir = mn_do_mul(self, instr, *args)
        elif instr.name[0:3] == 'NEG':
            instr_ir, extra_ir = mn_do_neg(self, instr, *args)
        elif instr.name[0:2] == 'OR':
            instr_ir, extra_ir = mn_do_or(self, instr, *args)
        elif instr.name[0:2] == 'RL':
            instr_ir, extra_ir = mn_do_rotate(self, instr, args[0], args[1],
                                              args[2], args[3].arg.arg,
                                              args[4].arg.arg)
        elif instr.name == 'STMW':
            instr_ir, extra_ir = mn_do_stmw(self, instr, *args)
        elif instr.name[0:2] == 'ST':
            instr_ir, extra_ir = mn_do_store(self, instr, *args)
        elif instr.name[0:4] == 'SUBF':
            if instr.name[0:5] == 'SUBFZ':
                last_arg = ExprInt(0)
            elif instr.name[0:5] == 'SUBFM':
                last_arg = ExprInt(0xFFFFFFFF)
            else:
                last_arg = args[2]
            instr_ir, extra_ir = mn_do_sub(self, instr, args[0], args[1],
                                           last_arg)
        elif instr.name[0:3] == 'XOR':
            instr_ir, extra_ir = mn_do_xor(self, instr, *args)
        else:
            instr_ir, extra_ir = sem_dir[instr.name](self, instr, *args)

        return instr_ir, extra_ir

    def get_next_instr(self, instr):
        l = self.loc_db.get_or_create_offset_location(instr.offset  + 4)
        return l

    def get_next_break_loc_key(self, instr):
        l = self.loc_db.get_or_create_offset_location(instr.offset  + 4)
        return l

Module variables

var BREAKPOINT_READ

var BREAKPOINT_WRITE

var EXCEPT_ACCESS_VIOL

var EXCEPT_BREAKPOINT_INTERN

var EXCEPT_BREAKPOINT_MEMORY

var EXCEPT_CODE_AUTOMOD

var EXCEPT_DIV_BY_ZERO

var EXCEPT_DO_NOT_UPDATE_PC

var EXCEPT_ILLEGAL_INSN

var EXCEPT_INT_XX

var EXCEPT_NUM_UPDT_EIP

var EXCEPT_PRIV_INSN

var EXCEPT_SOFT_BP

var EXCEPT_SPR_ACCESS

var EXCEPT_UNK_MNEMO

var EXPRAFF

var EXPRCOMPOSE

var EXPRCOND

var EXPRID

var EXPRINT

var EXPRLOC

var EXPRMEM

var EXPROP

var EXPRSLICE

var EXPR_ORDER_DICT

var PAGE_EXEC

var PAGE_READ

var PAGE_WRITE

var PRIORITY_MAX

var SPR_ACCESS_GPR_MASK

var SPR_ACCESS_GPR_OFF

var SPR_ACCESS_IS_WRITE

var SPR_ACCESS_SPR_MASK

var SPR_ACCESS_SPR_OFF

var TOK_EQUAL

var TOK_INF

var TOK_INF_EQUAL

var TOK_INF_EQUAL_SIGNED

var TOK_INF_EQUAL_UNSIGNED

var TOK_INF_SIGNED

var TOK_INF_UNSIGNED

var TOK_POS

var TOK_POS_STRICT

var all_regs_ids

var all_regs_ids_byname

var all_regs_ids_init

var all_regs_ids_no_alias

var crf_dict

var crfbitregs_expr

var crfbitregs_init

var crfbitregs_str

var crfregs_expr

var crfregs_init

var crfregs_str

var ctx

var field

var flag

var gpregs_expr

var gpregs_init

var gpregs_str

var i

var mod_size2uint

var otherregs_expr

var otherregs_init

var otherregs_str

var priorities

var priorities_list

var regs_flt_expr

var regs_init

var sbuild

var sem_dir

var size_to_IEEE754_info

var spr_dict

var superregs_expr

var superregs_init

var superregs_str

var xerbcreg_expr

var xerbcreg_init

var xerbcreg_str

var xerbitregs_expr

var xerbitregs_init

var xerbitregs_str

Functions

def byte_swap(

expr)

def byte_swap(expr):
    nbytes = expr.size / 8
    bytes = [ expr[i*8:i*8+8] for i in xrange(nbytes - 1, -1, -1) ]
    return ExprCompose(bytes)

def crbit_to_reg(

bit)

def crbit_to_reg(bit):
    bit = bit.arg.arg
    crid = bit / 4
    bitname = [ 'LT', 'GT', 'EQ', 'SO' ][bit % 4]
    return all_regs_ids_byname["CR%d_%s" % (crid, bitname)]

def mn_b(

ir, instr, arg1, arg2=None)

def mn_b(ir, instr, arg1, arg2 = None):
    if arg2 is not None:
        arg1 = arg2
    return [ ExprAff(PC, arg1), ExprAff(ir.IRDst, arg1) ], []

def mn_bl(

ir, instr, arg1, arg2=None)

def mn_bl(ir, instr, arg1, arg2 = None):
    if arg2 is not None:
        arg1 = arg2
    dst = ir.get_next_instr(instr)
    return [ ExprAff(LR, ExprLoc(dst, 32)),
             ExprAff(PC, arg1),
             ExprAff(ir.IRDst, arg1) ], []

def mn_compute_flags(

rvalue, overflow_expr=None)

def mn_compute_flags(rvalue, overflow_expr=None):
    ret = []
    ret.append(ExprAff(CR0_LT, rvalue.msb()))
    ret.append(ExprAff(CR0_GT, (ExprCond(rvalue, ExprInt(1, 1),
                                         ExprInt(0, 1)) & ~rvalue.msb())))
    ret.append(ExprAff(CR0_EQ, ExprCond(rvalue, ExprInt(0, 1),
                                        ExprInt(1, 1))))
    if overflow_expr != None:
        ret.append(ExprAff(CR0_SO, XER_SO | overflow_expr))
    else:
        ret.append(ExprAff(CR0_SO, XER_SO))

    return ret

def mn_do_add(

ir, instr, arg1, arg2, arg3)

def mn_do_add(ir, instr, arg1, arg2, arg3):
    assert instr.name[0:3] == 'ADD'

    flags_update = []

    has_dot = False
    has_c = False
    has_e = False
    has_o = False

    for l in instr.name[3:]:
        if l == '.':
            has_dot = True
        elif l == 'C':
            has_c = True
        elif l == 'E':
            has_e = True
        elif l == 'O':
            has_o = True
        elif l == 'I' or l == 'M' or l == 'S' or l == 'Z':
            pass	# Taken care of earlier
        else:
            assert False

    rvalue = arg2 + arg3

    if has_e:
        rvalue = rvalue + XER_CA.zeroExtend(32)

    over_expr = None
    if has_o:
        msb1 = arg2.msb()
        msb2 = arg3.msb()
        msba = rvalue.msb()
        over_expr = ~(msb1 ^ msb2) & (msb1 ^ msba)
        flags_update.append(ExprAff(XER_OV, over_expr))
        flags_update.append(ExprAff(XER_SO, XER_SO | over_expr))

    if has_dot:
        flags_update += mn_compute_flags(rvalue, over_expr)

    if has_c or has_e:
        carry_expr = (((arg2 ^ arg3) ^ rvalue) ^
                      ((arg2 ^ rvalue) & (~(arg2 ^ arg3)))).msb()
        flags_update.append(ExprAff(XER_CA, carry_expr))

    return ([ ExprAff(arg1, rvalue) ] + flags_update), []

def mn_do_and(

ir, instr, ra, rs, arg2)

def mn_do_and(ir, instr, ra, rs, arg2):
    if len(instr.name) > 3 and instr.name[3] == 'C':
        oarg = ~arg2
    else:
        oarg = arg2

    rvalue = rs & oarg
    ret = [ ExprAff(ra, rvalue) ]

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue)

    return ret, []

def mn_do_cntlzw(

ir, instr, ra, rs)

def mn_do_cntlzw(ir, instr, ra, rs):
    ret = [ ExprAff(ra, ExprOp('cntleadzeros', rs)) ]

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue)

    return ret, []

def mn_do_cond_branch(

ir, instr, dest)

def mn_do_cond_branch(ir, instr, dest):
    bo = instr.additional_info.bo
    bi = instr.additional_info.bi
    ret = []

    if bo & 0b00100:
        ctr_cond = True
    else:
        ret.append(ExprAff(CTR, CTR - ExprInt(1, 32)))
        ctr_cond = ExprCond(CTR ^ ExprInt(1, 32), ExprInt(1, 1), ExprInt(0, 1))
        if bo & 0b00010:
            ctr_cond = ~ctr_cond

    if (bo & 0b10000):
        cond_cond = True
    else:
        cond_cond = mn_get_condition(instr)
        if not (bo & 0b01000):
            cond_cond = ~cond_cond

    if ctr_cond != True or cond_cond != True:
        if ctr_cond != True:
            condition = ctr_cond
            if cond_cond != True:
                condition = condition & cond_cond
        else:
            condition = cond_cond
        dst = ir.get_next_instr(instr)
        dest_expr = ExprCond(condition, dest,
                             ExprLoc(dst, 32))
    else:
        dest_expr = dest

    if instr.name[-1] == 'L' or instr.name[-2:-1] == 'LA':
        dst = ir.get_next_instr(instr)
        ret.append(ExprAff(LR, ExprLoc(dst, 32)))

    ret.append(ExprAff(PC, dest_expr))
    ret.append(ExprAff(ir.IRDst, dest_expr))

    return ret, []

def mn_do_cr(

ir, instr, crd, cra, crb)

def mn_do_cr(ir, instr, crd, cra, crb):
    a = crbit_to_reg(cra)
    b = crbit_to_reg(crb)
    d = crbit_to_reg(crd)

    op = instr.name[2:]

    if op == 'AND':
        r = a & b
    elif op == 'ANDC':
        r = a & ~b
    elif op == 'EQV':
        r = ~(a ^ b)
    elif op == 'NAND':
        r = ~(a & b)
    elif op == 'NOR':
        r = ~(a | b)
    elif op == 'OR':
        r = a | b
    elif op == 'ORC':
        r = a | ~b
    elif op == 'XOR':
        r = a ^ b
    else:
        raise "Unknown operation on CR"
    return [ ExprAff(d, r) ], []

def mn_do_div(

ir, instr, rd, ra, rb)

def mn_do_div(ir, instr, rd, ra, rb):
    assert instr.name[0:4] == 'DIVW'

    flags_update = []

    has_dot = False
    has_c = False
    has_o = False
    has_u = False

    for l in instr.name[3:]:
        if l == '.':
            has_dot = True
        elif l == 'C':
            has_c = True
        elif l == 'O':
            has_o = True
        elif l == 'U':
            has_u = True
        elif l == 'W':
            pass
        else:
            assert False

    if has_u:
        op = 'udiv'
    else:
        op = 'idiv'

    rvalue = ExprOp(op, ra, rb)

    over_expr = None
    if has_o:
        over_expr = ExprCond(rb, ExprInt(0, 1), ExprInt(1, 1))
        if not has_u:
            over_expr = over_expr | (ExprCond(ra ^ 0x80000000, ExprInt(0, 1),
                                              ExprInt(1, 1)) &
                                     ExprCond(rb ^ 0xFFFFFFFF, ExprInt(0, 1),
                                              ExprInt(1, 1)))
        flags_update.append(ExprAff(XER_OV, over_expr))
        flags_update.append(ExprAff(XER_SO, XER_SO | over_expr))

    if has_dot:
        flags_update += mn_compute_flags(rvalue, over_expr)

    return ([ ExprAff(rd, rvalue) ] + flags_update), []

def mn_do_eqv(

ir, instr, ra, rs, rb)

def mn_do_eqv(ir, instr, ra, rs, rb):
    rvalue = ~(rs ^ rb)
    ret = [ ExprAff(ra, rvalue) ]

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue)

    return ret, []

def mn_do_exts(

ir, instr, ra, rs)

def mn_do_exts(ir, instr, ra, rs):
    if instr.name[4] == 'B':
        size = 8
    elif instr.name[4] == 'H':
        size = 16
    else:
        assert False

    rvalue = rs[0:size].signExtend(32)
    ret = [ ExprAff(ra, rvalue) ]

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue)

    return ret, []

def mn_do_lmw(

ir, instr, rd, src)

def mn_do_lmw(ir, instr, rd, src):
    ret = []
    address = src.arg
    ri = int(rd.name[1:],10)
    i = 0
    while ri <= 31:
        ret.append(ExprAff(all_regs_ids_byname["R%d" % ri],
                           ExprMem(address + ExprInt(i, 32), 32)))
        ri += 1
        i += 4

    return ret, []

def mn_do_load(

ir, instr, arg1, arg2, arg3=None)

def mn_do_load(ir, instr, arg1, arg2, arg3=None):
    assert instr.name[0] == 'L'

    ret = []

    if instr.name[1] == 'M':
        return mn_do_lmw(ir, instr, arg1, arg2)
    elif instr.name[1] == 'S':
        raise RuntimeError("LSWI, and LSWX need implementing")
        pass # XXX

    size = {'B': 8, 'H': 16, 'W': 32}[instr.name[1]]

    has_a = False
    has_b = False
    has_u = False
    is_lwarx = False

    for l in instr.name[2:]:
        if l == 'A':
            has_a = True
        elif l == 'B':
            has_b = True
        elif l == 'U':
            has_u = True
        elif l == 'X' or l == 'Z':
            pass	# Taken care of earlier
        elif l == 'R' and not has_b:
            is_lwarx = True
        else:
            assert False

    if arg3 is None:
        assert isinstance(arg2, ExprMem)

        address = arg2.arg
    else:
        address = arg2 + arg3

    src = ExprMem(address, size)

    if has_b:
        src = byte_swap(src)

    if has_a:
        src = src.signExtend(32)
    else:
        src = src.zeroExtend(32)

    ret.append(ExprAff(arg1, src))
    if has_u:
        if arg3 is None:
            ret.append(ExprAff(arg2.arg.args[0], address))
        else:
            ret.append(ExprAff(arg2, address))

    if is_lwarx:
        ret.append(ExprAff(reserve, ExprInt(1, 1)))
        ret.append(ExprAff(reserve_address, address))	# XXX should be the PA

    return ret, []

def mn_do_lswi(

ir, instr, rd, ra, nb)

def mn_do_lswi(ir, instr, rd, ra, nb):
    if nb == 0:
        nb = 32
    i = 32
    raise "%r not implemented" % instr

def mn_do_lswx(

ir, instr, rd, ra, nb)

def mn_do_lswx(ir, instr, rd, ra, nb):
    raise "%r not implemented" % instr

def mn_do_mcrf(

ir, instr, crfd, crfs)

def mn_do_mcrf(ir, instr, crfd, crfs):
    ret = []

    for bit in [ 'LT', 'GT', 'EQ', 'SO' ]:
        d = all_regs_ids_byname["%s_%s" % (crfd, bit)]
        s = all_regs_ids_byname["%s_%s" % (crfs, bit)]
        ret.append(ExprAff(d, s))

    return ret, []

def mn_do_mcrxr(

ir, instr, crfd)

def mn_do_mcrxr(ir, instr, crfd):
    ret = []

    for (bit, val) in [ ('LT', XER_SO), ('GT', XER_OV), ('EQ', XER_CA),
                        ('SO', ExprInt(0, 1)) ]:
        ret.append(ExprAff(all_regs_ids_byname["%s_%s" % (crfd, bit)], val))

    return ret, []

def mn_do_mfcr(

ir, instr, rd)

def mn_do_mfcr(ir, instr, rd):
    return ([ ExprAff(rd, ExprCompose(*[ all_regs_ids_byname["CR%d_%s" % (i, b)]
                                        for i in xrange(7, -1, -1)
                                        for b in ['SO', 'EQ', 'GT', 'LT']]))],
            [])

def mn_do_mul(

ir, instr, rd, ra, arg2)

def mn_do_mul(ir, instr, rd, ra, arg2):
    variant = instr.name[3:]
    if variant[-1] == '.':
        variant = variant[:-2]

    if variant == 'HW':
        v1 = ra.signExtend(64)
        v2 = arg2.signExtend(64)
        shift = 32
    elif variant == 'HWU':
        v1 = ra.zeroExtend(64)
        v2 = arg2.zeroExtend(64)
        shift = 32
    else:
        v1 = ra
        v2 = arg2
        shift = 0

    rvalue = ExprOp('*', v1, v2)
    if shift != 0:
        rvalue = rvalue[shift : shift + 32]

    ret = [ ExprAff(rd, rvalue) ]

    over_expr = None
    if variant[-1] == 'O':
        over_expr = ExprCond((rvalue.signExtend(64) ^
                              ExprOp('*', v1.signExtend(64),
                                     v2.signExtend(64))),
                             ExprInt(1, 1), ExprInt(0, 1))
        ret.append(ExprAff(XER_OV, over_expr))
        ret.append(ExprAff(XER_SO, XER_SO | over_expr))

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue, over_expr)

    return ret, []

def mn_do_nand(

ir, instr, ra, rs, rb)

def mn_do_nand(ir, instr, ra, rs, rb):
    rvalue = ~(rs & rb)
    ret = [ ExprAff(ra, rvalue) ]

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue)

    return ret, []

def mn_do_neg(

ir, instr, rd, ra)

def mn_do_neg(ir, instr, rd, ra):
    rvalue = -ra
    ret = [ ExprAff(rd, rvalue) ]
    has_o = False

    over_expr = None
    if instr.name[-1] == 'O' or instr.name[-2] == 'O':
        has_o = True
        over_expr = ExprCond(ra ^ ExprInt(0x80000000, 32),
                             ExprInt(0, 1), ExprInt(1, 1))
        ret.append(ExprAff(XER_OV, over_expr))
        ret.append(ExprAff(XER_SO, XER_SO | over_expr))

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue, over_expr)

    return ret, []

def mn_do_nop_warn(

ir, instr, *args)

def mn_do_nop_warn(ir, instr, *args):
    print "Warning, instruction %s implemented as NOP" % instr
    return [], []

def mn_do_nor(

ir, instr, ra, rs, rb)

def mn_do_nor(ir, instr, ra, rs, rb):

    rvalue = ~(rs | rb)
    ret = [ ExprAff(ra, rvalue) ]

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue)

    return ret, []

def mn_do_or(

ir, instr, ra, rs, arg2)

def mn_do_or(ir, instr, ra, rs, arg2):
    if len(instr.name) > 2 and instr.name[2] == 'C':
        oarg = ~arg2
    else:
        oarg = arg2

    rvalue = rs | oarg
    ret = [ ExprAff(ra, rvalue) ]

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue)

    return ret, []

def mn_do_rfi(

ir, instr)

def mn_do_rfi(ir, instr):
    dest = ExprCompose(ExprInt(0, 2), SRR0[2:32])
    ret = [ ExprAff(MSR, (MSR &
                          ~ExprInt(0b1111111101110011, 32) |
                          ExprCompose(SRR1[0:2], ExprInt(0, 2),
                                      SRR1[4:7], ExprInt(0, 1), 
                                      SRR1[8:16], ExprInt(0, 16)))),
            ExprAff(PC, dest),
            ExprAff(ir.IRDst, dest) ]
    return ret, []

def mn_do_rotate(

ir, instr, ra, rs, shift, mb, me)

def mn_do_rotate(ir, instr, ra, rs, shift, mb, me):
    r = ExprOp('<<<', rs, shift)
    if mb <= me:
        m = ExprInt(((1 << (32 - mb)) - 1) & ~((1 << (32 - me - 1)) - 1), 32)
    else:
        m = ExprInt(((1 << (32 - mb)) - 1) | ~((1 << (32 - me - 1)) - 1), 32)
    rvalue = r & m
    if instr.name[0:6] == 'RLWIMI':
        rvalue = rvalue | (ra & ~m)

    ret = [ ExprAff(ra, rvalue) ]

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue)

    return ret, []

def mn_do_slw(

ir, instr, ra, rs, rb)

def mn_do_slw(ir, instr, ra, rs, rb):

    rvalue = ExprCond(rb[5:6], ExprInt(0, 32),
                      ExprOp('<<', rs, rb & ExprInt(0b11111, 32)))
    ret = [ ExprAff(ra, rvalue) ]

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue)

    return ret, []

def mn_do_sraw(

ir, instr, ra, rs, rb)

def mn_do_sraw(ir, instr, ra, rs, rb):
    rvalue = ExprCond(rb[5:6], ExprInt(0xFFFFFFFF, 32),
                      ExprOp('a>>', rs, rb & ExprInt(0b11111, 32)))
    ret = [ ExprAff(ra, rvalue) ]

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue)

    mask = ExprCond(rb[5:6], ExprInt(0xFFFFFFFF, 32),
                    (ExprInt(0xFFFFFFFF, 32) >>
                     (ExprInt(32, 32) - (rb & ExprInt(0b11111, 32)))))
    ret.append(ExprAff(XER_CA, rs.msb() &
                       ExprCond(rs & mask, ExprInt(1, 1), ExprInt(0, 1))))

    return ret, []

def mn_do_srawi(

ir, instr, ra, rs, imm)

def mn_do_srawi(ir, instr, ra, rs, imm):
    rvalue = ExprOp('a>>', rs, imm)
    ret = [ ExprAff(ra, rvalue) ]

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue)

    mask = ExprInt(0xFFFFFFFF >> (32 - imm.arg.arg), 32)

    ret.append(ExprAff(XER_CA, rs.msb() &
                       ExprCond(rs & mask, ExprInt(1, 1), ExprInt(0, 1))))

    return ret, []

def mn_do_srw(

ir, instr, ra, rs, rb)

def mn_do_srw(ir, instr, ra, rs, rb):
    rvalue = rs >> (rb & ExprInt(0b11111, 32))
    ret = [ ExprAff(ra, rvalue) ]

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue)

    return ret, []

def mn_do_stmw(

ir, instr, rs, dest)

def mn_do_stmw(ir, instr, rs, dest):
    ret = []
    address = dest.arg
    ri = int(rs.name[1:],10)
    i = 0
    while ri <= 31:
        ret.append(ExprAff(ExprMem(address + ExprInt(i,32), 32),
                           all_regs_ids_byname["R%d" % ri]))
        ri += 1
        i += 4

    return ret, []

def mn_do_store(

ir, instr, arg1, arg2, arg3=None)

def mn_do_store(ir, instr, arg1, arg2, arg3=None):
    assert instr.name[0:2] == 'ST'

    ret = []
    additional_ir = []

    if instr.name[2] == 'S':
        raise RuntimeError("STSWI, and STSWX need implementing")
        pass # XXX

    size = {'B': 8, 'H': 16, 'W': 32}[instr.name[2]]

    has_b = False
    has_u = False
    is_stwcx = False

    for l in instr.name[3:]:
        if l == 'B' or l == 'R':
            has_b = True
        elif l == 'U':
            has_u = True
        elif l == 'X' or l == 'Z':
            pass	# Taken care of earlier
        elif l == 'C' or l == '.':
            is_stwcx = True
        else:
            assert False

    if arg3 is None:
        assert isinstance(arg2, ExprMem)

        address = arg2.arg
    else:
        address = arg2 + arg3

    dest = ExprMem(address, size)

    src = arg1[0:size]
    if has_b:
        src = byte_swap(src)

    ret.append(ExprAff(dest, src))
    if has_u:
        if arg3 is None:
            ret.append(ExprAff(arg2.arg.args[0], address))
        else:
            ret.append(ExprAff(arg2, address))

    if is_stwcx:
        loc_do = ExprLoc(ir.loc_db.add_location(), ir.IRDst.size)
        loc_dont = ExprLoc(ir.loc_db.add_location(), ir.IRDst.size)
        loc_next = ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size)
        flags = [ ExprAff(CR0_LT, ExprInt(0,1)),
                  ExprAff(CR0_GT, ExprInt(0,1)),
                  ExprAff(CR0_SO, XER_SO)]
        ret += flags
        ret.append(ExprAff(CR0_EQ, ExprInt(1,1)))
        ret.append(ExprAff(ir.IRDst, loc_next))
        dont = flags + [ ExprAff(CR0_EQ, ExprInt(0,1)),
                         ExprAff(ir.IRDst, loc_next) ]
        additional_ir = [ IRBlock(loc_do, [ AssignBlock(ret) ]),
                          IRBlock(loc_dont, [ AssignBlock(dont) ]) ]
        ret = [ ExprAff(reserve, ExprInt(0, 1)),
                ExprAff(ir.IRDst, ExprCond(reserve, loc_do, loc_dont)) ]

    return ret, additional_ir

def mn_do_sub(

ir, instr, arg1, arg2, arg3)

def mn_do_sub(ir, instr, arg1, arg2, arg3):
    assert instr.name[0:4] == 'SUBF'

    flags_update = []

    has_dot = False
    has_c = False
    has_e = False
    has_o = False

    for l in instr.name[4:]:
        if l == '.':
            has_dot = True
        elif l == 'C':
            has_c = True
        elif l == 'E':
            has_e = True
        elif l == 'O':
            has_o = True
        elif l == 'I' or l == 'M' or l == 'S' or l == 'Z':
            pass	# Taken care of earlier
        else:
            assert False

    if has_e:
        arg3 = arg3 + XER_CA.zeroExtend(32)
        arg2 = arg2 + ExprInt(1, 32)

    rvalue = arg3 - arg2

    over_expr = None
    if has_o:
        msb1 = arg2.msb()
        msb2 = arg3.msb()
        msba = rvalue.msb()
        over_expr = (msb1 ^ msb2) & (msb1 ^ msba)
        flags_update.append(ExprAff(XER_OV, over_expr))
        flags_update.append(ExprAff(XER_SO, XER_SO | over_expr))

    if has_dot:
        flags_update += mn_compute_flags(rvalue, over_expr)

    if has_c or has_e:
        carry_expr = ((((arg3 ^ arg2) ^ rvalue) ^
                       ((arg3 ^ rvalue) & (arg3 ^ arg2))).msb())
        flags_update.append(ExprAff(XER_CA, ~carry_expr))

    return ([ ExprAff(arg1, rvalue) ] + flags_update), []

def mn_do_xor(

ir, instr, ra, rs, rb)

def mn_do_xor(ir, instr, ra, rs, rb):
    rvalue = rs ^ rb
    ret = [ ExprAff(ra, rvalue) ]

    if instr.name[-1] == '.':
        ret += mn_compute_flags(rvalue)

    return ret, []

def mn_get_condition(

instr)

def mn_get_condition(instr):
    bit = instr.additional_info.bi & 0b11
    cr = instr.args[0].name
    return all_regs_ids_byname[cr + '_' + ['LT', 'GT', 'EQ', 'SO'][bit]]

def mn_mfspr(

ir, instr, arg1, arg2)

def mn_mfspr(ir, instr, arg1, arg2):
    sprid = arg2.arg.arg
    gprid = int(arg1.name[1:])
    if sprid in spr_dict:
        return [ ExprAff(arg1, spr_dict[sprid]) ], []
    elif sprid == 1:		# XER
        return [ ExprAff(arg1, ExprCompose(XER_BC, ExprInt(0, 22),
                                           XER_CA, XER_OV, XER_SO)) ], []
    else:
        return [ ExprAff(spr_access,
                         ExprInt(((sprid << SPR_ACCESS_SPR_OFF) |
                                    (gprid << SPR_ACCESS_GPR_OFF)), 32)),
                 ExprAff(exception_flags, ExprInt(EXCEPT_SPR_ACCESS, 32)) ], []

def mn_mtcrf(

ir, instr, crm, rs)

def mn_mtcrf(ir, instr, crm, rs):
    ret = []

    for i in xrange(8):
        if crm.arg.arg & (1 << (7 - i)):
            j = (28 - 4 * i) + 3
            for b in ['LT', 'GT', 'EQ', 'SO']:
                ret.append(ExprAff(all_regs_ids_byname["CR%d_%s" % (i, b)],
                                   rs[j:j+1]))
                j -= 1

    return ret, []

def mn_mtmsr(

ir, instr, rs)

def mn_mtmsr(ir, instr, rs):
    print "%08x: MSR assigned" % instr.offset
    return [ ExprAff(MSR, rs) ], []

def mn_mtspr(

ir, instr, arg1, arg2)

def mn_mtspr(ir, instr, arg1, arg2):
    sprid = arg1.arg.arg
    gprid = int(arg2.name[1:])
    if sprid in spr_dict:
        return [ ExprAff(spr_dict[sprid], arg2) ], []
    elif sprid == 1:		# XER
        return [ ExprAff(XER_SO, arg2[31:32]),
                 ExprAff(XER_OV, arg2[30:31]),
                 ExprAff(XER_CA, arg2[29:30]),
                 ExprAff(XER_BC, arg2[0:7]) ], []
    else:
        return [ ExprAff(spr_access,
                         ExprInt(((sprid << SPR_ACCESS_SPR_OFF) |
                                    (gprid << SPR_ACCESS_GPR_OFF) |
                                    SPR_ACCESS_IS_WRITE), 32)),
                 ExprAff(exception_flags, ExprInt(EXCEPT_SPR_ACCESS, 32)) ], []

def mn_nop(

ir, instr, *args)

def mn_nop(ir, instr, *args):
    return [], []

def mn_stb(

ir, instr, arg1, arg2)

def mn_stb(ir, instr, arg1, arg2):
    dest = ExprMem(arg2.arg, 8)
    return [ExprAff(dest, ExprSlice(arg1, 0, 8))], []

Classes

class ir_ppc32b

class ir_ppc32b(IntermediateRepresentation):

    def __init__(self, loc_db=None):
        super(ir_ppc32b, self).__init__(mn_ppc, 'b', loc_db)
        self.pc = mn_ppc.getpc()
        self.sp = mn_ppc.getsp()
        self.IRDst = expr.ExprId('IRDst', 32)
        self.addrsize = 32

    def get_ir(self, instr):
        args = instr.args[:]
        if instr.name[0:5] in [ 'ADDIS', 'ORIS', 'XORIS', 'ANDIS' ]:
            args[2] = ExprInt(args[2].arg << 16, 32)
        if instr.name[0:3] == 'ADD':
            if instr.name[0:4] == 'ADDZ':
                last_arg = ExprInt(0, 32)
            elif instr.name[0:4] == 'ADDM':
                last_arg = ExprInt(0xFFFFFFFF, 32)
            else:
                last_arg = args[2]
            instr_ir, extra_ir = mn_do_add(self, instr, args[0], args[1],
                                           last_arg)
        elif instr.name[0:3] == 'AND':
            instr_ir, extra_ir = mn_do_and(self, instr, *args)
        elif instr.additional_info.bo_bi_are_defined:
            name = instr.name
            if name[-1] == '+' or name[-1] == '-':
                name = name[0:-1]
            if name[-3:] == 'CTR' or name[-4:] == 'CTRL':
                arg1 = ExprCompose(ExprInt(0, 2), CTR[2:32])
            elif name[-2:] == 'LR' or name[-3:] == 'LRL':
                arg1 = ExprCompose(ExprInt(0, 2), LR[2:32])
            else:
                arg1 = args[1]
            instr_ir, extra_ir = mn_do_cond_branch(self, instr, arg1)
        elif instr.name[0:2] == 'CR':
            instr_ir, extra_ir = mn_do_cr(self, instr, *args)
        elif instr.name[0:3] == 'DCB':
            instr_ir, extra_ir = mn_do_nop_warn(self, instr, *args)
        elif instr.name[0:3] == 'DIV':
            instr_ir, extra_ir = mn_do_div(self, instr, *args)
        elif instr.name[0:4] == 'EXTS':
            instr_ir, extra_ir = mn_do_exts(self, instr, *args)
        elif instr.name[0] == 'L':
            instr_ir, extra_ir = mn_do_load(self, instr, *args)
        elif instr.name[0:3] == 'MUL':
            instr_ir, extra_ir = mn_do_mul(self, instr, *args)
        elif instr.name[0:3] == 'NEG':
            instr_ir, extra_ir = mn_do_neg(self, instr, *args)
        elif instr.name[0:2] == 'OR':
            instr_ir, extra_ir = mn_do_or(self, instr, *args)
        elif instr.name[0:2] == 'RL':
            instr_ir, extra_ir = mn_do_rotate(self, instr, args[0], args[1],
                                              args[2], args[3].arg.arg,
                                              args[4].arg.arg)
        elif instr.name == 'STMW':
            instr_ir, extra_ir = mn_do_stmw(self, instr, *args)
        elif instr.name[0:2] == 'ST':
            instr_ir, extra_ir = mn_do_store(self, instr, *args)
        elif instr.name[0:4] == 'SUBF':
            if instr.name[0:5] == 'SUBFZ':
                last_arg = ExprInt(0)
            elif instr.name[0:5] == 'SUBFM':
                last_arg = ExprInt(0xFFFFFFFF)
            else:
                last_arg = args[2]
            instr_ir, extra_ir = mn_do_sub(self, instr, args[0], args[1],
                                           last_arg)
        elif instr.name[0:3] == 'XOR':
            instr_ir, extra_ir = mn_do_xor(self, instr, *args)
        else:
            instr_ir, extra_ir = sem_dir[instr.name](self, instr, *args)

        return instr_ir, extra_ir

    def get_next_instr(self, instr):
        l = self.loc_db.get_or_create_offset_location(instr.offset  + 4)
        return l

    def get_next_break_loc_key(self, instr):
        l = self.loc_db.get_or_create_offset_location(instr.offset  + 4)
        return l

Ancestors (in MRO)

  • ir_ppc32b
  • miasm2.ir.ir.IntermediateRepresentation
  • __builtin__.object

Instance variables

var IRDst

var addrsize

var pc

var sp

Methods

def __init__(

self, loc_db=None)

def __init__(self, loc_db=None):
    super(ir_ppc32b, self).__init__(mn_ppc, 'b', loc_db)
    self.pc = mn_ppc.getpc()
    self.sp = mn_ppc.getsp()
    self.IRDst = expr.ExprId('IRDst', 32)
    self.addrsize = 32

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

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 instr in block.lines:
        if loc_key is None:
            assignments = []
            loc_key = self.get_loc_key_for_instr(instr)
        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 add_bloc(

self, block, gen_pc_updt=False)

DEPRECATED function Use add_block instead of add_block

def add_bloc(self, block, gen_pc_updt=False):
    """
    DEPRECATED function
    Use add_block instead of add_block
    """
    self.add_block(block, gen_pc_updt)

def add_block(

self, block, gen_pc_updt=False)

DEPRECATED function Use add_block instead of add_block

def add_block(self, block, gen_pc_updt=False):
    """
    DEPRECATED function
    Use add_block instead of add_block
    """
    warnings.warn("""DEPRECATION WARNING
    ircfg is now out of IntermediateRepresentation
    Use:
    ircfg = ir_arch.new_ircfg()
    ir_arch.add_asmblock_to_ircfg(block, ircfg)
    """)
    raise RuntimeError("API Deprecated")

def add_instr_to_current_state(

self, instr, block, assignments, ir_blocks_all, gen_pc_updt)

Add the IR effects of an instruction to the current state.

Returns a bool: True if the current assignments list must be split False in other cases.

@instr: native instruction @block: native block source @assignments: list of current AssignBlocks @ir_blocks_all: list of additional effects @gen_pc_updt: insert PC update effects between instructions

def add_instr_to_current_state(self, instr, block, assignments, ir_blocks_all, gen_pc_updt):
    """
    Add the IR effects of an instruction to the current state.
    Returns a bool:
    * True if the current assignments list must be split
    * False in other cases.
    @instr: native instruction
    @block: native block source
    @assignments: list of current AssignBlocks
    @ir_blocks_all: list of additional effects
    @gen_pc_updt: insert PC update effects between instructions
    """
    if gen_pc_updt is not False:
        self.gen_pc_update(assignments, instr)
    assignblk, ir_blocks_extra = self.instr2ir(instr)
    assignments.append(assignblk)
    ir_blocks_all += ir_blocks_extra
    if ir_blocks_extra:
        return True
    return False

def add_instr_to_ircfg(

self, instr, ircfg, loc_key=None, gen_pc_updt=False)

Add the native instruction @instr to the @ircfg @instr: instruction instance @ircfg: IRCFG instance @loc_key: loc_key instance of the instruction destination @gen_pc_updt: insert PC update effects between instructions

def add_instr_to_ircfg(self, instr, ircfg, loc_key=None, gen_pc_updt=False):
    """
    Add the native instruction @instr to the @ircfg
    @instr: instruction instance
    @ircfg: IRCFG instance
    @loc_key: loc_key instance of the instruction destination
    @gen_pc_updt: insert PC update effects between instructions
    """
    if loc_key is None:
        offset = getattr(instr, "offset", None)
        loc_key = self.loc_db.add_location(offset=offset)
    block = AsmBlock(loc_key)
    block.lines = [instr]
    self.add_asmblock_to_ircfg(block, ircfg, gen_pc_updt)
    return loc_key

def expr_fix_regs_for_mode(

self, expr, *args, **kwargs)

def expr_fix_regs_for_mode(self, expr, *args, **kwargs):
    return expr

def expraff_fix_regs_for_mode(

self, expr, *args, **kwargs)

def expraff_fix_regs_for_mode(self, expr, *args, **kwargs):
    return expr

def gen_loc_key_and_expr(

self, size)

Return a loc_key and it's corresponding ExprLoc @size: size of expression

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 gen_pc_update(

self, assignments, instr)

def gen_pc_update(self, assignments, instr):
    offset = m2_expr.ExprInt(instr.offset, self.pc.size)
    assignments.append(AssignBlock({self.pc:offset}, instr))

def get_ir(

self, instr)

def get_ir(self, instr):
    args = instr.args[:]
    if instr.name[0:5] in [ 'ADDIS', 'ORIS', 'XORIS', 'ANDIS' ]:
        args[2] = ExprInt(args[2].arg << 16, 32)
    if instr.name[0:3] == 'ADD':
        if instr.name[0:4] == 'ADDZ':
            last_arg = ExprInt(0, 32)
        elif instr.name[0:4] == 'ADDM':
            last_arg = ExprInt(0xFFFFFFFF, 32)
        else:
            last_arg = args[2]
        instr_ir, extra_ir = mn_do_add(self, instr, args[0], args[1],
                                       last_arg)
    elif instr.name[0:3] == 'AND':
        instr_ir, extra_ir = mn_do_and(self, instr, *args)
    elif instr.additional_info.bo_bi_are_defined:
        name = instr.name
        if name[-1] == '+' or name[-1] == '-':
            name = name[0:-1]
        if name[-3:] == 'CTR' or name[-4:] == 'CTRL':
            arg1 = ExprCompose(ExprInt(0, 2), CTR[2:32])
        elif name[-2:] == 'LR' or name[-3:] == 'LRL':
            arg1 = ExprCompose(ExprInt(0, 2), LR[2:32])
        else:
            arg1 = args[1]
        instr_ir, extra_ir = mn_do_cond_branch(self, instr, arg1)
    elif instr.name[0:2] == 'CR':
        instr_ir, extra_ir = mn_do_cr(self, instr, *args)
    elif instr.name[0:3] == 'DCB':
        instr_ir, extra_ir = mn_do_nop_warn(self, instr, *args)
    elif instr.name[0:3] == 'DIV':
        instr_ir, extra_ir = mn_do_div(self, instr, *args)
    elif instr.name[0:4] == 'EXTS':
        instr_ir, extra_ir = mn_do_exts(self, instr, *args)
    elif instr.name[0] == 'L':
        instr_ir, extra_ir = mn_do_load(self, instr, *args)
    elif instr.name[0:3] == 'MUL':
        instr_ir, extra_ir = mn_do_mul(self, instr, *args)
    elif instr.name[0:3] == 'NEG':
        instr_ir, extra_ir = mn_do_neg(self, instr, *args)
    elif instr.name[0:2] == 'OR':
        instr_ir, extra_ir = mn_do_or(self, instr, *args)
    elif instr.name[0:2] == 'RL':
        instr_ir, extra_ir = mn_do_rotate(self, instr, args[0], args[1],
                                          args[2], args[3].arg.arg,
                                          args[4].arg.arg)
    elif instr.name == 'STMW':
        instr_ir, extra_ir = mn_do_stmw(self, instr, *args)
    elif instr.name[0:2] == 'ST':
        instr_ir, extra_ir = mn_do_store(self, instr, *args)
    elif instr.name[0:4] == 'SUBF':
        if instr.name[0:5] == 'SUBFZ':
            last_arg = ExprInt(0)
        elif instr.name[0:5] == 'SUBFM':
            last_arg = ExprInt(0xFFFFFFFF)
        else:
            last_arg = args[2]
        instr_ir, extra_ir = mn_do_sub(self, instr, args[0], args[1],
                                       last_arg)
    elif instr.name[0:3] == 'XOR':
        instr_ir, extra_ir = mn_do_xor(self, instr, *args)
    else:
        instr_ir, extra_ir = sem_dir[instr.name](self, instr, *args)
    return instr_ir, extra_ir

def get_loc_key_for_instr(

self, instr)

Returns the loc_key associated to an instruction @instr: current instruction

def get_loc_key_for_instr(self, instr):
    """Returns the loc_key associated to an instruction
    @instr: current instruction"""
    return self.loc_db.get_or_create_offset_location(instr.offset)

def get_next_break_loc_key(

self, instr)

def get_next_break_loc_key(self, instr):
    l = self.loc_db.get_or_create_offset_location(instr.offset  + 4)
    return l

def get_next_instr(

self, instr)

def get_next_instr(self, instr):
    l = self.loc_db.get_or_create_offset_location(instr.offset  + 4)
    return l

def get_next_loc_key(

self, instr)

def get_next_loc_key(self, instr):
    loc_key = self.loc_db.get_or_create_offset_location(instr.offset + instr.l)
    return loc_key

def instr2ir(

self, instr)

def instr2ir(self, instr):
    ir_bloc_cur, extra_irblocks = self.get_ir(instr)
    for index, irb in enumerate(extra_irblocks):
        irs = []
        for assignblk in irb:
            irs.append(AssignBlock(assignblk, instr))
        extra_irblocks[index] = IRBlock(irb.loc_key, irs)
    assignblk = AssignBlock(ir_bloc_cur, instr)
    return assignblk, extra_irblocks

def irbloc_fix_regs_for_mode(

self, irblock, *args, **kwargs)

def irbloc_fix_regs_for_mode(self, irblock, *args, **kwargs):
    return irblock

def is_pc_written(

self, block)

Return the first Assignblk of the @blockin which PC is written @block: IRBlock instance

def is_pc_written(self, block):
    """Return the first Assignblk of the @blockin which PC is written
    @block: IRBlock instance"""
    all_pc = self.arch.pc.values()
    for assignblk in block:
        if assignblk.dst in all_pc:
            return assignblk
    return None

def new_ircfg(

self, *args, **kwargs)

Return a new instance of IRCFG

def new_ircfg(self, *args, **kwargs):
    """
    Return a new instance of IRCFG
    """
    return IRCFG(self.IRDst, self.loc_db, *args, **kwargs)

def new_ircfg_from_asmcfg(

self, asmcfg, *args, **kwargs)

Return a new instance of IRCFG from an @asmcfg @asmcfg: AsmCFG instance

def new_ircfg_from_asmcfg(self, asmcfg, *args, **kwargs):
    """
    Return a new instance of IRCFG from an @asmcfg
    @asmcfg: AsmCFG instance
    """
    ircfg = IRCFG(self.IRDst, self.loc_db, *args, **kwargs)
    for block in asmcfg.blocks:
        self.add_asmblock_to_ircfg(block, ircfg)
    return ircfg

def post_add_asmblock_to_ircfg(

self, block, ircfg, ir_blocks)

def post_add_asmblock_to_ircfg(self, block, ircfg, ir_blocks):
    self.set_empty_dst_to_next(block, ir_blocks)
    new_irblocks = []
    for irblock in ir_blocks:
        new_irblock = self.irbloc_fix_regs_for_mode(irblock, self.attrib)
        ircfg.add_irblock(new_irblock)
        new_irblocks.append(new_irblock)
    return new_irblocks

def set_empty_dst_to_next(

self, block, ir_blocks)

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])