Top

miasm2.arch.arm.arch module

#-*- coding:utf-8 -*-

import logging
from pyparsing import *
from miasm2.expression.expression import *
from miasm2.core.cpu import *
from collections import defaultdict
from miasm2.core.bin_stream import bin_stream
import miasm2.arch.arm.regs as regs_module
from miasm2.arch.arm.regs import *
from miasm2.core.asm_ast import AstInt, AstId, AstMem, AstOp

# A1 encoding

log = logging.getLogger("armdis")
console_handler = logging.StreamHandler()
console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s"))
log.addHandler(console_handler)
log.setLevel(logging.DEBUG)

# arm regs ##############
reg_dum = ExprId('DumReg', 32)

PC, _ = gen_reg('PC')

# GP
regs_str = ['R%d' % r for r in xrange(0x10)]
regs_str[13] = 'SP'
regs_str[14] = 'LR'
regs_str[15] = 'PC'
regs_expr = [ExprId(x, 32) for x in regs_str]

gpregs = reg_info(regs_str, regs_expr)

gpregs_pc = reg_info(regs_str[-1:], regs_expr[-1:])
gpregs_sp = reg_info(regs_str[13:14], regs_expr[13:14])

gpregs_nosppc = reg_info(regs_str[:13] + [str(reg_dum), regs_str[14]],
                         regs_expr[:13] + [reg_dum, regs_expr[14]])

gpregs_nopc = reg_info(regs_str[:14],
                       regs_expr[:14])

gpregs_nosp = reg_info(regs_str[:13] + [str(reg_dum), regs_str[14], regs_str[15]],
                       regs_expr[:13] + [reg_dum, regs_expr[14], regs_expr[15]])


# psr
sr_flags = "cxsf"
cpsr_regs_str = []
spsr_regs_str = []
for i in xrange(0x10):
    o = ""
    for j in xrange(4):
        if i & (1 << j):
            o += sr_flags[j]
    cpsr_regs_str.append("CPSR_%s" % o)
    spsr_regs_str.append("SPSR_%s" % o)

# psr_regs_str = ['CPSR', 'SPSR']
# psr_regs_expr = [ExprId(x, 32) for x in psr_regs_str]

# psr_regs = reg_info(psr_regs_str, psr_regs_expr)

cpsr_regs_expr = [ExprId(x, 32) for x in cpsr_regs_str]
spsr_regs_expr = [ExprId(x, 32) for x in spsr_regs_str]

cpsr_regs = reg_info(cpsr_regs_str, cpsr_regs_expr)
spsr_regs = reg_info(spsr_regs_str, spsr_regs_expr)

# CP
cpregs_str = ['c%d' % r for r in xrange(0x10)]
cpregs_expr = [ExprId(x, 32) for x in cpregs_str]

cp_regs = reg_info(cpregs_str, cpregs_expr)

# P
pregs_str = ['p%d' % r for r in xrange(0x10)]
pregs_expr = [ExprId(x, 32) for x in pregs_str]

p_regs = reg_info(pregs_str, pregs_expr)

conditional_branch = ["BEQ", "BNE", "BCS", "BCC", "BMI", "BPL", "BVS",
                      "BVC", "BHI", "BLS", "BGE", "BLT", "BGT", "BLE"]

unconditional_branch = ["B", "BX", "BL", "BLX"]

barrier_expr = {
    0b1111: ExprId("SY", 32),
    0b1110: ExprId("ST", 32),
    0b1101: ExprId("LD", 32),
    0b1011: ExprId("ISH", 32),
    0b1010: ExprId("ISHST", 32),
    0b1001: ExprId("ISHLD", 32),
    0b0111: ExprId("NSH", 32),
    0b0110: ExprId("NSHST", 32),
    0b0011: ExprId("OSH", 32),
    0b0010: ExprId("OSHST", 32),
    0b0001: ExprId("OSHLD", 32),
}

barrier_info = reg_info_dct(barrier_expr)



# parser helper ###########

def cb_tok_reg_duo(tokens):
    tokens = tokens[0]
    i1 = gpregs.expr.index(tokens[0].name)
    i2 = gpregs.expr.index(tokens[1].name)
    o = []
    for i in xrange(i1, i2 + 1):
        o.append(AstId(gpregs.expr[i]))
    return o

LPARENTHESIS = Literal("(")
RPARENTHESIS = Literal(")")

LACC = Suppress(Literal("{"))
RACC = Suppress(Literal("}"))
MINUS = Suppress(Literal("-"))
CIRCUNFLEX = Literal("^")


def check_bounds(left_bound, right_bound, value):
    if left_bound <= value and value <= right_bound:
        return AstInt(value)
    else:
        raise ValueError('shift operator immediate value out of bound')


def check_values(values, value):
    if value in values:
        return AstInt(value)
    else:
        raise ValueError('shift operator immediate value out of bound')

int_1_31 = str_int.copy().setParseAction(lambda v: check_bounds(1, 31, v[0]))
int_1_32 = str_int.copy().setParseAction(lambda v: check_bounds(1, 32, v[0]))

int_8_16_24 = str_int.copy().setParseAction(lambda v: check_values([8, 16, 24], v[0]))


def cb_reglistparse(tokens):
    tokens = tokens[0]
    if tokens[-1] == "^":
        return AstOp('sbit', AstOp('reglist', *tokens[:-1]))
    return AstOp('reglist', *tokens)


allshifts = ['<<', '>>', 'a>>', '>>>', 'rrx']
allshifts_armt = ['<<', '>>', 'a>>', '>>>', 'rrx']

shift2expr_dct = {'LSL': '<<', 'LSR': '>>', 'ASR': 'a>>',
                  'ROR': ">>>", 'RRX': "rrx"}

expr2shift_dct = dict([(x[1], x[0]) for x in shift2expr_dct.items()])


def op_shift2expr(tokens):
    return shift2expr_dct[tokens[0]]

reg_duo = Group(gpregs.parser + MINUS +
                gpregs.parser).setParseAction(cb_tok_reg_duo)
reg_or_duo = reg_duo | gpregs.parser
gpreg_list = Group(LACC + delimitedList(
    reg_or_duo, delim=',') + RACC + Optional(CIRCUNFLEX))
gpreg_list.setParseAction(cb_reglistparse)

LBRACK = Suppress("[")
RBRACK = Suppress("]")
COMMA = Suppress(",")
all_binaryop_1_31_shifts_t = literal_list(
    ['LSL', 'ROR']).setParseAction(op_shift2expr)
all_binaryop_1_32_shifts_t = literal_list(
    ['LSR', 'ASR']).setParseAction(op_shift2expr)
all_unaryop_shifts_t = literal_list(['RRX']).setParseAction(op_shift2expr)

ror_shifts_t = literal_list(['ROR']).setParseAction(op_shift2expr)


allshifts_t_armt = literal_list(
    ['LSL', 'LSR', 'ASR', 'ROR', 'RRX']).setParseAction(op_shift2expr)

gpreg_p = gpregs.parser

psr_p = cpsr_regs.parser | spsr_regs.parser


def cb_shift(tokens):
    if len(tokens) == 1:
        ret = tokens[0]
    elif len(tokens) == 2:
        ret = AstOp(tokens[1], tokens[0])
    elif len(tokens) == 3:
        ret = AstOp(tokens[1], tokens[0], tokens[2])
    else:
        raise ValueError("Bad arg")
    return ret

shift_off = (gpregs.parser + Optional(
    (all_unaryop_shifts_t) |
    (all_binaryop_1_31_shifts_t + (gpregs.parser | int_1_31)) |
    (all_binaryop_1_32_shifts_t + (gpregs.parser | int_1_32))
)).setParseAction(cb_shift)
shift_off |= base_expr


rot2_expr = (gpregs.parser + Optional(
    (ror_shifts_t + (int_8_16_24))
)).setParseAction(cb_shift)


OP_LSL = Suppress("LSL")

def cb_deref_reg_reg(tokens):
    if len(tokens) != 2:
        raise ValueError("Bad mem format")
    return AstMem(AstOp('+', tokens[0], tokens[1]), 8)

def cb_deref_reg_reg_lsl_1(tokens):
    if len(tokens) != 3:
        raise ValueError("Bad mem format")
    reg1, reg2, index = tokens
    if not isinstance(index, AstInt) or index.value != 1:
        raise ValueError("Bad index")
    ret = AstMem(AstOp('+', reg1, AstOp('<<', reg2, index)), 16)
    return ret


deref_reg_reg = (LBRACK + gpregs.parser + COMMA + gpregs.parser + RBRACK).setParseAction(cb_deref_reg_reg)
deref_reg_reg_lsl_1 = (LBRACK + gpregs.parser + COMMA + gpregs.parser + OP_LSL + base_expr + RBRACK).setParseAction(cb_deref_reg_reg_lsl_1)



(gpregs.parser + Optional(
    (ror_shifts_t + (int_8_16_24))
)).setParseAction(cb_shift)



reg_or_base = gpregs.parser | base_expr

def deref2expr_nooff(tokens):
    tokens = tokens[0]
    # XXX default
    return ExprOp("preinc", tokens[0], ExprInt(0, 32))


def cb_deref_preinc(tokens):
    tokens = tokens[0]
    if len(tokens) == 1:
        return AstOp("preinc", tokens[0], AstInt(0))
    elif len(tokens) == 2:
        return AstOp("preinc", tokens[0], tokens[1])
    else:
        raise NotImplementedError('len(tokens) > 2')


def cb_deref_pre_mem(tokens):
    tokens = tokens[0]
    if len(tokens) == 1:
        return AstMem(AstOp("preinc", tokens[0], AstInt(0)), 32)
    elif len(tokens) == 2:
        return AstMem(AstOp("preinc", tokens[0], tokens[1]), 32)
    else:
        raise NotImplementedError('len(tokens) > 2')


def cb_deref_post(tokens):
    tokens = tokens[0]
    return AstOp("postinc", tokens[0], tokens[1])


def cb_deref_wb(tokens):
    tokens = tokens[0]
    if tokens[-1] == '!':
        return AstMem(AstOp('wback', *tokens[:-1]), 32)
    return AstMem(tokens[0], 32)

# shift_off.setParseAction(deref_off)
deref_nooff = Group(
    LBRACK + gpregs.parser + RBRACK).setParseAction(deref2expr_nooff)
deref_pre = Group(LBRACK + gpregs.parser + Optional(
    COMMA + shift_off) + RBRACK).setParseAction(cb_deref_preinc)
deref_post = Group(LBRACK + gpregs.parser + RBRACK +
                   COMMA + shift_off).setParseAction(cb_deref_post)
deref = Group((deref_post | deref_pre | deref_nooff)
              + Optional('!')).setParseAction(cb_deref_wb)


def cb_gpreb_wb(tokens):
    assert len(tokens) == 1
    tokens = tokens[0]
    if tokens[-1] == '!':
        return AstOp('wback', *tokens[:-1])
    return tokens[0]

gpregs_wb = Group(gpregs.parser + Optional('!')).setParseAction(cb_gpreb_wb)


cond_list_full = ['EQ', 'NE', 'CS', 'CC', 'MI', 'PL', 'VS', 'VC',
                  'HI', 'LS', 'GE', 'LT', 'GT', 'LE', 'NV']


cond_list = ['EQ', 'NE', 'CS', 'CC', 'MI', 'PL', 'VS', 'VC',
             'HI', 'LS', 'GE', 'LT', 'GT', 'LE', '']  # , 'NV']
cond_dct = dict([(x[1], x[0]) for x in enumerate(cond_list)])
bm_cond = bs_mod_name(l=4, fname='cond', mn_mod=cond_list)



cond_dct_barmt = dict([(x[0], x[1]) for x in enumerate(cond_list) if x[0] & 0b1110 != 0b1110])
bm_cond_barmt = bs_mod_name(l=4, fname='cond', mn_mod=cond_dct_barmt)



def permut_args(order, args):
    l = []
    for i, x in enumerate(order):
        l.append((x.__class__, i))
    l = dict(l)
    out = [None for x in xrange(len(args))]
    for a in args:
        out[l[a.__class__]] = a
    return out


class additional_info:

    def __init__(self):
        self.except_on_instr = False
        self.lnk = None
        self.cond = None


class instruction_arm(instruction):
    __slots__ = []
    delayslot = 0

    def __init__(self, *args, **kargs):
        super(instruction_arm, self).__init__(*args, **kargs)

    @staticmethod
    def arg2str(expr, index=None, loc_db=None):
        wb = False
        if expr.is_id() or expr.is_int():
            return str(expr)
        elif expr.is_loc():
            if loc_db is not None:
                return loc_db.pretty_str(expr.loc_key)
            else:
                return str(expr)
        if isinstance(expr, ExprOp) and expr.op in expr2shift_dct:
            if len(expr.args) == 1:
                return '%s %s' % (expr.args[0], expr2shift_dct[expr.op])
            elif len(expr.args) == 2:
                return '%s %s %s' % (expr.args[0], expr2shift_dct[expr.op], expr.args[1])
            else:
                raise NotImplementedError('zarb arg2str')


        sb = False
        if isinstance(expr, ExprOp) and expr.op == "sbit":
            sb = True
            expr = expr.args[0]
        if isinstance(expr, ExprOp) and expr.op == "reglist":
            o = [gpregs.expr.index(x) for x in expr.args]
            out = reglist2str(o)
            if sb:
                out += "^"
            return out


        if isinstance(expr, ExprOp) and expr.op == 'wback':
            wb = True
            expr = expr.args[0]
        if isinstance(expr, ExprId):
            out = str(expr)
            if wb:
                out += "!"
            return out

        if not isinstance(expr, ExprMem):
            return str(expr)

        expr = expr.arg
        if isinstance(expr, ExprOp) and expr.op == 'wback':
            wb = True
            expr = expr.args[0]


        if isinstance(expr, ExprId):
            r, s = expr, None
        elif len(expr.args) == 1 and isinstance(expr.args[0], ExprId):
            r, s = expr.args[0], None
        elif isinstance(expr.args[0], ExprId):
            r, s = expr.args[0], expr.args[1]
        else:
            r, s = expr.args[0].args
        if isinstance(s, ExprOp) and s.op in expr2shift_dct:
            s = ' '.join([str(x)
                for x in s.args[0], expr2shift_dct[s.op], s.args[1]])

        if isinstance(expr, ExprOp) and expr.op == 'postinc':
            o = '[%s]' % r
            if s and not (isinstance(s, ExprInt) and s.arg == 0):
                o += ', %s' % s
        else:
            if s and not (isinstance(s, ExprInt) and s.arg == 0):
                o = '[%s, %s]' % (r, s)
            else:
                o = '[%s]' % (r)


        if wb:
            o += "!"
        return o


    def dstflow(self):
        if self.is_subcall():
            return True
        return self.name in conditional_branch + unconditional_branch

    def dstflow2label(self, loc_db):
        expr = self.args[0]
        if not isinstance(expr, ExprInt):
            return
        if self.name == 'BLX':
            addr = expr.arg + self.offset
        else:
            addr = expr.arg + self.offset
        loc_key = loc_db.get_or_create_offset_location(addr)
        self.args[0] = ExprLoc(loc_key, expr.size)

    def breakflow(self):
        if self.is_subcall():
            return True
        if self.name in conditional_branch + unconditional_branch:
            return True
        if self.name.startswith("LDM") and PC in self.args[1].args:
            return True
        if self.args and PC in self.args[0].get_r():
            return True
        return False

    def is_subcall(self):
        if self.name == 'BLX':
            return True
        return self.additional_info.lnk

    def getdstflow(self, loc_db):
        return [self.args[0]]

    def splitflow(self):
        if self.additional_info.lnk:
            return True
        if self.name == 'BLX':
            return True
        if self.name == 'BX':
            return False
        return self.breakflow() and self.additional_info.cond != 14

    def get_symbol_size(self, symbol, loc_db):
        return 32

    def fixDstOffset(self):
        e = self.args[0]
        if self.offset is None:
            raise ValueError('symbol not resolved %s' % l)
        if not isinstance(e, ExprInt):
            log.debug('dyn dst %r', e)
            return
        off = e.arg - self.offset
        if int(off % 4):
            raise ValueError('strange offset! %r' % off)
        self.args[0] = ExprInt(off, 32)

    def get_args_expr(self):
        args = [a for a in self.args]
        return args

    def get_asm_offset(self, expr):
        # LDR XXX, [PC, offset] => PC is self.offset+8
        return ExprInt(self.offset+8, expr.size)

class instruction_armt(instruction_arm):
    __slots__ = []
    delayslot = 0

    def __init__(self, *args, **kargs):
        super(instruction_armt, self).__init__(*args, **kargs)

    def dstflow(self):
        if self.name in ["CBZ", "CBNZ"]:
            return True
        return self.name in conditional_branch + unconditional_branch

    def dstflow2label(self, loc_db):
        if self.name in ["CBZ", "CBNZ"]:
            expr = self.args[1]
        else:
            expr = self.args[0]
        if not isinstance(expr, ExprInt):
            return
        if self.name == 'BLX':
            addr = expr.arg + (self.offset & 0xfffffffc)
        elif self.name == 'BL':
            addr = expr.arg + self.offset
        elif self.name.startswith('BP'):
            addr = expr.arg + self.offset
        elif self.name.startswith('CB'):
            addr = expr.arg + self.offset + self.l + 2
        else:
            addr = expr.arg + self.offset

        loc_key = loc_db.get_or_create_offset_location(addr)
        dst = ExprLoc(loc_key, expr.size)

        if self.name in ["CBZ", "CBNZ"]:
            self.args[1] = dst
        else:
            self.args[0] = dst

    def breakflow(self):
        if self.name in conditional_branch + unconditional_branch +["CBZ", "CBNZ", 'TBB', 'TBH']:
            return True
        if self.name.startswith("LDM") and PC in self.args[1].args:
            return True
        if self.args and PC in self.args[0].get_r():
            return True
        return False

    def getdstflow(self, loc_db):
        if self.name in ['CBZ', 'CBNZ']:
            return [self.args[1]]
        return [self.args[0]]

    def splitflow(self):
        if self.name in conditional_branch + ['BL', 'BLX', 'CBZ', 'CBNZ']:
            return True
        return False

    def is_subcall(self):
        return self.name in ['BL', 'BLX']

    def fixDstOffset(self):
        e = self.args[0]
        if self.offset is None:
            raise ValueError('symbol not resolved %s' % l)
        if not isinstance(e, ExprInt):
            log.debug('dyn dst %r', e)
            return
        # The first +2 is to compensate instruction len, but strangely, 32 bits
        # thumb2 instructions len is 2... For the second +2, didn't find it in
        # the doc.
        off = e.arg - self.offset
        if int(off % 2):
            raise ValueError('strange offset! %r' % off)
        self.args[0] = ExprInt(off, 32)

    def get_asm_offset(self, expr):
        # ADR XXX, PC, imm => PC is 4 aligned + imm
        new_offset = ((self.offset+self.l)/4)*4
        return ExprInt(new_offset, expr.size)


class mn_arm(cls_mn):
    delayslot = 0
    name = "arm"
    regs = regs_module
    bintree = {}
    num = 0
    all_mn = []
    all_mn_mode = defaultdict(list)
    all_mn_name = defaultdict(list)
    all_mn_inst = defaultdict(list)
    pc = {'l':PC, 'b':PC}
    sp = {'l':SP, 'b':SP}
    instruction = instruction_arm
    max_instruction_len = 4
    alignment = 4

    @classmethod
    def getpc(cls, attrib = None):
        return PC

    @classmethod
    def getsp(cls, attrib = None):
        return SP

    def additional_info(self):
        info = additional_info()
        info.lnk = False
        if hasattr(self, "lnk"):
            info.lnk = self.lnk.value != 0
        if hasattr(self, "cond"):
            info.cond = self.cond.value
        else:
            info.cond = None
        return info

    @classmethod
    def getbits(cls, bs, attrib, start, n):
        if not n:
            return 0
        o = 0
        if n > bs.getlen() * 8:
            raise ValueError('not enought bits %r %r' % (n, len(bs.bin) * 8))
        while n:
            offset = start / 8
            n_offset = cls.endian_offset(attrib, offset)
            c = cls.getbytes(bs, n_offset, 1)
            if not c:
                raise IOError
            c = ord(c)
            r = 8 - start % 8
            c &= (1 << r) - 1
            l = min(r, n)
            c >>= (r - l)
            o <<= l
            o |= c
            n -= l
            start += l
        return o

    @classmethod
    def endian_offset(cls, attrib, offset):
        if attrib == "l":
            return (offset & ~3) + 3 - offset % 4
        elif attrib == "b":
            return offset
        else:
            raise NotImplementedError('bad attrib')

    @classmethod
    def check_mnemo(cls, fields):
        l = sum([x.l for x in fields])
        assert l == 32, "len %r" % l

    @classmethod
    def getmn(cls, name):
        return name.upper()

    @classmethod
    def mod_fields(cls, fields):
        l = sum([x.l for x in fields])
        if l == 32:
            return fields
        return [bm_cond] + fields

    @classmethod
    def gen_modes(cls, subcls, name, bases, dct, fields):
        dct['mode'] = None
        return [(subcls, name, bases, dct, fields)]

    def value(self, mode):
        v = super(mn_arm, self).value(mode)
        if mode == 'l':
            return [x[::-1] for x in v]
        elif mode == 'b':
            return [x for x in v]
        else:
            raise NotImplementedError('bad attrib')


    def get_symbol_size(self, symbol, loc_db, mode):
        return 32


class mn_armt(cls_mn):
    name = "armt"
    regs = regs_module
    delayslot = 0
    bintree = {}
    num = 0
    all_mn = []
    all_mn_mode = defaultdict(list)
    all_mn_name = defaultdict(list)
    all_mn_inst = defaultdict(list)
    pc = PC
    sp = SP
    instruction = instruction_armt
    max_instruction_len = 4
    alignment = 4

    @classmethod
    def getpc(cls, attrib = None):
        return PC

    @classmethod
    def getsp(cls, attrib = None):
        return SP

    def additional_info(self):
        info = additional_info()
        info.lnk = False
        if hasattr(self, "lnk"):
            info.lnk = self.lnk.value != 0
        info.cond = 14  # COND_ALWAYS
        return info


    @classmethod
    def getbits(cls, bs, attrib, start, n):
        if not n:
            return 0
        o = 0
        if n > bs.getlen() * 8:
            raise ValueError('not enought bits %r %r' % (n, len(bs.bin) * 8))
        while n:
            offset = start / 8
            n_offset = cls.endian_offset(attrib, offset)
            c = cls.getbytes(bs, n_offset, 1)
            if not c:
                raise IOError
            c = ord(c)
            r = 8 - start % 8
            c &= (1 << r) - 1
            l = min(r, n)
            c >>= (r - l)
            o <<= l
            o |= c
            n -= l
            start += l
        return o

    @classmethod
    def endian_offset(cls, attrib, offset):
        if attrib == "l":
            return (offset & ~1) + 1 - offset % 2
        elif attrib == "b":
            return offset
        else:
            raise NotImplementedError('bad attrib')

    @classmethod
    def check_mnemo(cls, fields):
        l = sum([x.l for x in fields])
        assert l in [16, 32], "len %r" % l

    @classmethod
    def getmn(cls, name):
        return name.upper()

    @classmethod
    def mod_fields(cls, fields):
        return list(fields)

    @classmethod
    def gen_modes(cls, subcls, name, bases, dct, fields):
        dct['mode'] = None
        return [(subcls, name, bases, dct, fields)]

    def value(self, mode):
        v = super(mn_armt, self).value(mode)
        if mode == 'l':
            out = []
            for x in v:
                if len(x) == 2:
                    out.append(x[::-1])
                elif len(x) == 4:
                    out.append(x[:2][::-1] + x[2:4][::-1])
            return out
        elif mode == 'b':
            return [x for x in v]
        else:
            raise NotImplementedError('bad attrib')

    def get_args_expr(self):
        args = [a.expr for a in self.args]
        return args

    def get_symbol_size(self, symbol, loc_db, mode):
        return 32


class arm_arg(m_arg):
    def asm_ast_to_expr(self, arg, loc_db):
        if isinstance(arg, AstId):
            if isinstance(arg.name, ExprId):
                return arg.name
            if arg.name in gpregs.str:
                return None
            loc_key = loc_db.get_or_create_name_location(arg.name)
            return ExprLoc(loc_key, 32)
        if isinstance(arg, AstOp):
            args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
            if None in args:
                return None
            return ExprOp(arg.op, *args)
        if isinstance(arg, AstInt):
            return ExprInt(arg.value, 32)
        if isinstance(arg, AstMem):
            ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
            if ptr is None:
                return None
            return ExprMem(ptr, arg.size)
        return None


class arm_reg(reg_noarg, arm_arg):
    pass


class arm_gpreg_noarg(reg_noarg):
    reg_info = gpregs
    parser = reg_info.parser


class arm_gpreg(arm_reg):
    reg_info = gpregs
    parser = reg_info.parser


class arm_reg_wb(arm_reg):
    reg_info = gpregs
    parser = gpregs_wb

    def decode(self, v):
        v = v & self.lmask
        e = self.reg_info.expr[v]
        if self.parent.wback.value:
            e = ExprOp('wback', e)
        self.expr = e
        return True

    def encode(self):
        e = self.expr
        self.parent.wback.value = 0
        if isinstance(e, ExprOp) and e.op == 'wback':
            self.parent.wback.value = 1
            e = e.args[0]
        if isinstance(e, ExprId):
            self.value = self.reg_info.expr.index(e)
        else:
            self.parent.wback.value = 1
            self.value = self.reg_info.expr.index(e.args[0])
        return True


class arm_psr(arm_arg):
    parser = psr_p

    def decode(self, v):
        v = v & self.lmask
        if self.parent.psr.value == 0:
            e = cpsr_regs.expr[v]
        else:
            e = spsr_regs.expr[v]
        self.expr = e
        return True

    def encode(self):
        e = self.expr
        if e in spsr_regs.expr:
            self.parent.psr.value = 1
            v = spsr_regs.expr.index(e)
        elif e in cpsr_regs.expr:
            self.parent.psr.value = 0
            v = cpsr_regs.expr.index(e)
        else:
            return False
        self.value = v
        return True


class arm_cpreg(arm_reg):
    reg_info = cp_regs
    parser = reg_info.parser


class arm_preg(arm_reg):
    reg_info = p_regs
    parser = reg_info.parser


class arm_imm(imm_noarg, arm_arg):
    parser = base_expr


class arm_offs(arm_imm):
    parser = base_expr

    def int2expr(self, v):
        if v & ~self.intmask != 0:
            return None
        return ExprInt(v, self.intsize)

    def decodeval(self, v):
        v <<= 2
        # Add pipeline offset
        v += 8
        return v

    def encodeval(self, v):
        if v%4 != 0:
            return False
        # Remove pipeline offset
        v -= 8
        return v >> 2

    def decode(self, v):
        v = v & self.lmask
        if (1 << (self.l - 1)) & v:
            v |= ~0 ^ self.lmask
        v = self.decodeval(v)
        self.expr = ExprInt(v, 32)
        return True

    def encode(self):
        if not isinstance(self.expr, ExprInt):
            return False
        v = int(self.expr)
        if (1 << (self.l - 1)) & v:
            v = -((0xffffffff ^ v) + 1)
        v = self.encodeval(v)
        if v is False:
            return False
        self.value = (v & 0xffffffff) & self.lmask
        return True


class arm_imm8_12(arm_arg):
    parser = deref

    def decode(self, v):
        v = v & self.lmask
        if self.parent.updown.value:
            e = ExprInt(v << 2, 32)
        else:
            e = ExprInt(-v << 2, 32)
        if self.parent.ppi.value:
            e = ExprOp('preinc', self.parent.rn.expr, e)
        else:
            e = ExprOp('postinc', self.parent.rn.expr, e)
        if self.parent.wback.value == 1:
            e = ExprOp('wback', e)
        self.expr = ExprMem(e, 32)
        return True

    def encode(self):
        self.parent.updown.value = 1
        e = self.expr
        if not isinstance(e, ExprMem):
            return False
        e = e.arg
        if isinstance(e, ExprOp) and e.op == 'wback':
            self.parent.wback.value = 1
            e = e.args[0]
        else:
            self.parent.wback.value = 0
        if e.op == "postinc":
            self.parent.ppi.value = 0
        elif e.op == "preinc":
            self.parent.ppi.value = 1
        else:
            # XXX default
            self.parent.ppi.value = 1
        self.parent.rn.expr = e.args[0]
        if len(e.args) == 1:
            self.value = 0
            return True
        e = e.args[1]
        if not isinstance(e, ExprInt):
            log.debug('should be int %r', e)
            return False
        v = int(e)
        if v < 0 or v & (1 << 31):
            self.parent.updown.value = 0
            v = -v & 0xFFFFFFFF
        if v & 0x3:
            log.debug('arg should be 4 aligned')
            return False
        v >>= 2
        self.value = v
        return True


class arm_imm_4_12(arm_arg):
    parser = reg_or_base

    def decode(self, v):
        v = v & self.lmask
        imm = (self.parent.imm4.value << 12) | v
        self.expr = ExprInt(imm, 32)
        return True

    def encode(self):
        if not isinstance(self.expr, ExprInt):
            return False
        v = int(self.expr)
        if v > 0xffff:
            return False
        self.parent.imm4.value = v >> 12
        self.value = v & 0xfff
        return True


class arm_imm_12_4(arm_arg):
    parser = base_expr

    def decode(self, v):
        v = v & self.lmask
        imm =  (self.parent.imm.value << 4) | v
        self.expr = ExprInt(imm, 32)
        return True

    def encode(self):
        if not isinstance(self.expr, ExprInt):
            return False
        v = int(self.expr)
        if v > 0xffff:
            return False
        self.parent.imm.value = (v >> 4) & 0xfff
        self.value = v & 0xf
        return True


class arm_op2(arm_arg):
    parser = shift_off

    def str_to_imm_rot_form(self, s, neg=False):
        if neg:
            s = -s & 0xffffffff
        for i in xrange(0, 32, 2):
            v = myrol32(s, i)
            if 0 <= v < 0x100:
                return ((i / 2) << 8) | v
        return None

    def decode(self, v):
        val = v & self.lmask
        if self.parent.immop.value:
            rot = val >> 8
            imm = val & 0xff
            imm = myror32(imm, rot * 2)
            self.expr = ExprInt(imm, 32)
            return True
        rm = val & 0xf
        shift = val >> 4
        shift_kind = shift & 1
        shift_type = (shift >> 1) & 3
        shift >>= 3
        if shift_kind:
            # shift kind is reg
            if shift & 1:
                return False
            rs = shift >> 1
            if rs == 0xf:
                return False
            shift_op = regs_expr[rs]
        else:
            # shift kind is imm
            amount = shift
            shift_op = ExprInt(amount, 32)
        a = regs_expr[rm]
        if shift_op == ExprInt(0, 32):
            if shift_type == 3:
                self.expr = ExprOp(allshifts[4], a)
            else:
                self.expr = a
        else:
            self.expr = ExprOp(allshifts[shift_type], a, shift_op)
        return True

    def encode(self):
        e = self.expr
        # pure imm
        if isinstance(e, ExprInt):
            val = self.str_to_imm_rot_form(int(e))
            if val is None:
                return False
            self.parent.immop.value = 1
            self.value = val
            return True

        self.parent.immop.value = 0
        # pure reg
        if isinstance(e, ExprId):
            rm = gpregs.expr.index(e)
            shift_kind = 0
            shift_type = 0
            amount = 0
            self.value = (
                ((((amount << 2) | shift_type) << 1) | shift_kind) << 4) | rm
            return True
        # rot reg
        if not isinstance(e, ExprOp):
            log.debug('bad reg rot1 %r', e)
            return False
        rm = gpregs.expr.index(e.args[0])
        shift_type = allshifts.index(e.op)
        if e.op == 'rrx':
            shift_kind = 0
            amount = 0
            shift_type = 3
        elif isinstance(e.args[1], ExprInt):
            shift_kind = 0
            amount = int(e.args[1])
            # LSR/ASR of 32 => 0
            if amount == 32 and e.op in ['>>', 'a>>']:
                amount = 0
        else:
            shift_kind = 1
            amount = gpregs.expr.index(e.args[1]) << 1
        self.value = (
            ((((amount << 2) | shift_type) << 1) | shift_kind) << 4) | rm
        return True

# op2imm + rn


class arm_op2imm(arm_imm8_12):
    parser = deref

    def str_to_imm_rot_form(self, s, neg=False):
        if neg:
            s = -s & 0xffffffff
        if 0 <= s < (1 << 12):
            return s
        return None

    def decode(self, v):
        val = v & self.lmask
        if self.parent.immop.value == 0:
            imm = val
            if self.parent.updown.value == 0:
                imm = -imm
            if self.parent.ppi.value:
                e = ExprOp('preinc', self.parent.rn.expr, ExprInt(imm, 32))
            else:
                e = ExprOp('postinc', self.parent.rn.expr, ExprInt(imm, 32))
            if self.parent.wback.value == 1:
                e = ExprOp('wback', e)
            self.expr = ExprMem(e, 32)
            return True
        rm = val & 0xf
        shift = val >> 4
        shift_kind = shift & 1
        shift_type = (shift >> 1) & 3
        shift >>= 3
        # print self.parent.immop.value, hex(shift), hex(shift_kind),
        # hex(shift_type)
        if shift_kind:
            # log.debug('error in disasm xx')
            return False
        else:
            # shift kind is imm
            amount = shift
            shift_op = ExprInt(amount, 32)
        a = regs_expr[rm]
        if shift_op == ExprInt(0, 32):
            pass
        else:
            a = ExprOp(allshifts[shift_type], a, shift_op)
        if self.parent.ppi.value:
            e = ExprOp('preinc', self.parent.rn.expr, a)
        else:
            e = ExprOp('postinc', self.parent.rn.expr, a)
        if self.parent.wback.value == 1:
            e = ExprOp('wback', e)
        self.expr = ExprMem(e, 32)
        return True

    def encode(self):
        self.parent.immop.value = 1
        self.parent.updown.value = 1

        e = self.expr
        assert(isinstance(e, ExprMem))
        e = e.arg
        if e.op == 'wback':
            self.parent.wback.value = 1
            e = e.args[0]
        else:
            self.parent.wback.value = 0
        if e.op == "postinc":
            self.parent.ppi.value = 0
        elif e.op == "preinc":
            self.parent.ppi.value = 1
        else:
            # XXX default
            self.parent.ppi.value = 1

        # if len(v) <1:
        #    raise ValueError('cannot parse', s)
        self.parent.rn.expr = e.args[0]
        if len(e.args) == 1:
            self.parent.immop.value = 0
            self.value = 0
            return True
        # pure imm
        if isinstance(e.args[1], ExprInt):
            self.parent.immop.value = 0
            val = self.str_to_imm_rot_form(int(e.args[1]))
            if val is None:
                val = self.str_to_imm_rot_form(int(e.args[1]), True)
                if val is None:
                    log.debug('cannot encode inm')
                    return False
                self.parent.updown.value = 0
            self.value = val
            return True
        # pure reg
        if isinstance(e.args[1], ExprId):
            rm = gpregs.expr.index(e.args[1])
            shift_kind = 0
            shift_type = 0
            amount = 0
            self.value = (
                ((((amount << 2) | shift_type) << 1) | shift_kind) << 4) | rm
            return True
        # rot reg
        if not isinstance(e.args[1], ExprOp):
            log.debug('bad reg rot2 %r', e)
            return False
        e = e.args[1]
        rm = gpregs.expr.index(e.args[0])
        shift_type = allshifts.index(e.op)
        if isinstance(e.args[1], ExprInt):
            shift_kind = 0
            amount = int(e.args[1])
        else:
            shift_kind = 1
            amount = gpregs.expr.index(e.args[1]) << 1
        self.value = (
            ((((amount << 2) | shift_type) << 1) | shift_kind) << 4) | rm
        return True


def reglist2str(rlist):
    out = []
    i = 0
    while i < len(rlist):
        j = i + 1
        while j < len(rlist) and rlist[j] < 13 and rlist[j] == rlist[j - 1] + 1:
            j += 1
        j -= 1
        if j < i + 2:
            out.append(regs_str[rlist[i]])
            i += 1
        else:
            out.append(regs_str[rlist[i]] + '-' + regs_str[rlist[j]])
            i = j + 1
    return "{" + ", ".join(out) + '}'


class arm_rlist(arm_arg):
    parser = gpreg_list

    def encode(self):
        self.parent.sbit.value = 0
        e = self.expr
        if isinstance(e, ExprOp) and e.op == "sbit":
            e = e.args[0]
            self.parent.sbit.value = 1
        rlist = [gpregs.expr.index(x) for x in e.args]
        v = 0
        for r in rlist:
            v |= 1 << r
        self.value = v
        return True

    def decode(self, v):
        v = v & self.lmask
        out = []
        for i in xrange(0x10):
            if 1 << i & v:
                out.append(gpregs.expr[i])
        if not out:
            return False
        e = ExprOp('reglist', *out)
        if self.parent.sbit.value == 1:
            e = ExprOp('sbit', e)
        self.expr = e
        return True


class updown_b_nosp_mn(bs_mod_name):
    mn_mod = ['D', 'I']

    def modname(self, name, f_i):
        return name + self.args['mn_mod'][f_i]


class ppi_b_nosp_mn(bs_mod_name):
    prio = 5
    mn_mod = ['A', 'B']


class updown_b_sp_mn(bs_mod_name):
    mn_mod = ['A', 'D']

    def modname(self, name, f_i):
        if name.startswith("STM"):
            f_i = [1, 0][f_i]
        return name + self.args['mn_mod'][f_i]


class ppi_b_sp_mn(bs_mod_name):
    mn_mod = ['F', 'E']

    def modname(self, name, f_i):
        if name.startswith("STM"):
            f_i = [1, 0][f_i]
        return name + self.args['mn_mod'][f_i]


class arm_reg_wb_nosp(arm_reg_wb):

    def decode(self, v):
        v = v & self.lmask
        if v == 13:
            return False
        e = self.reg_info.expr[v]
        if self.parent.wback.value:
            e = ExprOp('wback', e)
        self.expr = e
        return True


class arm_offs_blx(arm_imm):

    def decode(self, v):
        v = v & self.lmask
        v = (v << 2) + (self.parent.lowb.value << 1)
        v = sign_ext(v, 26, 32)
        # Add pipeline offset
        v += 8
        self.expr = ExprInt(v, 32)
        return True

    def encode(self):
        if not isinstance(self.expr, ExprInt):
            return False
        # Remove pipeline offset
        v = int(self.expr.arg - 8)
        if v & 0x80000000:
            v &= (1 << 26) - 1
        self.parent.lowb.value = (v >> 1) & 1
        self.value = v >> 2
        return True


class bs_lnk(bs_mod_name):

    def modname(self, name, i):
        return name[:1] + self.args['mn_mod'][i] + name[1:]


class armt_rm_cp(bsi):

    def decode(self, v):
        if v != gpregs.expr.index(self.parent.rm.expr):
            return False
        return True

    def encode(self):
        self.value = gpregs.expr.index(self.parent.rm.expr)
        return True


accum = bs(l=1)
scc = bs_mod_name(l=1, fname='scc', mn_mod=['', 'S'])
dumscc = bs("1")
rd = bs(l=4, cls=(arm_gpreg,))
rdl = bs(l=4, cls=(arm_gpreg,))

rn = bs(l=4, cls=(arm_gpreg,), fname="rn")
rs = bs(l=4, cls=(arm_gpreg,))
rm = bs(l=4, cls=(arm_gpreg,), fname='rm')
ra = bs(l=4, cls=(arm_gpreg,))
rt = bs(l=4, cls=(arm_gpreg,), fname='rt')
rt2 = bs(l=4, cls=(arm_gpreg,))

rm_cp = bs(l=4, cls=(armt_rm_cp,))

op2 = bs(l=12, cls=(arm_op2,))
lnk = bs_lnk(l=1, fname='lnk', mn_mod=['', 'L'])
offs = bs(l=24, cls=(arm_offs,), fname="offs")

rn_noarg = bs(l=4, cls=(arm_gpreg_noarg,), fname="rn")
rm_noarg = bs(l=4, cls=(arm_gpreg_noarg,), fname="rm", order = -1)

immop = bs(l=1, fname='immop')
dumr = bs(l=4, default_val="0000", fname="dumr")
# psr = bs(l=1, cls=(arm_psr,), fname="psr")

psr = bs(l=1, fname="psr")
psr_field = bs(l=4, cls=(arm_psr,))

ppi = bs(l=1, fname='ppi')
updown = bs(l=1, fname='updown')
trb = bs_mod_name(l=1, fname='trb', mn_mod=['', 'B'])
wback = bs_mod_name(l=1, fname="wback", mn_mod=['', 'T'])
wback_no_t = bs(l=1, fname="wback")

op2imm = bs(l=12, cls=(arm_op2imm,))

updown_b_nosp = updown_b_nosp_mn(l=1, mn_mod=['D', 'I'], fname='updown')
ppi_b_nosp = ppi_b_nosp_mn(l=1, mn_mod=['A', 'B'], fname='ppi')
updown_b_sp = updown_b_sp_mn(l=1, mn_mod=['A', 'D'], fname='updown')
ppi_b_sp = ppi_b_sp_mn(l=1, mn_mod=['F', 'E'], fname='ppi')

sbit = bs(l=1, fname="sbit")
rn_sp = bs("1101", cls=(arm_reg_wb,), fname='rnsp')
rn_wb = bs(l=4, cls=(arm_reg_wb_nosp,), fname='rn')
rlist = bs(l=16, cls=(arm_rlist,), fname='rlist')

swi_i = bs(l=24, cls=(arm_imm,), fname="swi_i")

opc = bs(l=4, cls=(arm_imm, m_arg), fname='opc')
crn = bs(l=4, cls=(arm_cpreg,), fname='crn')
crd = bs(l=4, cls=(arm_cpreg,), fname='crd')
crm = bs(l=4, cls=(arm_cpreg,), fname='crm')
cpnum = bs(l=4, cls=(arm_preg,), fname='cpnum')
cp = bs(l=3, cls=(arm_imm, m_arg), fname='cp')

imm8_12 = bs(l=8, cls=(arm_imm8_12, m_arg), fname='imm')
tl = bs_mod_name(l=1, fname="tl", mn_mod=['', 'L'])

cpopc = bs(l=3, cls=(arm_imm, m_arg), fname='cpopc')
imm20 = bs(l=20, cls=(arm_imm, m_arg))
imm4 = bs(l=4, cls=(arm_imm, m_arg))
imm12 = bs(l=12, cls=(arm_imm, m_arg))
imm16 = bs(l=16, cls=(arm_imm, m_arg))

imm12_off = bs(l=12, fname="imm")

imm2_noarg = bs(l=2, fname="imm")
imm4_noarg = bs(l=4, fname="imm4")


imm_4_12 = bs(l=12, cls=(arm_imm_4_12,))

imm12_noarg = bs(l=12, fname="imm")
imm_12_4 = bs(l=4, cls=(arm_imm_12_4,))

lowb = bs(l=1, fname='lowb')
offs_blx = bs(l=24, cls=(arm_offs_blx,), fname="offs")

fix_cond = bs("1111", fname="cond")

class mul_part_x(bs_mod_name):
    prio = 5
    mn_mod = ['B', 'T']

class mul_part_y(bs_mod_name):
    prio = 6
    mn_mod = ['B', 'T']

mul_x = mul_part_x(l=1, fname='x', mn_mod=['B', 'T'])
mul_y = mul_part_y(l=1, fname='y', mn_mod=['B', 'T'])

class arm_immed(arm_arg):
    parser = deref

    def decode(self, v):
        if self.parent.immop.value == 1:
            imm = ExprInt((self.parent.immedH.value << 4) | v, 32)
        else:
            imm = gpregs.expr[v]
        if self.parent.updown.value == 0:
            imm = -imm
        if self.parent.ppi.value:
            e = ExprOp('preinc', self.parent.rn.expr, imm)
        else:
            e = ExprOp('postinc', self.parent.rn.expr, imm)
        if self.parent.wback.value == 1:
            e = ExprOp('wback', e)
        self.expr = ExprMem(e, 32)

        return True

    def encode(self):
        self.parent.immop.value = 1
        self.parent.updown.value = 1
        e = self.expr
        if not isinstance(e, ExprMem):
            return False
        e = e.arg
        if isinstance(e, ExprOp) and e.op == 'wback':
            self.parent.wback.value = 1
            e = e.args[0]
        else:
            self.parent.wback.value = 0
        if e.op == "postinc":
            self.parent.ppi.value = 0
        elif e.op == "preinc":
            self.parent.ppi.value = 1
        else:
            # XXX default
            self.parent.ppi.value = 1
        self.parent.rn.expr = e.args[0]
        if len(e.args) == 1:
            self.value = 0
            self.parent.immedH.value = 0
            return True
        e = e.args[1]
        if isinstance(e, ExprInt):
            v = int(e)
            if v < 0 or v & (1 << 31):
                self.parent.updown.value = 0
                v = (-v) & 0xFFFFFFFF
            if v > 0xff:
                log.debug('cannot encode imm XXX')
                return False
            self.value = v & 0xF
            self.parent.immedH.value = v >> 4
            return True

        self.parent.immop.value = 0
        if isinstance(e, ExprOp) and len(e.args) == 1 and e.op == "-":
            self.parent.updown.value = 0
            e = e.args[0]
        if e in gpregs.expr:
            self.value = gpregs.expr.index(e)
            self.parent.immedH.value = 0x0
            return True
        else:
            raise ValueError('e should be int: %r' % e)

immedH = bs(l=4, fname='immedH')
immedL = bs(l=4, cls=(arm_immed, m_arg), fname='immedL')
hb = bs(l=1)


class armt2_rot_rm(arm_arg):
    parser = shift_off
    def decode(self, v):
        r = self.parent.rm.expr
        if v == 00:
            e = r
        else:
            raise NotImplementedError('rotation')
        self.expr = e
        return True
    def encode(self):
        e = self.expr
        if isinstance(e, ExprId):
            self.value = 0
        else:
            raise NotImplementedError('rotation')
        return True

rot_rm = bs(l=2, cls=(armt2_rot_rm,), fname="rot_rm")


class arm_mem_rn_imm(arm_arg):
    parser = deref
    def decode(self, v):
        value = self.parent.imm.value
        if self.parent.rw.value == 0:
            value = -value
        imm = ExprInt(value, 32)
        reg = gpregs.expr[v]
        if value:
            expr = ExprMem(reg + imm, 32)
        else:
            expr = ExprMem(reg, 32)
        self.expr = expr
        return True

    def encode(self):
        self.parent.add_imm.value = 1
        self.parent.imm.value = 0
        expr = self.expr
        if not isinstance(expr, ExprMem):
            return False
        ptr = expr.arg
        if ptr in gpregs.expr:
            self.value = gpregs.expr.index(ptr)
        elif (isinstance(ptr, ExprOp) and
              len(ptr.args) == 2 and
              ptr.op == 'preinc'):
            reg, imm = ptr.args
            if not reg in gpregs.expr:
                return False
            self.value = gpregs.expr.index(reg)
            if not isinstance(imm, ExprInt):
                return False
            value = int(imm)
            if value & 0x80000000:
                value = -value
                self.parent.add_imm.value = 0
            self.parent.imm.value = value
        else:
            return False
        return True

mem_rn_imm = bs(l=4, cls=(arm_mem_rn_imm,), order=1)

def armop(name, fields, args=None, alias=False):
    dct = {"fields": fields}
    dct["alias"] = alias
    if args is not None:
        dct['args'] = args
    type(name, (mn_arm,), dct)


def armtop(name, fields, args=None, alias=False):
    dct = {"fields": fields}
    dct["alias"] = alias
    if args is not None:
        dct['args'] = args
    type(name, (mn_armt,), dct)


op_list = ['AND', 'EOR', 'SUB', 'RSB', 'ADD', 'ADC', 'SBC', 'RSC',
           'TST', 'TEQ', 'CMP', 'CMN', 'ORR', 'MOV', 'BIC', 'MVN']
data_mov_name = {'MOV': 13, 'MVN': 15}
data_test_name = {'TST': 8, 'TEQ': 9, 'CMP': 10, 'CMN': 11}

data_name = {}
for i, n in enumerate(op_list):
    if n in data_mov_name.keys() + data_test_name.keys():
        continue
    data_name[n] = i
bs_data_name = bs_name(l=4, name=data_name)

bs_data_mov_name = bs_name(l=4, name=data_mov_name)

bs_data_test_name = bs_name(l=4, name=data_test_name)


transfer_name = {'STR': 0, 'LDR': 1}
bs_transfer_name = bs_name(l=1, name=transfer_name)

transferh_name = {'STRH': 0, 'LDRH': 1}
bs_transferh_name = bs_name(l=1, name=transferh_name)


transfer_ldr_name = {'LDRD': 0, 'LDRSB': 1}
bs_transfer_ldr_name = bs_name(l=1, name=transfer_ldr_name)

btransfer_name = {'STM': 0, 'LDM': 1}
bs_btransfer_name = bs_name(l=1, name=btransfer_name)

ctransfer_name = {'STC': 0, 'LDC': 1}
bs_ctransfer_name = bs_name(l=1, name=ctransfer_name)

mr_name = {'MCR': 0, 'MRC': 1}
bs_mr_name = bs_name(l=1, name=mr_name)


bs_addi = bs(l=1, fname="add_imm")
bs_rw = bs_mod_name(l=1, fname='rw', mn_mod=['W', ''])

armop("mul", [bs('000000'), bs('0'), scc, rd, bs('0000'), rs, bs('1001'), rm], [rd, rm, rs])
armop("umull", [bs('000010'), bs('0'), scc, rd, rdl, rs, bs('1001'), rm], [rdl, rd, rm, rs])
armop("umlal", [bs('000010'), bs('1'), scc, rd, rdl, rs, bs('1001'), rm], [rdl, rd, rm, rs])
armop("smull", [bs('000011'), bs('0'), scc, rd, rdl, rs, bs('1001'), rm], [rdl, rd, rm, rs])
armop("smlal", [bs('000011'), bs('1'), scc, rd, rdl, rs, bs('1001'), rm], [rdl, rd, rm, rs])
armop("mla", [bs('000000'), bs('1'), scc, rd, rn, rs, bs('1001'), rm], [rd, rm, rs, rn])
armop("mrs", [bs('00010'), psr, bs('00'), psr_field, rd, bs('000000000000')], [rd, psr])
armop("msr", [bs('00010'), psr, bs('10'), psr_field, bs('1111'), bs('0000'), bs('0000'), rm], [psr_field, rm])
armop("data", [bs('00'), immop, bs_data_name, scc, rn, rd, op2], [rd, rn, op2])
armop("data_mov", [bs('00'), immop, bs_data_mov_name, scc, bs('0000'), rd, op2], [rd, op2])
armop("data_test", [bs('00'), immop, bs_data_test_name, dumscc, rn, dumr, op2])
armop("b", [bs('101'), lnk, offs])

armop("smul", [bs('00010110'), rd, bs('0000'), rs, bs('1'), mul_y, mul_x, bs('0'), rm], [rd, rm, rs])

# TODO TEST
#armop("und", [bs('011'), imm20, bs('1'), imm4])
armop("transfer", [bs('01'), immop, ppi, updown, trb, wback_no_t, bs_transfer_name, rn_noarg, rd, op2imm], [rd, op2imm])
armop("transferh", [bs('000'), ppi, updown, immop, wback_no_t, bs_transferh_name, rn_noarg, rd, immedH, bs('1011'), immedL], [rd, immedL])
armop("ldrd", [bs('000'), ppi, updown, immop, wback_no_t, bs_transfer_ldr_name, rn_noarg, rd, immedH, bs('1101'), immedL], [rd, immedL])
armop("ldrsh", [bs('000'),  ppi, updown, immop, wback_no_t, bs('1'), rn_noarg, rd, immedH, bs('1'), bs('1'), bs('1'), bs('1'), immedL], [rd, immedL])
armop("strd", [bs('000'),  ppi, updown, immop, wback_no_t, bs('0'), rn_noarg, rd, immedH, bs('1'), bs('1'), bs('1'), bs('1'), immedL], [rd, immedL])
armop("btransfersp", [bs('100'),  ppi_b_sp, updown_b_sp, sbit, wback_no_t, bs_btransfer_name, rn_sp, rlist])
armop("btransfer", [bs('100'),  ppi_b_nosp, updown_b_nosp, sbit, wback_no_t, bs_btransfer_name, rn_wb, rlist])
# TODO: TEST
armop("swp", [bs('00010'), trb, bs('00'), rn, rd, bs('0000'), bs('1001'), rm])
armop("svc", [bs('1111'), swi_i])
armop("cdp", [bs('1110'), opc, crn, crd, cpnum, cp, bs('0'), crm], [cpnum, opc, crd, crn, crm, cp])
armop("cdata", [bs('110'), ppi, updown, tl, wback_no_t, bs_ctransfer_name, rn_noarg, crd, cpnum, imm8_12], [cpnum, crd, imm8_12])
armop("mr", [bs('1110'), cpopc, bs_mr_name, crn, rd, cpnum, cp, bs('1'), crm], [cpnum, cpopc, rd, crn, crm, cp])
armop("bkpt", [bs('00010010'), imm12_noarg, bs('0111'), imm_12_4])
armop("bx", [bs('000100101111111111110001'), rn])
armop("mov", [bs('00110000'), imm4_noarg, rd, imm_4_12], [rd, imm_4_12])
armop("movt", [bs('00110100'), imm4_noarg, rd, imm_4_12], [rd, imm_4_12])
armop("blx", [bs('00010010'), bs('1111'), bs('1111'), bs('1111'), bs('0011'), rm], [rm])
armop("blx", [fix_cond, bs('101'), lowb, offs_blx], [offs_blx])
armop("clz", [bs('00010110'), bs('1111'), rd, bs('1111'), bs('0001'), rm], [rd, rm])
armop("qadd", [bs('00010000'), rn, rd, bs('0000'), bs('0101'), rm], [rd, rm, rn])

armop("uxtb", [bs('01101110'), bs('1111'), rd, rot_rm, bs('00'), bs('0111'), rm_noarg])
armop("uxth", [bs('01101111'), bs('1111'), rd, rot_rm, bs('00'), bs('0111'), rm_noarg])
armop("sxtb", [bs('01101010'), bs('1111'), rd, rot_rm, bs('00'), bs('0111'), rm_noarg])
armop("sxth", [bs('01101011'), bs('1111'), rd, rot_rm, bs('00'), bs('0111'), rm_noarg])

armop("rev", [bs('01101011'), bs('1111'), rd, bs('1111'), bs('0011'), rm])

armop("pld", [bs8(0xF5), bs_addi, bs_rw, bs('01'), mem_rn_imm, bs('1111'), imm12_off])

armop("isb", [bs8(0xF5), bs8(0x7F), bs8(0xF0), bs8(0x6F)])

class arm_widthm1(arm_imm, m_arg):
    def decode(self, v):
        self.expr = ExprInt(v+1, 32)
        return True

    def encode(self):
        if not isinstance(self.expr, ExprInt):
            return False
        v = int(self.expr) +  -1
        if v > self.lmask:
            return False
        self.value = v
        return True


class arm_rm_rot2(arm_arg):
    parser = rot2_expr
    def decode(self, v):
        expr = gpregs.expr[v]
        shift_value = self.parent.rot2.value
        if shift_value:
            expr = ExprOp(allshifts[3], expr, ExprInt(shift_value * 8, 32))
        self.expr = expr
        return True
    def encode(self):
        if self.expr in gpregs.expr:
            self.value = gpregs.expr.index(self.expr)
            self.parent.rot2.value = 0
        elif (isinstance(self.expr, ExprOp) and
              self.expr.op == allshifts[3]):
            reg, value = self.expr.args
            if reg not in gpregs.expr:
                return False
            self.value = gpregs.expr.index(reg)
            if not isinstance(value, ExprInt):
                return False
            value = int(value)
            if not value in [8, 16, 24]:
                return False
            self.parent.rot2.value = value / 8
        return True

class arm_gpreg_nopc(reg_noarg):
    reg_info = gpregs_nopc
    parser = reg_info.parser


    def decode(self, v):
        ret = super(arm_gpreg_nopc, self).decode(v)
        if ret is False:
            return False
        if self.expr == reg_dum:
            return False
        return True


class arm_gpreg_nosp(reg_noarg):
    reg_info = gpregs_nosp
    parser = reg_info.parser

    def decode(self, v):
        ret = super(arm_gpreg_nosp, self).decode(v)
        if ret is False:
            return False
        if self.expr == reg_dum:
            return False
        return True


rm_rot2 = bs(l=4, cls=(arm_rm_rot2,), fname="rm")
rot2 = bs(l=2, fname="rot2")

widthm1 = bs(l=5, cls=(arm_widthm1, m_arg))
lsb = bs(l=5, cls=(arm_imm, m_arg))

rd_nopc = bs(l=4, cls=(arm_gpreg_nopc, arm_arg), fname="rd")
rn_nopc = bs(l=4, cls=(arm_gpreg_nopc, arm_arg), fname="rn")
ra_nopc = bs(l=4, cls=(arm_gpreg_nopc, arm_arg), fname="ra")
rt_nopc = bs(l=4, cls=(arm_gpreg_nopc, arm_arg), fname="rt")

rn_nosp = bs(l=4, cls=(arm_gpreg_nosp, arm_arg), fname="rn")

rn_nopc_noarg = bs(l=4, cls=(arm_gpreg_nopc,), fname="rn")

armop("ubfx", [bs('0111111'), widthm1, rd, lsb, bs('101'), rn], [rd, rn, lsb, widthm1])

armop("bfc", [bs('0111110'), widthm1, rd, lsb, bs('001'), bs('1111')], [rd, lsb, widthm1])

armop("uxtab", [bs('01101110'), rn_nopc, rd, rot2, bs('000111'), rm_rot2], [rd, rn_nopc, rm_rot2])



#
# thumnb #######################
#
# ARM7-TDMI-manual-pt3
gpregs_l = reg_info(regs_str[:8], regs_expr[:8])
gpregs_h = reg_info(regs_str[8:], regs_expr[8:])

gpregs_sppc = reg_info(regs_str[-1:] + regs_str[13:14],
                       regs_expr[-1:] + regs_expr[13:14])

deref_reg_imm = Group(LBRACK + gpregs.parser + Optional(
    COMMA + shift_off) + RBRACK).setParseAction(cb_deref_pre_mem)
deref_low = Group(LBRACK + gpregs_l.parser + Optional(
    COMMA + shift_off) + RBRACK).setParseAction(cb_deref_pre_mem)
deref_pc = Group(LBRACK + gpregs_pc.parser + Optional(
    COMMA + shift_off) + RBRACK).setParseAction(cb_deref_pre_mem)
deref_sp = Group(LBRACK + gpregs_sp.parser + COMMA +
                 shift_off + RBRACK).setParseAction(cb_deref_pre_mem)

gpregs_l_wb = Group(
    gpregs_l.parser + Optional('!')).setParseAction(cb_gpreb_wb)


gpregs_l_13 = reg_info(regs_str[:13], regs_expr[:13])


class arm_offreg(arm_arg):
    parser = deref_pc

    def decodeval(self, v):
        return v

    def encodeval(self, v):
        return v

    def decode(self, v):
        v = v & self.lmask
        v = self.decodeval(v)
        if v:
            self.expr = self.off_reg + ExprInt(v, 32)
        else:
            self.expr = self.off_reg

        e = self.expr
        if isinstance(e, ExprOp) and e.op == 'wback':
            self.parent.wback.value = 1
            e = e.args[0]
        return True

    def encode(self):
        e = self.expr
        if not (isinstance(e, ExprOp) and e.op == "preinc"):
            log.debug('cannot encode %r', e)
            return False
        if e.args[0] != self.off_reg:
            log.debug('cannot encode reg %r', e.args[0])
            return False
        v = int(e.args[1])
        v = self.encodeval(v)
        self.value = v
        return True


class arm_offpc(arm_offreg):
    off_reg = regs_expr[15]

    def decode(self, v):
        v = v & self.lmask
        v <<= 2
        if v:
            self.expr = ExprMem(self.off_reg + ExprInt(v, 32), 32)
        else:
            self.expr = ExprMem(self.off_reg, 32)

        e = self.expr.arg
        if isinstance(e, ExprOp) and e.op == 'wback':
            self.parent.wback.value = 1
            e = e.args[0]
        return True

    def encode(self):
        e = self.expr
        if not isinstance(e, ExprMem):
            return False
        e = e.arg
        if not (isinstance(e, ExprOp) and e.op == "preinc"):
            log.debug('cannot encode %r', e)
            return False
        if e.args[0] != self.off_reg:
            log.debug('cannot encode reg %r', e.args[0])
            return False
        v = int(e.args[1])
        if v & 3:
            return False
        v >>= 2
        if v > self.lmask:
            return False
        self.value = v
        return True




class arm_offsp(arm_offpc):
    parser = deref_sp
    off_reg = regs_expr[13]


class arm_offspc(arm_offs):

    def decodeval(self, v):
        v = v << 1
        # Add pipeline offset
        v += 2 + 2
        return v

    def encodeval(self, v):
        # Remove pipeline offset
        v -= 2 + 2
        if v % 2 != 0:
            return False
        if v > (1 << (self.l - 1)) - 1:
            return False
        return v >> 1
        return False


class arm_off8sppc(arm_imm):

    def decodeval(self, v):
        return v << 2

    def encodeval(self, v):
        return v >> 2


class arm_off7(arm_imm):

    def decodeval(self, v):
        return v << 2

    def encodeval(self, v):
        return v >> 2

class arm_deref_reg_imm(arm_arg):
    parser = deref_reg_imm

    def decode(self, v):
        v = v & self.lmask
        rbase = regs_expr[v]
        e = ExprOp('preinc', rbase, self.parent.off.expr)
        self.expr = ExprMem(e, 32)
        return True

    def encode(self):
        self.parent.off.expr = None
        e = self.expr
        if not isinstance(e, ExprMem):
            return False
        e = e.arg
        if not (isinstance(e, ExprOp) and e.op == 'preinc'):
            log.debug('cannot encode %r', e)
            return False
        off = e.args[1]
        if isinstance(off, ExprId):
            self.parent.off.expr = off
        elif isinstance(off, ExprInt):
            self.parent.off.expr = off
        else:
            log.debug('cannot encode off %r', off)
            return False
        self.value = gpregs.expr.index(e.args[0])
        if self.value >= 1 << self.l:
            log.debug('cannot encode reg %r', off)
            return False
        return True

class arm_derefl(arm_deref_reg_imm):
    parser = deref_low


class arm_offbw(imm_noarg):

    def decode(self, v):
        v = v & self.lmask
        if self.parent.trb.value == 0:
            v <<= 2
        self.expr = ExprInt(v, 32)
        return True

    def encode(self):
        if not isinstance(self.expr, ExprInt):
            return False
        v = int(self.expr)
        if self.parent.trb.value == 0:
            if v & 3:
                log.debug('off must be aligned %r', v)
                return False
            v >>= 2
        if v > self.lmask:
            return False
        self.value = v
        return True



class arm_off(imm_noarg):

    def decode(self, v):
        v = v & self.lmask
        self.expr = ExprInt(v, 32)
        return True

    def encode(self):
        if not isinstance(self.expr, ExprInt):
            return False
        v = int(self.expr)
        if v > self.lmask:
            return False
        self.value = v
        return True


class arm_offh(imm_noarg):

    def decode(self, v):
        v = v & self.lmask
        v <<= 1
        self.expr = ExprInt(v, 32)
        return True

    def encode(self):
        if not isinstance(self.expr, ExprInt):
            return False
        v = int(self.expr)
        if v & 1:
            log.debug('off must be aligned %r', v)
            return False
        v >>= 1
        if v > self.lmask:
            return False
        self.value = v
        return True


class armt_rlist(arm_arg):
    parser = gpreg_list

    def encode(self):
        e = self.expr
        rlist = [gpregs_l.expr.index(x) for x in e.args]
        v = 0
        for r in rlist:
            v |= 1 << r
        self.value = v
        return True

    def decode(self, v):
        v = v & self.lmask
        out = []
        for i in xrange(0x10):
            if 1 << i & v:
                out.append(gpregs.expr[i])
        if not out:
            return False
        e = ExprOp('reglist', *out)
        self.expr = e
        return True


class armt_rlist13(armt_rlist):
    parser = gpreg_list

    def encode(self):
        e = self.expr
        rlist = []
        reg_l = list(e.args)

        self.parent.pclr.value = 0
        if self.parent.name.startswith('PUSH'):
            if regs_expr[14] in reg_l:
                reg_l.remove(regs_expr[14])
                self.parent.pclr.value = 1
        else:
            if regs_expr[15] in reg_l:
                reg_l.remove(regs_expr[15])
                self.parent.pclr.value = 1

        for reg in reg_l:
            if reg not in gpregs_l_13.expr:
                return False
            rlist.append(gpregs_l_13.expr.index(reg))
        v = 0
        for r in rlist:
            v |= 1 << r
        self.value = v
        return True

    def decode(self, v):
        v = v & self.lmask
        out = []
        for i in xrange(13):
            if 1 << i & v:
                out.append(gpregs_l_13.expr[i])

        if self.parent.pclr.value == 1:
            if self.parent.name.startswith("PUSH"):
                out += [regs_expr[14]]
            else:
                out += [regs_expr[15]]

        if not out:
            return False
        e = ExprOp('reglist', *out)
        self.expr = e
        return True



class armt_rlist13_pc_lr(armt_rlist):
    parser = gpreg_list

    def encode(self):
        e = self.expr
        rlist = []
        reg_l = list(e.args)

        self.parent.pc_in.value = 0
        self.parent.lr_in.value = 0
        if regs_expr[14] in reg_l:
            reg_l.remove(regs_expr[14])
            self.parent.lr_in.value = 1
        if regs_expr[15] in reg_l:
            reg_l.remove(regs_expr[15])
            self.parent.pc_in.value = 1

        for reg in reg_l:
            if reg not in gpregs_l_13.expr:
                return False
            rlist.append(gpregs_l_13.expr.index(reg))
        v = 0
        for r in rlist:
            v |= 1 << r
        self.value = v
        return True

    def decode(self, v):
        v = v & self.lmask
        out = []
        for i in xrange(13):
            if 1 << i & v:
                out.append(gpregs_l_13.expr[i])

        if self.parent.lr_in.value == 1:
            out += [regs_expr[14]]
        if self.parent.pc_in.value == 1:
            out += [regs_expr[15]]

        if not out:
            return False
        e = ExprOp('reglist', *out)
        self.expr = e
        return True



class armt_rlist_pclr(armt_rlist):

    def encode(self):
        e = self.expr
        reg_l = list(e.args)
        self.parent.pclr.value = 0
        if self.parent.pp.value == 0:
            if regs_expr[14] in reg_l:
                reg_l.remove(regs_expr[14])
                self.parent.pclr.value = 1
        else:
            if regs_expr[15] in reg_l:
                reg_l.remove(regs_expr[15])
                self.parent.pclr.value = 1
        rlist = [gpregs.expr.index(x) for x in reg_l]
        v = 0
        for r in rlist:
            v |= 1 << r
        if v > self.lmask:
            return False
        self.value = v
        return True

    def decode(self, v):
        v = v & self.lmask
        out = []
        for i in xrange(0x10):
            if 1 << i & v:
                out.append(gpregs.expr[i])

        if self.parent.pclr.value == 1:
            if self.parent.pp.value == 0:
                out += [regs_expr[14]]
            else:
                out += [regs_expr[15]]
        if not out:
            return False
        e = ExprOp('reglist', *out)
        self.expr = e
        return True


class armt_reg_wb(arm_reg_wb):
    reg_info = gpregs_l
    parser = gpregs_l_wb

    def decode(self, v):
        v = v & self.lmask
        e = self.reg_info.expr[v]
        if not e in self.parent.trlist.expr.args:
            e = ExprOp('wback', e)
        self.expr = e
        return True

    def encode(self):
        e = self.expr
        if isinstance(e, ExprOp):
            if e.op != 'wback':
                return False
            e = e.args[0]
        self.value = self.reg_info.expr.index(e)
        return True


class arm_gpreg_l(arm_reg):
    reg_info = gpregs_l
    parser = reg_info.parser


class arm_gpreg_h(arm_reg):
    reg_info = gpregs_h
    parser = reg_info.parser


class arm_gpreg_l_noarg(arm_gpreg_noarg):
    reg_info = gpregs_l
    parser = reg_info.parser


class arm_sppc(arm_reg):
    reg_info = gpregs_sppc
    parser = reg_info.parser


class arm_sp(arm_reg):
    reg_info = gpregs_sp
    parser = reg_info.parser


off5 = bs(l=5, cls=(arm_imm,), fname="off")
off3 = bs(l=3, cls=(arm_imm,), fname="off")
off8 = bs(l=8, cls=(arm_imm,), fname="off")
off7 = bs(l=7, cls=(arm_off7,), fname="off")

rdl = bs(l=3, cls=(arm_gpreg_l,), fname="rd")
rnl = bs(l=3, cls=(arm_gpreg_l,), fname="rn")
rsl = bs(l=3, cls=(arm_gpreg_l,), fname="rs")
rml = bs(l=3, cls=(arm_gpreg_l,), fname="rm")
rol = bs(l=3, cls=(arm_gpreg_l,), fname="ro")
rbl = bs(l=3, cls=(arm_gpreg_l,), fname="rb")
rbl_deref = bs(l=3, cls=(arm_derefl,), fname="rb")
dumrh = bs(l=3, default_val="000")

rdh = bs(l=3, cls=(arm_gpreg_h,), fname="rd")
rsh = bs(l=3, cls=(arm_gpreg_h,), fname="rs")

offpc8 = bs(l=8, cls=(arm_offpc,), fname="offs")
offsp8 = bs(l=8, cls=(arm_offsp,), fname="offs")
rol_noarg = bs(l=3, cls=(arm_gpreg_l_noarg,), fname="off")

off5bw = bs(l=5, cls=(arm_offbw,), fname="off")
off5h = bs(l=5, cls=(arm_offh,), fname="off")
sppc = bs(l=1, cls=(arm_sppc,))

off12 = bs(l=12, cls=(arm_off,), fname="off", order=-1)
rn_deref = bs(l=4, cls=(arm_deref_reg_imm,), fname="rt")



pclr = bs(l=1, fname='pclr', order=-2)


pc_in = bs(l=1, fname='pc_in', order=-2)
lr_in = bs(l=1, fname='lr_in', order=-2)


sp = bs(l=0, cls=(arm_sp,))


off8s = bs(l=8, cls=(arm_offs,), fname="offs")
trlistpclr = bs(l=8, cls=(armt_rlist_pclr,))
trlist = bs(l=8, cls=(armt_rlist,), fname="trlist", order = -1)
trlist13 = bs(l=13, cls=(armt_rlist13,), fname="trlist", order = -1)
trlist13pclr = bs(l=13, cls=(armt_rlist13_pc_lr,), fname="trlist", order = -1)


rbl_wb = bs(l=3, cls=(armt_reg_wb,), fname='rb')

offs8 = bs(l=8, cls=(arm_offspc,), fname="offs")
offs11 = bs(l=11, cls=(arm_offspc,), fname="offs")

hl = bs(l=1, prio=default_prio + 1, fname='hl')
off8sppc = bs(l=8, cls=(arm_off8sppc,), fname="off")

imm8_d1 = bs(l=8, default_val="00000001")
imm8 = bs(l=8, cls=(arm_imm,), default_val = "00000001")


mshift_name = {'LSLS': 0, 'LSRS': 1, 'ASRS': 2}
bs_mshift_name = bs_name(l=2, name=mshift_name)


addsub_name = {'ADDS': 0, 'SUBS': 1}
bs_addsub_name = bs_name(l=1, name=addsub_name)

mov_cmp_add_sub_name = {'MOVS': 0, 'CMP': 1, 'ADDS': 2, 'SUBS': 3}
bs_mov_cmp_add_sub_name = bs_name(l=2, name=mov_cmp_add_sub_name)

alu_name = {'ANDS': 0, 'EORS': 1, 'LSLS': 2, 'LSRS': 3,
            'ASRS': 4, 'ADCS': 5, 'SBCS': 6, 'RORS': 7,
            'TST': 8, 'NEGS': 9, 'CMP': 10, 'CMN': 11,
            'ORRS': 12, 'MULS': 13, 'BICS': 14, 'MVNS': 15}
bs_alu_name = bs_name(l=4, name=alu_name)

hiregop_name = {'ADDS': 0, 'CMP': 1, 'MOV': 2}
bs_hiregop_name = bs_name(l=2, name=hiregop_name)

ldr_str_name = {'STR': 0, 'LDR': 1}
bs_ldr_str_name = bs_name(l=1, name=ldr_str_name)

ldrh_strh_name = {'STRH': 0, 'LDRH': 1}
bs_ldrh_strh_name = bs_name(l=1, name=ldrh_strh_name)

ldstsp_name = {'STR': 0, 'LDR': 1}
bs_ldstsp_name = bs_name(l=1, name=ldstsp_name)

addsubsp_name = {'ADD': 0, 'SUB': 1}
bs_addsubsp_name = bs_name(l=1, name=addsubsp_name)

pushpop_name = {'PUSH': 0, 'POP': 1}
bs_pushpop_name = bs_name(l=1, name=pushpop_name, fname='pp')

tbtransfer_name = {'STMIA': 0, 'LDMIA': 1}
bs_tbtransfer_name = bs_name(l=1, name=tbtransfer_name)

br_name = {'BEQ': 0, 'BNE': 1, 'BCS': 2, 'BCC': 3, 'BMI': 4,
           'BPL': 5, 'BVS': 6, 'BVC': 7, 'BHI': 8, 'BLS': 9,
           'BGE': 10, 'BLT': 11, 'BGT': 12, 'BLE': 13}
bs_br_name = bs_name(l=4, name=br_name)


armtop("mshift", [bs('000'), bs_mshift_name, off5, rsl, rdl], [rdl, rsl, off5])
armtop("addsubr", [bs('000110'),  bs_addsub_name, rnl, rsl, rdl], [rdl, rsl, rnl])
armtop("addsubi", [bs('000111'),  bs_addsub_name, off3, rsl, rdl], [rdl, rsl, off3])
armtop("mcas", [bs('001'), bs_mov_cmp_add_sub_name, rnl, off8])
armtop("alu", [bs('010000'), bs_alu_name, rsl, rdl], [rdl, rsl])
  # should not be used ??
armtop("hiregop00", [bs('010001'), bs_hiregop_name, bs('00'), rsl, rdl], [rdl, rsl])
armtop("hiregop01", [bs('010001'), bs_hiregop_name, bs('01'), rsh, rdl], [rdl, rsh])
armtop("hiregop10", [bs('010001'), bs_hiregop_name, bs('10'), rsl, rdh], [rdh, rsl])
armtop("hiregop11", [bs('010001'), bs_hiregop_name, bs('11'), rsh, rdh], [rdh, rsh])
armtop("bx", [bs('010001'), bs('11'), bs('00'), rsl, dumrh])
armtop("bx", [bs('010001'), bs('11'), bs('01'), rsh, dumrh])
armtop("ldr", [bs('01001'),  rdl, offpc8])
armtop("ldrstr", [bs('0101'), bs_ldr_str_name, trb, bs('0'), rol_noarg, rbl_deref, rdl], [rdl, rbl_deref])
armtop("strh", [bs('0101'), bs('00'), bs('1'), rol_noarg, rbl_deref, rdl], [rdl, rbl_deref])
armtop("ldrh", [bs('0101'), bs('10'), bs('1'), rol_noarg, rbl_deref, rdl], [rdl, rbl_deref])
armtop("ldsb", [bs('0101'), bs('01'), bs('1'), rol_noarg, rbl_deref, rdl], [rdl, rbl_deref])
armtop("ldsh", [bs('0101'), bs('11'), bs('1'), rol_noarg, rbl_deref, rdl], [rdl, rbl_deref])
armtop("ldst", [bs('011'), trb, bs_ldr_str_name, off5bw, rbl_deref, rdl], [rdl, rbl_deref])
armtop("ldhsth", [bs('1000'), bs_ldrh_strh_name, off5h, rbl_deref, rdl], [rdl, rbl_deref])
armtop("ldstsp", [bs('1001'), bs_ldstsp_name, rdl, offsp8], [rdl, offsp8])
armtop("add", [bs('1010'), sppc, rdl, off8sppc], [rdl, sppc, off8sppc])
armtop("addsp", [bs('10110000'), bs_addsubsp_name, sp, off7], [sp, off7])
armtop("pushpop", [bs('1011'), bs_pushpop_name, bs('10'), pclr, trlistpclr], [trlistpclr])
armtop("btransfersp", [bs('1100'),  bs_tbtransfer_name, rbl_wb, trlist])
armtop("br", [bs('1101'),  bs_br_name, offs8])
armtop("blx", [bs("01000111"),  bs('10'), rnl, bs('000')])
armtop("svc", [bs('11011111'),  imm8])
armtop("b", [bs('11100'),  offs11])
armtop("und", [bs('1101'), bs('1110'), imm8_d1])

armtop("rev",  [bs('10111010'), bs('00'), rsl, rdl], [rdl, rsl])

armtop("uxtb", [bs('10110010'), bs('11'), rml, rdl], [rdl, rml])
armtop("uxth", [bs('10110010'), bs('10'), rml, rdl], [rdl, rml])
armtop("sxtb", [bs('10110010'), bs('01'), rml, rdl], [rdl, rml])
armtop("sxth", [bs('10110010'), bs('00'), rml, rdl], [rdl, rml])

# thumb2 ######################
#
# ARM Architecture Reference Manual Thumb-2 Supplement

armt_gpreg_shift_off = (gpregs_nosppc.parser + allshifts_t_armt + (gpregs.parser | int_1_31)).setParseAction(cb_shift)


armt_gpreg_shift_off |= gpregs_nosppc.parser


class arm_gpreg_nosppc(arm_reg):
    reg_info = gpregs_nosppc
    parser = reg_info.parser

    def decode(self, v):
        ret = super(arm_gpreg_nosppc, self).decode(v)
        if ret is False:
            return False
        if self.expr == reg_dum:
            return False
        return True


class armt_gpreg_rm_shift_off(arm_reg):
    parser = armt_gpreg_shift_off

    def decode(self, v):
        v = v & self.lmask
        if v >= len(gpregs_nosppc.expr):
            return False
        r = gpregs_nosppc.expr[v]
        if r == reg_dum:
            return False

        i = int(self.parent.imm5_3.value) << 2
        i |= int(self.parent.imm5_2.value)

        if self.parent.stype.value < 3 or i != 0:
            shift = allshifts_armt[self.parent.stype.value]
        else:
            shift = allshifts_armt[4]
        self.expr = ExprOp(shift, r, ExprInt(i, 32))
        return True

    def encode(self):
        e = self.expr
        if isinstance(e, ExprId):
            if e not in gpregs_nosppc.expr:
                return False
            self.value = gpregs_nosppc.expr.index(e)
            self.parent.stype.value = 0
            self.parent.imm5_3.value = 0
            self.parent.imm5_2.value = 0
            return True
        if not e.is_op():
            return False
        shift = e.op
        r = gpregs_nosppc.expr.index(e.args[0])
        self.value = r
        i = int(e.args[1])
        if shift == 'rrx':
            if i != 1:
                log.debug('rrx shift must be 1')
                return False
            self.parent.imm5_3.value = 0
            self.parent.imm5_2.value = 0
            self.parent.stype.value = 3
            return True
        self.parent.stype.value = allshifts_armt.index(shift)
        self.parent.imm5_2.value = i & 3
        self.parent.imm5_3.value = i >> 2
        return True

rn_nosppc = bs(l=4, cls=(arm_gpreg_nosppc,), fname="rn")
rd_nosppc = bs(l=4, cls=(arm_gpreg_nosppc,), fname="rd")
rm_sh = bs(l=4, cls=(armt_gpreg_rm_shift_off,), fname="rm")


class armt2_imm12(arm_imm):

    def decode(self, v):
        v = v & self.lmask
        v |= int(self.parent.imm12_3.value) << 8
        v |= int(self.parent.imm12_1.value) << 11

        # simple encoding
        if 0 <= v < 0x100:
            self.expr = ExprInt(v, 32)
            return True
        # 00XY00XY form
        if v >> 8 == 1:
            v &= 0xFF
            self.expr = ExprInt((v << 16) | v, 32)
            return True
        # XY00XY00 form
        if v >> 8 == 2:
            v &= 0xFF
            self.expr = ExprInt((v << 24) | (v << 8), 32)
            return True
        # XYXYXYXY
        if v >> 8 == 3:
            v &= 0xFF
            self.expr = ExprInt((v << 24) | (v << 16) | (v << 8) | v, 32)
            return True
        r = v >> 7
        v = 0x80 | (v & 0x7F)
        self.expr = ExprInt(myror32(v, r), 32)
        return True

    def encode(self):
        if not self.expr.is_int():
            return False
        v = int(self.expr)
        value = None
        # simple encoding
        if 0 <= v < 0x100:
            value = v
        elif v & 0xFF00FF00 == 0 and v & 0xFF == (v >> 16) & 0xff:
            # 00XY00XY form
            value = (1 << 8) | (v & 0xFF)
        elif v & 0x00FF00FF == 0 and (v >> 8) & 0xff == (v >> 24) & 0xff:
            # XY00XY00 form
            value = (2 << 8) | ((v >> 8) & 0xff)
        elif (v & 0xFF ==
             (v >> 8)  & 0xFF ==
             (v >> 16) & 0xFF ==
             (v >> 24) & 0xFF):
            # XYXYXYXY form
            value = (3 << 8) | ((v >> 16) & 0xff)
        else:
            # rol encoding
            for i in xrange(32):
                o = myrol32(v, i)
                if 0x80 <= o <= 0xFF:
                    value = (i << 7) | (o & 0x7F)
                    break
        if value is None:
            log.debug('cannot encode imm12')
            return False
        self.value = value & self.lmask
        self.parent.imm12_3.value = (value >> 8) & self.parent.imm12_3.lmask
        self.parent.imm12_1.value = (value >> 11) & self.parent.imm12_1.lmask
        return True




class armt4_imm12(arm_imm):

    def decode(self, v):
        v = v & self.lmask
        v |= int(self.parent.imm12_3.value) << 8
        v |= int(self.parent.imm12_1.value) << 11
        self.expr = ExprInt(v, 32)
        return True

    def encode(self):
        if not self.expr.is_int():
            return False
        value = int(self.expr)
        if value >= (1 << 16):
            return False
        self.value = value & self.lmask
        self.parent.imm12_3.value = (value >> 8) & self.parent.imm12_3.lmask
        self.parent.imm12_1.value = (value >> 11) & self.parent.imm12_1.lmask
        return True



class armt2_imm16(arm_imm):

    def decode(self, v):
        v = v & self.lmask
        v |= int(self.parent.imm16_3.value) << 8
        v |= int(self.parent.imm16_1.value) << 11
        v |= int(self.parent.imm16_4.value) << 12
        self.expr = ExprInt(v, 32)
        return True

    def encode(self):
        if not self.expr.is_int():
            return False
        value = int(self.expr)
        if value >= (1 << 16):
            return False
        self.value = value & self.lmask
        self.parent.imm16_3.value = (value >> 8) & self.parent.imm16_3.lmask
        self.parent.imm16_1.value = (value >> 11) & self.parent.imm16_1.lmask
        self.parent.imm16_4.value = (value >> 12) & self.parent.imm16_4.lmask
        return True


class armt2_lsb5(arm_imm):

    def decode(self, v):
        v = v & self.lmask
        v |= int(self.parent.lsb5_3.value) << 2
        self.expr = ExprInt(v, 32)
        return True

    def encode(self):
        if not self.expr.is_int():
            return False
        value = int(self.expr)
        self.value = value & self.lmask
        self.parent.lsb5_3.value = (value >> 2) & self.parent.lsb5_3.lmask
        return True


class armt_widthm1(arm_imm):
    parser = base_expr

    def decodeval(self, v):
        return v + 1

    def encodeval(self, v):
        if v <= 0:
            return False
        return v - 1




class armt2_off20(arm_imm):

    def decode(self, v):
        v = v & self.lmask
        v <<= 1
        v |= int(self.parent.off20_6.value) << 12
        v |= int(self.parent.off20_j1.value) << 18
        v |= int(self.parent.off20_j2.value) << 19
        v |= int(self.parent.off20_s.value) << 20
        self.expr = ExprInt(v, 32)
        return True

    def encode(self):
        if not self.expr.is_int():
            return False
        value = int(self.expr)
        if value & 1:
            return False
        self.value = (value >> 1) & self.lmask
        self.parent.off20_6.value = (value >> 12) & self.parent.off20_6.lmask
        self.parent.off20_j1.value = (value >> 18) & self.parent.off20_j1.lmask
        self.parent.off20_j2.value = (value >> 19) & self.parent.off20_j2.lmask
        self.parent.off20_s.value = (value >> 20) & self.parent.off20_s.lmask
        return True



class armt2_imm10l(arm_imm):

    def decode(self, v):
        v = v & self.lmask
        s = self.parent.sign.value
        j1 = self.parent.j1.value
        j2 = self.parent.j2.value
        imm10h = self.parent.imm10h.value
        imm10l = v

        i1, i2 = j1 ^ s ^ 1, j2 ^ s ^ 1

        v = (s << 24) | (i1 << 23) | (i2 << 22) | (imm10h << 12) | (imm10l << 2)
        v = sign_ext(v, 25, 32)
        self.expr = ExprInt(v, 32)
        return True

    def encode(self):
        if not isinstance(self.expr, ExprInt):
            return False
        v = self.expr.arg.arg
        s = 0
        if v & 0x80000000:
            s = 1
            v &= (1<<26) - 1
        if v >= (1 << 26):
            return False
        i1, i2, imm10h, imm10l = (v >> 23) & 1, (v >> 22) & 1, (v >> 12) & 0x3ff, (v >> 2) & 0x3ff
        j1, j2 = i1 ^ s ^ 1, i2 ^ s ^ 1
        self.parent.sign.value = s
        self.parent.j1.value = j1
        self.parent.j2.value = j2
        self.parent.imm10h.value = imm10h
        self.value = imm10l
        return True


class armt2_imm11l(arm_imm):

    def decode(self, v):
        v = v & self.lmask
        s = self.parent.sign.value
        j1 = self.parent.j1.value
        j2 = self.parent.j2.value
        imm10h = self.parent.imm10h.value
        imm11l = v

        i1, i2 = j1 ^ s ^ 1, j2 ^ s ^ 1

        v = (s << 24) | (i1 << 23) | (i2 << 22) | (imm10h << 12) | (imm11l << 1)
        v = sign_ext(v, 25, 32)
        self.expr = ExprInt(v + 4, 32)
        return True

    def encode(self):
        if not isinstance(self.expr, ExprInt):
            return False
        v = self.expr.arg.arg - 4
        s = 0
        if v & 0x80000000:
            s = 1
            v &= (1<<26) - 1
        if v >= (1 << 26):
            return False
        if v & 1:
            return False
        i1, i2, imm10h, imm11l = (v >> 23) & 1, (v >> 22) & 1, (v >> 12) & 0x3ff, (v >> 1) & 0x7ff
        j1, j2 = i1 ^ s ^ 1, i2 ^ s ^ 1
        self.parent.sign.value = s
        self.parent.j1.value = j1
        self.parent.j2.value = j2
        self.parent.imm10h.value = imm10h
        self.value = imm11l
        return True



class armt2_imm6_11l(arm_imm):

    def decode(self, v):
        v = v & self.lmask
        s = self.parent.sign.value
        j1 = self.parent.j1.value
        j2 = self.parent.j2.value
        imm6h = self.parent.imm6h.value
        imm11l = v

        v = (s << 20) | (j2 << 19) | (j1 << 18) | (imm6h << 12) | (imm11l << 1)
        v = sign_ext(v, 21, 32)
        self.expr = ExprInt(v + 4, 32)
        return True

    def encode(self):
        if not isinstance(self.expr, ExprInt):
            return False
        v = self.expr.arg.arg - 4
        s = 0
        if v != sign_ext(v & ((1 << 22) - 1), 21, 32):
            return False 
        if v & 0x80000000:
            s = 1
        v &= (1<<22) - 1
        if v & 1:
            return False
        i2, i1, imm6h, imm11l = (v >> 19) & 1, (v >> 18) & 1, (v >> 12) & 0x3f, (v >> 1) & 0x7ff
        self.parent.sign.value = s
        self.parent.j1.value = i1
        self.parent.j2.value = i2
        self.parent.imm6h.value = imm6h
        self.value = imm11l
        return True



imm12_1 = bs(l=1, fname="imm12_1", order=1)
imm12_3 = bs(l=3, fname="imm12_3", order=1)
imm12_8 = bs(l=8, cls=(armt2_imm12,), fname="imm", order=2)


imm12_8_t4 = bs(l=8, cls=(armt4_imm12,), fname="imm", order=2)


imm16_1 = bs(l=1, fname="imm16_1", order=1)
imm16_3 = bs(l=3, fname="imm16_3", order=1)
imm16_4 = bs(l=4, fname="imm16_4", order=1)
imm16_8 = bs(l=8, cls=(armt2_imm16,), fname="imm", order=2)


imm5_3 = bs(l=3, fname="imm5_3")
imm5_2 = bs(l=2, fname="imm5_2")
imm_stype = bs(l=2, fname="stype")

imm_stype_00 = bs('00', fname="stype")
imm_stype_11 = bs('11', fname="stype")


imm1 = bs(l=1, fname="imm1")



off20_6 = bs(l=6, fname="off20_6", order=1)
off20_11 = bs(l=11, cls=(armt2_off20,), fname="imm", order=2)



lsb5_3 = bs(l=3, fname="lsb5_3", order=1)
lsb5_2 = bs(l=2, cls=(armt2_lsb5,), fname="imm", order=2)

widthm1 = bs(l=5, cls=(armt_widthm1,), fname="imm", order=2)



class armt_imm5_1(arm_imm):

    def decode(self, v):
        v = ((self.parent.imm1.value << 5) | v) << 1
        self.expr = ExprInt(v, 32)
        return True

    def encode(self):
        if not isinstance(self.expr, ExprInt):
            return False
        v = self.expr.arg.arg
        if v & 0x1:
            return False
        self.parent.imm1.value = (v >> 6) & 1
        self.value = (v >> 1) & 0x1f
        return True

aif_str = ["X", "F", "I", "IF", "A", "AF", "AI", "AIF"]
aif_expr = [ExprId(x, 32) if x != None else None for x in aif_str]

aif_reg = reg_info(aif_str, aif_expr)

class armt_aif(reg_noarg, arm_arg):
    reg_info = aif_reg
    parser = reg_info.parser

    def decode(self, v):
        if v == 0:
            return False
        return super(armt_aif, self).decode(v)

    def encode(self):
        ret = super(armt_aif, self).encode()
        if not ret:
            return ret
        return self.value != 0

    def fromstring(self, text, loc_db, parser_result=None):
        start, stop = super(armt_aif, self).fromstring(text, loc_db, parser_result)
        if self.expr.name == "X":
            return None, None
        return start, stop


class armt_it_arg(arm_arg):
    arg_E = ExprId('E', 1)
    arg_NE = ExprId('NE', 1)

    def decode(self, v):
        if v:
            return self.arg_E
        else:
            return self.arg_NE

    def encode(self):
        if self.expr == self.arg_E:
            return 1
        elif self.expr == self.arg_NE:
            return 0

class armt_itmask(bs_divert):
    prio = 2

    def divert(self, i, candidates):
        out = []
        for cls, _, bases, dct, fields in candidates:
            for value in xrange(1, 0x10):
                nfields = fields[:]
                s = int2bin(value, self.args['l'])
                args = dict(self.args)
                args.update({'strbits': s})
                f = bs(**args)
                nfields[i] = f
                inv = nfields[-2].value
                ndct = dict(dct)
                ndct['name'] = self.modname(ndct['name'], value, inv)
                out.append((cls, ndct['name'], bases, ndct, nfields))
        return out

    def modname(self, name, value, inv):
        count = 0
        while value & (1 << count) == 0:
            count += 1
        out = []
        values = ['E', 'T']
        if inv== 1:
            values.reverse()
        for index in xrange(3 - count):
            if value & (1 << (3 - index)):
                out.append(values[0])
            else:
                out.append(values[1])
        return name + "".join(out)



class armt_cond_lsb(bs_divert):
    prio = 2

    def divert(self, i, candidates):
        out = []
        for cls, _, bases, dct, fields in candidates:
            for value in xrange(2):
                nfields = fields[:]
                s = int2bin(value, self.args['l'])
                args = dict(self.args)
                args.update({'strbits': s})
                f = bs(**args)
                nfields[i] = f
                ndct = dict(dct)
                out.append((cls, ndct['name'], bases, ndct, nfields))
        return out


cond_expr = [ExprId(x, 32) for x in cond_list_full]
cond_info = reg_info(cond_list_full, cond_expr)

class armt_cond_arg(arm_arg):
    parser = cond_info.parser

    def decode(self, v):
        v = (v << 1) | self.parent.condlsb.value
        self.expr = ExprId(cond_list_full[v], 32)
        return True

    def encode(self):
        index = cond_list_full.index(self.expr.name)
        self.value = index >> 1
        if index & 1 != self.parent.condlsb.value:
            return False
        return True


class armt_op2imm(arm_imm8_12):
    parser = deref

    def str_to_imm_rot_form(self, s, neg=False):
        if neg:
            s = -s & 0xffffffff
        if 0 <= s < (1 << 12):
            return s
        return None

    def decodeval(self, v):
        return v

    def encodeval(self, v):
        return v

    def decode(self, v):
        val = v & self.lmask
        val = self.decodeval(val)
        if val is False:
            return False
        imm = val
        if self.parent.updown.value == 0:
            imm = -imm
        if self.parent.ppi.value == 0 and self.parent.wback.value == 0:
            return False
        if self.parent.ppi.value:
            e = ExprOp('preinc', self.parent.rn.expr, ExprInt(imm, 32))
            if self.parent.wback.value == 1:
                e = ExprOp('wback', e)
        else:
            e = ExprOp('postinc', self.parent.rn.expr, ExprInt(imm, 32))
        self.expr = ExprMem(e, 32)
        return True

    def encode(self):
        self.parent.updown.value = 1
        self.parent.wback.value = 0

        e = self.expr
        assert(isinstance(e, ExprMem))
        e = e.arg
        if e.op == 'wback':
            self.parent.wback.value = 1
            e = e.args[0]
        if e.op == "postinc":
            self.parent.ppi.value = 0
            self.parent.wback.value = 1
        elif e.op == "preinc":
            self.parent.ppi.value = 1
        else:
            # XXX default
            self.parent.ppi.value = 1

        self.parent.rn.expr = e.args[0]

        if len(e.args) == 1:
            self.value = 0
            return True
        # pure imm
        if isinstance(e.args[1], ExprInt):
            val = self.str_to_imm_rot_form(int(e.args[1]))
            if val is None:
                val = self.str_to_imm_rot_form(int(e.args[1]), True)
                if val is None:
                    log.debug('cannot encode inm')
                    return False
                self.parent.updown.value = 0
            val = self.encodeval(val)
            if val is False:
                return False
            self.value = val
            return True
        # pure reg
        if isinstance(e.args[1], ExprId):
            rm = gpregs.expr.index(e.args[1])
            shift_kind = 0
            shift_type = 0
            amount = 0
            val = (((((amount << 2) | shift_type) << 1) | shift_kind) << 4) | rm
            val = self.encodeval(val)
            if val is False:
                return False
            self.value = val
            return True
        return False


class armt_op2imm00(armt_op2imm):

    def decodeval(self, v):
        return v << 2

    def encodeval(self, v):
        if v & 3:
            return False
        return v >> 2


class armt_deref_reg(arm_imm8_12):
    parser = deref

    def decode(self, v):
        base = self.parent.rn.expr
        off = gpregs.expr[v]
        if self.parent.imm.value != 0:
            off = off << ExprInt(self.parent.imm.value, 32)
        e = ExprMem(ExprOp('preinc', base, off), 8)
        self.expr = e
        return True

    def encode(self):
        if not isinstance(self.expr, ExprMem):
            return False
        ptr = self.expr.arg
        if not ptr.is_op('preinc'):
            return False
        if len(ptr.args) != 2:
            return False
        base, off = ptr.args
        if base.is_id() and off.is_id():
            self.parent.rn.expr = base
            self.parent.imm.value = 0
            self.value = gpregs.expr.index(off)
        elif off.is_int():
            return False
        elif off.is_op('<<'):
            if len(off.args) != 2:
                return False
            reg, off = off.args
            self.parent.rn.expr = base
            self.parent.imm.value = 0
            self.value = gpregs.expr.index(reg)
            off = int(off)
            if off > self.parent.imm.lmask:
                return False
            self.parent.imm.value = off
        return True


class armt_deref_reg_reg(arm_arg):
    parser = deref_reg_reg
    reg_info = gpregs

    def decode(self, v):
        expr = self.reg_info.expr[v]
        expr = ExprMem(self.parent.rn.expr + expr, 8)
        self.expr = expr
        return True

    def encode(self):
        expr = self.expr
        if not expr.is_mem():
            return False
        ptr = expr.arg
        if not ptr.is_op('+') or len(ptr.args) != 2:
            return False
        reg1, reg2 = ptr.args
        self.parent.rn.expr = reg1
        self.value = self.reg_info.expr.index(reg2)
        return True


class armt_deref_reg_reg_lsl_1(arm_reg):
    parser = deref_reg_reg_lsl_1
    reg_info = gpregs

    def decode(self, v):
        expr = self.reg_info.expr[v]
        expr = ExprMem(self.parent.rn.expr + (expr << ExprInt(1, 32)), 16)
        self.expr = expr
        return True

    def encode(self):
        expr = self.expr
        if not expr.is_mem():
            return False
        ptr = expr.arg
        if not ptr.is_op('+') or len(ptr.args) != 2:
            return False
        reg1, reg_shift = ptr.args
        self.parent.rn.expr = reg1
        if not reg_shift.is_op('<<') or len(reg_shift.args) != 2:
            return False
        if reg_shift.args[1] != ExprInt(1, 32):
            return False
        self.value = self.reg_info.expr.index(reg_shift.args[0])
        return True


aif = bs(l=3, cls=(armt_aif,))


imm5_off = bs(l=5, cls=(armt_imm5_1,), fname="imm5_off")

tsign = bs(l=1, fname="sign")
tj1 = bs(l=1, fname="j1")
tj2 = bs(l=1, fname="j2")

timm6h = bs(l=6, fname="imm6h")
timm10H = bs(l=10, fname="imm10h")
timm10L = bs(l=10, cls=(armt2_imm10l,), fname="imm10l")
timm11L = bs(l=11, cls=(armt2_imm11l,), fname="imm11l")

timm6h11l = bs(l=11, cls=(armt2_imm6_11l,), fname="imm6h11l")

itcond = bs(l=4, fname="itcond")
itmask = armt_itmask(l=4, fname="itmask")
bs_cond_arg_msb = bs(l=3, cls=(armt_cond_arg,))


condlsb = armt_cond_lsb(l=1, fname="condlsb")

deref_immpuw = bs(l=8, cls=(armt_op2imm,))
deref_immpuw00 = bs(l=8, cls=(armt_op2imm00,))


rm_deref_reg = bs(l=4, cls=(armt_deref_reg,))

bs_deref_reg_reg = bs(l=4, cls=(armt_deref_reg_reg,))
bs_deref_reg_reg_lsl_1 = bs(l=4, cls=(armt_deref_reg_reg_lsl_1,))


class armt_barrier_option(reg_noarg, arm_arg):
    reg_info = barrier_info
    parser = reg_info.parser

    def decode(self, v):
        v = v & self.lmask
        if v not in self.reg_info.dct_expr:
            return False
        self.expr = self.reg_info.dct_expr[v]
        return True

    def encode(self):
        if not self.expr in self.reg_info.dct_expr_inv:
            log.debug("cannot encode reg %r", self.expr)
            return False
        self.value = self.reg_info.dct_expr_inv[self.expr]
        if self.value > self.lmask:
            log.debug("cannot encode field value %x %x",
                      self.value, self.lmask)
            return False
        return True

    def check_fbits(self, v):
        return v & self.fmask == self.fbits

barrier_option = bs(l=4, cls=(armt_barrier_option,))

armtop("adc", [bs('11110'),  imm12_1, bs('0'), bs('1010'), scc, rn_nosppc, bs('0'), imm12_3, rd_nosppc, imm12_8])
armtop("adc", [bs('11101'),  bs('01'), bs('1010'), scc, rn_nosppc, bs('0'), imm5_3, rd_nosppc, imm5_2, imm_stype, rm_sh])
armtop("bl", [bs('11110'), tsign, timm10H, bs('11'), tj1, bs('1'), tj2, timm11L])
armtop("blx", [bs('11110'), tsign, timm10H, bs('11'), tj1, bs('0'), tj2, timm10L, bs('0')])
armtop("cbz", [bs('101100'), imm1, bs('1'), imm5_off, rnl], [rnl, imm5_off])
armtop("cbnz", [bs('101110'), imm1, bs('1'), imm5_off, rnl], [rnl, imm5_off])

armtop("bkpt", [bs('1011'), bs('1110'), imm8])


armtop("it", [bs('10111111'), bs_cond_arg_msb, condlsb, itmask])


armtop("nop", [bs8(0xBF),bs8(0x0)])
armtop("wfi", [bs8(0xBF),bs8(0x30)])
armtop("cpsid", [bs8(0xB6),bs('0111'), bs('0'), aif], [aif])
armtop("cpsie", [bs8(0xB6),bs('0110'), bs('0'), aif], [aif])

armtop("push", [bs('1110100'), bs('10'), bs('0'), bs('1'), bs('0'), bs('1101'), bs('0'), pclr, bs('0'), trlist13], [trlist13])
armtop("pop",  [bs('1110100'), bs('01'), bs('0'), bs('1'), bs('1'), bs('1101'), pc_in, lr_in, bs('0'), trlist13pclr], [trlist13pclr])
armtop("mov", [bs('11110'), imm12_1, bs('00010'), scc, bs('1111'), bs('0'), imm12_3, rd_nosppc, imm12_8])
armtop("asr", [bs('11111010'), bs('0100'), rm, bs('1111'), rd, bs('0000'), rs], [rd, rm, rs])
armtop("lsl", [bs('11111010'), bs('0000'), rm, bs('1111'), rd, bs('0000'), rs], [rd, rm, rs])
armtop("sel", [bs('11111010'), bs('1010'), rm, bs('1111'), rd, bs('1000'), rs], [rd, rm, rs])
armtop("rev", [bs('11111010'), bs('1001'), rm, bs('1111'), rd, bs('1000'), rm_cp], [rd, rm])
armtop("uadd8", [bs('111110101000'), rn, bs('1111'), rd, bs('0100'), rm], [rd, rn, rm])
armtop("mvn", [bs('11101010011'), scc, bs('11110'), imm5_3, rd_nosppc, imm5_2, imm_stype, rm_sh] )
armtop("and", [bs('11101010000'), scc, rn_nosppc, bs('0'), imm5_3, rd_nosppc, imm5_2, imm_stype, rm_sh], [rd_nosppc, rn_nosppc, rm_sh] )
armtop("orr", [bs('11101010010'), scc, rn_nosppc, bs('0'), imm5_3, rd_nosppc, imm5_2, imm_stype, rm_sh], [rd_nosppc, rn_nosppc, rm_sh] )
armtop("bic", [bs('11101010001'), scc, rn_nosppc, bs('0'), imm5_3, rd_nosppc, imm5_2, imm_stype, rm_sh], [rd_nosppc, rn_nosppc, rm_sh] )
armtop("add", [bs('11101011000'), scc, rn_nosppc, bs('0'), imm5_3, rd_nosppc, imm5_2, imm_stype, rm_sh], [rd_nosppc, rn_nosppc, rm_sh] )
armtop("sub", [bs('11101011101'), scc, rn_nosppc, bs('0'), imm5_3, rd_nosppc, imm5_2, imm_stype, rm_sh], [rd_nosppc, rn_nosppc, rm_sh] )
armtop("eor", [bs('11101010100'), scc, rn_nosppc, bs('0'), imm5_3, rd_nosppc, imm5_2, imm_stype, rm_sh], [rd_nosppc, rn_nosppc, rm_sh] )
armtop("rsb", [bs('11101011110'), scc, rn, bs('0'), imm5_3, rd, imm5_2, imm_stype, rm_sh], [rd, rn, rm_sh] )
armtop("orn", [bs('11101010011'), scc, rn_nopc, bs('0'), imm5_3, rd, imm5_2, imm_stype, rm_sh], [rd, rn_nopc, rm_sh] )
# lsl
armtop("mov", [bs('11101010010'), scc, bs('1111'), bs('0'), imm5_3, rd_nosppc, imm5_2, imm_stype_00, rm_sh], [rd_nosppc, rm_sh] )
armtop("mov", [bs('11101010010'), scc, bs('1111'), bs('0'), imm5_3, rd_nosppc, imm5_2, imm_stype_11, rm_sh], [rd_nosppc, rm_sh] )


armtop("orr", [bs('11110'), imm12_1, bs('00010'), scc, rn_nosppc, bs('0'), imm12_3, rd, imm12_8] )
armtop("add", [bs('11110'), imm12_1, bs('01000'), scc, rn, bs('0'), imm12_3, rd, imm12_8], [rd, rn, imm12_8])
armtop("bic", [bs('11110'), imm12_1, bs('00001'), scc, rn_nosppc, bs('0'), imm12_3, rd, imm12_8], [rd, rn_nosppc, imm12_8])
armtop("and", [bs('11110'), imm12_1, bs('00000'), scc, rn, bs('0'), imm12_3, rd_nopc, imm12_8], [rd_nopc, rn, imm12_8])
armtop("sub", [bs('11110'), imm12_1, bs('01101'), scc, rn, bs('0'), imm12_3, rd_nopc, imm12_8], [rd_nopc, rn, imm12_8])
armtop("add", [bs('11110'), imm12_1, bs('10000'), scc, rn_nosppc, bs('0'), imm12_3, rd, imm12_8_t4], [rd, rn_nosppc, imm12_8_t4])
armtop("cmp", [bs('11110'), imm12_1, bs('01101'), bs('1'), rn, bs('0'), imm12_3, bs('1111'), imm12_8] )


armtop("mvn", [bs('11110'), imm12_1, bs('00011'), scc, bs('1111'), bs('0'), imm12_3, rd, imm12_8])
armtop("rsb", [bs('11110'), imm12_1, bs('01110'), scc, rn_nosppc, bs('0'), imm12_3, rd, imm12_8], [rd, rn_nosppc, imm12_8])
armtop("sub", [bs('11110'), imm12_1, bs('101010'), rn_nosppc, bs('0'), imm12_3, rd, imm12_8_t4], [rd, rn_nosppc, imm12_8_t4])
armtop("tst", [bs('11110'), imm12_1, bs('000001'), rn, bs('0'), imm12_3, bs('1111'), imm12_8], [rn, imm12_8])

armtop("mov",  [bs('11110'), imm16_1, bs('100100'), imm16_4, bs('0'), imm16_3, rd, imm16_8] )
armtop("movt", [bs('11110'), imm16_1, bs('101100'), imm16_4, bs('0'), imm16_3, rd, imm16_8] )

armtop("sdiv", [bs('111110111001'), rn, bs('1111'), rd, bs('1111'), rm], [rd, rn, rm] )
armtop("udiv", [bs('111110111011'), rn, bs('1111'), rd, bs('1111'), rm], [rd, rn, rm] )
armtop("mls",  [bs('111110110000'), rn, ra, rd, bs('0001'), rm], [rd, rn, rm, ra] )
armtop("mla",  [bs('111110110000'), rn, ra_nopc, rd, bs('0000'), rm], [rd, rn, rm, ra_nopc] )
armtop("mul",  [bs('111110110000'), rn, bs('1111'), rd, bs('0000'), rm], [rd, rn, rm] )

armtop("smlabb", [bs('111110110001'), rn, ra_nopc, rd, bs('00'), bs('00'), rm], [rd, rn, rm, ra_nopc])
armtop("smlabt", [bs('111110110001'), rn, ra_nopc, rd, bs('00'), bs('01'), rm], [rd, rn, rm, ra_nopc])
armtop("smlatb", [bs('111110110001'), rn, ra_nopc, rd, bs('00'), bs('10'), rm], [rd, rn, rm, ra_nopc])
armtop("smlatt", [bs('111110110001'), rn, ra_nopc, rd, bs('00'), bs('11'), rm], [rd, rn, rm, ra_nopc])

armtop("b", [bs('11110'), tsign, bm_cond_barmt, timm6h, bs('10'), tj1, bs('0'), tj2, timm6h11l], [timm6h11l])
armtop("b", [bs('11110'), tsign, timm10H, bs('10'), tj1, bs('1'), tj2, timm11L], [timm11L])

armtop("ubfx", [bs('111100111100'), rn, bs('0'), lsb5_3, rd, lsb5_2, bs('0'), widthm1], [rd, rn, lsb5_2, widthm1])
armtop("uxth", [bs('111110100001'), bs('1111'), bs('1111'), rd, bs('10'), rot2, rm_rot2], [rd, rm_rot2])



armtop("str",  [bs('111110001100'), rn_deref, rt, off12], [rt, rn_deref])
armtop("str",  [bs('111110000100'), rn_noarg, rt, bs('000000'), imm2_noarg, rm_deref_reg], [rt, rm_deref_reg])
armtop("str",  [bs('111110000100'), rn_noarg, rt, bs('1'), ppi, updown, wback_no_t, deref_immpuw], [rt, deref_immpuw])
armtop("strb", [bs('111110001000'), rn_deref, rt, off12], [rt, rn_deref])
armtop("strb", [bs('111110000000'), rn_noarg, rt, bs('1'), ppi, updown, wback_no_t, deref_immpuw], [rt, deref_immpuw])
armtop("strh", [bs('111110001010'), rn_deref, rt, off12], [rt, rn_deref])
armtop("strh", [bs('111110000010'), rn_noarg, rt, bs('1'), ppi, updown, wback_no_t, deref_immpuw], [rt, deref_immpuw])

armtop("strd", [bs('1110100'), ppi, updown, bs('1'), wback_no_t, bs('0'), rn_nopc_noarg, rt, rt2, deref_immpuw00], [rt, rt2, deref_immpuw00])
armtop("ldrd", [bs('1110100'), ppi, updown, bs('1'), wback_no_t, bs('1'), rn_nopc_noarg, rt, rt2, deref_immpuw00], [rt, rt2, deref_immpuw00])


armtop("ldr",  [bs('111110001101'), rn_deref, rt, off12], [rt, rn_deref])
armtop("ldr",  [bs('111110000101'), rn_noarg, rt, bs('1'), ppi, updown, wback_no_t, deref_immpuw], [rt, deref_immpuw])
armtop("ldr",  [bs('111110000101'), rn_noarg, rt, bs('000000'), imm2_noarg, rm_deref_reg], [rt, rm_deref_reg])
armtop("ldrb", [bs('111110000001'), rn_noarg, rt, bs('000000'), imm2_noarg, rm_deref_reg], [rt, rm_deref_reg])
armtop("ldrb", [bs('111110000001'), rn_noarg, rt, bs('1'), ppi, updown, wback_no_t, deref_immpuw], [rt, deref_immpuw])
armtop("ldrb", [bs('111110001001'), rn_deref, rt_nopc, off12], [rt_nopc, rn_deref])
armtop("ldrsb",[bs('111110011001'), rn_deref, rt, off12], [rt, rn_deref])
armtop("ldrsh",[bs('111110011011'), rn_deref, rt, off12], [rt, rn_deref])
armtop("ldrh", [bs('111110001011'), rn_deref, rt, off12], [rt, rn_deref])
armtop("ldrh", [bs('111110000011'), rn_noarg, rt, bs('1'), ppi, updown, wback_no_t, deref_immpuw], [rt, deref_immpuw])

armtop("pld",  [bs('111110001001'), rn_deref, bs('1111'), off12], [rn_deref])
armtop("pldw", [bs('111110001011'), rn_deref, bs('1111'), off12], [rn_deref])

armtop("clz",  [bs('111110101011'), rm, bs('1111'), rd, bs('1000'), rm_cp], [rd, rm])
armtop("tbb",  [bs('111010001101'), rn_noarg, bs('11110000000'), bs('0'), bs_deref_reg_reg], [bs_deref_reg_reg])
armtop("tbh",  [bs('111010001101'), rn_noarg, bs('11110000000'), bs('1'), bs_deref_reg_reg_lsl_1], [bs_deref_reg_reg_lsl_1])
armtop("dsb",  [bs('111100111011'), bs('1111'), bs('1000'), bs('1111'), bs('0100'), barrier_option])

Module variables

var CIRCUNFLEX

var COMMA

var EXPRAFF

var EXPRCOMPOSE

var EXPRCOND

var EXPRID

var EXPRINT

var EXPRLOC

var EXPRMEM

var EXPROP

var EXPRSLICE

var EXPR_ORDER_DICT

var LACC

var LBRACK

var LPARENTHESIS

var MINUS

var OP_LSL

var PRIORITY_MAX

var RACC

var RBRACK

var RPARENTHESIS

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 accum

var addsub_name

var addsubsp_name

var aif

var aif_expr

var aif_reg

var aif_str

var all_binaryop_1_31_shifts_t

var all_binaryop_1_32_shifts_t

var all_regs_ids

var all_regs_ids_byname

var all_regs_ids_init

var all_regs_ids_no_alias

var all_unaryop_shifts_t

var allshifts

var allshifts_armt

var allshifts_t_armt

var alphanums

var alphas

var alphas8bit

var alu_name

var armt_gpreg_shift_off

var attrib_to_regs

var barrier_expr

var barrier_info

var barrier_option

var bm_cond

var bm_cond_barmt

var br_name

var bs_addi

var bs_addsub_name

var bs_addsubsp_name

var bs_alu_name

var bs_br_name

var bs_btransfer_name

var bs_cond_arg_msb

var bs_ctransfer_name

var bs_data_mov_name

var bs_data_name

var bs_data_test_name

var bs_deref_reg_reg

var bs_deref_reg_reg_lsl_1

var bs_hiregop_name

var bs_ldr_str_name

var bs_ldrh_strh_name

var bs_ldstsp_name

var bs_mov_cmp_add_sub_name

var bs_mr_name

var bs_mshift_name

var bs_pushpop_name

var bs_rw

var bs_tbtransfer_name

var bs_transfer_ldr_name

var bs_transfer_name

var bs_transferh_name

var btransfer_name

var cond_dct

var cond_dct_barmt

var cond_expr

var cond_info

var cond_list

var cond_list_full

var conditional_branch

var condlsb

var console_handler

var cp

var cp_regs

var cpnum

var cpopc

var cpregs_expr

var cpregs_str

var cpsr_regs

var cpsr_regs_expr

var cpsr_regs_str

var crd

var crm

var crn

var ctransfer_name

var data_mov_name

var data_name

var data_test_name

var default_prio

var deref

var deref_immpuw

var deref_immpuw00

var deref_low

var deref_nooff

var deref_pc

var deref_post

var deref_pre

var deref_reg_imm

var deref_reg_reg

var deref_reg_reg_lsl_1

var deref_sp

var dumr

var dumrh

var dumscc

var expr2shift_dct

var fix_cond

var ge_regs

var gpreg_list

var gpreg_p

var gpregs

var gpregs_h

var gpregs_l

var gpregs_l_13

var gpregs_l_wb

var gpregs_nopc

var gpregs_nosp

var gpregs_nosppc

var gpregs_pc

var gpregs_sp

var gpregs_sppc

var gpregs_wb

var hb

var hexnums

var hiregop_name

var hl

var i

var imm1

var imm12

var imm12_1

var imm12_3

var imm12_8

var imm12_8_t4

var imm12_noarg

var imm12_off

var imm16

var imm16_1

var imm16_3

var imm16_4

var imm16_8

var imm20

var imm2_noarg

var imm4

var imm4_noarg

var imm5_2

var imm5_3

var imm5_off

var imm8

var imm8_12

var imm8_d1

var imm_12_4

var imm_4_12

var imm_stype

var imm_stype_00

var imm_stype_11

var immedH

var immedL

var immop

var int_1_31

var int_1_32

var int_8_16_24

var itcond

var itmask

var j

var ldr_str_name

var ldrh_strh_name

var ldstsp_name

var lnk

var log

var lowb

var lr_in

var lsb

var lsb5_2

var lsb5_3

var mem_rn_imm

var mod_size2uint

var mov_cmp_add_sub_name

var mr_name

var mshift_name

var mul_x

var mul_y

var n

var nums

var o

var off12

var off20_11

var off20_6

var off3

var off5

var off5bw

var off5h

var off7

var off8

var off8s

var off8sppc

var offpc8

var offs

var offs11

var offs8

var offs_blx

var offsp8

var op2

var op2imm

var op_list

var opc

var p_regs

var pc_in

var pclr

var ppi

var ppi_b_nosp

var ppi_b_sp

var pregs_expr

var pregs_str

var printables

var priorities

var priorities_list

var psr

var psr_field

var psr_p

var punc8bit

var pushpop_name

var r

var ra

var ra_nopc

var rbl

var rbl_deref

var rbl_wb

var rd

var rd_nopc

var rd_nosppc

var rdh

var rdl

var reg_cf

var reg_dum

var reg_duo

var reg_ge0

var reg_ge1

var reg_ge2

var reg_ge3

var reg_nf

var reg_of

var reg_or_base

var reg_or_duo

var reg_zf

var regs32_expr

var regs32_str

var regs_expr

var regs_flt_expr

var regs_init

var regs_str

var rlist

var rm

var rm_cp

var rm_deref_reg

var rm_noarg

var rm_rot2

var rm_sh

var rml

var rn

var rn_deref

var rn_noarg

var rn_nopc

var rn_nopc_noarg

var rn_nosp

var rn_nosppc

var rn_sp

var rn_wb

var rnl

var rol

var rol_noarg

var ror_shifts_t

var rot2

var rot2_expr

var rot_rm

var rs

var rsh

var rsl

var rt

var rt2

var rt_nopc

var sbit

var scc

var shift2expr_dct

var shift_off

var size_to_IEEE754_info

var sp

var sppc

var spsr_regs

var spsr_regs_expr

var spsr_regs_str

var sr_flags

var swi_i

var tbtransfer_name

var timm10H

var timm10L

var timm11L

var timm6h

var timm6h11l

var tj1

var tj2

var tl

var total_scans

var transfer_ldr_name

var transfer_name

var transferh_name

var trb

var trlist

var trlist13

var trlist13pclr

var trlistpclr

var tsign

var unconditional_branch

var updown

var updown_b_nosp

var updown_b_sp

var wback

var wback_no_t

var widthm1

var x

Functions

def armop(

name, fields, args=None, alias=False)

def armop(name, fields, args=None, alias=False):
    dct = {"fields": fields}
    dct["alias"] = alias
    if args is not None:
        dct['args'] = args
    type(name, (mn_arm,), dct)

def armtop(

name, fields, args=None, alias=False)

def armtop(name, fields, args=None, alias=False):
    dct = {"fields": fields}
    dct["alias"] = alias
    if args is not None:
        dct['args'] = args
    type(name, (mn_armt,), dct)

def cb_deref_post(

tokens)

def cb_deref_post(tokens):
    tokens = tokens[0]
    return AstOp("postinc", tokens[0], tokens[1])

def cb_deref_pre_mem(

tokens)

def cb_deref_pre_mem(tokens):
    tokens = tokens[0]
    if len(tokens) == 1:
        return AstMem(AstOp("preinc", tokens[0], AstInt(0)), 32)
    elif len(tokens) == 2:
        return AstMem(AstOp("preinc", tokens[0], tokens[1]), 32)
    else:
        raise NotImplementedError('len(tokens) > 2')

def cb_deref_preinc(

tokens)

def cb_deref_preinc(tokens):
    tokens = tokens[0]
    if len(tokens) == 1:
        return AstOp("preinc", tokens[0], AstInt(0))
    elif len(tokens) == 2:
        return AstOp("preinc", tokens[0], tokens[1])
    else:
        raise NotImplementedError('len(tokens) > 2')

def cb_deref_reg_reg(

tokens)

def cb_deref_reg_reg(tokens):
    if len(tokens) != 2:
        raise ValueError("Bad mem format")
    return AstMem(AstOp('+', tokens[0], tokens[1]), 8)

def cb_deref_reg_reg_lsl_1(

tokens)

def cb_deref_reg_reg_lsl_1(tokens):
    if len(tokens) != 3:
        raise ValueError("Bad mem format")
    reg1, reg2, index = tokens
    if not isinstance(index, AstInt) or index.value != 1:
        raise ValueError("Bad index")
    ret = AstMem(AstOp('+', reg1, AstOp('<<', reg2, index)), 16)
    return ret

def cb_deref_wb(

tokens)

def cb_deref_wb(tokens):
    tokens = tokens[0]
    if tokens[-1] == '!':
        return AstMem(AstOp('wback', *tokens[:-1]), 32)
    return AstMem(tokens[0], 32)

def cb_gpreb_wb(

tokens)

def cb_gpreb_wb(tokens):
    assert len(tokens) == 1
    tokens = tokens[0]
    if tokens[-1] == '!':
        return AstOp('wback', *tokens[:-1])
    return tokens[0]

def cb_reglistparse(

tokens)

def cb_reglistparse(tokens):
    tokens = tokens[0]
    if tokens[-1] == "^":
        return AstOp('sbit', AstOp('reglist', *tokens[:-1]))
    return AstOp('reglist', *tokens)

def cb_shift(

tokens)

def cb_shift(tokens):
    if len(tokens) == 1:
        ret = tokens[0]
    elif len(tokens) == 2:
        ret = AstOp(tokens[1], tokens[0])
    elif len(tokens) == 3:
        ret = AstOp(tokens[1], tokens[0], tokens[2])
    else:
        raise ValueError("Bad arg")
    return ret

def cb_tok_reg_duo(

tokens)

def cb_tok_reg_duo(tokens):
    tokens = tokens[0]
    i1 = gpregs.expr.index(tokens[0].name)
    i2 = gpregs.expr.index(tokens[1].name)
    o = []
    for i in xrange(i1, i2 + 1):
        o.append(AstId(gpregs.expr[i]))
    return o

def check_bounds(

left_bound, right_bound, value)

def check_bounds(left_bound, right_bound, value):
    if left_bound <= value and value <= right_bound:
        return AstInt(value)
    else:
        raise ValueError('shift operator immediate value out of bound')

def check_values(

values, value)

def check_values(values, value):
    if value in values:
        return AstInt(value)
    else:
        raise ValueError('shift operator immediate value out of bound')

def deref2expr_nooff(

tokens)

def deref2expr_nooff(tokens):
    tokens = tokens[0]
    # XXX default
    return ExprOp("preinc", tokens[0], ExprInt(0, 32))

def op_shift2expr(

tokens)

def op_shift2expr(tokens):
    return shift2expr_dct[tokens[0]]

def permut_args(

order, args)

def permut_args(order, args):
    l = []
    for i, x in enumerate(order):
        l.append((x.__class__, i))
    l = dict(l)
    out = [None for x in xrange(len(args))]
    for a in args:
        out[l[a.__class__]] = a
    return out

def reglist2str(

rlist)

def reglist2str(rlist):
    out = []
    i = 0
    while i < len(rlist):
        j = i + 1
        while j < len(rlist) and rlist[j] < 13 and rlist[j] == rlist[j - 1] + 1:
            j += 1
        j -= 1
        if j < i + 2:
            out.append(regs_str[rlist[i]])
            i += 1
        else:
            out.append(regs_str[rlist[i]] + '-' + regs_str[rlist[j]])
            i = j + 1
    return "{" + ", ".join(out) + '}'

Classes

class additional_info

class additional_info:

    def __init__(self):
        self.except_on_instr = False
        self.lnk = None
        self.cond = None

Ancestors (in MRO)

Instance variables

var cond

var except_on_instr

var lnk

Methods

def __init__(

self)

def __init__(self):
    self.except_on_instr = False
    self.lnk = None
    self.cond = None

class arm_arg

class arm_arg(m_arg):
    def asm_ast_to_expr(self, arg, loc_db):
        if isinstance(arg, AstId):
            if isinstance(arg.name, ExprId):
                return arg.name
            if arg.name in gpregs.str:
                return None
            loc_key = loc_db.get_or_create_name_location(arg.name)
            return ExprLoc(loc_key, 32)
        if isinstance(arg, AstOp):
            args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
            if None in args:
                return None
            return ExprOp(arg.op, *args)
        if isinstance(arg, AstInt):
            return ExprInt(arg.value, 32)
        if isinstance(arg, AstMem):
            ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
            if ptr is None:
                return None
            return ExprMem(ptr, arg.size)
        return None

Ancestors (in MRO)

  • arm_arg
  • miasm2.core.cpu.m_arg
  • __builtin__.object

Methods

def asm_ast_to_expr(

self, arg, loc_db)

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def fromstring(

self, text, loc_db, parser_result=None)

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_cpreg

class arm_cpreg(arm_reg):
    reg_info = cp_regs
    parser = reg_info.parser

Ancestors (in MRO)

Class variables

var parser

Inheritance: arm_reg.parser

var reg_info

Inheritance: arm_reg.reg_info

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_reg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def check_fbits(

self, v)

Inheritance: arm_reg.check_fbits

def check_fbits(self, v):
    return v & self.fmask == self.fbits

def decode(

self, v)

Inheritance: arm_reg.decode

def decode(self, v):
    v = v & self.lmask
    if v >= len(self.reg_info.expr):
        return False
    self.expr = self.reg_info.expr[v]
    return True

def encode(

self)

Inheritance: arm_reg.encode

def encode(self):
    if not self.expr in self.reg_info.expr:
        log.debug("cannot encode reg %r", self.expr)
        return False
    self.value = self.reg_info.expr.index(self.expr)
    if self.value > self.lmask:
        log.debug("cannot encode field value %x %x",
                  self.value, self.lmask)
        return False
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_reg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.parses_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_deref_reg_imm

class arm_deref_reg_imm(arm_arg):
    parser = deref_reg_imm

    def decode(self, v):
        v = v & self.lmask
        rbase = regs_expr[v]
        e = ExprOp('preinc', rbase, self.parent.off.expr)
        self.expr = ExprMem(e, 32)
        return True

    def encode(self):
        self.parent.off.expr = None
        e = self.expr
        if not isinstance(e, ExprMem):
            return False
        e = e.arg
        if not (isinstance(e, ExprOp) and e.op == 'preinc'):
            log.debug('cannot encode %r', e)
            return False
        off = e.args[1]
        if isinstance(off, ExprId):
            self.parent.off.expr = off
        elif isinstance(off, ExprInt):
            self.parent.off.expr = off
        else:
            log.debug('cannot encode off %r', off)
            return False
        self.value = gpregs.expr.index(e.args[0])
        if self.value >= 1 << self.l:
            log.debug('cannot encode reg %r', off)
            return False
        return True

Ancestors (in MRO)

Class variables

var parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_arg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

def decode(self, v):
    v = v & self.lmask
    rbase = regs_expr[v]
    e = ExprOp('preinc', rbase, self.parent.off.expr)
    self.expr = ExprMem(e, 32)
    return True

def encode(

self)

def encode(self):
    self.parent.off.expr = None
    e = self.expr
    if not isinstance(e, ExprMem):
        return False
    e = e.arg
    if not (isinstance(e, ExprOp) and e.op == 'preinc'):
        log.debug('cannot encode %r', e)
        return False
    off = e.args[1]
    if isinstance(off, ExprId):
        self.parent.off.expr = off
    elif isinstance(off, ExprInt):
        self.parent.off.expr = off
    else:
        log.debug('cannot encode off %r', off)
        return False
    self.value = gpregs.expr.index(e.args[0])
    if self.value >= 1 << self.l:
        log.debug('cannot encode reg %r', off)
        return False
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_arg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_derefl

class arm_derefl(arm_deref_reg_imm):
    parser = deref_low

Ancestors (in MRO)

Class variables

var parser

Inheritance: arm_deref_reg_imm.parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_deref_reg_imm.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

Inheritance: arm_deref_reg_imm.decode

def decode(self, v):
    v = v & self.lmask
    rbase = regs_expr[v]
    e = ExprOp('preinc', rbase, self.parent.off.expr)
    self.expr = ExprMem(e, 32)
    return True

def encode(

self)

Inheritance: arm_deref_reg_imm.encode

def encode(self):
    self.parent.off.expr = None
    e = self.expr
    if not isinstance(e, ExprMem):
        return False
    e = e.arg
    if not (isinstance(e, ExprOp) and e.op == 'preinc'):
        log.debug('cannot encode %r', e)
        return False
    off = e.args[1]
    if isinstance(off, ExprId):
        self.parent.off.expr = off
    elif isinstance(off, ExprInt):
        self.parent.off.expr = off
    else:
        log.debug('cannot encode off %r', off)
        return False
    self.value = gpregs.expr.index(e.args[0])
    if self.value >= 1 << self.l:
        log.debug('cannot encode reg %r', off)
        return False
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_deref_reg_imm.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_gpreg

class arm_gpreg(arm_reg):
    reg_info = gpregs
    parser = reg_info.parser

Ancestors (in MRO)

Class variables

var parser

Inheritance: arm_reg.parser

var reg_info

Inheritance: arm_reg.reg_info

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_reg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def check_fbits(

self, v)

Inheritance: arm_reg.check_fbits

def check_fbits(self, v):
    return v & self.fmask == self.fbits

def decode(

self, v)

Inheritance: arm_reg.decode

def decode(self, v):
    v = v & self.lmask
    if v >= len(self.reg_info.expr):
        return False
    self.expr = self.reg_info.expr[v]
    return True

def encode(

self)

Inheritance: arm_reg.encode

def encode(self):
    if not self.expr in self.reg_info.expr:
        log.debug("cannot encode reg %r", self.expr)
        return False
    self.value = self.reg_info.expr.index(self.expr)
    if self.value > self.lmask:
        log.debug("cannot encode field value %x %x",
                  self.value, self.lmask)
        return False
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_reg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.parses_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_gpreg_h

class arm_gpreg_h(arm_reg):
    reg_info = gpregs_h
    parser = reg_info.parser

Ancestors (in MRO)

Class variables

var parser

Inheritance: arm_reg.parser

var reg_info

Inheritance: arm_reg.reg_info

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_reg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def check_fbits(

self, v)

Inheritance: arm_reg.check_fbits

def check_fbits(self, v):
    return v & self.fmask == self.fbits

def decode(

self, v)

Inheritance: arm_reg.decode

def decode(self, v):
    v = v & self.lmask
    if v >= len(self.reg_info.expr):
        return False
    self.expr = self.reg_info.expr[v]
    return True

def encode(

self)

Inheritance: arm_reg.encode

def encode(self):
    if not self.expr in self.reg_info.expr:
        log.debug("cannot encode reg %r", self.expr)
        return False
    self.value = self.reg_info.expr.index(self.expr)
    if self.value > self.lmask:
        log.debug("cannot encode field value %x %x",
                  self.value, self.lmask)
        return False
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_reg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.parses_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_gpreg_l

class arm_gpreg_l(arm_reg):
    reg_info = gpregs_l
    parser = reg_info.parser

Ancestors (in MRO)

Class variables

var parser

Inheritance: arm_reg.parser

var reg_info

Inheritance: arm_reg.reg_info

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_reg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def check_fbits(

self, v)

Inheritance: arm_reg.check_fbits

def check_fbits(self, v):
    return v & self.fmask == self.fbits

def decode(

self, v)

Inheritance: arm_reg.decode

def decode(self, v):
    v = v & self.lmask
    if v >= len(self.reg_info.expr):
        return False
    self.expr = self.reg_info.expr[v]
    return True

def encode(

self)

Inheritance: arm_reg.encode

def encode(self):
    if not self.expr in self.reg_info.expr:
        log.debug("cannot encode reg %r", self.expr)
        return False
    self.value = self.reg_info.expr.index(self.expr)
    if self.value > self.lmask:
        log.debug("cannot encode field value %x %x",
                  self.value, self.lmask)
        return False
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_reg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.parses_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_gpreg_l_noarg

class arm_gpreg_l_noarg(arm_gpreg_noarg):
    reg_info = gpregs_l
    parser = reg_info.parser

Ancestors (in MRO)

Class variables

var parser

Inheritance: arm_gpreg_noarg.parser

var reg_info

Inheritance: arm_gpreg_noarg.reg_info

Methods

def check_fbits(

self, v)

Inheritance: arm_gpreg_noarg.check_fbits

def check_fbits(self, v):
    return v & self.fmask == self.fbits

def decode(

self, v)

Inheritance: arm_gpreg_noarg.decode

def decode(self, v):
    v = v & self.lmask
    if v >= len(self.reg_info.expr):
        return False
    self.expr = self.reg_info.expr[v]
    return True

def encode(

self)

Inheritance: arm_gpreg_noarg.encode

def encode(self):
    if not self.expr in self.reg_info.expr:
        log.debug("cannot encode reg %r", self.expr)
        return False
    self.value = self.reg_info.expr.index(self.expr)
    if self.value > self.lmask:
        log.debug("cannot encode field value %x %x",
                  self.value, self.lmask)
        return False
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_gpreg_noarg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.parses_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_gpreg_noarg

class arm_gpreg_noarg(reg_noarg):
    reg_info = gpregs
    parser = reg_info.parser

Ancestors (in MRO)

Class variables

var parser

var reg_info

Methods

def check_fbits(

self, v)

def check_fbits(self, v):
    return v & self.fmask == self.fbits

def decode(

self, v)

def decode(self, v):
    v = v & self.lmask
    if v >= len(self.reg_info.expr):
        return False
    self.expr = self.reg_info.expr[v]
    return True

def encode(

self)

def encode(self):
    if not self.expr in self.reg_info.expr:
        log.debug("cannot encode reg %r", self.expr)
        return False
    self.value = self.reg_info.expr.index(self.expr)
    if self.value > self.lmask:
        log.debug("cannot encode field value %x %x",
                  self.value, self.lmask)
        return False
    return True

def fromstring(

self, text, loc_db, parser_result=None)

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.parses_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_gpreg_nopc

class arm_gpreg_nopc(reg_noarg):
    reg_info = gpregs_nopc
    parser = reg_info.parser


    def decode(self, v):
        ret = super(arm_gpreg_nopc, self).decode(v)
        if ret is False:
            return False
        if self.expr == reg_dum:
            return False
        return True

Ancestors (in MRO)

Class variables

var parser

var reg_info

Methods

def check_fbits(

self, v)

def check_fbits(self, v):
    return v & self.fmask == self.fbits

def decode(

self, v)

def decode(self, v):
    ret = super(arm_gpreg_nopc, self).decode(v)
    if ret is False:
        return False
    if self.expr == reg_dum:
        return False
    return True

def encode(

self)

def encode(self):
    if not self.expr in self.reg_info.expr:
        log.debug("cannot encode reg %r", self.expr)
        return False
    self.value = self.reg_info.expr.index(self.expr)
    if self.value > self.lmask:
        log.debug("cannot encode field value %x %x",
                  self.value, self.lmask)
        return False
    return True

def fromstring(

self, text, loc_db, parser_result=None)

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.parses_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_gpreg_nosp

class arm_gpreg_nosp(reg_noarg):
    reg_info = gpregs_nosp
    parser = reg_info.parser

    def decode(self, v):
        ret = super(arm_gpreg_nosp, self).decode(v)
        if ret is False:
            return False
        if self.expr == reg_dum:
            return False
        return True

Ancestors (in MRO)

Class variables

var parser

var reg_info

Methods

def check_fbits(

self, v)

def check_fbits(self, v):
    return v & self.fmask == self.fbits

def decode(

self, v)

def decode(self, v):
    ret = super(arm_gpreg_nosp, self).decode(v)
    if ret is False:
        return False
    if self.expr == reg_dum:
        return False
    return True

def encode(

self)

def encode(self):
    if not self.expr in self.reg_info.expr:
        log.debug("cannot encode reg %r", self.expr)
        return False
    self.value = self.reg_info.expr.index(self.expr)
    if self.value > self.lmask:
        log.debug("cannot encode field value %x %x",
                  self.value, self.lmask)
        return False
    return True

def fromstring(

self, text, loc_db, parser_result=None)

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.parses_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_gpreg_nosppc

class arm_gpreg_nosppc(arm_reg):
    reg_info = gpregs_nosppc
    parser = reg_info.parser

    def decode(self, v):
        ret = super(arm_gpreg_nosppc, self).decode(v)
        if ret is False:
            return False
        if self.expr == reg_dum:
            return False
        return True

Ancestors (in MRO)

Class variables

var parser

Inheritance: arm_reg.parser

var reg_info

Inheritance: arm_reg.reg_info

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_reg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def check_fbits(

self, v)

Inheritance: arm_reg.check_fbits

def check_fbits(self, v):
    return v & self.fmask == self.fbits

def decode(

self, v)

Inheritance: arm_reg.decode

def decode(self, v):
    ret = super(arm_gpreg_nosppc, self).decode(v)
    if ret is False:
        return False
    if self.expr == reg_dum:
        return False
    return True

def encode(

self)

Inheritance: arm_reg.encode

def encode(self):
    if not self.expr in self.reg_info.expr:
        log.debug("cannot encode reg %r", self.expr)
        return False
    self.value = self.reg_info.expr.index(self.expr)
    if self.value > self.lmask:
        log.debug("cannot encode field value %x %x",
                  self.value, self.lmask)
        return False
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_reg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.parses_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_imm

class arm_imm(imm_noarg, arm_arg):
    parser = base_expr

Ancestors (in MRO)

  • arm_imm
  • miasm2.core.cpu.imm_noarg
  • arm_arg
  • miasm2.core.cpu.m_arg
  • __builtin__.object

Class variables

var intmask

var intsize

var parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_arg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

def decode(self, v):
    v = v & self.lmask
    v = self.decodeval(v)
    e = self.int2expr(v)
    if not e:
        return False
    self.expr = e
    return True

def decodeval(

self, v)

def decodeval(self, v):
    return v

def encode(

self)

def encode(self):
    v = self.expr2int(self.expr)
    if v is None:
        return False
    v = self.encodeval(v)
    if v is False:
        return False
    if v > self.lmask:
        return False
    self.value = v
    return True

def encodeval(

self, v)

def encodeval(self, v):
    if v > self.lmask:
        return False
    return v

def expr2int(

self, e)

def expr2int(self, e):
    if not isinstance(e, m2_expr.ExprInt):
        return None
    v = int(e)
    if v & ~self.intmask != 0:
        return None
    return v

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_arg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
    else:
        try:
            e, start, stop = self.parser.scanString(text).next()
        except StopIteration:
            return None, None
    if e == [None]:
        return None, None
    assert(isinstance(e, m2_expr.Expr))
    if isinstance(e, tuple):
        self.expr = self.int2expr(e[1])
    elif isinstance(e, m2_expr.Expr):
        self.expr = e
    else:
        raise TypeError('zarb expr')
    if self.expr is None:
        log.debug('cannot fromstring int %r', text)
        return None, None
    return start, stop

def int2expr(

self, v)

def int2expr(self, v):
    if (v & ~self.intmask) != 0:
        return None
    return m2_expr.ExprInt(v, self.intsize)

class arm_imm8_12

class arm_imm8_12(arm_arg):
    parser = deref

    def decode(self, v):
        v = v & self.lmask
        if self.parent.updown.value:
            e = ExprInt(v << 2, 32)
        else:
            e = ExprInt(-v << 2, 32)
        if self.parent.ppi.value:
            e = ExprOp('preinc', self.parent.rn.expr, e)
        else:
            e = ExprOp('postinc', self.parent.rn.expr, e)
        if self.parent.wback.value == 1:
            e = ExprOp('wback', e)
        self.expr = ExprMem(e, 32)
        return True

    def encode(self):
        self.parent.updown.value = 1
        e = self.expr
        if not isinstance(e, ExprMem):
            return False
        e = e.arg
        if isinstance(e, ExprOp) and e.op == 'wback':
            self.parent.wback.value = 1
            e = e.args[0]
        else:
            self.parent.wback.value = 0
        if e.op == "postinc":
            self.parent.ppi.value = 0
        elif e.op == "preinc":
            self.parent.ppi.value = 1
        else:
            # XXX default
            self.parent.ppi.value = 1
        self.parent.rn.expr = e.args[0]
        if len(e.args) == 1:
            self.value = 0
            return True
        e = e.args[1]
        if not isinstance(e, ExprInt):
            log.debug('should be int %r', e)
            return False
        v = int(e)
        if v < 0 or v & (1 << 31):
            self.parent.updown.value = 0
            v = -v & 0xFFFFFFFF
        if v & 0x3:
            log.debug('arg should be 4 aligned')
            return False
        v >>= 2
        self.value = v
        return True

Ancestors (in MRO)

Class variables

var parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_arg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

def decode(self, v):
    v = v & self.lmask
    if self.parent.updown.value:
        e = ExprInt(v << 2, 32)
    else:
        e = ExprInt(-v << 2, 32)
    if self.parent.ppi.value:
        e = ExprOp('preinc', self.parent.rn.expr, e)
    else:
        e = ExprOp('postinc', self.parent.rn.expr, e)
    if self.parent.wback.value == 1:
        e = ExprOp('wback', e)
    self.expr = ExprMem(e, 32)
    return True

def encode(

self)

def encode(self):
    self.parent.updown.value = 1
    e = self.expr
    if not isinstance(e, ExprMem):
        return False
    e = e.arg
    if isinstance(e, ExprOp) and e.op == 'wback':
        self.parent.wback.value = 1
        e = e.args[0]
    else:
        self.parent.wback.value = 0
    if e.op == "postinc":
        self.parent.ppi.value = 0
    elif e.op == "preinc":
        self.parent.ppi.value = 1
    else:
        # XXX default
        self.parent.ppi.value = 1
    self.parent.rn.expr = e.args[0]
    if len(e.args) == 1:
        self.value = 0
        return True
    e = e.args[1]
    if not isinstance(e, ExprInt):
        log.debug('should be int %r', e)
        return False
    v = int(e)
    if v < 0 or v & (1 << 31):
        self.parent.updown.value = 0
        v = -v & 0xFFFFFFFF
    if v & 0x3:
        log.debug('arg should be 4 aligned')
        return False
    v >>= 2
    self.value = v
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_arg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_imm_12_4

class arm_imm_12_4(arm_arg):
    parser = base_expr

    def decode(self, v):
        v = v & self.lmask
        imm =  (self.parent.imm.value << 4) | v
        self.expr = ExprInt(imm, 32)
        return True

    def encode(self):
        if not isinstance(self.expr, ExprInt):
            return False
        v = int(self.expr)
        if v > 0xffff:
            return False
        self.parent.imm.value = (v >> 4) & 0xfff
        self.value = v & 0xf
        return True

Ancestors (in MRO)

Class variables

var parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_arg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

def decode(self, v):
    v = v & self.lmask
    imm =  (self.parent.imm.value << 4) | v
    self.expr = ExprInt(imm, 32)
    return True

def encode(

self)

def encode(self):
    if not isinstance(self.expr, ExprInt):
        return False
    v = int(self.expr)
    if v > 0xffff:
        return False
    self.parent.imm.value = (v >> 4) & 0xfff
    self.value = v & 0xf
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_arg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_imm_4_12

class arm_imm_4_12(arm_arg):
    parser = reg_or_base

    def decode(self, v):
        v = v & self.lmask
        imm = (self.parent.imm4.value << 12) | v
        self.expr = ExprInt(imm, 32)
        return True

    def encode(self):
        if not isinstance(self.expr, ExprInt):
            return False
        v = int(self.expr)
        if v > 0xffff:
            return False
        self.parent.imm4.value = v >> 12
        self.value = v & 0xfff
        return True

Ancestors (in MRO)

Class variables

var parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_arg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

def decode(self, v):
    v = v & self.lmask
    imm = (self.parent.imm4.value << 12) | v
    self.expr = ExprInt(imm, 32)
    return True

def encode(

self)

def encode(self):
    if not isinstance(self.expr, ExprInt):
        return False
    v = int(self.expr)
    if v > 0xffff:
        return False
    self.parent.imm4.value = v >> 12
    self.value = v & 0xfff
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_arg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_immed

class arm_immed(arm_arg):
    parser = deref

    def decode(self, v):
        if self.parent.immop.value == 1:
            imm = ExprInt((self.parent.immedH.value << 4) | v, 32)
        else:
            imm = gpregs.expr[v]
        if self.parent.updown.value == 0:
            imm = -imm
        if self.parent.ppi.value:
            e = ExprOp('preinc', self.parent.rn.expr, imm)
        else:
            e = ExprOp('postinc', self.parent.rn.expr, imm)
        if self.parent.wback.value == 1:
            e = ExprOp('wback', e)
        self.expr = ExprMem(e, 32)

        return True

    def encode(self):
        self.parent.immop.value = 1
        self.parent.updown.value = 1
        e = self.expr
        if not isinstance(e, ExprMem):
            return False
        e = e.arg
        if isinstance(e, ExprOp) and e.op == 'wback':
            self.parent.wback.value = 1
            e = e.args[0]
        else:
            self.parent.wback.value = 0
        if e.op == "postinc":
            self.parent.ppi.value = 0
        elif e.op == "preinc":
            self.parent.ppi.value = 1
        else:
            # XXX default
            self.parent.ppi.value = 1
        self.parent.rn.expr = e.args[0]
        if len(e.args) == 1:
            self.value = 0
            self.parent.immedH.value = 0
            return True
        e = e.args[1]
        if isinstance(e, ExprInt):
            v = int(e)
            if v < 0 or v & (1 << 31):
                self.parent.updown.value = 0
                v = (-v) & 0xFFFFFFFF
            if v > 0xff:
                log.debug('cannot encode imm XXX')
                return False
            self.value = v & 0xF
            self.parent.immedH.value = v >> 4
            return True

        self.parent.immop.value = 0
        if isinstance(e, ExprOp) and len(e.args) == 1 and e.op == "-":
            self.parent.updown.value = 0
            e = e.args[0]
        if e in gpregs.expr:
            self.value = gpregs.expr.index(e)
            self.parent.immedH.value = 0x0
            return True
        else:
            raise ValueError('e should be int: %r' % e)

Ancestors (in MRO)

Class variables

var parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_arg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

def decode(self, v):
    if self.parent.immop.value == 1:
        imm = ExprInt((self.parent.immedH.value << 4) | v, 32)
    else:
        imm = gpregs.expr[v]
    if self.parent.updown.value == 0:
        imm = -imm
    if self.parent.ppi.value:
        e = ExprOp('preinc', self.parent.rn.expr, imm)
    else:
        e = ExprOp('postinc', self.parent.rn.expr, imm)
    if self.parent.wback.value == 1:
        e = ExprOp('wback', e)
    self.expr = ExprMem(e, 32)
    return True

def encode(

self)

def encode(self):
    self.parent.immop.value = 1
    self.parent.updown.value = 1
    e = self.expr
    if not isinstance(e, ExprMem):
        return False
    e = e.arg
    if isinstance(e, ExprOp) and e.op == 'wback':
        self.parent.wback.value = 1
        e = e.args[0]
    else:
        self.parent.wback.value = 0
    if e.op == "postinc":
        self.parent.ppi.value = 0
    elif e.op == "preinc":
        self.parent.ppi.value = 1
    else:
        # XXX default
        self.parent.ppi.value = 1
    self.parent.rn.expr = e.args[0]
    if len(e.args) == 1:
        self.value = 0
        self.parent.immedH.value = 0
        return True
    e = e.args[1]
    if isinstance(e, ExprInt):
        v = int(e)
        if v < 0 or v & (1 << 31):
            self.parent.updown.value = 0
            v = (-v) & 0xFFFFFFFF
        if v > 0xff:
            log.debug('cannot encode imm XXX')
            return False
        self.value = v & 0xF
        self.parent.immedH.value = v >> 4
        return True
    self.parent.immop.value = 0
    if isinstance(e, ExprOp) and len(e.args) == 1 and e.op == "-":
        self.parent.updown.value = 0
        e = e.args[0]
    if e in gpregs.expr:
        self.value = gpregs.expr.index(e)
        self.parent.immedH.value = 0x0
        return True
    else:
        raise ValueError('e should be int: %r' % e)

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_arg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_mem_rn_imm

class arm_mem_rn_imm(arm_arg):
    parser = deref
    def decode(self, v):
        value = self.parent.imm.value
        if self.parent.rw.value == 0:
            value = -value
        imm = ExprInt(value, 32)
        reg = gpregs.expr[v]
        if value:
            expr = ExprMem(reg + imm, 32)
        else:
            expr = ExprMem(reg, 32)
        self.expr = expr
        return True

    def encode(self):
        self.parent.add_imm.value = 1
        self.parent.imm.value = 0
        expr = self.expr
        if not isinstance(expr, ExprMem):
            return False
        ptr = expr.arg
        if ptr in gpregs.expr:
            self.value = gpregs.expr.index(ptr)
        elif (isinstance(ptr, ExprOp) and
              len(ptr.args) == 2 and
              ptr.op == 'preinc'):
            reg, imm = ptr.args
            if not reg in gpregs.expr:
                return False
            self.value = gpregs.expr.index(reg)
            if not isinstance(imm, ExprInt):
                return False
            value = int(imm)
            if value & 0x80000000:
                value = -value
                self.parent.add_imm.value = 0
            self.parent.imm.value = value
        else:
            return False
        return True

Ancestors (in MRO)

Class variables

var parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_arg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

def decode(self, v):
    value = self.parent.imm.value
    if self.parent.rw.value == 0:
        value = -value
    imm = ExprInt(value, 32)
    reg = gpregs.expr[v]
    if value:
        expr = ExprMem(reg + imm, 32)
    else:
        expr = ExprMem(reg, 32)
    self.expr = expr
    return True

def encode(

self)

def encode(self):
    self.parent.add_imm.value = 1
    self.parent.imm.value = 0
    expr = self.expr
    if not isinstance(expr, ExprMem):
        return False
    ptr = expr.arg
    if ptr in gpregs.expr:
        self.value = gpregs.expr.index(ptr)
    elif (isinstance(ptr, ExprOp) and
          len(ptr.args) == 2 and
          ptr.op == 'preinc'):
        reg, imm = ptr.args
        if not reg in gpregs.expr:
            return False
        self.value = gpregs.expr.index(reg)
        if not isinstance(imm, ExprInt):
            return False
        value = int(imm)
        if value & 0x80000000:
            value = -value
            self.parent.add_imm.value = 0
        self.parent.imm.value = value
    else:
        return False
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_arg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_off

class arm_off(imm_noarg):

    def decode(self, v):
        v = v & self.lmask
        self.expr = ExprInt(v, 32)
        return True

    def encode(self):
        if not isinstance(self.expr, ExprInt):
            return False
        v = int(self.expr)
        if v > self.lmask:
            return False
        self.value = v
        return True

Ancestors (in MRO)

  • arm_off
  • miasm2.core.cpu.imm_noarg
  • __builtin__.object

Class variables

var intmask

var intsize

Methods

def decode(

self, v)

def decode(self, v):
    v = v & self.lmask
    self.expr = ExprInt(v, 32)
    return True

def decodeval(

self, v)

def decodeval(self, v):
    return v

def encode(

self)

def encode(self):
    if not isinstance(self.expr, ExprInt):
        return False
    v = int(self.expr)
    if v > self.lmask:
        return False
    self.value = v
    return True

def encodeval(

self, v)

def encodeval(self, v):
    if v > self.lmask:
        return False
    return v

def expr2int(

self, e)

def expr2int(self, e):
    if not isinstance(e, m2_expr.ExprInt):
        return None
    v = int(e)
    if v & ~self.intmask != 0:
        return None
    return v

def fromstring(

self, text, loc_db, parser_result=None)

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
    else:
        try:
            e, start, stop = self.parser.scanString(text).next()
        except StopIteration:
            return None, None
    if e == [None]:
        return None, None
    assert(isinstance(e, m2_expr.Expr))
    if isinstance(e, tuple):
        self.expr = self.int2expr(e[1])
    elif isinstance(e, m2_expr.Expr):
        self.expr = e
    else:
        raise TypeError('zarb expr')
    if self.expr is None:
        log.debug('cannot fromstring int %r', text)
        return None, None
    return start, stop

def int2expr(

self, v)

def int2expr(self, v):
    if (v & ~self.intmask) != 0:
        return None
    return m2_expr.ExprInt(v, self.intsize)

class arm_off7

class arm_off7(arm_imm):

    def decodeval(self, v):
        return v << 2

    def encodeval(self, v):
        return v >> 2

Ancestors (in MRO)

Class variables

var intmask

Inheritance: arm_imm.intmask

var intsize

Inheritance: arm_imm.intsize

var parser

Inheritance: arm_imm.parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_imm.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

Inheritance: arm_imm.decode

def decode(self, v):
    v = v & self.lmask
    v = self.decodeval(v)
    e = self.int2expr(v)
    if not e:
        return False
    self.expr = e
    return True

def decodeval(

self, v)

Inheritance: arm_imm.decodeval

def decodeval(self, v):
    return v << 2

def encode(

self)

Inheritance: arm_imm.encode

def encode(self):
    v = self.expr2int(self.expr)
    if v is None:
        return False
    v = self.encodeval(v)
    if v is False:
        return False
    if v > self.lmask:
        return False
    self.value = v
    return True

def encodeval(

self, v)

Inheritance: arm_imm.encodeval

def encodeval(self, v):
    return v >> 2

def expr2int(

self, e)

Inheritance: arm_imm.expr2int

def expr2int(self, e):
    if not isinstance(e, m2_expr.ExprInt):
        return None
    v = int(e)
    if v & ~self.intmask != 0:
        return None
    return v

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_imm.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
    else:
        try:
            e, start, stop = self.parser.scanString(text).next()
        except StopIteration:
            return None, None
    if e == [None]:
        return None, None
    assert(isinstance(e, m2_expr.Expr))
    if isinstance(e, tuple):
        self.expr = self.int2expr(e[1])
    elif isinstance(e, m2_expr.Expr):
        self.expr = e
    else:
        raise TypeError('zarb expr')
    if self.expr is None:
        log.debug('cannot fromstring int %r', text)
        return None, None
    return start, stop

def int2expr(

self, v)

Inheritance: arm_imm.int2expr

def int2expr(self, v):
    if (v & ~self.intmask) != 0:
        return None
    return m2_expr.ExprInt(v, self.intsize)

class arm_off8sppc

class arm_off8sppc(arm_imm):

    def decodeval(self, v):
        return v << 2

    def encodeval(self, v):
        return v >> 2

Ancestors (in MRO)

Class variables

var intmask

Inheritance: arm_imm.intmask

var intsize

Inheritance: arm_imm.intsize

var parser

Inheritance: arm_imm.parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_imm.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

Inheritance: arm_imm.decode

def decode(self, v):
    v = v & self.lmask
    v = self.decodeval(v)
    e = self.int2expr(v)
    if not e:
        return False
    self.expr = e
    return True

def decodeval(

self, v)

Inheritance: arm_imm.decodeval

def decodeval(self, v):
    return v << 2

def encode(

self)

Inheritance: arm_imm.encode

def encode(self):
    v = self.expr2int(self.expr)
    if v is None:
        return False
    v = self.encodeval(v)
    if v is False:
        return False
    if v > self.lmask:
        return False
    self.value = v
    return True

def encodeval(

self, v)

Inheritance: arm_imm.encodeval

def encodeval(self, v):
    return v >> 2

def expr2int(

self, e)

Inheritance: arm_imm.expr2int

def expr2int(self, e):
    if not isinstance(e, m2_expr.ExprInt):
        return None
    v = int(e)
    if v & ~self.intmask != 0:
        return None
    return v

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_imm.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
    else:
        try:
            e, start, stop = self.parser.scanString(text).next()
        except StopIteration:
            return None, None
    if e == [None]:
        return None, None
    assert(isinstance(e, m2_expr.Expr))
    if isinstance(e, tuple):
        self.expr = self.int2expr(e[1])
    elif isinstance(e, m2_expr.Expr):
        self.expr = e
    else:
        raise TypeError('zarb expr')
    if self.expr is None:
        log.debug('cannot fromstring int %r', text)
        return None, None
    return start, stop

def int2expr(

self, v)

Inheritance: arm_imm.int2expr

def int2expr(self, v):
    if (v & ~self.intmask) != 0:
        return None
    return m2_expr.ExprInt(v, self.intsize)

class arm_offbw

class arm_offbw(imm_noarg):

    def decode(self, v):
        v = v & self.lmask
        if self.parent.trb.value == 0:
            v <<= 2
        self.expr = ExprInt(v, 32)
        return True

    def encode(self):
        if not isinstance(self.expr, ExprInt):
            return False
        v = int(self.expr)
        if self.parent.trb.value == 0:
            if v & 3:
                log.debug('off must be aligned %r', v)
                return False
            v >>= 2
        if v > self.lmask:
            return False
        self.value = v
        return True

Ancestors (in MRO)

  • arm_offbw
  • miasm2.core.cpu.imm_noarg
  • __builtin__.object

Class variables

var intmask

var intsize

Methods

def decode(

self, v)

def decode(self, v):
    v = v & self.lmask
    if self.parent.trb.value == 0:
        v <<= 2
    self.expr = ExprInt(v, 32)
    return True

def decodeval(

self, v)

def decodeval(self, v):
    return v

def encode(

self)

def encode(self):
    if not isinstance(self.expr, ExprInt):
        return False
    v = int(self.expr)
    if self.parent.trb.value == 0:
        if v & 3:
            log.debug('off must be aligned %r', v)
            return False
        v >>= 2
    if v > self.lmask:
        return False
    self.value = v
    return True

def encodeval(

self, v)

def encodeval(self, v):
    if v > self.lmask:
        return False
    return v

def expr2int(

self, e)

def expr2int(self, e):
    if not isinstance(e, m2_expr.ExprInt):
        return None
    v = int(e)
    if v & ~self.intmask != 0:
        return None
    return v

def fromstring(

self, text, loc_db, parser_result=None)

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
    else:
        try:
            e, start, stop = self.parser.scanString(text).next()
        except StopIteration:
            return None, None
    if e == [None]:
        return None, None
    assert(isinstance(e, m2_expr.Expr))
    if isinstance(e, tuple):
        self.expr = self.int2expr(e[1])
    elif isinstance(e, m2_expr.Expr):
        self.expr = e
    else:
        raise TypeError('zarb expr')
    if self.expr is None:
        log.debug('cannot fromstring int %r', text)
        return None, None
    return start, stop

def int2expr(

self, v)

def int2expr(self, v):
    if (v & ~self.intmask) != 0:
        return None
    return m2_expr.ExprInt(v, self.intsize)

class arm_offh

class arm_offh(imm_noarg):

    def decode(self, v):
        v = v & self.lmask
        v <<= 1
        self.expr = ExprInt(v, 32)
        return True

    def encode(self):
        if not isinstance(self.expr, ExprInt):
            return False
        v = int(self.expr)
        if v & 1:
            log.debug('off must be aligned %r', v)
            return False
        v >>= 1
        if v > self.lmask:
            return False
        self.value = v
        return True

Ancestors (in MRO)

  • arm_offh
  • miasm2.core.cpu.imm_noarg
  • __builtin__.object

Class variables

var intmask

var intsize

Methods

def decode(

self, v)

def decode(self, v):
    v = v & self.lmask
    v <<= 1
    self.expr = ExprInt(v, 32)
    return True

def decodeval(

self, v)

def decodeval(self, v):
    return v

def encode(

self)

def encode(self):
    if not isinstance(self.expr, ExprInt):
        return False
    v = int(self.expr)
    if v & 1:
        log.debug('off must be aligned %r', v)
        return False
    v >>= 1
    if v > self.lmask:
        return False
    self.value = v
    return True

def encodeval(

self, v)

def encodeval(self, v):
    if v > self.lmask:
        return False
    return v

def expr2int(

self, e)

def expr2int(self, e):
    if not isinstance(e, m2_expr.ExprInt):
        return None
    v = int(e)
    if v & ~self.intmask != 0:
        return None
    return v

def fromstring(

self, text, loc_db, parser_result=None)

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
    else:
        try:
            e, start, stop = self.parser.scanString(text).next()
        except StopIteration:
            return None, None
    if e == [None]:
        return None, None
    assert(isinstance(e, m2_expr.Expr))
    if isinstance(e, tuple):
        self.expr = self.int2expr(e[1])
    elif isinstance(e, m2_expr.Expr):
        self.expr = e
    else:
        raise TypeError('zarb expr')
    if self.expr is None:
        log.debug('cannot fromstring int %r', text)
        return None, None
    return start, stop

def int2expr(

self, v)

def int2expr(self, v):
    if (v & ~self.intmask) != 0:
        return None
    return m2_expr.ExprInt(v, self.intsize)

class arm_offpc

class arm_offpc(arm_offreg):
    off_reg = regs_expr[15]

    def decode(self, v):
        v = v & self.lmask
        v <<= 2
        if v:
            self.expr = ExprMem(self.off_reg + ExprInt(v, 32), 32)
        else:
            self.expr = ExprMem(self.off_reg, 32)

        e = self.expr.arg
        if isinstance(e, ExprOp) and e.op == 'wback':
            self.parent.wback.value = 1
            e = e.args[0]
        return True

    def encode(self):
        e = self.expr
        if not isinstance(e, ExprMem):
            return False
        e = e.arg
        if not (isinstance(e, ExprOp) and e.op == "preinc"):
            log.debug('cannot encode %r', e)
            return False
        if e.args[0] != self.off_reg:
            log.debug('cannot encode reg %r', e.args[0])
            return False
        v = int(e.args[1])
        if v & 3:
            return False
        v >>= 2
        if v > self.lmask:
            return False
        self.value = v
        return True

Ancestors (in MRO)

Class variables

var off_reg

var parser

Inheritance: arm_offreg.parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_offreg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

Inheritance: arm_offreg.decode

def decode(self, v):
    v = v & self.lmask
    v <<= 2
    if v:
        self.expr = ExprMem(self.off_reg + ExprInt(v, 32), 32)
    else:
        self.expr = ExprMem(self.off_reg, 32)
    e = self.expr.arg
    if isinstance(e, ExprOp) and e.op == 'wback':
        self.parent.wback.value = 1
        e = e.args[0]
    return True

def decodeval(

self, v)

Inheritance: arm_offreg.decodeval

def decodeval(self, v):
    return v

def encode(

self)

Inheritance: arm_offreg.encode

def encode(self):
    e = self.expr
    if not isinstance(e, ExprMem):
        return False
    e = e.arg
    if not (isinstance(e, ExprOp) and e.op == "preinc"):
        log.debug('cannot encode %r', e)
        return False
    if e.args[0] != self.off_reg:
        log.debug('cannot encode reg %r', e.args[0])
        return False
    v = int(e.args[1])
    if v & 3:
        return False
    v >>= 2
    if v > self.lmask:
        return False
    self.value = v
    return True

def encodeval(

self, v)

Inheritance: arm_offreg.encodeval

def encodeval(self, v):
    return v

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_offreg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_offreg

class arm_offreg(arm_arg):
    parser = deref_pc

    def decodeval(self, v):
        return v

    def encodeval(self, v):
        return v

    def decode(self, v):
        v = v & self.lmask
        v = self.decodeval(v)
        if v:
            self.expr = self.off_reg + ExprInt(v, 32)
        else:
            self.expr = self.off_reg

        e = self.expr
        if isinstance(e, ExprOp) and e.op == 'wback':
            self.parent.wback.value = 1
            e = e.args[0]
        return True

    def encode(self):
        e = self.expr
        if not (isinstance(e, ExprOp) and e.op == "preinc"):
            log.debug('cannot encode %r', e)
            return False
        if e.args[0] != self.off_reg:
            log.debug('cannot encode reg %r', e.args[0])
            return False
        v = int(e.args[1])
        v = self.encodeval(v)
        self.value = v
        return True

Ancestors (in MRO)

Class variables

var parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_arg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

def decode(self, v):
    v = v & self.lmask
    v = self.decodeval(v)
    if v:
        self.expr = self.off_reg + ExprInt(v, 32)
    else:
        self.expr = self.off_reg
    e = self.expr
    if isinstance(e, ExprOp) and e.op == 'wback':
        self.parent.wback.value = 1
        e = e.args[0]
    return True

def decodeval(

self, v)

def decodeval(self, v):
    return v

def encode(

self)

def encode(self):
    e = self.expr
    if not (isinstance(e, ExprOp) and e.op == "preinc"):
        log.debug('cannot encode %r', e)
        return False
    if e.args[0] != self.off_reg:
        log.debug('cannot encode reg %r', e.args[0])
        return False
    v = int(e.args[1])
    v = self.encodeval(v)
    self.value = v
    return True

def encodeval(

self, v)

def encodeval(self, v):
    return v

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_arg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_offs

class arm_offs(arm_imm):
    parser = base_expr

    def int2expr(self, v):
        if v & ~self.intmask != 0:
            return None
        return ExprInt(v, self.intsize)

    def decodeval(self, v):
        v <<= 2
        # Add pipeline offset
        v += 8
        return v

    def encodeval(self, v):
        if v%4 != 0:
            return False
        # Remove pipeline offset
        v -= 8
        return v >> 2

    def decode(self, v):
        v = v & self.lmask
        if (1 << (self.l - 1)) & v:
            v |= ~0 ^ self.lmask
        v = self.decodeval(v)
        self.expr = ExprInt(v, 32)
        return True

    def encode(self):
        if not isinstance(self.expr, ExprInt):
            return False
        v = int(self.expr)
        if (1 << (self.l - 1)) & v:
            v = -((0xffffffff ^ v) + 1)
        v = self.encodeval(v)
        if v is False:
            return False
        self.value = (v & 0xffffffff) & self.lmask
        return True

Ancestors (in MRO)

Class variables

var intmask

Inheritance: arm_imm.intmask

var intsize

Inheritance: arm_imm.intsize

var parser

Inheritance: arm_imm.parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_imm.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

Inheritance: arm_imm.decode

def decode(self, v):
    v = v & self.lmask
    if (1 << (self.l - 1)) & v:
        v |= ~0 ^ self.lmask
    v = self.decodeval(v)
    self.expr = ExprInt(v, 32)
    return True

def decodeval(

self, v)

Inheritance: arm_imm.decodeval

def decodeval(self, v):
    v <<= 2
    # Add pipeline offset
    v += 8
    return v

def encode(

self)

Inheritance: arm_imm.encode

def encode(self):
    if not isinstance(self.expr, ExprInt):
        return False
    v = int(self.expr)
    if (1 << (self.l - 1)) & v:
        v = -((0xffffffff ^ v) + 1)
    v = self.encodeval(v)
    if v is False:
        return False
    self.value = (v & 0xffffffff) & self.lmask
    return True

def encodeval(

self, v)

Inheritance: arm_imm.encodeval

def encodeval(self, v):
    if v%4 != 0:
        return False
    # Remove pipeline offset
    v -= 8
    return v >> 2

def expr2int(

self, e)

Inheritance: arm_imm.expr2int

def expr2int(self, e):
    if not isinstance(e, m2_expr.ExprInt):
        return None
    v = int(e)
    if v & ~self.intmask != 0:
        return None
    return v

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_imm.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
    else:
        try:
            e, start, stop = self.parser.scanString(text).next()
        except StopIteration:
            return None, None
    if e == [None]:
        return None, None
    assert(isinstance(e, m2_expr.Expr))
    if isinstance(e, tuple):
        self.expr = self.int2expr(e[1])
    elif isinstance(e, m2_expr.Expr):
        self.expr = e
    else:
        raise TypeError('zarb expr')
    if self.expr is None:
        log.debug('cannot fromstring int %r', text)
        return None, None
    return start, stop

def int2expr(

self, v)

Inheritance: arm_imm.int2expr

def int2expr(self, v):
    if v & ~self.intmask != 0:
        return None
    return ExprInt(v, self.intsize)

class arm_offs_blx

class arm_offs_blx(arm_imm):

    def decode(self, v):
        v = v & self.lmask
        v = (v << 2) + (self.parent.lowb.value << 1)
        v = sign_ext(v, 26, 32)
        # Add pipeline offset
        v += 8
        self.expr = ExprInt(v, 32)
        return True

    def encode(self):
        if not isinstance(self.expr, ExprInt):
            return False
        # Remove pipeline offset
        v = int(self.expr.arg - 8)
        if v & 0x80000000:
            v &= (1 << 26) - 1
        self.parent.lowb.value = (v >> 1) & 1
        self.value = v >> 2
        return True

Ancestors (in MRO)

Class variables

var intmask

Inheritance: arm_imm.intmask

var intsize

Inheritance: arm_imm.intsize

var parser

Inheritance: arm_imm.parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_imm.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

Inheritance: arm_imm.decode

def decode(self, v):
    v = v & self.lmask
    v = (v << 2) + (self.parent.lowb.value << 1)
    v = sign_ext(v, 26, 32)
    # Add pipeline offset
    v += 8
    self.expr = ExprInt(v, 32)
    return True

def decodeval(

self, v)

Inheritance: arm_imm.decodeval

def decodeval(self, v):
    return v

def encode(

self)

Inheritance: arm_imm.encode

def encode(self):
    if not isinstance(self.expr, ExprInt):
        return False
    # Remove pipeline offset
    v = int(self.expr.arg - 8)
    if v & 0x80000000:
        v &= (1 << 26) - 1
    self.parent.lowb.value = (v >> 1) & 1
    self.value = v >> 2
    return True

def encodeval(

self, v)

Inheritance: arm_imm.encodeval

def encodeval(self, v):
    if v > self.lmask:
        return False
    return v

def expr2int(

self, e)

Inheritance: arm_imm.expr2int

def expr2int(self, e):
    if not isinstance(e, m2_expr.ExprInt):
        return None
    v = int(e)
    if v & ~self.intmask != 0:
        return None
    return v

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_imm.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
    else:
        try:
            e, start, stop = self.parser.scanString(text).next()
        except StopIteration:
            return None, None
    if e == [None]:
        return None, None
    assert(isinstance(e, m2_expr.Expr))
    if isinstance(e, tuple):
        self.expr = self.int2expr(e[1])
    elif isinstance(e, m2_expr.Expr):
        self.expr = e
    else:
        raise TypeError('zarb expr')
    if self.expr is None:
        log.debug('cannot fromstring int %r', text)
        return None, None
    return start, stop

def int2expr(

self, v)

Inheritance: arm_imm.int2expr

def int2expr(self, v):
    if (v & ~self.intmask) != 0:
        return None
    return m2_expr.ExprInt(v, self.intsize)

class arm_offsp

class arm_offsp(arm_offpc):
    parser = deref_sp
    off_reg = regs_expr[13]

Ancestors (in MRO)

Class variables

var off_reg

Inheritance: arm_offpc.off_reg

var parser

Inheritance: arm_offpc.parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_offpc.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

Inheritance: arm_offpc.decode

def decode(self, v):
    v = v & self.lmask
    v <<= 2
    if v:
        self.expr = ExprMem(self.off_reg + ExprInt(v, 32), 32)
    else:
        self.expr = ExprMem(self.off_reg, 32)
    e = self.expr.arg
    if isinstance(e, ExprOp) and e.op == 'wback':
        self.parent.wback.value = 1
        e = e.args[0]
    return True

def decodeval(

self, v)

Inheritance: arm_offpc.decodeval

def decodeval(self, v):
    return v

def encode(

self)

Inheritance: arm_offpc.encode

def encode(self):
    e = self.expr
    if not isinstance(e, ExprMem):
        return False
    e = e.arg
    if not (isinstance(e, ExprOp) and e.op == "preinc"):
        log.debug('cannot encode %r', e)
        return False
    if e.args[0] != self.off_reg:
        log.debug('cannot encode reg %r', e.args[0])
        return False
    v = int(e.args[1])
    if v & 3:
        return False
    v >>= 2
    if v > self.lmask:
        return False
    self.value = v
    return True

def encodeval(

self, v)

Inheritance: arm_offpc.encodeval

def encodeval(self, v):
    return v

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_offpc.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_offspc

class arm_offspc(arm_offs):

    def decodeval(self, v):
        v = v << 1
        # Add pipeline offset
        v += 2 + 2
        return v

    def encodeval(self, v):
        # Remove pipeline offset
        v -= 2 + 2
        if v % 2 != 0:
            return False
        if v > (1 << (self.l - 1)) - 1:
            return False
        return v >> 1
        return False

Ancestors (in MRO)

Class variables

var intmask

Inheritance: arm_offs.intmask

var intsize

Inheritance: arm_offs.intsize

var parser

Inheritance: arm_offs.parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_offs.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

Inheritance: arm_offs.decode

def decode(self, v):
    v = v & self.lmask
    if (1 << (self.l - 1)) & v:
        v |= ~0 ^ self.lmask
    v = self.decodeval(v)
    self.expr = ExprInt(v, 32)
    return True

def decodeval(

self, v)

Inheritance: arm_offs.decodeval

def decodeval(self, v):
    v = v << 1
    # Add pipeline offset
    v += 2 + 2
    return v

def encode(

self)

Inheritance: arm_offs.encode

def encode(self):
    if not isinstance(self.expr, ExprInt):
        return False
    v = int(self.expr)
    if (1 << (self.l - 1)) & v:
        v = -((0xffffffff ^ v) + 1)
    v = self.encodeval(v)
    if v is False:
        return False
    self.value = (v & 0xffffffff) & self.lmask
    return True

def encodeval(

self, v)

Inheritance: arm_offs.encodeval

def encodeval(self, v):
    # Remove pipeline offset
    v -= 2 + 2
    if v % 2 != 0:
        return False
    if v > (1 << (self.l - 1)) - 1:
        return False
    return v >> 1
    return False

def expr2int(

self, e)

Inheritance: arm_offs.expr2int

def expr2int(self, e):
    if not isinstance(e, m2_expr.ExprInt):
        return None
    v = int(e)
    if v & ~self.intmask != 0:
        return None
    return v

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_offs.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
    else:
        try:
            e, start, stop = self.parser.scanString(text).next()
        except StopIteration:
            return None, None
    if e == [None]:
        return None, None
    assert(isinstance(e, m2_expr.Expr))
    if isinstance(e, tuple):
        self.expr = self.int2expr(e[1])
    elif isinstance(e, m2_expr.Expr):
        self.expr = e
    else:
        raise TypeError('zarb expr')
    if self.expr is None:
        log.debug('cannot fromstring int %r', text)
        return None, None
    return start, stop

def int2expr(

self, v)

Inheritance: arm_offs.int2expr

def int2expr(self, v):
    if v & ~self.intmask != 0:
        return None
    return ExprInt(v, self.intsize)

class arm_op2

class arm_op2(arm_arg):
    parser = shift_off

    def str_to_imm_rot_form(self, s, neg=False):
        if neg:
            s = -s & 0xffffffff
        for i in xrange(0, 32, 2):
            v = myrol32(s, i)
            if 0 <= v < 0x100:
                return ((i / 2) << 8) | v
        return None

    def decode(self, v):
        val = v & self.lmask
        if self.parent.immop.value:
            rot = val >> 8
            imm = val & 0xff
            imm = myror32(imm, rot * 2)
            self.expr = ExprInt(imm, 32)
            return True
        rm = val & 0xf
        shift = val >> 4
        shift_kind = shift & 1
        shift_type = (shift >> 1) & 3
        shift >>= 3
        if shift_kind:
            # shift kind is reg
            if shift & 1:
                return False
            rs = shift >> 1
            if rs == 0xf:
                return False
            shift_op = regs_expr[rs]
        else:
            # shift kind is imm
            amount = shift
            shift_op = ExprInt(amount, 32)
        a = regs_expr[rm]
        if shift_op == ExprInt(0, 32):
            if shift_type == 3:
                self.expr = ExprOp(allshifts[4], a)
            else:
                self.expr = a
        else:
            self.expr = ExprOp(allshifts[shift_type], a, shift_op)
        return True

    def encode(self):
        e = self.expr
        # pure imm
        if isinstance(e, ExprInt):
            val = self.str_to_imm_rot_form(int(e))
            if val is None:
                return False
            self.parent.immop.value = 1
            self.value = val
            return True

        self.parent.immop.value = 0
        # pure reg
        if isinstance(e, ExprId):
            rm = gpregs.expr.index(e)
            shift_kind = 0
            shift_type = 0
            amount = 0
            self.value = (
                ((((amount << 2) | shift_type) << 1) | shift_kind) << 4) | rm
            return True
        # rot reg
        if not isinstance(e, ExprOp):
            log.debug('bad reg rot1 %r', e)
            return False
        rm = gpregs.expr.index(e.args[0])
        shift_type = allshifts.index(e.op)
        if e.op == 'rrx':
            shift_kind = 0
            amount = 0
            shift_type = 3
        elif isinstance(e.args[1], ExprInt):
            shift_kind = 0
            amount = int(e.args[1])
            # LSR/ASR of 32 => 0
            if amount == 32 and e.op in ['>>', 'a>>']:
                amount = 0
        else:
            shift_kind = 1
            amount = gpregs.expr.index(e.args[1]) << 1
        self.value = (
            ((((amount << 2) | shift_type) << 1) | shift_kind) << 4) | rm
        return True

Ancestors (in MRO)

Class variables

var parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_arg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

def decode(self, v):
    val = v & self.lmask
    if self.parent.immop.value:
        rot = val >> 8
        imm = val & 0xff
        imm = myror32(imm, rot * 2)
        self.expr = ExprInt(imm, 32)
        return True
    rm = val & 0xf
    shift = val >> 4
    shift_kind = shift & 1
    shift_type = (shift >> 1) & 3
    shift >>= 3
    if shift_kind:
        # shift kind is reg
        if shift & 1:
            return False
        rs = shift >> 1
        if rs == 0xf:
            return False
        shift_op = regs_expr[rs]
    else:
        # shift kind is imm
        amount = shift
        shift_op = ExprInt(amount, 32)
    a = regs_expr[rm]
    if shift_op == ExprInt(0, 32):
        if shift_type == 3:
            self.expr = ExprOp(allshifts[4], a)
        else:
            self.expr = a
    else:
        self.expr = ExprOp(allshifts[shift_type], a, shift_op)
    return True

def encode(

self)

def encode(self):
    e = self.expr
    # pure imm
    if isinstance(e, ExprInt):
        val = self.str_to_imm_rot_form(int(e))
        if val is None:
            return False
        self.parent.immop.value = 1
        self.value = val
        return True
    self.parent.immop.value = 0
    # pure reg
    if isinstance(e, ExprId):
        rm = gpregs.expr.index(e)
        shift_kind = 0
        shift_type = 0
        amount = 0
        self.value = (
            ((((amount << 2) | shift_type) << 1) | shift_kind) << 4) | rm
        return True
    # rot reg
    if not isinstance(e, ExprOp):
        log.debug('bad reg rot1 %r', e)
        return False
    rm = gpregs.expr.index(e.args[0])
    shift_type = allshifts.index(e.op)
    if e.op == 'rrx':
        shift_kind = 0
        amount = 0
        shift_type = 3
    elif isinstance(e.args[1], ExprInt):
        shift_kind = 0
        amount = int(e.args[1])
        # LSR/ASR of 32 => 0
        if amount == 32 and e.op in ['>>', 'a>>']:
            amount = 0
    else:
        shift_kind = 1
        amount = gpregs.expr.index(e.args[1]) << 1
    self.value = (
        ((((amount << 2) | shift_type) << 1) | shift_kind) << 4) | rm
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_arg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

def str_to_imm_rot_form(

self, s, neg=False)

def str_to_imm_rot_form(self, s, neg=False):
    if neg:
        s = -s & 0xffffffff
    for i in xrange(0, 32, 2):
        v = myrol32(s, i)
        if 0 <= v < 0x100:
            return ((i / 2) << 8) | v
    return None

class arm_op2imm

class arm_op2imm(arm_imm8_12):
    parser = deref

    def str_to_imm_rot_form(self, s, neg=False):
        if neg:
            s = -s & 0xffffffff
        if 0 <= s < (1 << 12):
            return s
        return None

    def decode(self, v):
        val = v & self.lmask
        if self.parent.immop.value == 0:
            imm = val
            if self.parent.updown.value == 0:
                imm = -imm
            if self.parent.ppi.value:
                e = ExprOp('preinc', self.parent.rn.expr, ExprInt(imm, 32))
            else:
                e = ExprOp('postinc', self.parent.rn.expr, ExprInt(imm, 32))
            if self.parent.wback.value == 1:
                e = ExprOp('wback', e)
            self.expr = ExprMem(e, 32)
            return True
        rm = val & 0xf
        shift = val >> 4
        shift_kind = shift & 1
        shift_type = (shift >> 1) & 3
        shift >>= 3
        # print self.parent.immop.value, hex(shift), hex(shift_kind),
        # hex(shift_type)
        if shift_kind:
            # log.debug('error in disasm xx')
            return False
        else:
            # shift kind is imm
            amount = shift
            shift_op = ExprInt(amount, 32)
        a = regs_expr[rm]
        if shift_op == ExprInt(0, 32):
            pass
        else:
            a = ExprOp(allshifts[shift_type], a, shift_op)
        if self.parent.ppi.value:
            e = ExprOp('preinc', self.parent.rn.expr, a)
        else:
            e = ExprOp('postinc', self.parent.rn.expr, a)
        if self.parent.wback.value == 1:
            e = ExprOp('wback', e)
        self.expr = ExprMem(e, 32)
        return True

    def encode(self):
        self.parent.immop.value = 1
        self.parent.updown.value = 1

        e = self.expr
        assert(isinstance(e, ExprMem))
        e = e.arg
        if e.op == 'wback':
            self.parent.wback.value = 1
            e = e.args[0]
        else:
            self.parent.wback.value = 0
        if e.op == "postinc":
            self.parent.ppi.value = 0
        elif e.op == "preinc":
            self.parent.ppi.value = 1
        else:
            # XXX default
            self.parent.ppi.value = 1

        # if len(v) <1:
        #    raise ValueError('cannot parse', s)
        self.parent.rn.expr = e.args[0]
        if len(e.args) == 1:
            self.parent.immop.value = 0
            self.value = 0
            return True
        # pure imm
        if isinstance(e.args[1], ExprInt):
            self.parent.immop.value = 0
            val = self.str_to_imm_rot_form(int(e.args[1]))
            if val is None:
                val = self.str_to_imm_rot_form(int(e.args[1]), True)
                if val is None:
                    log.debug('cannot encode inm')
                    return False
                self.parent.updown.value = 0
            self.value = val
            return True
        # pure reg
        if isinstance(e.args[1], ExprId):
            rm = gpregs.expr.index(e.args[1])
            shift_kind = 0
            shift_type = 0
            amount = 0
            self.value = (
                ((((amount << 2) | shift_type) << 1) | shift_kind) << 4) | rm
            return True
        # rot reg
        if not isinstance(e.args[1], ExprOp):
            log.debug('bad reg rot2 %r', e)
            return False
        e = e.args[1]
        rm = gpregs.expr.index(e.args[0])
        shift_type = allshifts.index(e.op)
        if isinstance(e.args[1], ExprInt):
            shift_kind = 0
            amount = int(e.args[1])
        else:
            shift_kind = 1
            amount = gpregs.expr.index(e.args[1]) << 1
        self.value = (
            ((((amount << 2) | shift_type) << 1) | shift_kind) << 4) | rm
        return True

Ancestors (in MRO)

Class variables

var parser

Inheritance: arm_imm8_12.parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_imm8_12.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

Inheritance: arm_imm8_12.decode

def decode(self, v):
    val = v & self.lmask
    if self.parent.immop.value == 0:
        imm = val
        if self.parent.updown.value == 0:
            imm = -imm
        if self.parent.ppi.value:
            e = ExprOp('preinc', self.parent.rn.expr, ExprInt(imm, 32))
        else:
            e = ExprOp('postinc', self.parent.rn.expr, ExprInt(imm, 32))
        if self.parent.wback.value == 1:
            e = ExprOp('wback', e)
        self.expr = ExprMem(e, 32)
        return True
    rm = val & 0xf
    shift = val >> 4
    shift_kind = shift & 1
    shift_type = (shift >> 1) & 3
    shift >>= 3
    # print self.parent.immop.value, hex(shift), hex(shift_kind),
    # hex(shift_type)
    if shift_kind:
        # log.debug('error in disasm xx')
        return False
    else:
        # shift kind is imm
        amount = shift
        shift_op = ExprInt(amount, 32)
    a = regs_expr[rm]
    if shift_op == ExprInt(0, 32):
        pass
    else:
        a = ExprOp(allshifts[shift_type], a, shift_op)
    if self.parent.ppi.value:
        e = ExprOp('preinc', self.parent.rn.expr, a)
    else:
        e = ExprOp('postinc', self.parent.rn.expr, a)
    if self.parent.wback.value == 1:
        e = ExprOp('wback', e)
    self.expr = ExprMem(e, 32)
    return True

def encode(

self)

Inheritance: arm_imm8_12.encode

def encode(self):
    self.parent.immop.value = 1
    self.parent.updown.value = 1
    e = self.expr
    assert(isinstance(e, ExprMem))
    e = e.arg
    if e.op == 'wback':
        self.parent.wback.value = 1
        e = e.args[0]
    else:
        self.parent.wback.value = 0
    if e.op == "postinc":
        self.parent.ppi.value = 0
    elif e.op == "preinc":
        self.parent.ppi.value = 1
    else:
        # XXX default
        self.parent.ppi.value = 1
    # if len(v) <1:
    #    raise ValueError('cannot parse', s)
    self.parent.rn.expr = e.args[0]
    if len(e.args) == 1:
        self.parent.immop.value = 0
        self.value = 0
        return True
    # pure imm
    if isinstance(e.args[1], ExprInt):
        self.parent.immop.value = 0
        val = self.str_to_imm_rot_form(int(e.args[1]))
        if val is None:
            val = self.str_to_imm_rot_form(int(e.args[1]), True)
            if val is None:
                log.debug('cannot encode inm')
                return False
            self.parent.updown.value = 0
        self.value = val
        return True
    # pure reg
    if isinstance(e.args[1], ExprId):
        rm = gpregs.expr.index(e.args[1])
        shift_kind = 0
        shift_type = 0
        amount = 0
        self.value = (
            ((((amount << 2) | shift_type) << 1) | shift_kind) << 4) | rm
        return True
    # rot reg
    if not isinstance(e.args[1], ExprOp):
        log.debug('bad reg rot2 %r', e)
        return False
    e = e.args[1]
    rm = gpregs.expr.index(e.args[0])
    shift_type = allshifts.index(e.op)
    if isinstance(e.args[1], ExprInt):
        shift_kind = 0
        amount = int(e.args[1])
    else:
        shift_kind = 1
        amount = gpregs.expr.index(e.args[1]) << 1
    self.value = (
        ((((amount << 2) | shift_type) << 1) | shift_kind) << 4) | rm
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_imm8_12.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

def str_to_imm_rot_form(

self, s, neg=False)

def str_to_imm_rot_form(self, s, neg=False):
    if neg:
        s = -s & 0xffffffff
    if 0 <= s < (1 << 12):
        return s
    return None

class arm_preg

class arm_preg(arm_reg):
    reg_info = p_regs
    parser = reg_info.parser

Ancestors (in MRO)

Class variables

var parser

Inheritance: arm_reg.parser

var reg_info

Inheritance: arm_reg.reg_info

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_reg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def check_fbits(

self, v)

Inheritance: arm_reg.check_fbits

def check_fbits(self, v):
    return v & self.fmask == self.fbits

def decode(

self, v)

Inheritance: arm_reg.decode

def decode(self, v):
    v = v & self.lmask
    if v >= len(self.reg_info.expr):
        return False
    self.expr = self.reg_info.expr[v]
    return True

def encode(

self)

Inheritance: arm_reg.encode

def encode(self):
    if not self.expr in self.reg_info.expr:
        log.debug("cannot encode reg %r", self.expr)
        return False
    self.value = self.reg_info.expr.index(self.expr)
    if self.value > self.lmask:
        log.debug("cannot encode field value %x %x",
                  self.value, self.lmask)
        return False
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_reg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.parses_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_psr

class arm_psr(arm_arg):
    parser = psr_p

    def decode(self, v):
        v = v & self.lmask
        if self.parent.psr.value == 0:
            e = cpsr_regs.expr[v]
        else:
            e = spsr_regs.expr[v]
        self.expr = e
        return True

    def encode(self):
        e = self.expr
        if e in spsr_regs.expr:
            self.parent.psr.value = 1
            v = spsr_regs.expr.index(e)
        elif e in cpsr_regs.expr:
            self.parent.psr.value = 0
            v = cpsr_regs.expr.index(e)
        else:
            return False
        self.value = v
        return True

Ancestors (in MRO)

Class variables

var parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_arg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

def decode(self, v):
    v = v & self.lmask
    if self.parent.psr.value == 0:
        e = cpsr_regs.expr[v]
    else:
        e = spsr_regs.expr[v]
    self.expr = e
    return True

def encode(

self)

def encode(self):
    e = self.expr
    if e in spsr_regs.expr:
        self.parent.psr.value = 1
        v = spsr_regs.expr.index(e)
    elif e in cpsr_regs.expr:
        self.parent.psr.value = 0
        v = cpsr_regs.expr.index(e)
    else:
        return False
    self.value = v
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_arg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_reg

class arm_reg(reg_noarg, arm_arg):
    pass

Ancestors (in MRO)

  • arm_reg
  • miasm2.core.cpu.reg_noarg
  • arm_arg
  • miasm2.core.cpu.m_arg
  • __builtin__.object

Class variables

var parser

var reg_info

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_arg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def check_fbits(

self, v)

def check_fbits(self, v):
    return v & self.fmask == self.fbits

def decode(

self, v)

def decode(self, v):
    v = v & self.lmask
    if v >= len(self.reg_info.expr):
        return False
    self.expr = self.reg_info.expr[v]
    return True

def encode(

self)

def encode(self):
    if not self.expr in self.reg_info.expr:
        log.debug("cannot encode reg %r", self.expr)
        return False
    self.value = self.reg_info.expr.index(self.expr)
    if self.value > self.lmask:
        log.debug("cannot encode field value %x %x",
                  self.value, self.lmask)
        return False
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_arg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.parses_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_reg_wb

class arm_reg_wb(arm_reg):
    reg_info = gpregs
    parser = gpregs_wb

    def decode(self, v):
        v = v & self.lmask
        e = self.reg_info.expr[v]
        if self.parent.wback.value:
            e = ExprOp('wback', e)
        self.expr = e
        return True

    def encode(self):
        e = self.expr
        self.parent.wback.value = 0
        if isinstance(e, ExprOp) and e.op == 'wback':
            self.parent.wback.value = 1
            e = e.args[0]
        if isinstance(e, ExprId):
            self.value = self.reg_info.expr.index(e)
        else:
            self.parent.wback.value = 1
            self.value = self.reg_info.expr.index(e.args[0])
        return True

Ancestors (in MRO)

Class variables

var parser

Inheritance: arm_reg.parser

var reg_info

Inheritance: arm_reg.reg_info

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_reg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def check_fbits(

self, v)

Inheritance: arm_reg.check_fbits

def check_fbits(self, v):
    return v & self.fmask == self.fbits

def decode(

self, v)

Inheritance: arm_reg.decode

def decode(self, v):
    v = v & self.lmask
    e = self.reg_info.expr[v]
    if self.parent.wback.value:
        e = ExprOp('wback', e)
    self.expr = e
    return True

def encode(

self)

Inheritance: arm_reg.encode

def encode(self):
    e = self.expr
    self.parent.wback.value = 0
    if isinstance(e, ExprOp) and e.op == 'wback':
        self.parent.wback.value = 1
        e = e.args[0]
    if isinstance(e, ExprId):
        self.value = self.reg_info.expr.index(e)
    else:
        self.parent.wback.value = 1
        self.value = self.reg_info.expr.index(e.args[0])
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_reg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.parses_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_reg_wb_nosp

class arm_reg_wb_nosp(arm_reg_wb):

    def decode(self, v):
        v = v & self.lmask
        if v == 13:
            return False
        e = self.reg_info.expr[v]
        if self.parent.wback.value:
            e = ExprOp('wback', e)
        self.expr = e
        return True

Ancestors (in MRO)

Class variables

var parser

Inheritance: arm_reg_wb.parser

var reg_info

Inheritance: arm_reg_wb.reg_info

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_reg_wb.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def check_fbits(

self, v)

Inheritance: arm_reg_wb.check_fbits

def check_fbits(self, v):
    return v & self.fmask == self.fbits

def decode(

self, v)

Inheritance: arm_reg_wb.decode

def decode(self, v):
    v = v & self.lmask
    if v == 13:
        return False
    e = self.reg_info.expr[v]
    if self.parent.wback.value:
        e = ExprOp('wback', e)
    self.expr = e
    return True

def encode(

self)

Inheritance: arm_reg_wb.encode

def encode(self):
    e = self.expr
    self.parent.wback.value = 0
    if isinstance(e, ExprOp) and e.op == 'wback':
        self.parent.wback.value = 1
        e = e.args[0]
    if isinstance(e, ExprId):
        self.value = self.reg_info.expr.index(e)
    else:
        self.parent.wback.value = 1
        self.value = self.reg_info.expr.index(e.args[0])
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_reg_wb.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.parses_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_rlist

class arm_rlist(arm_arg):
    parser = gpreg_list

    def encode(self):
        self.parent.sbit.value = 0
        e = self.expr
        if isinstance(e, ExprOp) and e.op == "sbit":
            e = e.args[0]
            self.parent.sbit.value = 1
        rlist = [gpregs.expr.index(x) for x in e.args]
        v = 0
        for r in rlist:
            v |= 1 << r
        self.value = v
        return True

    def decode(self, v):
        v = v & self.lmask
        out = []
        for i in xrange(0x10):
            if 1 << i & v:
                out.append(gpregs.expr[i])
        if not out:
            return False
        e = ExprOp('reglist', *out)
        if self.parent.sbit.value == 1:
            e = ExprOp('sbit', e)
        self.expr = e
        return True

Ancestors (in MRO)

Class variables

var parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_arg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

def decode(self, v):
    v = v & self.lmask
    out = []
    for i in xrange(0x10):
        if 1 << i & v:
            out.append(gpregs.expr[i])
    if not out:
        return False
    e = ExprOp('reglist', *out)
    if self.parent.sbit.value == 1:
        e = ExprOp('sbit', e)
    self.expr = e
    return True

def encode(

self)

def encode(self):
    self.parent.sbit.value = 0
    e = self.expr
    if isinstance(e, ExprOp) and e.op == "sbit":
        e = e.args[0]
        self.parent.sbit.value = 1
    rlist = [gpregs.expr.index(x) for x in e.args]
    v = 0
    for r in rlist:
        v |= 1 << r
    self.value = v
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_arg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_rm_rot2

class arm_rm_rot2(arm_arg):
    parser = rot2_expr
    def decode(self, v):
        expr = gpregs.expr[v]
        shift_value = self.parent.rot2.value
        if shift_value:
            expr = ExprOp(allshifts[3], expr, ExprInt(shift_value * 8, 32))
        self.expr = expr
        return True
    def encode(self):
        if self.expr in gpregs.expr:
            self.value = gpregs.expr.index(self.expr)
            self.parent.rot2.value = 0
        elif (isinstance(self.expr, ExprOp) and
              self.expr.op == allshifts[3]):
            reg, value = self.expr.args
            if reg not in gpregs.expr:
                return False
            self.value = gpregs.expr.index(reg)
            if not isinstance(value, ExprInt):
                return False
            value = int(value)
            if not value in [8, 16, 24]:
                return False
            self.parent.rot2.value = value / 8
        return True

Ancestors (in MRO)

Class variables

var parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_arg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

def decode(self, v):
    expr = gpregs.expr[v]
    shift_value = self.parent.rot2.value
    if shift_value:
        expr = ExprOp(allshifts[3], expr, ExprInt(shift_value * 8, 32))
    self.expr = expr
    return True

def encode(

self)

def encode(self):
    if self.expr in gpregs.expr:
        self.value = gpregs.expr.index(self.expr)
        self.parent.rot2.value = 0
    elif (isinstance(self.expr, ExprOp) and
          self.expr.op == allshifts[3]):
        reg, value = self.expr.args
        if reg not in gpregs.expr:
            return False
        self.value = gpregs.expr.index(reg)
        if not isinstance(value, ExprInt):
            return False
        value = int(value)
        if not value in [8, 16, 24]:
            return False
        self.parent.rot2.value = value / 8
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_arg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_sp

class arm_sp(arm_reg):
    reg_info = gpregs_sp
    parser = reg_info.parser

Ancestors (in MRO)

Class variables

var parser

Inheritance: arm_reg.parser

var reg_info

Inheritance: arm_reg.reg_info

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_reg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def check_fbits(

self, v)

Inheritance: arm_reg.check_fbits

def check_fbits(self, v):
    return v & self.fmask == self.fbits

def decode(

self, v)

Inheritance: arm_reg.decode

def decode(self, v):
    v = v & self.lmask
    if v >= len(self.reg_info.expr):
        return False
    self.expr = self.reg_info.expr[v]
    return True

def encode(

self)

Inheritance: arm_reg.encode

def encode(self):
    if not self.expr in self.reg_info.expr:
        log.debug("cannot encode reg %r", self.expr)
        return False
    self.value = self.reg_info.expr.index(self.expr)
    if self.value > self.lmask:
        log.debug("cannot encode field value %x %x",
                  self.value, self.lmask)
        return False
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_reg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.parses_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_sppc

class arm_sppc(arm_reg):
    reg_info = gpregs_sppc
    parser = reg_info.parser

Ancestors (in MRO)

Class variables

var parser

Inheritance: arm_reg.parser

var reg_info

Inheritance: arm_reg.reg_info

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_reg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def check_fbits(

self, v)

Inheritance: arm_reg.check_fbits

def check_fbits(self, v):
    return v & self.fmask == self.fbits

def decode(

self, v)

Inheritance: arm_reg.decode

def decode(self, v):
    v = v & self.lmask
    if v >= len(self.reg_info.expr):
        return False
    self.expr = self.reg_info.expr[v]
    return True

def encode(

self)

Inheritance: arm_reg.encode

def encode(self):
    if not self.expr in self.reg_info.expr:
        log.debug("cannot encode reg %r", self.expr)
        return False
    self.value = self.reg_info.expr.index(self.expr)
    if self.value > self.lmask:
        log.debug("cannot encode field value %x %x",
                  self.value, self.lmask)
        return False
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_reg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.parses_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class arm_widthm1

class arm_widthm1(arm_imm, m_arg):
    def decode(self, v):
        self.expr = ExprInt(v+1, 32)
        return True

    def encode(self):
        if not isinstance(self.expr, ExprInt):
            return False
        v = int(self.expr) +  -1
        if v > self.lmask:
            return False
        self.value = v
        return True

Ancestors (in MRO)

Class variables

var intmask

Inheritance: arm_imm.intmask

var intsize

Inheritance: arm_imm.intsize

var parser

Inheritance: arm_imm.parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_imm.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

Inheritance: arm_imm.decode

def decode(self, v):
    self.expr = ExprInt(v+1, 32)
    return True

def decodeval(

self, v)

Inheritance: arm_imm.decodeval

def decodeval(self, v):
    return v

def encode(

self)

Inheritance: arm_imm.encode

def encode(self):
    if not isinstance(self.expr, ExprInt):
        return False
    v = int(self.expr) +  -1
    if v > self.lmask:
        return False
    self.value = v
    return True

def encodeval(

self, v)

Inheritance: arm_imm.encodeval

def encodeval(self, v):
    if v > self.lmask:
        return False
    return v

def expr2int(

self, e)

Inheritance: arm_imm.expr2int

def expr2int(self, e):
    if not isinstance(e, m2_expr.ExprInt):
        return None
    v = int(e)
    if v & ~self.intmask != 0:
        return None
    return v

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_imm.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
    else:
        try:
            e, start, stop = self.parser.scanString(text).next()
        except StopIteration:
            return None, None
    if e == [None]:
        return None, None
    assert(isinstance(e, m2_expr.Expr))
    if isinstance(e, tuple):
        self.expr = self.int2expr(e[1])
    elif isinstance(e, m2_expr.Expr):
        self.expr = e
    else:
        raise TypeError('zarb expr')
    if self.expr is None:
        log.debug('cannot fromstring int %r', text)
        return None, None
    return start, stop

def int2expr(

self, v)

Inheritance: arm_imm.int2expr

def int2expr(self, v):
    if (v & ~self.intmask) != 0:
        return None
    return m2_expr.ExprInt(v, self.intsize)

class armt2_imm10l

class armt2_imm10l(arm_imm):

    def decode(self, v):
        v = v & self.lmask
        s = self.parent.sign.value
        j1 = self.parent.j1.value
        j2 = self.parent.j2.value
        imm10h = self.parent.imm10h.value
        imm10l = v

        i1, i2 = j1 ^ s ^ 1, j2 ^ s ^ 1

        v = (s << 24) | (i1 << 23) | (i2 << 22) | (imm10h << 12) | (imm10l << 2)
        v = sign_ext(v, 25, 32)
        self.expr = ExprInt(v, 32)
        return True

    def encode(self):
        if not isinstance(self.expr, ExprInt):
            return False
        v = self.expr.arg.arg
        s = 0
        if v & 0x80000000:
            s = 1
            v &= (1<<26) - 1
        if v >= (1 << 26):
            return False
        i1, i2, imm10h, imm10l = (v >> 23) & 1, (v >> 22) & 1, (v >> 12) & 0x3ff, (v >> 2) & 0x3ff
        j1, j2 = i1 ^ s ^ 1, i2 ^ s ^ 1
        self.parent.sign.value = s
        self.parent.j1.value = j1
        self.parent.j2.value = j2
        self.parent.imm10h.value = imm10h
        self.value = imm10l
        return True

Ancestors (in MRO)

Class variables

var intmask

Inheritance: arm_imm.intmask

var intsize

Inheritance: arm_imm.intsize

var parser

Inheritance: arm_imm.parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_imm.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

Inheritance: arm_imm.decode

def decode(self, v):
    v = v & self.lmask
    s = self.parent.sign.value
    j1 = self.parent.j1.value
    j2 = self.parent.j2.value
    imm10h = self.parent.imm10h.value
    imm10l = v
    i1, i2 = j1 ^ s ^ 1, j2 ^ s ^ 1
    v = (s << 24) | (i1 << 23) | (i2 << 22) | (imm10h << 12) | (imm10l << 2)
    v = sign_ext(v, 25, 32)
    self.expr = ExprInt(v, 32)
    return True

def decodeval(

self, v)

Inheritance: arm_imm.decodeval

def decodeval(self, v):
    return v

def encode(

self)

Inheritance: arm_imm.encode

def encode(self):
    if not isinstance(self.expr, ExprInt):
        return False
    v = self.expr.arg.arg
    s = 0
    if v & 0x80000000:
        s = 1
        v &= (1<<26) - 1
    if v >= (1 << 26):
        return False
    i1, i2, imm10h, imm10l = (v >> 23) & 1, (v >> 22) & 1, (v >> 12) & 0x3ff, (v >> 2) & 0x3ff
    j1, j2 = i1 ^ s ^ 1, i2 ^ s ^ 1
    self.parent.sign.value = s
    self.parent.j1.value = j1
    self.parent.j2.value = j2
    self.parent.imm10h.value = imm10h
    self.value = imm10l
    return True

def encodeval(

self, v)

Inheritance: arm_imm.encodeval

def encodeval(self, v):
    if v > self.lmask:
        return False
    return v

def expr2int(

self, e)

Inheritance: arm_imm.expr2int

def expr2int(self, e):
    if not isinstance(e, m2_expr.ExprInt):
        return None
    v = int(e)
    if v & ~self.intmask != 0:
        return None
    return v

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_imm.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
    else:
        try:
            e, start, stop = self.parser.scanString(text).next()
        except StopIteration:
            return None, None
    if e == [None]:
        return None, None
    assert(isinstance(e, m2_expr.Expr))
    if isinstance(e, tuple):
        self.expr = self.int2expr(e[1])
    elif isinstance(e, m2_expr.Expr):
        self.expr = e
    else:
        raise TypeError('zarb expr')
    if self.expr is None:
        log.debug('cannot fromstring int %r', text)
        return None, None
    return start, stop

def int2expr(

self, v)

Inheritance: arm_imm.int2expr

def int2expr(self, v):
    if (v & ~self.intmask) != 0:
        return None
    return m2_expr.ExprInt(v, self.intsize)

class armt2_imm11l

class armt2_imm11l(arm_imm):

    def decode(self, v):
        v = v & self.lmask
        s = self.parent.sign.value
        j1 = self.parent.j1.value
        j2 = self.parent.j2.value
        imm10h = self.parent.imm10h.value
        imm11l = v

        i1, i2 = j1 ^ s ^ 1, j2 ^ s ^ 1

        v = (s << 24) | (i1 << 23) | (i2 << 22) | (imm10h << 12) | (imm11l << 1)
        v = sign_ext(v, 25, 32)
        self.expr = ExprInt(v + 4, 32)
        return True

    def encode(self):
        if not isinstance(self.expr, ExprInt):
            return False
        v = self.expr.arg.arg - 4
        s = 0
        if v & 0x80000000:
            s = 1
            v &= (1<<26) - 1
        if v >= (1 << 26):
            return False
        if v & 1:
            return False
        i1, i2, imm10h, imm11l = (v >> 23) & 1, (v >> 22) & 1, (v >> 12) & 0x3ff, (v >> 1) & 0x7ff
        j1, j2 = i1 ^ s ^ 1, i2 ^ s ^ 1
        self.parent.sign.value = s
        self.parent.j1.value = j1
        self.parent.j2.value = j2
        self.parent.imm10h.value = imm10h
        self.value = imm11l
        return True

Ancestors (in MRO)

Class variables

var intmask

Inheritance: arm_imm.intmask

var intsize

Inheritance: arm_imm.intsize

var parser

Inheritance: arm_imm.parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_imm.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

Inheritance: arm_imm.decode

def decode(self, v):
    v = v & self.lmask
    s = self.parent.sign.value
    j1 = self.parent.j1.value
    j2 = self.parent.j2.value
    imm10h = self.parent.imm10h.value
    imm11l = v
    i1, i2 = j1 ^ s ^ 1, j2 ^ s ^ 1
    v = (s << 24) | (i1 << 23) | (i2 << 22) | (imm10h << 12) | (imm11l << 1)
    v = sign_ext(v, 25, 32)
    self.expr = ExprInt(v + 4, 32)
    return True

def decodeval(

self, v)

Inheritance: arm_imm.decodeval

def decodeval(self, v):
    return v

def encode(

self)

Inheritance: arm_imm.encode

def encode(self):
    if not isinstance(self.expr, ExprInt):
        return False
    v = self.expr.arg.arg - 4
    s = 0
    if v & 0x80000000:
        s = 1
        v &= (1<<26) - 1
    if v >= (1 << 26):
        return False
    if v & 1:
        return False
    i1, i2, imm10h, imm11l = (v >> 23) & 1, (v >> 22) & 1, (v >> 12) & 0x3ff, (v >> 1) & 0x7ff
    j1, j2 = i1 ^ s ^ 1, i2 ^ s ^ 1
    self.parent.sign.value = s
    self.parent.j1.value = j1
    self.parent.j2.value = j2
    self.parent.imm10h.value = imm10h
    self.value = imm11l
    return True

def encodeval(

self, v)

Inheritance: arm_imm.encodeval

def encodeval(self, v):
    if v > self.lmask:
        return False
    return v

def expr2int(

self, e)

Inheritance: arm_imm.expr2int

def expr2int(self, e):
    if not isinstance(e, m2_expr.ExprInt):
        return None
    v = int(e)
    if v & ~self.intmask != 0:
        return None
    return v

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_imm.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
    else:
        try:
            e, start, stop = self.parser.scanString(text).next()
        except StopIteration:
            return None, None
    if e == [None]:
        return None, None
    assert(isinstance(e, m2_expr.Expr))
    if isinstance(e, tuple):
        self.expr = self.int2expr(e[1])
    elif isinstance(e, m2_expr.Expr):
        self.expr = e
    else:
        raise TypeError('zarb expr')
    if self.expr is None:
        log.debug('cannot fromstring int %r', text)
        return None, None
    return start, stop

def int2expr(

self, v)

Inheritance: arm_imm.int2expr

def int2expr(self, v):
    if (v & ~self.intmask) != 0:
        return None
    return m2_expr.ExprInt(v, self.intsize)

class armt2_imm12

class armt2_imm12(arm_imm):

    def decode(self, v):
        v = v & self.lmask
        v |= int(self.parent.imm12_3.value) << 8
        v |= int(self.parent.imm12_1.value) << 11

        # simple encoding
        if 0 <= v < 0x100:
            self.expr = ExprInt(v, 32)
            return True
        # 00XY00XY form
        if v >> 8 == 1:
            v &= 0xFF
            self.expr = ExprInt((v << 16) | v, 32)
            return True
        # XY00XY00 form
        if v >> 8 == 2:
            v &= 0xFF
            self.expr = ExprInt((v << 24) | (v << 8), 32)
            return True
        # XYXYXYXY
        if v >> 8 == 3:
            v &= 0xFF
            self.expr = ExprInt((v << 24) | (v << 16) | (v << 8) | v, 32)
            return True
        r = v >> 7
        v = 0x80 | (v & 0x7F)
        self.expr = ExprInt(myror32(v, r), 32)
        return True

    def encode(self):
        if not self.expr.is_int():
            return False
        v = int(self.expr)
        value = None
        # simple encoding
        if 0 <= v < 0x100:
            value = v
        elif v & 0xFF00FF00 == 0 and v & 0xFF == (v >> 16) & 0xff:
            # 00XY00XY form
            value = (1 << 8) | (v & 0xFF)
        elif v & 0x00FF00FF == 0 and (v >> 8) & 0xff == (v >> 24) & 0xff:
            # XY00XY00 form
            value = (2 << 8) | ((v >> 8) & 0xff)
        elif (v & 0xFF ==
             (v >> 8)  & 0xFF ==
             (v >> 16) & 0xFF ==
             (v >> 24) & 0xFF):
            # XYXYXYXY form
            value = (3 << 8) | ((v >> 16) & 0xff)
        else:
            # rol encoding
            for i in xrange(32):
                o = myrol32(v, i)
                if 0x80 <= o <= 0xFF:
                    value = (i << 7) | (o & 0x7F)
                    break
        if value is None:
            log.debug('cannot encode imm12')
            return False
        self.value = value & self.lmask
        self.parent.imm12_3.value = (value >> 8) & self.parent.imm12_3.lmask
        self.parent.imm12_1.value = (value >> 11) & self.parent.imm12_1.lmask
        return True

Ancestors (in MRO)

Class variables

var intmask

Inheritance: arm_imm.intmask

var intsize

Inheritance: arm_imm.intsize

var parser

Inheritance: arm_imm.parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_imm.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

Inheritance: arm_imm.decode

def decode(self, v):
    v = v & self.lmask
    v |= int(self.parent.imm12_3.value) << 8
    v |= int(self.parent.imm12_1.value) << 11
    # simple encoding
    if 0 <= v < 0x100:
        self.expr = ExprInt(v, 32)
        return True
    # 00XY00XY form
    if v >> 8 == 1:
        v &= 0xFF
        self.expr = ExprInt((v << 16) | v, 32)
        return True
    # XY00XY00 form
    if v >> 8 == 2:
        v &= 0xFF
        self.expr = ExprInt((v << 24) | (v << 8), 32)
        return True
    # XYXYXYXY
    if v >> 8 == 3:
        v &= 0xFF
        self.expr = ExprInt((v << 24) | (v << 16) | (v << 8) | v, 32)
        return True
    r = v >> 7
    v = 0x80 | (v & 0x7F)
    self.expr = ExprInt(myror32(v, r), 32)
    return True

def decodeval(

self, v)

Inheritance: arm_imm.decodeval

def decodeval(self, v):
    return v

def encode(

self)

Inheritance: arm_imm.encode

def encode(self):
    if not self.expr.is_int():
        return False
    v = int(self.expr)
    value = None
    # simple encoding
    if 0 <= v < 0x100:
        value = v
    elif v & 0xFF00FF00 == 0 and v & 0xFF == (v >> 16) & 0xff:
        # 00XY00XY form
        value = (1 << 8) | (v & 0xFF)
    elif v & 0x00FF00FF == 0 and (v >> 8) & 0xff == (v >> 24) & 0xff:
        # XY00XY00 form
        value = (2 << 8) | ((v >> 8) & 0xff)
    elif (v & 0xFF ==
         (v >> 8)  & 0xFF ==
         (v >> 16) & 0xFF ==
         (v >> 24) & 0xFF):
        # XYXYXYXY form
        value = (3 << 8) | ((v >> 16) & 0xff)
    else:
        # rol encoding
        for i in xrange(32):
            o = myrol32(v, i)
            if 0x80 <= o <= 0xFF:
                value = (i << 7) | (o & 0x7F)
                break
    if value is None:
        log.debug('cannot encode imm12')
        return False
    self.value = value & self.lmask
    self.parent.imm12_3.value = (value >> 8) & self.parent.imm12_3.lmask
    self.parent.imm12_1.value = (value >> 11) & self.parent.imm12_1.lmask
    return True

def encodeval(

self, v)

Inheritance: arm_imm.encodeval

def encodeval(self, v):
    if v > self.lmask:
        return False
    return v

def expr2int(

self, e)

Inheritance: arm_imm.expr2int

def expr2int(self, e):
    if not isinstance(e, m2_expr.ExprInt):
        return None
    v = int(e)
    if v & ~self.intmask != 0:
        return None
    return v

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_imm.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
    else:
        try:
            e, start, stop = self.parser.scanString(text).next()
        except StopIteration:
            return None, None
    if e == [None]:
        return None, None
    assert(isinstance(e, m2_expr.Expr))
    if isinstance(e, tuple):
        self.expr = self.int2expr(e[1])
    elif isinstance(e, m2_expr.Expr):
        self.expr = e
    else:
        raise TypeError('zarb expr')
    if self.expr is None:
        log.debug('cannot fromstring int %r', text)
        return None, None
    return start, stop

def int2expr(

self, v)

Inheritance: arm_imm.int2expr

def int2expr(self, v):
    if (v & ~self.intmask) != 0:
        return None
    return m2_expr.ExprInt(v, self.intsize)

class armt2_imm16

class armt2_imm16(arm_imm):

    def decode(self, v):
        v = v & self.lmask
        v |= int(self.parent.imm16_3.value) << 8
        v |= int(self.parent.imm16_1.value) << 11
        v |= int(self.parent.imm16_4.value) << 12
        self.expr = ExprInt(v, 32)
        return True

    def encode(self):
        if not self.expr.is_int():
            return False
        value = int(self.expr)
        if value >= (1 << 16):
            return False
        self.value = value & self.lmask
        self.parent.imm16_3.value = (value >> 8) & self.parent.imm16_3.lmask
        self.parent.imm16_1.value = (value >> 11) & self.parent.imm16_1.lmask
        self.parent.imm16_4.value = (value >> 12) & self.parent.imm16_4.lmask
        return True

Ancestors (in MRO)

Class variables

var intmask

Inheritance: arm_imm.intmask

var intsize

Inheritance: arm_imm.intsize

var parser

Inheritance: arm_imm.parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_imm.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

Inheritance: arm_imm.decode

def decode(self, v):
    v = v & self.lmask
    v |= int(self.parent.imm16_3.value) << 8
    v |= int(self.parent.imm16_1.value) << 11
    v |= int(self.parent.imm16_4.value) << 12
    self.expr = ExprInt(v, 32)
    return True

def decodeval(

self, v)

Inheritance: arm_imm.decodeval

def decodeval(self, v):
    return v

def encode(

self)

Inheritance: arm_imm.encode

def encode(self):
    if not self.expr.is_int():
        return False
    value = int(self.expr)
    if value >= (1 << 16):
        return False
    self.value = value & self.lmask
    self.parent.imm16_3.value = (value >> 8) & self.parent.imm16_3.lmask
    self.parent.imm16_1.value = (value >> 11) & self.parent.imm16_1.lmask
    self.parent.imm16_4.value = (value >> 12) & self.parent.imm16_4.lmask
    return True

def encodeval(

self, v)

Inheritance: arm_imm.encodeval

def encodeval(self, v):
    if v > self.lmask:
        return False
    return v

def expr2int(

self, e)

Inheritance: arm_imm.expr2int

def expr2int(self, e):
    if not isinstance(e, m2_expr.ExprInt):
        return None
    v = int(e)
    if v & ~self.intmask != 0:
        return None
    return v

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_imm.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
    else:
        try:
            e, start, stop = self.parser.scanString(text).next()
        except StopIteration:
            return None, None
    if e == [None]:
        return None, None
    assert(isinstance(e, m2_expr.Expr))
    if isinstance(e, tuple):
        self.expr = self.int2expr(e[1])
    elif isinstance(e, m2_expr.Expr):
        self.expr = e
    else:
        raise TypeError('zarb expr')
    if self.expr is None:
        log.debug('cannot fromstring int %r', text)
        return None, None
    return start, stop

def int2expr(

self, v)

Inheritance: arm_imm.int2expr

def int2expr(self, v):
    if (v & ~self.intmask) != 0:
        return None
    return m2_expr.ExprInt(v, self.intsize)

class armt2_imm6_11l

class armt2_imm6_11l(arm_imm):

    def decode(self, v):
        v = v & self.lmask
        s = self.parent.sign.value
        j1 = self.parent.j1.value
        j2 = self.parent.j2.value
        imm6h = self.parent.imm6h.value
        imm11l = v

        v = (s << 20) | (j2 << 19) | (j1 << 18) | (imm6h << 12) | (imm11l << 1)
        v = sign_ext(v, 21, 32)
        self.expr = ExprInt(v + 4, 32)
        return True

    def encode(self):
        if not isinstance(self.expr, ExprInt):
            return False
        v = self.expr.arg.arg - 4
        s = 0
        if v != sign_ext(v & ((1 << 22) - 1), 21, 32):
            return False 
        if v & 0x80000000:
            s = 1
        v &= (1<<22) - 1
        if v & 1:
            return False
        i2, i1, imm6h, imm11l = (v >> 19) & 1, (v >> 18) & 1, (v >> 12) & 0x3f, (v >> 1) & 0x7ff
        self.parent.sign.value = s
        self.parent.j1.value = i1
        self.parent.j2.value = i2
        self.parent.imm6h.value = imm6h
        self.value = imm11l
        return True

Ancestors (in MRO)

Class variables

var intmask

Inheritance: arm_imm.intmask

var intsize

Inheritance: arm_imm.intsize

var parser

Inheritance: arm_imm.parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_imm.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

Inheritance: arm_imm.decode

def decode(self, v):
    v = v & self.lmask
    s = self.parent.sign.value
    j1 = self.parent.j1.value
    j2 = self.parent.j2.value
    imm6h = self.parent.imm6h.value
    imm11l = v
    v = (s << 20) | (j2 << 19) | (j1 << 18) | (imm6h << 12) | (imm11l << 1)
    v = sign_ext(v, 21, 32)
    self.expr = ExprInt(v + 4, 32)
    return True

def decodeval(

self, v)

Inheritance: arm_imm.decodeval

def decodeval(self, v):
    return v

def encode(

self)

Inheritance: arm_imm.encode

def encode(self):
    if not isinstance(self.expr, ExprInt):
        return False
    v = self.expr.arg.arg - 4
    s = 0
    if v != sign_ext(v & ((1 << 22) - 1), 21, 32):
        return False 
    if v & 0x80000000:
        s = 1
    v &= (1<<22) - 1
    if v & 1:
        return False
    i2, i1, imm6h, imm11l = (v >> 19) & 1, (v >> 18) & 1, (v >> 12) & 0x3f, (v >> 1) & 0x7ff
    self.parent.sign.value = s
    self.parent.j1.value = i1
    self.parent.j2.value = i2
    self.parent.imm6h.value = imm6h
    self.value = imm11l
    return True

def encodeval(

self, v)

Inheritance: arm_imm.encodeval

def encodeval(self, v):
    if v > self.lmask:
        return False
    return v

def expr2int(

self, e)

Inheritance: arm_imm.expr2int

def expr2int(self, e):
    if not isinstance(e, m2_expr.ExprInt):
        return None
    v = int(e)
    if v & ~self.intmask != 0:
        return None
    return v

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_imm.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
    else:
        try:
            e, start, stop = self.parser.scanString(text).next()
        except StopIteration:
            return None, None
    if e == [None]:
        return None, None
    assert(isinstance(e, m2_expr.Expr))
    if isinstance(e, tuple):
        self.expr = self.int2expr(e[1])
    elif isinstance(e, m2_expr.Expr):
        self.expr = e
    else:
        raise TypeError('zarb expr')
    if self.expr is None:
        log.debug('cannot fromstring int %r', text)
        return None, None
    return start, stop

def int2expr(

self, v)

Inheritance: arm_imm.int2expr

def int2expr(self, v):
    if (v & ~self.intmask) != 0:
        return None
    return m2_expr.ExprInt(v, self.intsize)

class armt2_lsb5

class armt2_lsb5(arm_imm):

    def decode(self, v):
        v = v & self.lmask
        v |= int(self.parent.lsb5_3.value) << 2
        self.expr = ExprInt(v, 32)
        return True

    def encode(self):
        if not self.expr.is_int():
            return False
        value = int(self.expr)
        self.value = value & self.lmask
        self.parent.lsb5_3.value = (value >> 2) & self.parent.lsb5_3.lmask
        return True

Ancestors (in MRO)

Class variables

var intmask

Inheritance: arm_imm.intmask

var intsize

Inheritance: arm_imm.intsize

var parser

Inheritance: arm_imm.parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_imm.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

Inheritance: arm_imm.decode

def decode(self, v):
    v = v & self.lmask
    v |= int(self.parent.lsb5_3.value) << 2
    self.expr = ExprInt(v, 32)
    return True

def decodeval(

self, v)

Inheritance: arm_imm.decodeval

def decodeval(self, v):
    return v

def encode(

self)

Inheritance: arm_imm.encode

def encode(self):
    if not self.expr.is_int():
        return False
    value = int(self.expr)
    self.value = value & self.lmask
    self.parent.lsb5_3.value = (value >> 2) & self.parent.lsb5_3.lmask
    return True

def encodeval(

self, v)

Inheritance: arm_imm.encodeval

def encodeval(self, v):
    if v > self.lmask:
        return False
    return v

def expr2int(

self, e)

Inheritance: arm_imm.expr2int

def expr2int(self, e):
    if not isinstance(e, m2_expr.ExprInt):
        return None
    v = int(e)
    if v & ~self.intmask != 0:
        return None
    return v

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_imm.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
    else:
        try:
            e, start, stop = self.parser.scanString(text).next()
        except StopIteration:
            return None, None
    if e == [None]:
        return None, None
    assert(isinstance(e, m2_expr.Expr))
    if isinstance(e, tuple):
        self.expr = self.int2expr(e[1])
    elif isinstance(e, m2_expr.Expr):
        self.expr = e
    else:
        raise TypeError('zarb expr')
    if self.expr is None:
        log.debug('cannot fromstring int %r', text)
        return None, None
    return start, stop

def int2expr(

self, v)

Inheritance: arm_imm.int2expr

def int2expr(self, v):
    if (v & ~self.intmask) != 0:
        return None
    return m2_expr.ExprInt(v, self.intsize)

class armt2_off20

class armt2_off20(arm_imm):

    def decode(self, v):
        v = v & self.lmask
        v <<= 1
        v |= int(self.parent.off20_6.value) << 12
        v |= int(self.parent.off20_j1.value) << 18
        v |= int(self.parent.off20_j2.value) << 19
        v |= int(self.parent.off20_s.value) << 20
        self.expr = ExprInt(v, 32)
        return True

    def encode(self):
        if not self.expr.is_int():
            return False
        value = int(self.expr)
        if value & 1:
            return False
        self.value = (value >> 1) & self.lmask
        self.parent.off20_6.value = (value >> 12) & self.parent.off20_6.lmask
        self.parent.off20_j1.value = (value >> 18) & self.parent.off20_j1.lmask
        self.parent.off20_j2.value = (value >> 19) & self.parent.off20_j2.lmask
        self.parent.off20_s.value = (value >> 20) & self.parent.off20_s.lmask
        return True

Ancestors (in MRO)

Class variables

var intmask

Inheritance: arm_imm.intmask

var intsize

Inheritance: arm_imm.intsize

var parser

Inheritance: arm_imm.parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_imm.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

Inheritance: arm_imm.decode

def decode(self, v):
    v = v & self.lmask
    v <<= 1
    v |= int(self.parent.off20_6.value) << 12
    v |= int(self.parent.off20_j1.value) << 18
    v |= int(self.parent.off20_j2.value) << 19
    v |= int(self.parent.off20_s.value) << 20
    self.expr = ExprInt(v, 32)
    return True

def decodeval(

self, v)

Inheritance: arm_imm.decodeval

def decodeval(self, v):
    return v

def encode(

self)

Inheritance: arm_imm.encode

def encode(self):
    if not self.expr.is_int():
        return False
    value = int(self.expr)
    if value & 1:
        return False
    self.value = (value >> 1) & self.lmask
    self.parent.off20_6.value = (value >> 12) & self.parent.off20_6.lmask
    self.parent.off20_j1.value = (value >> 18) & self.parent.off20_j1.lmask
    self.parent.off20_j2.value = (value >> 19) & self.parent.off20_j2.lmask
    self.parent.off20_s.value = (value >> 20) & self.parent.off20_s.lmask
    return True

def encodeval(

self, v)

Inheritance: arm_imm.encodeval

def encodeval(self, v):
    if v > self.lmask:
        return False
    return v

def expr2int(

self, e)

Inheritance: arm_imm.expr2int

def expr2int(self, e):
    if not isinstance(e, m2_expr.ExprInt):
        return None
    v = int(e)
    if v & ~self.intmask != 0:
        return None
    return v

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_imm.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
    else:
        try:
            e, start, stop = self.parser.scanString(text).next()
        except StopIteration:
            return None, None
    if e == [None]:
        return None, None
    assert(isinstance(e, m2_expr.Expr))
    if isinstance(e, tuple):
        self.expr = self.int2expr(e[1])
    elif isinstance(e, m2_expr.Expr):
        self.expr = e
    else:
        raise TypeError('zarb expr')
    if self.expr is None:
        log.debug('cannot fromstring int %r', text)
        return None, None
    return start, stop

def int2expr(

self, v)

Inheritance: arm_imm.int2expr

def int2expr(self, v):
    if (v & ~self.intmask) != 0:
        return None
    return m2_expr.ExprInt(v, self.intsize)

class armt2_rot_rm

class armt2_rot_rm(arm_arg):
    parser = shift_off
    def decode(self, v):
        r = self.parent.rm.expr
        if v == 00:
            e = r
        else:
            raise NotImplementedError('rotation')
        self.expr = e
        return True
    def encode(self):
        e = self.expr
        if isinstance(e, ExprId):
            self.value = 0
        else:
            raise NotImplementedError('rotation')
        return True

Ancestors (in MRO)

Class variables

var parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_arg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

def decode(self, v):
    r = self.parent.rm.expr
    if v == 00:
        e = r
    else:
        raise NotImplementedError('rotation')
    self.expr = e
    return True

def encode(

self)

def encode(self):
    e = self.expr
    if isinstance(e, ExprId):
        self.value = 0
    else:
        raise NotImplementedError('rotation')
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_arg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class armt4_imm12

class armt4_imm12(arm_imm):

    def decode(self, v):
        v = v & self.lmask
        v |= int(self.parent.imm12_3.value) << 8
        v |= int(self.parent.imm12_1.value) << 11
        self.expr = ExprInt(v, 32)
        return True

    def encode(self):
        if not self.expr.is_int():
            return False
        value = int(self.expr)
        if value >= (1 << 16):
            return False
        self.value = value & self.lmask
        self.parent.imm12_3.value = (value >> 8) & self.parent.imm12_3.lmask
        self.parent.imm12_1.value = (value >> 11) & self.parent.imm12_1.lmask
        return True

Ancestors (in MRO)

Class variables

var intmask

Inheritance: arm_imm.intmask

var intsize

Inheritance: arm_imm.intsize

var parser

Inheritance: arm_imm.parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_imm.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

Inheritance: arm_imm.decode

def decode(self, v):
    v = v & self.lmask
    v |= int(self.parent.imm12_3.value) << 8
    v |= int(self.parent.imm12_1.value) << 11
    self.expr = ExprInt(v, 32)
    return True

def decodeval(

self, v)

Inheritance: arm_imm.decodeval

def decodeval(self, v):
    return v

def encode(

self)

Inheritance: arm_imm.encode

def encode(self):
    if not self.expr.is_int():
        return False
    value = int(self.expr)
    if value >= (1 << 16):
        return False
    self.value = value & self.lmask
    self.parent.imm12_3.value = (value >> 8) & self.parent.imm12_3.lmask
    self.parent.imm12_1.value = (value >> 11) & self.parent.imm12_1.lmask
    return True

def encodeval(

self, v)

Inheritance: arm_imm.encodeval

def encodeval(self, v):
    if v > self.lmask:
        return False
    return v

def expr2int(

self, e)

Inheritance: arm_imm.expr2int

def expr2int(self, e):
    if not isinstance(e, m2_expr.ExprInt):
        return None
    v = int(e)
    if v & ~self.intmask != 0:
        return None
    return v

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_imm.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
    else:
        try:
            e, start, stop = self.parser.scanString(text).next()
        except StopIteration:
            return None, None
    if e == [None]:
        return None, None
    assert(isinstance(e, m2_expr.Expr))
    if isinstance(e, tuple):
        self.expr = self.int2expr(e[1])
    elif isinstance(e, m2_expr.Expr):
        self.expr = e
    else:
        raise TypeError('zarb expr')
    if self.expr is None:
        log.debug('cannot fromstring int %r', text)
        return None, None
    return start, stop

def int2expr(

self, v)

Inheritance: arm_imm.int2expr

def int2expr(self, v):
    if (v & ~self.intmask) != 0:
        return None
    return m2_expr.ExprInt(v, self.intsize)

class armt_aif

class armt_aif(reg_noarg, arm_arg):
    reg_info = aif_reg
    parser = reg_info.parser

    def decode(self, v):
        if v == 0:
            return False
        return super(armt_aif, self).decode(v)

    def encode(self):
        ret = super(armt_aif, self).encode()
        if not ret:
            return ret
        return self.value != 0

    def fromstring(self, text, loc_db, parser_result=None):
        start, stop = super(armt_aif, self).fromstring(text, loc_db, parser_result)
        if self.expr.name == "X":
            return None, None
        return start, stop

Ancestors (in MRO)

  • armt_aif
  • miasm2.core.cpu.reg_noarg
  • arm_arg
  • miasm2.core.cpu.m_arg
  • __builtin__.object

Class variables

var parser

var reg_info

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_arg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def check_fbits(

self, v)

def check_fbits(self, v):
    return v & self.fmask == self.fbits

def decode(

self, v)

def decode(self, v):
    if v == 0:
        return False
    return super(armt_aif, self).decode(v)

def encode(

self)

def encode(self):
    ret = super(armt_aif, self).encode()
    if not ret:
        return ret
    return self.value != 0

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_arg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    start, stop = super(armt_aif, self).fromstring(text, loc_db, parser_result)
    if self.expr.name == "X":
        return None, None
    return start, stop

class armt_barrier_option

class armt_barrier_option(reg_noarg, arm_arg):
    reg_info = barrier_info
    parser = reg_info.parser

    def decode(self, v):
        v = v & self.lmask
        if v not in self.reg_info.dct_expr:
            return False
        self.expr = self.reg_info.dct_expr[v]
        return True

    def encode(self):
        if not self.expr in self.reg_info.dct_expr_inv:
            log.debug("cannot encode reg %r", self.expr)
            return False
        self.value = self.reg_info.dct_expr_inv[self.expr]
        if self.value > self.lmask:
            log.debug("cannot encode field value %x %x",
                      self.value, self.lmask)
            return False
        return True

    def check_fbits(self, v):
        return v & self.fmask == self.fbits

Ancestors (in MRO)

Class variables

var parser

var reg_info

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_arg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def check_fbits(

self, v)

def check_fbits(self, v):
    return v & self.fmask == self.fbits

def decode(

self, v)

def decode(self, v):
    v = v & self.lmask
    if v not in self.reg_info.dct_expr:
        return False
    self.expr = self.reg_info.dct_expr[v]
    return True

def encode(

self)

def encode(self):
    if not self.expr in self.reg_info.dct_expr_inv:
        log.debug("cannot encode reg %r", self.expr)
        return False
    self.value = self.reg_info.dct_expr_inv[self.expr]
    if self.value > self.lmask:
        log.debug("cannot encode field value %x %x",
                  self.value, self.lmask)
        return False
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_arg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.parses_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class armt_cond_arg

class armt_cond_arg(arm_arg):
    parser = cond_info.parser

    def decode(self, v):
        v = (v << 1) | self.parent.condlsb.value
        self.expr = ExprId(cond_list_full[v], 32)
        return True

    def encode(self):
        index = cond_list_full.index(self.expr.name)
        self.value = index >> 1
        if index & 1 != self.parent.condlsb.value:
            return False
        return True

Ancestors (in MRO)

Class variables

var parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_arg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

def decode(self, v):
    v = (v << 1) | self.parent.condlsb.value
    self.expr = ExprId(cond_list_full[v], 32)
    return True

def encode(

self)

def encode(self):
    index = cond_list_full.index(self.expr.name)
    self.value = index >> 1
    if index & 1 != self.parent.condlsb.value:
        return False
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_arg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class armt_cond_lsb

class armt_cond_lsb(bs_divert):
    prio = 2

    def divert(self, i, candidates):
        out = []
        for cls, _, bases, dct, fields in candidates:
            for value in xrange(2):
                nfields = fields[:]
                s = int2bin(value, self.args['l'])
                args = dict(self.args)
                args.update({'strbits': s})
                f = bs(**args)
                nfields[i] = f
                ndct = dict(dct)
                out.append((cls, ndct['name'], bases, ndct, nfields))
        return out

Ancestors (in MRO)

Class variables

var prio

Methods

def __init__(

self, **kargs)

def __init__(self, **kargs):
    self.args = kargs

def divert(

self, i, candidates)

def divert(self, i, candidates):
    out = []
    for cls, _, bases, dct, fields in candidates:
        for value in xrange(2):
            nfields = fields[:]
            s = int2bin(value, self.args['l'])
            args = dict(self.args)
            args.update({'strbits': s})
            f = bs(**args)
            nfields[i] = f
            ndct = dict(dct)
            out.append((cls, ndct['name'], bases, ndct, nfields))
    return out

class armt_deref_reg

class armt_deref_reg(arm_imm8_12):
    parser = deref

    def decode(self, v):
        base = self.parent.rn.expr
        off = gpregs.expr[v]
        if self.parent.imm.value != 0:
            off = off << ExprInt(self.parent.imm.value, 32)
        e = ExprMem(ExprOp('preinc', base, off), 8)
        self.expr = e
        return True

    def encode(self):
        if not isinstance(self.expr, ExprMem):
            return False
        ptr = self.expr.arg
        if not ptr.is_op('preinc'):
            return False
        if len(ptr.args) != 2:
            return False
        base, off = ptr.args
        if base.is_id() and off.is_id():
            self.parent.rn.expr = base
            self.parent.imm.value = 0
            self.value = gpregs.expr.index(off)
        elif off.is_int():
            return False
        elif off.is_op('<<'):
            if len(off.args) != 2:
                return False
            reg, off = off.args
            self.parent.rn.expr = base
            self.parent.imm.value = 0
            self.value = gpregs.expr.index(reg)
            off = int(off)
            if off > self.parent.imm.lmask:
                return False
            self.parent.imm.value = off
        return True

Ancestors (in MRO)

Class variables

var parser

Inheritance: arm_imm8_12.parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_imm8_12.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

Inheritance: arm_imm8_12.decode

def decode(self, v):
    base = self.parent.rn.expr
    off = gpregs.expr[v]
    if self.parent.imm.value != 0:
        off = off << ExprInt(self.parent.imm.value, 32)
    e = ExprMem(ExprOp('preinc', base, off), 8)
    self.expr = e
    return True

def encode(

self)

Inheritance: arm_imm8_12.encode

def encode(self):
    if not isinstance(self.expr, ExprMem):
        return False
    ptr = self.expr.arg
    if not ptr.is_op('preinc'):
        return False
    if len(ptr.args) != 2:
        return False
    base, off = ptr.args
    if base.is_id() and off.is_id():
        self.parent.rn.expr = base
        self.parent.imm.value = 0
        self.value = gpregs.expr.index(off)
    elif off.is_int():
        return False
    elif off.is_op('<<'):
        if len(off.args) != 2:
            return False
        reg, off = off.args
        self.parent.rn.expr = base
        self.parent.imm.value = 0
        self.value = gpregs.expr.index(reg)
        off = int(off)
        if off > self.parent.imm.lmask:
            return False
        self.parent.imm.value = off
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_imm8_12.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class armt_deref_reg_reg

class armt_deref_reg_reg(arm_arg):
    parser = deref_reg_reg
    reg_info = gpregs

    def decode(self, v):
        expr = self.reg_info.expr[v]
        expr = ExprMem(self.parent.rn.expr + expr, 8)
        self.expr = expr
        return True

    def encode(self):
        expr = self.expr
        if not expr.is_mem():
            return False
        ptr = expr.arg
        if not ptr.is_op('+') or len(ptr.args) != 2:
            return False
        reg1, reg2 = ptr.args
        self.parent.rn.expr = reg1
        self.value = self.reg_info.expr.index(reg2)
        return True

Ancestors (in MRO)

Class variables

var parser

var reg_info

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_arg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

def decode(self, v):
    expr = self.reg_info.expr[v]
    expr = ExprMem(self.parent.rn.expr + expr, 8)
    self.expr = expr
    return True

def encode(

self)

def encode(self):
    expr = self.expr
    if not expr.is_mem():
        return False
    ptr = expr.arg
    if not ptr.is_op('+') or len(ptr.args) != 2:
        return False
    reg1, reg2 = ptr.args
    self.parent.rn.expr = reg1
    self.value = self.reg_info.expr.index(reg2)
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_arg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class armt_deref_reg_reg_lsl_1

class armt_deref_reg_reg_lsl_1(arm_reg):
    parser = deref_reg_reg_lsl_1
    reg_info = gpregs

    def decode(self, v):
        expr = self.reg_info.expr[v]
        expr = ExprMem(self.parent.rn.expr + (expr << ExprInt(1, 32)), 16)
        self.expr = expr
        return True

    def encode(self):
        expr = self.expr
        if not expr.is_mem():
            return False
        ptr = expr.arg
        if not ptr.is_op('+') or len(ptr.args) != 2:
            return False
        reg1, reg_shift = ptr.args
        self.parent.rn.expr = reg1
        if not reg_shift.is_op('<<') or len(reg_shift.args) != 2:
            return False
        if reg_shift.args[1] != ExprInt(1, 32):
            return False
        self.value = self.reg_info.expr.index(reg_shift.args[0])
        return True

Ancestors (in MRO)

Class variables

var parser

Inheritance: arm_reg.parser

var reg_info

Inheritance: arm_reg.reg_info

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_reg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def check_fbits(

self, v)

Inheritance: arm_reg.check_fbits

def check_fbits(self, v):
    return v & self.fmask == self.fbits

def decode(

self, v)

Inheritance: arm_reg.decode

def decode(self, v):
    expr = self.reg_info.expr[v]
    expr = ExprMem(self.parent.rn.expr + (expr << ExprInt(1, 32)), 16)
    self.expr = expr
    return True

def encode(

self)

Inheritance: arm_reg.encode

def encode(self):
    expr = self.expr
    if not expr.is_mem():
        return False
    ptr = expr.arg
    if not ptr.is_op('+') or len(ptr.args) != 2:
        return False
    reg1, reg_shift = ptr.args
    self.parent.rn.expr = reg1
    if not reg_shift.is_op('<<') or len(reg_shift.args) != 2:
        return False
    if reg_shift.args[1] != ExprInt(1, 32):
        return False
    self.value = self.reg_info.expr.index(reg_shift.args[0])
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_reg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.parses_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class armt_gpreg_rm_shift_off

class armt_gpreg_rm_shift_off(arm_reg):
    parser = armt_gpreg_shift_off

    def decode(self, v):
        v = v & self.lmask
        if v >= len(gpregs_nosppc.expr):
            return False
        r = gpregs_nosppc.expr[v]
        if r == reg_dum:
            return False

        i = int(self.parent.imm5_3.value) << 2
        i |= int(self.parent.imm5_2.value)

        if self.parent.stype.value < 3 or i != 0:
            shift = allshifts_armt[self.parent.stype.value]
        else:
            shift = allshifts_armt[4]
        self.expr = ExprOp(shift, r, ExprInt(i, 32))
        return True

    def encode(self):
        e = self.expr
        if isinstance(e, ExprId):
            if e not in gpregs_nosppc.expr:
                return False
            self.value = gpregs_nosppc.expr.index(e)
            self.parent.stype.value = 0
            self.parent.imm5_3.value = 0
            self.parent.imm5_2.value = 0
            return True
        if not e.is_op():
            return False
        shift = e.op
        r = gpregs_nosppc.expr.index(e.args[0])
        self.value = r
        i = int(e.args[1])
        if shift == 'rrx':
            if i != 1:
                log.debug('rrx shift must be 1')
                return False
            self.parent.imm5_3.value = 0
            self.parent.imm5_2.value = 0
            self.parent.stype.value = 3
            return True
        self.parent.stype.value = allshifts_armt.index(shift)
        self.parent.imm5_2.value = i & 3
        self.parent.imm5_3.value = i >> 2
        return True

Ancestors (in MRO)

Class variables

var parser

Inheritance: arm_reg.parser

var reg_info

Inheritance: arm_reg.reg_info

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_reg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def check_fbits(

self, v)

Inheritance: arm_reg.check_fbits

def check_fbits(self, v):
    return v & self.fmask == self.fbits

def decode(

self, v)

Inheritance: arm_reg.decode

def decode(self, v):
    v = v & self.lmask
    if v >= len(gpregs_nosppc.expr):
        return False
    r = gpregs_nosppc.expr[v]
    if r == reg_dum:
        return False
    i = int(self.parent.imm5_3.value) << 2
    i |= int(self.parent.imm5_2.value)
    if self.parent.stype.value < 3 or i != 0:
        shift = allshifts_armt[self.parent.stype.value]
    else:
        shift = allshifts_armt[4]
    self.expr = ExprOp(shift, r, ExprInt(i, 32))
    return True

def encode(

self)

Inheritance: arm_reg.encode

def encode(self):
    e = self.expr
    if isinstance(e, ExprId):
        if e not in gpregs_nosppc.expr:
            return False
        self.value = gpregs_nosppc.expr.index(e)
        self.parent.stype.value = 0
        self.parent.imm5_3.value = 0
        self.parent.imm5_2.value = 0
        return True
    if not e.is_op():
        return False
    shift = e.op
    r = gpregs_nosppc.expr.index(e.args[0])
    self.value = r
    i = int(e.args[1])
    if shift == 'rrx':
        if i != 1:
            log.debug('rrx shift must be 1')
            return False
        self.parent.imm5_3.value = 0
        self.parent.imm5_2.value = 0
        self.parent.stype.value = 3
        return True
    self.parent.stype.value = allshifts_armt.index(shift)
    self.parent.imm5_2.value = i & 3
    self.parent.imm5_3.value = i >> 2
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_reg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.parses_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class armt_imm5_1

class armt_imm5_1(arm_imm):

    def decode(self, v):
        v = ((self.parent.imm1.value << 5) | v) << 1
        self.expr = ExprInt(v, 32)
        return True

    def encode(self):
        if not isinstance(self.expr, ExprInt):
            return False
        v = self.expr.arg.arg
        if v & 0x1:
            return False
        self.parent.imm1.value = (v >> 6) & 1
        self.value = (v >> 1) & 0x1f
        return True

Ancestors (in MRO)

Class variables

var intmask

Inheritance: arm_imm.intmask

var intsize

Inheritance: arm_imm.intsize

var parser

Inheritance: arm_imm.parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_imm.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

Inheritance: arm_imm.decode

def decode(self, v):
    v = ((self.parent.imm1.value << 5) | v) << 1
    self.expr = ExprInt(v, 32)
    return True

def decodeval(

self, v)

Inheritance: arm_imm.decodeval

def decodeval(self, v):
    return v

def encode(

self)

Inheritance: arm_imm.encode

def encode(self):
    if not isinstance(self.expr, ExprInt):
        return False
    v = self.expr.arg.arg
    if v & 0x1:
        return False
    self.parent.imm1.value = (v >> 6) & 1
    self.value = (v >> 1) & 0x1f
    return True

def encodeval(

self, v)

Inheritance: arm_imm.encodeval

def encodeval(self, v):
    if v > self.lmask:
        return False
    return v

def expr2int(

self, e)

Inheritance: arm_imm.expr2int

def expr2int(self, e):
    if not isinstance(e, m2_expr.ExprInt):
        return None
    v = int(e)
    if v & ~self.intmask != 0:
        return None
    return v

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_imm.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
    else:
        try:
            e, start, stop = self.parser.scanString(text).next()
        except StopIteration:
            return None, None
    if e == [None]:
        return None, None
    assert(isinstance(e, m2_expr.Expr))
    if isinstance(e, tuple):
        self.expr = self.int2expr(e[1])
    elif isinstance(e, m2_expr.Expr):
        self.expr = e
    else:
        raise TypeError('zarb expr')
    if self.expr is None:
        log.debug('cannot fromstring int %r', text)
        return None, None
    return start, stop

def int2expr(

self, v)

Inheritance: arm_imm.int2expr

def int2expr(self, v):
    if (v & ~self.intmask) != 0:
        return None
    return m2_expr.ExprInt(v, self.intsize)

class armt_it_arg

class armt_it_arg(arm_arg):
    arg_E = ExprId('E', 1)
    arg_NE = ExprId('NE', 1)

    def decode(self, v):
        if v:
            return self.arg_E
        else:
            return self.arg_NE

    def encode(self):
        if self.expr == self.arg_E:
            return 1
        elif self.expr == self.arg_NE:
            return 0

Ancestors (in MRO)

Class variables

var arg_E

var arg_NE

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_arg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

def decode(self, v):
    if v:
        return self.arg_E
    else:
        return self.arg_NE

def encode(

self)

def encode(self):
    if self.expr == self.arg_E:
        return 1
    elif self.expr == self.arg_NE:
        return 0

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_arg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class armt_itmask

class armt_itmask(bs_divert):
    prio = 2

    def divert(self, i, candidates):
        out = []
        for cls, _, bases, dct, fields in candidates:
            for value in xrange(1, 0x10):
                nfields = fields[:]
                s = int2bin(value, self.args['l'])
                args = dict(self.args)
                args.update({'strbits': s})
                f = bs(**args)
                nfields[i] = f
                inv = nfields[-2].value
                ndct = dict(dct)
                ndct['name'] = self.modname(ndct['name'], value, inv)
                out.append((cls, ndct['name'], bases, ndct, nfields))
        return out

    def modname(self, name, value, inv):
        count = 0
        while value & (1 << count) == 0:
            count += 1
        out = []
        values = ['E', 'T']
        if inv== 1:
            values.reverse()
        for index in xrange(3 - count):
            if value & (1 << (3 - index)):
                out.append(values[0])
            else:
                out.append(values[1])
        return name + "".join(out)

Ancestors (in MRO)

  • armt_itmask
  • miasm2.core.cpu.bs_divert
  • __builtin__.object

Class variables

var prio

Methods

def __init__(

self, **kargs)

def __init__(self, **kargs):
    self.args = kargs

def divert(

self, i, candidates)

def divert(self, i, candidates):
    out = []
    for cls, _, bases, dct, fields in candidates:
        for value in xrange(1, 0x10):
            nfields = fields[:]
            s = int2bin(value, self.args['l'])
            args = dict(self.args)
            args.update({'strbits': s})
            f = bs(**args)
            nfields[i] = f
            inv = nfields[-2].value
            ndct = dict(dct)
            ndct['name'] = self.modname(ndct['name'], value, inv)
            out.append((cls, ndct['name'], bases, ndct, nfields))
    return out

def modname(

self, name, value, inv)

def modname(self, name, value, inv):
    count = 0
    while value & (1 << count) == 0:
        count += 1
    out = []
    values = ['E', 'T']
    if inv== 1:
        values.reverse()
    for index in xrange(3 - count):
        if value & (1 << (3 - index)):
            out.append(values[0])
        else:
            out.append(values[1])
    return name + "".join(out)

class armt_op2imm

class armt_op2imm(arm_imm8_12):
    parser = deref

    def str_to_imm_rot_form(self, s, neg=False):
        if neg:
            s = -s & 0xffffffff
        if 0 <= s < (1 << 12):
            return s
        return None

    def decodeval(self, v):
        return v

    def encodeval(self, v):
        return v

    def decode(self, v):
        val = v & self.lmask
        val = self.decodeval(val)
        if val is False:
            return False
        imm = val
        if self.parent.updown.value == 0:
            imm = -imm
        if self.parent.ppi.value == 0 and self.parent.wback.value == 0:
            return False
        if self.parent.ppi.value:
            e = ExprOp('preinc', self.parent.rn.expr, ExprInt(imm, 32))
            if self.parent.wback.value == 1:
                e = ExprOp('wback', e)
        else:
            e = ExprOp('postinc', self.parent.rn.expr, ExprInt(imm, 32))
        self.expr = ExprMem(e, 32)
        return True

    def encode(self):
        self.parent.updown.value = 1
        self.parent.wback.value = 0

        e = self.expr
        assert(isinstance(e, ExprMem))
        e = e.arg
        if e.op == 'wback':
            self.parent.wback.value = 1
            e = e.args[0]
        if e.op == "postinc":
            self.parent.ppi.value = 0
            self.parent.wback.value = 1
        elif e.op == "preinc":
            self.parent.ppi.value = 1
        else:
            # XXX default
            self.parent.ppi.value = 1

        self.parent.rn.expr = e.args[0]

        if len(e.args) == 1:
            self.value = 0
            return True
        # pure imm
        if isinstance(e.args[1], ExprInt):
            val = self.str_to_imm_rot_form(int(e.args[1]))
            if val is None:
                val = self.str_to_imm_rot_form(int(e.args[1]), True)
                if val is None:
                    log.debug('cannot encode inm')
                    return False
                self.parent.updown.value = 0
            val = self.encodeval(val)
            if val is False:
                return False
            self.value = val
            return True
        # pure reg
        if isinstance(e.args[1], ExprId):
            rm = gpregs.expr.index(e.args[1])
            shift_kind = 0
            shift_type = 0
            amount = 0
            val = (((((amount << 2) | shift_type) << 1) | shift_kind) << 4) | rm
            val = self.encodeval(val)
            if val is False:
                return False
            self.value = val
            return True
        return False

Ancestors (in MRO)

Class variables

var parser

Inheritance: arm_imm8_12.parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_imm8_12.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

Inheritance: arm_imm8_12.decode

def decode(self, v):
    val = v & self.lmask
    val = self.decodeval(val)
    if val is False:
        return False
    imm = val
    if self.parent.updown.value == 0:
        imm = -imm
    if self.parent.ppi.value == 0 and self.parent.wback.value == 0:
        return False
    if self.parent.ppi.value:
        e = ExprOp('preinc', self.parent.rn.expr, ExprInt(imm, 32))
        if self.parent.wback.value == 1:
            e = ExprOp('wback', e)
    else:
        e = ExprOp('postinc', self.parent.rn.expr, ExprInt(imm, 32))
    self.expr = ExprMem(e, 32)
    return True

def decodeval(

self, v)

def decodeval(self, v):
    return v

def encode(

self)

Inheritance: arm_imm8_12.encode

def encode(self):
    self.parent.updown.value = 1
    self.parent.wback.value = 0
    e = self.expr
    assert(isinstance(e, ExprMem))
    e = e.arg
    if e.op == 'wback':
        self.parent.wback.value = 1
        e = e.args[0]
    if e.op == "postinc":
        self.parent.ppi.value = 0
        self.parent.wback.value = 1
    elif e.op == "preinc":
        self.parent.ppi.value = 1
    else:
        # XXX default
        self.parent.ppi.value = 1
    self.parent.rn.expr = e.args[0]
    if len(e.args) == 1:
        self.value = 0
        return True
    # pure imm
    if isinstance(e.args[1], ExprInt):
        val = self.str_to_imm_rot_form(int(e.args[1]))
        if val is None:
            val = self.str_to_imm_rot_form(int(e.args[1]), True)
            if val is None:
                log.debug('cannot encode inm')
                return False
            self.parent.updown.value = 0
        val = self.encodeval(val)
        if val is False:
            return False
        self.value = val
        return True
    # pure reg
    if isinstance(e.args[1], ExprId):
        rm = gpregs.expr.index(e.args[1])
        shift_kind = 0
        shift_type = 0
        amount = 0
        val = (((((amount << 2) | shift_type) << 1) | shift_kind) << 4) | rm
        val = self.encodeval(val)
        if val is False:
            return False
        self.value = val
        return True
    return False

def encodeval(

self, v)

def encodeval(self, v):
    return v

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_imm8_12.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

def str_to_imm_rot_form(

self, s, neg=False)

def str_to_imm_rot_form(self, s, neg=False):
    if neg:
        s = -s & 0xffffffff
    if 0 <= s < (1 << 12):
        return s
    return None

class armt_op2imm00

class armt_op2imm00(armt_op2imm):

    def decodeval(self, v):
        return v << 2

    def encodeval(self, v):
        if v & 3:
            return False
        return v >> 2

Ancestors (in MRO)

Class variables

var parser

Inheritance: armt_op2imm.parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: armt_op2imm.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

Inheritance: armt_op2imm.decode

def decode(self, v):
    val = v & self.lmask
    val = self.decodeval(val)
    if val is False:
        return False
    imm = val
    if self.parent.updown.value == 0:
        imm = -imm
    if self.parent.ppi.value == 0 and self.parent.wback.value == 0:
        return False
    if self.parent.ppi.value:
        e = ExprOp('preinc', self.parent.rn.expr, ExprInt(imm, 32))
        if self.parent.wback.value == 1:
            e = ExprOp('wback', e)
    else:
        e = ExprOp('postinc', self.parent.rn.expr, ExprInt(imm, 32))
    self.expr = ExprMem(e, 32)
    return True

def decodeval(

self, v)

Inheritance: armt_op2imm.decodeval

def decodeval(self, v):
    return v << 2

def encode(

self)

Inheritance: armt_op2imm.encode

def encode(self):
    self.parent.updown.value = 1
    self.parent.wback.value = 0
    e = self.expr
    assert(isinstance(e, ExprMem))
    e = e.arg
    if e.op == 'wback':
        self.parent.wback.value = 1
        e = e.args[0]
    if e.op == "postinc":
        self.parent.ppi.value = 0
        self.parent.wback.value = 1
    elif e.op == "preinc":
        self.parent.ppi.value = 1
    else:
        # XXX default
        self.parent.ppi.value = 1
    self.parent.rn.expr = e.args[0]
    if len(e.args) == 1:
        self.value = 0
        return True
    # pure imm
    if isinstance(e.args[1], ExprInt):
        val = self.str_to_imm_rot_form(int(e.args[1]))
        if val is None:
            val = self.str_to_imm_rot_form(int(e.args[1]), True)
            if val is None:
                log.debug('cannot encode inm')
                return False
            self.parent.updown.value = 0
        val = self.encodeval(val)
        if val is False:
            return False
        self.value = val
        return True
    # pure reg
    if isinstance(e.args[1], ExprId):
        rm = gpregs.expr.index(e.args[1])
        shift_kind = 0
        shift_type = 0
        amount = 0
        val = (((((amount << 2) | shift_type) << 1) | shift_kind) << 4) | rm
        val = self.encodeval(val)
        if val is False:
            return False
        self.value = val
        return True
    return False

def encodeval(

self, v)

Inheritance: armt_op2imm.encodeval

def encodeval(self, v):
    if v & 3:
        return False
    return v >> 2

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: armt_op2imm.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

def str_to_imm_rot_form(

self, s, neg=False)

Inheritance: armt_op2imm.str_to_imm_rot_form

def str_to_imm_rot_form(self, s, neg=False):
    if neg:
        s = -s & 0xffffffff
    if 0 <= s < (1 << 12):
        return s
    return None

class armt_reg_wb

class armt_reg_wb(arm_reg_wb):
    reg_info = gpregs_l
    parser = gpregs_l_wb

    def decode(self, v):
        v = v & self.lmask
        e = self.reg_info.expr[v]
        if not e in self.parent.trlist.expr.args:
            e = ExprOp('wback', e)
        self.expr = e
        return True

    def encode(self):
        e = self.expr
        if isinstance(e, ExprOp):
            if e.op != 'wback':
                return False
            e = e.args[0]
        self.value = self.reg_info.expr.index(e)
        return True

Ancestors (in MRO)

Class variables

var parser

Inheritance: arm_reg_wb.parser

var reg_info

Inheritance: arm_reg_wb.reg_info

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_reg_wb.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def check_fbits(

self, v)

Inheritance: arm_reg_wb.check_fbits

def check_fbits(self, v):
    return v & self.fmask == self.fbits

def decode(

self, v)

Inheritance: arm_reg_wb.decode

def decode(self, v):
    v = v & self.lmask
    e = self.reg_info.expr[v]
    if not e in self.parent.trlist.expr.args:
        e = ExprOp('wback', e)
    self.expr = e
    return True

def encode(

self)

Inheritance: arm_reg_wb.encode

def encode(self):
    e = self.expr
    if isinstance(e, ExprOp):
        if e.op != 'wback':
            return False
        e = e.args[0]
    self.value = self.reg_info.expr.index(e)
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_reg_wb.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.parses_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class armt_rlist

class armt_rlist(arm_arg):
    parser = gpreg_list

    def encode(self):
        e = self.expr
        rlist = [gpregs_l.expr.index(x) for x in e.args]
        v = 0
        for r in rlist:
            v |= 1 << r
        self.value = v
        return True

    def decode(self, v):
        v = v & self.lmask
        out = []
        for i in xrange(0x10):
            if 1 << i & v:
                out.append(gpregs.expr[i])
        if not out:
            return False
        e = ExprOp('reglist', *out)
        self.expr = e
        return True

Ancestors (in MRO)

Class variables

var parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_arg.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

def decode(self, v):
    v = v & self.lmask
    out = []
    for i in xrange(0x10):
        if 1 << i & v:
            out.append(gpregs.expr[i])
    if not out:
        return False
    e = ExprOp('reglist', *out)
    self.expr = e
    return True

def encode(

self)

def encode(self):
    e = self.expr
    rlist = [gpregs_l.expr.index(x) for x in e.args]
    v = 0
    for r in rlist:
        v |= 1 << r
    self.value = v
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_arg.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class armt_rlist13

class armt_rlist13(armt_rlist):
    parser = gpreg_list

    def encode(self):
        e = self.expr
        rlist = []
        reg_l = list(e.args)

        self.parent.pclr.value = 0
        if self.parent.name.startswith('PUSH'):
            if regs_expr[14] in reg_l:
                reg_l.remove(regs_expr[14])
                self.parent.pclr.value = 1
        else:
            if regs_expr[15] in reg_l:
                reg_l.remove(regs_expr[15])
                self.parent.pclr.value = 1

        for reg in reg_l:
            if reg not in gpregs_l_13.expr:
                return False
            rlist.append(gpregs_l_13.expr.index(reg))
        v = 0
        for r in rlist:
            v |= 1 << r
        self.value = v
        return True

    def decode(self, v):
        v = v & self.lmask
        out = []
        for i in xrange(13):
            if 1 << i & v:
                out.append(gpregs_l_13.expr[i])

        if self.parent.pclr.value == 1:
            if self.parent.name.startswith("PUSH"):
                out += [regs_expr[14]]
            else:
                out += [regs_expr[15]]

        if not out:
            return False
        e = ExprOp('reglist', *out)
        self.expr = e
        return True

Ancestors (in MRO)

Class variables

var parser

Inheritance: armt_rlist.parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: armt_rlist.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

Inheritance: armt_rlist.decode

def decode(self, v):
    v = v & self.lmask
    out = []
    for i in xrange(13):
        if 1 << i & v:
            out.append(gpregs_l_13.expr[i])
    if self.parent.pclr.value == 1:
        if self.parent.name.startswith("PUSH"):
            out += [regs_expr[14]]
        else:
            out += [regs_expr[15]]
    if not out:
        return False
    e = ExprOp('reglist', *out)
    self.expr = e
    return True

def encode(

self)

Inheritance: armt_rlist.encode

def encode(self):
    e = self.expr
    rlist = []
    reg_l = list(e.args)
    self.parent.pclr.value = 0
    if self.parent.name.startswith('PUSH'):
        if regs_expr[14] in reg_l:
            reg_l.remove(regs_expr[14])
            self.parent.pclr.value = 1
    else:
        if regs_expr[15] in reg_l:
            reg_l.remove(regs_expr[15])
            self.parent.pclr.value = 1
    for reg in reg_l:
        if reg not in gpregs_l_13.expr:
            return False
        rlist.append(gpregs_l_13.expr.index(reg))
    v = 0
    for r in rlist:
        v |= 1 << r
    self.value = v
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: armt_rlist.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class armt_rlist13_pc_lr

class armt_rlist13_pc_lr(armt_rlist):
    parser = gpreg_list

    def encode(self):
        e = self.expr
        rlist = []
        reg_l = list(e.args)

        self.parent.pc_in.value = 0
        self.parent.lr_in.value = 0
        if regs_expr[14] in reg_l:
            reg_l.remove(regs_expr[14])
            self.parent.lr_in.value = 1
        if regs_expr[15] in reg_l:
            reg_l.remove(regs_expr[15])
            self.parent.pc_in.value = 1

        for reg in reg_l:
            if reg not in gpregs_l_13.expr:
                return False
            rlist.append(gpregs_l_13.expr.index(reg))
        v = 0
        for r in rlist:
            v |= 1 << r
        self.value = v
        return True

    def decode(self, v):
        v = v & self.lmask
        out = []
        for i in xrange(13):
            if 1 << i & v:
                out.append(gpregs_l_13.expr[i])

        if self.parent.lr_in.value == 1:
            out += [regs_expr[14]]
        if self.parent.pc_in.value == 1:
            out += [regs_expr[15]]

        if not out:
            return False
        e = ExprOp('reglist', *out)
        self.expr = e
        return True

Ancestors (in MRO)

Class variables

var parser

Inheritance: armt_rlist.parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: armt_rlist.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

Inheritance: armt_rlist.decode

def decode(self, v):
    v = v & self.lmask
    out = []
    for i in xrange(13):
        if 1 << i & v:
            out.append(gpregs_l_13.expr[i])
    if self.parent.lr_in.value == 1:
        out += [regs_expr[14]]
    if self.parent.pc_in.value == 1:
        out += [regs_expr[15]]
    if not out:
        return False
    e = ExprOp('reglist', *out)
    self.expr = e
    return True

def encode(

self)

Inheritance: armt_rlist.encode

def encode(self):
    e = self.expr
    rlist = []
    reg_l = list(e.args)
    self.parent.pc_in.value = 0
    self.parent.lr_in.value = 0
    if regs_expr[14] in reg_l:
        reg_l.remove(regs_expr[14])
        self.parent.lr_in.value = 1
    if regs_expr[15] in reg_l:
        reg_l.remove(regs_expr[15])
        self.parent.pc_in.value = 1
    for reg in reg_l:
        if reg not in gpregs_l_13.expr:
            return False
        rlist.append(gpregs_l_13.expr.index(reg))
    v = 0
    for r in rlist:
        v |= 1 << r
    self.value = v
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: armt_rlist.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class armt_rlist_pclr

class armt_rlist_pclr(armt_rlist):

    def encode(self):
        e = self.expr
        reg_l = list(e.args)
        self.parent.pclr.value = 0
        if self.parent.pp.value == 0:
            if regs_expr[14] in reg_l:
                reg_l.remove(regs_expr[14])
                self.parent.pclr.value = 1
        else:
            if regs_expr[15] in reg_l:
                reg_l.remove(regs_expr[15])
                self.parent.pclr.value = 1
        rlist = [gpregs.expr.index(x) for x in reg_l]
        v = 0
        for r in rlist:
            v |= 1 << r
        if v > self.lmask:
            return False
        self.value = v
        return True

    def decode(self, v):
        v = v & self.lmask
        out = []
        for i in xrange(0x10):
            if 1 << i & v:
                out.append(gpregs.expr[i])

        if self.parent.pclr.value == 1:
            if self.parent.pp.value == 0:
                out += [regs_expr[14]]
            else:
                out += [regs_expr[15]]
        if not out:
            return False
        e = ExprOp('reglist', *out)
        self.expr = e
        return True

Ancestors (in MRO)

Class variables

var parser

Inheritance: armt_rlist.parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: armt_rlist.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

Inheritance: armt_rlist.decode

def decode(self, v):
    v = v & self.lmask
    out = []
    for i in xrange(0x10):
        if 1 << i & v:
            out.append(gpregs.expr[i])
    if self.parent.pclr.value == 1:
        if self.parent.pp.value == 0:
            out += [regs_expr[14]]
        else:
            out += [regs_expr[15]]
    if not out:
        return False
    e = ExprOp('reglist', *out)
    self.expr = e
    return True

def encode(

self)

Inheritance: armt_rlist.encode

def encode(self):
    e = self.expr
    reg_l = list(e.args)
    self.parent.pclr.value = 0
    if self.parent.pp.value == 0:
        if regs_expr[14] in reg_l:
            reg_l.remove(regs_expr[14])
            self.parent.pclr.value = 1
    else:
        if regs_expr[15] in reg_l:
            reg_l.remove(regs_expr[15])
            self.parent.pclr.value = 1
    rlist = [gpregs.expr.index(x) for x in reg_l]
    v = 0
    for r in rlist:
        v |= 1 << r
    if v > self.lmask:
        return False
    self.value = v
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: armt_rlist.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
        self.expr = e
        return start, stop
    try:
        v, start, stop = self.parser.scanString(text).next()
    except StopIteration:
        return None, None
    arg = v[0]
    expr = self.asm_ast_to_expr(arg, loc_db)
    self.expr = expr
    return start, stop

class armt_rm_cp

class armt_rm_cp(bsi):

    def decode(self, v):
        if v != gpregs.expr.index(self.parent.rm.expr):
            return False
        return True

    def encode(self):
        self.value = gpregs.expr.index(self.parent.rm.expr)
        return True

Ancestors (in MRO)

  • armt_rm_cp
  • miasm2.core.cpu.bsi
  • __builtin__.object

Instance variables

var lmask

Methods

def __init__(

self, parent, strbits, l, cls, fname, order, lmask, fbits, fmask, value, flen, **kargs)

def __init__(self, parent, strbits, l, cls, fname, order,
             lmask, fbits, fmask, value, flen, **kargs):
    self.parent = parent
    self.strbits = strbits
    self.l = l
    self.cls = cls
    self.fname = fname
    self.order = order
    self.fbits = fbits
    self.fmask = fmask
    self.flen = flen
    self.value = value
    self.kargs = kargs
    self.__dict__.update(self.kargs)

def clone(

self)

def clone(self):
    s = self.__class__(self.parent,
                       self.strbits, self.l, self.cls,
                       self.fname, self.order, self.lmask, self.fbits,
                       self.fmask, self.value, self.flen, **self.kargs)
    s.__dict__.update(self.kargs)
    if hasattr(self, 'expr'):
        s.expr = self.expr
    return s

def decode(

self, v)

def decode(self, v):
    if v != gpregs.expr.index(self.parent.rm.expr):
        return False
    return True

def encode(

self)

def encode(self):
    self.value = gpregs.expr.index(self.parent.rm.expr)
    return True

class armt_widthm1

class armt_widthm1(arm_imm):
    parser = base_expr

    def decodeval(self, v):
        return v + 1

    def encodeval(self, v):
        if v <= 0:
            return False
        return v - 1

Ancestors (in MRO)

Class variables

var intmask

Inheritance: arm_imm.intmask

var intsize

Inheritance: arm_imm.intsize

var parser

Inheritance: arm_imm.parser

Methods

def asm_ast_to_expr(

self, arg, loc_db)

Inheritance: arm_imm.asm_ast_to_expr

def asm_ast_to_expr(self, arg, loc_db):
    if isinstance(arg, AstId):
        if isinstance(arg.name, ExprId):
            return arg.name
        if arg.name in gpregs.str:
            return None
        loc_key = loc_db.get_or_create_name_location(arg.name)
        return ExprLoc(loc_key, 32)
    if isinstance(arg, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
        if None in args:
            return None
        return ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return ExprInt(arg.value, 32)
    if isinstance(arg, AstMem):
        ptr = self.asm_ast_to_expr(arg.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, arg.size)
    return None

def decode(

self, v)

Inheritance: arm_imm.decode

def decode(self, v):
    v = v & self.lmask
    v = self.decodeval(v)
    e = self.int2expr(v)
    if not e:
        return False
    self.expr = e
    return True

def decodeval(

self, v)

Inheritance: arm_imm.decodeval

def decodeval(self, v):
    return v + 1

def encode(

self)

Inheritance: arm_imm.encode

def encode(self):
    v = self.expr2int(self.expr)
    if v is None:
        return False
    v = self.encodeval(v)
    if v is False:
        return False
    if v > self.lmask:
        return False
    self.value = v
    return True

def encodeval(

self, v)

Inheritance: arm_imm.encodeval

def encodeval(self, v):
    if v <= 0:
        return False
    return v - 1

def expr2int(

self, e)

Inheritance: arm_imm.expr2int

def expr2int(self, e):
    if not isinstance(e, m2_expr.ExprInt):
        return None
    v = int(e)
    if v & ~self.intmask != 0:
        return None
    return v

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: arm_imm.fromstring

def fromstring(self, text, loc_db, parser_result=None):
    if parser_result:
        e, start, stop = parser_result[self.parser]
    else:
        try:
            e, start, stop = self.parser.scanString(text).next()
        except StopIteration:
            return None, None
    if e == [None]:
        return None, None
    assert(isinstance(e, m2_expr.Expr))
    if isinstance(e, tuple):
        self.expr = self.int2expr(e[1])
    elif isinstance(e, m2_expr.Expr):
        self.expr = e
    else:
        raise TypeError('zarb expr')
    if self.expr is None:
        log.debug('cannot fromstring int %r', text)
        return None, None
    return start, stop

def int2expr(

self, v)

Inheritance: arm_imm.int2expr

def int2expr(self, v):
    if (v & ~self.intmask) != 0:
        return None
    return m2_expr.ExprInt(v, self.intsize)

class bs_lnk

class bs_lnk(bs_mod_name):

    def modname(self, name, i):
        return name[:1] + self.args['mn_mod'][i] + name[1:]

Ancestors (in MRO)

  • bs_lnk
  • miasm2.core.cpu.bs_mod_name
  • miasm2.core.cpu.bs_divert
  • __builtin__.object

Class variables

var prio

Methods

def __init__(

self, **kargs)

def __init__(self, **kargs):
    self.args = kargs

def divert(

self, i, candidates)

def divert(self, i, candidates):
    out = []
    for cls, _, bases, dct, fields in candidates:
        tab = self.args['mn_mod']
        if isinstance(tab, list):
            tmp = {}
            for j, v in enumerate(tab):
                tmp[j] = v
            tab = tmp
        for value, new_name in tab.iteritems():
            nfields = fields[:]
            s = int2bin(value, self.args['l'])
            args = dict(self.args)
            args.update({'strbits': s})
            f = bs(**args)
            nfields[i] = f
            ndct = dict(dct)
            ndct['name'] = self.modname(ndct['name'], value)
            out.append((cls, new_name, bases, ndct, nfields))
    return out

def modname(

self, name, i)

def modname(self, name, i):
    return name[:1] + self.args['mn_mod'][i] + name[1:]

class instruction_arm

class instruction_arm(instruction):
    __slots__ = []
    delayslot = 0

    def __init__(self, *args, **kargs):
        super(instruction_arm, self).__init__(*args, **kargs)

    @staticmethod
    def arg2str(expr, index=None, loc_db=None):
        wb = False
        if expr.is_id() or expr.is_int():
            return str(expr)
        elif expr.is_loc():
            if loc_db is not None:
                return loc_db.pretty_str(expr.loc_key)
            else:
                return str(expr)
        if isinstance(expr, ExprOp) and expr.op in expr2shift_dct:
            if len(expr.args) == 1:
                return '%s %s' % (expr.args[0], expr2shift_dct[expr.op])
            elif len(expr.args) == 2:
                return '%s %s %s' % (expr.args[0], expr2shift_dct[expr.op], expr.args[1])
            else:
                raise NotImplementedError('zarb arg2str')


        sb = False
        if isinstance(expr, ExprOp) and expr.op == "sbit":
            sb = True
            expr = expr.args[0]
        if isinstance(expr, ExprOp) and expr.op == "reglist":
            o = [gpregs.expr.index(x) for x in expr.args]
            out = reglist2str(o)
            if sb:
                out += "^"
            return out


        if isinstance(expr, ExprOp) and expr.op == 'wback':
            wb = True
            expr = expr.args[0]
        if isinstance(expr, ExprId):
            out = str(expr)
            if wb:
                out += "!"
            return out

        if not isinstance(expr, ExprMem):
            return str(expr)

        expr = expr.arg
        if isinstance(expr, ExprOp) and expr.op == 'wback':
            wb = True
            expr = expr.args[0]


        if isinstance(expr, ExprId):
            r, s = expr, None
        elif len(expr.args) == 1 and isinstance(expr.args[0], ExprId):
            r, s = expr.args[0], None
        elif isinstance(expr.args[0], ExprId):
            r, s = expr.args[0], expr.args[1]
        else:
            r, s = expr.args[0].args
        if isinstance(s, ExprOp) and s.op in expr2shift_dct:
            s = ' '.join([str(x)
                for x in s.args[0], expr2shift_dct[s.op], s.args[1]])

        if isinstance(expr, ExprOp) and expr.op == 'postinc':
            o = '[%s]' % r
            if s and not (isinstance(s, ExprInt) and s.arg == 0):
                o += ', %s' % s
        else:
            if s and not (isinstance(s, ExprInt) and s.arg == 0):
                o = '[%s, %s]' % (r, s)
            else:
                o = '[%s]' % (r)


        if wb:
            o += "!"
        return o


    def dstflow(self):
        if self.is_subcall():
            return True
        return self.name in conditional_branch + unconditional_branch

    def dstflow2label(self, loc_db):
        expr = self.args[0]
        if not isinstance(expr, ExprInt):
            return
        if self.name == 'BLX':
            addr = expr.arg + self.offset
        else:
            addr = expr.arg + self.offset
        loc_key = loc_db.get_or_create_offset_location(addr)
        self.args[0] = ExprLoc(loc_key, expr.size)

    def breakflow(self):
        if self.is_subcall():
            return True
        if self.name in conditional_branch + unconditional_branch:
            return True
        if self.name.startswith("LDM") and PC in self.args[1].args:
            return True
        if self.args and PC in self.args[0].get_r():
            return True
        return False

    def is_subcall(self):
        if self.name == 'BLX':
            return True
        return self.additional_info.lnk

    def getdstflow(self, loc_db):
        return [self.args[0]]

    def splitflow(self):
        if self.additional_info.lnk:
            return True
        if self.name == 'BLX':
            return True
        if self.name == 'BX':
            return False
        return self.breakflow() and self.additional_info.cond != 14

    def get_symbol_size(self, symbol, loc_db):
        return 32

    def fixDstOffset(self):
        e = self.args[0]
        if self.offset is None:
            raise ValueError('symbol not resolved %s' % l)
        if not isinstance(e, ExprInt):
            log.debug('dyn dst %r', e)
            return
        off = e.arg - self.offset
        if int(off % 4):
            raise ValueError('strange offset! %r' % off)
        self.args[0] = ExprInt(off, 32)

    def get_args_expr(self):
        args = [a for a in self.args]
        return args

    def get_asm_offset(self, expr):
        # LDR XXX, [PC, offset] => PC is self.offset+8
        return ExprInt(self.offset+8, expr.size)

Ancestors (in MRO)

Class variables

var additional_info

var args

var b

var data

var delayslot

var l

var mode

var name

var offset

Static methods

def arg2str(

expr, index=None, loc_db=None)

@staticmethod
def arg2str(expr, index=None, loc_db=None):
    wb = False
    if expr.is_id() or expr.is_int():
        return str(expr)
    elif expr.is_loc():
        if loc_db is not None:
            return loc_db.pretty_str(expr.loc_key)
        else:
            return str(expr)
    if isinstance(expr, ExprOp) and expr.op in expr2shift_dct:
        if len(expr.args) == 1:
            return '%s %s' % (expr.args[0], expr2shift_dct[expr.op])
        elif len(expr.args) == 2:
            return '%s %s %s' % (expr.args[0], expr2shift_dct[expr.op], expr.args[1])
        else:
            raise NotImplementedError('zarb arg2str')
    sb = False
    if isinstance(expr, ExprOp) and expr.op == "sbit":
        sb = True
        expr = expr.args[0]
    if isinstance(expr, ExprOp) and expr.op == "reglist":
        o = [gpregs.expr.index(x) for x in expr.args]
        out = reglist2str(o)
        if sb:
            out += "^"
        return out
    if isinstance(expr, ExprOp) and expr.op == 'wback':
        wb = True
        expr = expr.args[0]
    if isinstance(expr, ExprId):
        out = str(expr)
        if wb:
            out += "!"
        return out
    if not isinstance(expr, ExprMem):
        return str(expr)
    expr = expr.arg
    if isinstance(expr, ExprOp) and expr.op == 'wback':
        wb = True
        expr = expr.args[0]
    if isinstance(expr, ExprId):
        r, s = expr, None
    elif len(expr.args) == 1 and isinstance(expr.args[0], ExprId):
        r, s = expr.args[0], None
    elif isinstance(expr.args[0], ExprId):
        r, s = expr.args[0], expr.args[1]
    else:
        r, s = expr.args[0].args
    if isinstance(s, ExprOp) and s.op in expr2shift_dct:
        s = ' '.join([str(x)
            for x in s.args[0], expr2shift_dct[s.op], s.args[1]])
    if isinstance(expr, ExprOp) and expr.op == 'postinc':
        o = '[%s]' % r
        if s and not (isinstance(s, ExprInt) and s.arg == 0):
            o += ', %s' % s
    else:
        if s and not (isinstance(s, ExprInt) and s.arg == 0):
            o = '[%s, %s]' % (r, s)
        else:
            o = '[%s]' % (r)
    if wb:
        o += "!"
    return o

Methods

def __init__(

self, *args, **kargs)

def __init__(self, *args, **kargs):
    super(instruction_arm, self).__init__(*args, **kargs)

def breakflow(

self)

def breakflow(self):
    if self.is_subcall():
        return True
    if self.name in conditional_branch + unconditional_branch:
        return True
    if self.name.startswith("LDM") and PC in self.args[1].args:
        return True
    if self.args and PC in self.args[0].get_r():
        return True
    return False

def dstflow(

self)

def dstflow(self):
    if self.is_subcall():
        return True
    return self.name in conditional_branch + unconditional_branch

def dstflow2label(

self, loc_db)

def dstflow2label(self, loc_db):
    expr = self.args[0]
    if not isinstance(expr, ExprInt):
        return
    if self.name == 'BLX':
        addr = expr.arg + self.offset
    else:
        addr = expr.arg + self.offset
    loc_key = loc_db.get_or_create_offset_location(addr)
    self.args[0] = ExprLoc(loc_key, expr.size)

def fixDstOffset(

self)

def fixDstOffset(self):
    e = self.args[0]
    if self.offset is None:
        raise ValueError('symbol not resolved %s' % l)
    if not isinstance(e, ExprInt):
        log.debug('dyn dst %r', e)
        return
    off = e.arg - self.offset
    if int(off % 4):
        raise ValueError('strange offset! %r' % off)
    self.args[0] = ExprInt(off, 32)

def gen_args(

self, args)

def gen_args(self, args):
    out = ', '.join([str(x) for x in args])
    return out

def get_args_expr(

self)

def get_args_expr(self):
    args = [a for a in self.args]
    return args

def get_asm_next_offset(

self, expr)

def get_asm_next_offset(self, expr):
    return m2_expr.ExprInt(self.offset+self.l, expr.size)

def get_asm_offset(

self, expr)

def get_asm_offset(self, expr):
    # LDR XXX, [PC, offset] => PC is self.offset+8
    return ExprInt(self.offset+8, expr.size)

def get_info(

self, c)

def get_info(self, c):
    return

def get_symbol_size(

self, symbol, loc_db)

def get_symbol_size(self, symbol, loc_db):
    return 32

def getdstflow(

self, loc_db)

def getdstflow(self, loc_db):
    return [self.args[0]]

def is_subcall(

self)

def is_subcall(self):
    if self.name == 'BLX':
        return True
    return self.additional_info.lnk

def resolve_args_with_symbols(

self, symbols=None)

def resolve_args_with_symbols(self, symbols=None):
    if symbols is None:
        symbols = {}
    args_out = []
    for expr in self.args:
        # try to resolve symbols using symbols (0 for default value)
        loc_keys = m2_expr.get_expr_locs(expr)
        fixed_expr = {}
        for exprloc in loc_keys:
            loc_key = exprloc.loc_key
            names = symbols.get_location_names(loc_key)
            # special symbols
            if '$' in names:
                fixed_expr[exprloc] = self.get_asm_offset(exprloc)
                continue
            if '_' in names:
                fixed_expr[exprloc] = self.get_asm_next_offset(exprloc)
                continue
            if not names:
                raise ValueError('Unresolved symbol: %r' % exprloc)
            offset = symbols.get_location_offset(loc_key)
            if offset is None:
                raise ValueError(
                    'The offset of loc_key "%s" cannot be determined' % names
                )
            else:
                # Fix symbol with its offset
                size = exprloc.size
                if size is None:
                    default_size = self.get_symbol_size(exprloc, symbols)
                    size = default_size
                value = m2_expr.ExprInt(offset, size)
            fixed_expr[exprloc] = value
        expr = expr.replace_expr(fixed_expr)
        expr = expr_simp(expr)
        args_out.append(expr)
    return args_out

def splitflow(

self)

def splitflow(self):
    if self.additional_info.lnk:
        return True
    if self.name == 'BLX':
        return True
    if self.name == 'BX':
        return False
    return self.breakflow() and self.additional_info.cond != 14

def to_string(

self, loc_db=None)

def to_string(self, loc_db=None):
    o = "%-10s " % self.name
    args = []
    for i, arg in enumerate(self.args):
        if not isinstance(arg, m2_expr.Expr):
            raise ValueError('zarb arg type')
        x = self.arg2str(arg, i, loc_db)
        args.append(x)
    o += self.gen_args(args)
    return o

class instruction_armt

class instruction_armt(instruction_arm):
    __slots__ = []
    delayslot = 0

    def __init__(self, *args, **kargs):
        super(instruction_armt, self).__init__(*args, **kargs)

    def dstflow(self):
        if self.name in ["CBZ", "CBNZ"]:
            return True
        return self.name in conditional_branch + unconditional_branch

    def dstflow2label(self, loc_db):
        if self.name in ["CBZ", "CBNZ"]:
            expr = self.args[1]
        else:
            expr = self.args[0]
        if not isinstance(expr, ExprInt):
            return
        if self.name == 'BLX':
            addr = expr.arg + (self.offset & 0xfffffffc)
        elif self.name == 'BL':
            addr = expr.arg + self.offset
        elif self.name.startswith('BP'):
            addr = expr.arg + self.offset
        elif self.name.startswith('CB'):
            addr = expr.arg + self.offset + self.l + 2
        else:
            addr = expr.arg + self.offset

        loc_key = loc_db.get_or_create_offset_location(addr)
        dst = ExprLoc(loc_key, expr.size)

        if self.name in ["CBZ", "CBNZ"]:
            self.args[1] = dst
        else:
            self.args[0] = dst

    def breakflow(self):
        if self.name in conditional_branch + unconditional_branch +["CBZ", "CBNZ", 'TBB', 'TBH']:
            return True
        if self.name.startswith("LDM") and PC in self.args[1].args:
            return True
        if self.args and PC in self.args[0].get_r():
            return True
        return False

    def getdstflow(self, loc_db):
        if self.name in ['CBZ', 'CBNZ']:
            return [self.args[1]]
        return [self.args[0]]

    def splitflow(self):
        if self.name in conditional_branch + ['BL', 'BLX', 'CBZ', 'CBNZ']:
            return True
        return False

    def is_subcall(self):
        return self.name in ['BL', 'BLX']

    def fixDstOffset(self):
        e = self.args[0]
        if self.offset is None:
            raise ValueError('symbol not resolved %s' % l)
        if not isinstance(e, ExprInt):
            log.debug('dyn dst %r', e)
            return
        # The first +2 is to compensate instruction len, but strangely, 32 bits
        # thumb2 instructions len is 2... For the second +2, didn't find it in
        # the doc.
        off = e.arg - self.offset
        if int(off % 2):
            raise ValueError('strange offset! %r' % off)
        self.args[0] = ExprInt(off, 32)

    def get_asm_offset(self, expr):
        # ADR XXX, PC, imm => PC is 4 aligned + imm
        new_offset = ((self.offset+self.l)/4)*4
        return ExprInt(new_offset, expr.size)

Ancestors (in MRO)

Class variables

var additional_info

Inheritance: instruction_arm.additional_info

var args

Inheritance: instruction_arm.args

var b

Inheritance: instruction_arm.b

var data

Inheritance: instruction_arm.data

var delayslot

Inheritance: instruction_arm.delayslot

var l

Inheritance: instruction_arm.l

var mode

Inheritance: instruction_arm.mode

var name

Inheritance: instruction_arm.name

var offset

Inheritance: instruction_arm.offset

Static methods

def arg2str(

expr, index=None, loc_db=None)

Inheritance: instruction_arm.arg2str

@staticmethod
def arg2str(expr, index=None, loc_db=None):
    wb = False
    if expr.is_id() or expr.is_int():
        return str(expr)
    elif expr.is_loc():
        if loc_db is not None:
            return loc_db.pretty_str(expr.loc_key)
        else:
            return str(expr)
    if isinstance(expr, ExprOp) and expr.op in expr2shift_dct:
        if len(expr.args) == 1:
            return '%s %s' % (expr.args[0], expr2shift_dct[expr.op])
        elif len(expr.args) == 2:
            return '%s %s %s' % (expr.args[0], expr2shift_dct[expr.op], expr.args[1])
        else:
            raise NotImplementedError('zarb arg2str')
    sb = False
    if isinstance(expr, ExprOp) and expr.op == "sbit":
        sb = True
        expr = expr.args[0]
    if isinstance(expr, ExprOp) and expr.op == "reglist":
        o = [gpregs.expr.index(x) for x in expr.args]
        out = reglist2str(o)
        if sb:
            out += "^"
        return out
    if isinstance(expr, ExprOp) and expr.op == 'wback':
        wb = True
        expr = expr.args[0]
    if isinstance(expr, ExprId):
        out = str(expr)
        if wb:
            out += "!"
        return out
    if not isinstance(expr, ExprMem):
        return str(expr)
    expr = expr.arg
    if isinstance(expr, ExprOp) and expr.op == 'wback':
        wb = True
        expr = expr.args[0]
    if isinstance(expr, ExprId):
        r, s = expr, None
    elif len(expr.args) == 1 and isinstance(expr.args[0], ExprId):
        r, s = expr.args[0], None
    elif isinstance(expr.args[0], ExprId):
        r, s = expr.args[0], expr.args[1]
    else:
        r, s = expr.args[0].args
    if isinstance(s, ExprOp) and s.op in expr2shift_dct:
        s = ' '.join([str(x)
            for x in s.args[0], expr2shift_dct[s.op], s.args[1]])
    if isinstance(expr, ExprOp) and expr.op == 'postinc':
        o = '[%s]' % r
        if s and not (isinstance(s, ExprInt) and s.arg == 0):
            o += ', %s' % s
    else:
        if s and not (isinstance(s, ExprInt) and s.arg == 0):
            o = '[%s, %s]' % (r, s)
        else:
            o = '[%s]' % (r)
    if wb:
        o += "!"
    return o

Methods

def __init__(

self, *args, **kargs)

Inheritance: instruction_arm.__init__

def __init__(self, *args, **kargs):
    super(instruction_armt, self).__init__(*args, **kargs)

def breakflow(

self)

Inheritance: instruction_arm.breakflow

def breakflow(self):
    if self.name in conditional_branch + unconditional_branch +["CBZ", "CBNZ", 'TBB', 'TBH']:
        return True
    if self.name.startswith("LDM") and PC in self.args[1].args:
        return True
    if self.args and PC in self.args[0].get_r():
        return True
    return False

def dstflow(

self)

Inheritance: instruction_arm.dstflow

def dstflow(self):
    if self.name in ["CBZ", "CBNZ"]:
        return True
    return self.name in conditional_branch + unconditional_branch

def dstflow2label(

self, loc_db)

Inheritance: instruction_arm.dstflow2label

def dstflow2label(self, loc_db):
    if self.name in ["CBZ", "CBNZ"]:
        expr = self.args[1]
    else:
        expr = self.args[0]
    if not isinstance(expr, ExprInt):
        return
    if self.name == 'BLX':
        addr = expr.arg + (self.offset & 0xfffffffc)
    elif self.name == 'BL':
        addr = expr.arg + self.offset
    elif self.name.startswith('BP'):
        addr = expr.arg + self.offset
    elif self.name.startswith('CB'):
        addr = expr.arg + self.offset + self.l + 2
    else:
        addr = expr.arg + self.offset
    loc_key = loc_db.get_or_create_offset_location(addr)
    dst = ExprLoc(loc_key, expr.size)
    if self.name in ["CBZ", "CBNZ"]:
        self.args[1] = dst
    else:
        self.args[0] = dst

def fixDstOffset(

self)

Inheritance: instruction_arm.fixDstOffset

def fixDstOffset(self):
    e = self.args[0]
    if self.offset is None:
        raise ValueError('symbol not resolved %s' % l)
    if not isinstance(e, ExprInt):
        log.debug('dyn dst %r', e)
        return
    # The first +2 is to compensate instruction len, but strangely, 32 bits
    # thumb2 instructions len is 2... For the second +2, didn't find it in
    # the doc.
    off = e.arg - self.offset
    if int(off % 2):
        raise ValueError('strange offset! %r' % off)
    self.args[0] = ExprInt(off, 32)

def gen_args(

self, args)

Inheritance: instruction_arm.gen_args

def gen_args(self, args):
    out = ', '.join([str(x) for x in args])
    return out

def get_args_expr(

self)

Inheritance: instruction_arm.get_args_expr

def get_args_expr(self):
    args = [a for a in self.args]
    return args

def get_asm_next_offset(

self, expr)

Inheritance: instruction_arm.get_asm_next_offset

def get_asm_next_offset(self, expr):
    return m2_expr.ExprInt(self.offset+self.l, expr.size)

def get_asm_offset(

self, expr)

Inheritance: instruction_arm.get_asm_offset

def get_asm_offset(self, expr):
    # ADR XXX, PC, imm => PC is 4 aligned + imm
    new_offset = ((self.offset+self.l)/4)*4
    return ExprInt(new_offset, expr.size)

def get_info(

self, c)

Inheritance: instruction_arm.get_info

def get_info(self, c):
    return

def get_symbol_size(

self, symbol, loc_db)

Inheritance: instruction_arm.get_symbol_size

def get_symbol_size(self, symbol, loc_db):
    return 32

def getdstflow(

self, loc_db)

Inheritance: instruction_arm.getdstflow

def getdstflow(self, loc_db):
    if self.name in ['CBZ', 'CBNZ']:
        return [self.args[1]]
    return [self.args[0]]

def is_subcall(

self)

Inheritance: instruction_arm.is_subcall

def is_subcall(self):
    return self.name in ['BL', 'BLX']

def resolve_args_with_symbols(

self, symbols=None)

Inheritance: instruction_arm.resolve_args_with_symbols

def resolve_args_with_symbols(self, symbols=None):
    if symbols is None:
        symbols = {}
    args_out = []
    for expr in self.args:
        # try to resolve symbols using symbols (0 for default value)
        loc_keys = m2_expr.get_expr_locs(expr)
        fixed_expr = {}
        for exprloc in loc_keys:
            loc_key = exprloc.loc_key
            names = symbols.get_location_names(loc_key)
            # special symbols
            if '$' in names:
                fixed_expr[exprloc] = self.get_asm_offset(exprloc)
                continue
            if '_' in names:
                fixed_expr[exprloc] = self.get_asm_next_offset(exprloc)
                continue
            if not names:
                raise ValueError('Unresolved symbol: %r' % exprloc)
            offset = symbols.get_location_offset(loc_key)
            if offset is None:
                raise ValueError(
                    'The offset of loc_key "%s" cannot be determined' % names
                )
            else:
                # Fix symbol with its offset
                size = exprloc.size
                if size is None:
                    default_size = self.get_symbol_size(exprloc, symbols)
                    size = default_size
                value = m2_expr.ExprInt(offset, size)
            fixed_expr[exprloc] = value
        expr = expr.replace_expr(fixed_expr)
        expr = expr_simp(expr)
        args_out.append(expr)
    return args_out

def splitflow(

self)

Inheritance: instruction_arm.splitflow

def splitflow(self):
    if self.name in conditional_branch + ['BL', 'BLX', 'CBZ', 'CBNZ']:
        return True
    return False

def to_string(

self, loc_db=None)

Inheritance: instruction_arm.to_string

def to_string(self, loc_db=None):
    o = "%-10s " % self.name
    args = []
    for i, arg in enumerate(self.args):
        if not isinstance(arg, m2_expr.Expr):
            raise ValueError('zarb arg type')
        x = self.arg2str(arg, i, loc_db)
        args.append(x)
    o += self.gen_args(args)
    return o

class mn_arm

class mn_arm(cls_mn):
    delayslot = 0
    name = "arm"
    regs = regs_module
    bintree = {}
    num = 0
    all_mn = []
    all_mn_mode = defaultdict(list)
    all_mn_name = defaultdict(list)
    all_mn_inst = defaultdict(list)
    pc = {'l':PC, 'b':PC}
    sp = {'l':SP, 'b':SP}
    instruction = instruction_arm
    max_instruction_len = 4
    alignment = 4

    @classmethod
    def getpc(cls, attrib = None):
        return PC

    @classmethod
    def getsp(cls, attrib = None):
        return SP

    def additional_info(self):
        info = additional_info()
        info.lnk = False
        if hasattr(self, "lnk"):
            info.lnk = self.lnk.value != 0
        if hasattr(self, "cond"):
            info.cond = self.cond.value
        else:
            info.cond = None
        return info

    @classmethod
    def getbits(cls, bs, attrib, start, n):
        if not n:
            return 0
        o = 0
        if n > bs.getlen() * 8:
            raise ValueError('not enought bits %r %r' % (n, len(bs.bin) * 8))
        while n:
            offset = start / 8
            n_offset = cls.endian_offset(attrib, offset)
            c = cls.getbytes(bs, n_offset, 1)
            if not c:
                raise IOError
            c = ord(c)
            r = 8 - start % 8
            c &= (1 << r) - 1
            l = min(r, n)
            c >>= (r - l)
            o <<= l
            o |= c
            n -= l
            start += l
        return o

    @classmethod
    def endian_offset(cls, attrib, offset):
        if attrib == "l":
            return (offset & ~3) + 3 - offset % 4
        elif attrib == "b":
            return offset
        else:
            raise NotImplementedError('bad attrib')

    @classmethod
    def check_mnemo(cls, fields):
        l = sum([x.l for x in fields])
        assert l == 32, "len %r" % l

    @classmethod
    def getmn(cls, name):
        return name.upper()

    @classmethod
    def mod_fields(cls, fields):
        l = sum([x.l for x in fields])
        if l == 32:
            return fields
        return [bm_cond] + fields

    @classmethod
    def gen_modes(cls, subcls, name, bases, dct, fields):
        dct['mode'] = None
        return [(subcls, name, bases, dct, fields)]

    def value(self, mode):
        v = super(mn_arm, self).value(mode)
        if mode == 'l':
            return [x[::-1] for x in v]
        elif mode == 'b':
            return [x for x in v]
        else:
            raise NotImplementedError('bad attrib')


    def get_symbol_size(self, symbol, loc_db, mode):
        return 32

Ancestors (in MRO)

  • mn_arm
  • miasm2.core.cpu.cls_mn
  • __builtin__.object

Class variables

var alignment

var all_mn

var all_mn_inst

var all_mn_mode

var all_mn_name

var args_symb

var bintree

var delayslot

var instruction

var max_instruction_len

var name

var num

var pc

var regs

var sp

Methods

def add_pre_dis_info(

self, prefix=None)

def add_pre_dis_info(self, prefix=None):
    return True

def additional_info(

self)

def additional_info(self):
    info = additional_info()
    info.lnk = False
    if hasattr(self, "lnk"):
        info.lnk = self.lnk.value != 0
    if hasattr(self, "cond"):
        info.cond = self.cond.value
    else:
        info.cond = None
    return info

def args2str(

self)

def args2str(self):
    args = []
    for arg in self.args:
        # XXX todo test
        if not (isinstance(arg, m2_expr.Expr) or
                isinstance(arg.expr, m2_expr.Expr)):
            raise ValueError('zarb arg type')
        x = str(arg)
        args.append(x)
    return args

def asm(

cls, instr, symbols=None)

Re asm instruction by searching mnemo using name and args. We then can modify args and get the hex of a modified instruction

@classmethod
def asm(cls, instr, symbols=None):
    """
    Re asm instruction by searching mnemo using name and args. We then
    can modify args and get the hex of a modified instruction
    """
    clist = cls.all_mn_name[instr.name]
    clist = [x for x in clist]
    vals = []
    candidates = []
    args = instr.resolve_args_with_symbols(symbols)
    for cc in clist:
        for c in cls.get_cls_instance(
            cc, instr.mode, instr.additional_info):
            cannot_parse = False
            if len(c.args) != len(instr.args):
                continue
            # only fix args expr
            for i in xrange(len(c.args)):
                c.args[i].expr = args[i]
            v = c.value(instr.mode)
            if not v:
                log.debug("cannot encode %r", c)
                cannot_parse = True
            if cannot_parse:
                continue
            vals += v
            candidates.append((c, v))
    if len(vals) == 0:
        raise ValueError('cannot asm %r %r' %
                         (instr.name, [str(x) for x in instr.args]))
    if len(vals) != 1:
        log.debug('asm multiple args ret default')
    vals = cls.filter_asm_candidates(instr, candidates)
    return vals

def check_mnemo(

cls, fields)

@classmethod
def check_mnemo(cls, fields):
    l = sum([x.l for x in fields])
    assert l == 32, "len %r" % l

def decoded2bytes(

self, result)

def decoded2bytes(self, result):
    if not result:
        return []
    out = []
    for decoded in result:
        decoded.sort()
        o = self.encodefields(decoded)
        if o is None:
            continue
        out.append(o)
    out = list(set(out))
    return out

def dis(

cls, bs_o, mode_o=None, offset=0)

@classmethod
def dis(cls, bs_o, mode_o = None, offset=0):
    if not isinstance(bs_o, bin_stream):
        bs_o = bin_stream_str(bs_o)
    bs_o.enter_atomic_mode()
    offset_o = offset
    try:
        pre_dis_info, bs, mode, offset, prefix_len = cls.pre_dis(
            bs_o, mode_o, offset)
    except:
        bs_o.leave_atomic_mode()
        raise
    candidates = cls.guess_mnemo(bs, mode, pre_dis_info, offset)
    if not candidates:
        bs_o.leave_atomic_mode()
        raise Disasm_Exception('cannot disasm (guess) at %X' % offset)
    out = []
    out_c = []
    if hasattr(bs, 'getlen'):
        bs_l = bs.getlen()
    else:
        bs_l = len(bs)
    alias = False
    for c in candidates:
        log.debug("*" * 40, mode, c.mode)
        log.debug(c.fields)
        c = cls.all_mn_inst[c][0]
        c.reset_class()
        c.mode = mode
        if not c.add_pre_dis_info(pre_dis_info):
            continue
        todo = {}
        getok = True
        fname_values = dict(pre_dis_info)
        offset_b = offset * 8
        total_l = 0
        for i, f in enumerate(c.fields_order):
            if f.flen is not None:
                l = f.flen(mode, fname_values)
            else:
                l = f.l
            if l is not None:
                total_l += l
                f.l = l
                f.is_present = True
                log.debug("FIELD %s %s %s %s", f.__class__, f.fname,
                          offset_b, l)
                if bs_l * 8 - offset_b < l:
                    getok = False
                    break
                try:
                    bv = cls.getbits(bs, mode, offset_b, l)
                except:
                    bs_o.leave_atomic_mode()
                    raise
                offset_b += l
                if not f.fname in fname_values:
                    fname_values[f.fname] = bv
                todo[i] = bv
            else:
                f.is_present = False
                todo[i] = None
        if not getok:
            continue
        c.l = prefix_len + total_l / 8
        for i in c.to_decode:
            f = c.fields_order[i]
            if f.is_present:
                ret = f.decode(todo[i])
                if not ret:
                    log.debug("cannot decode %r", f)
                    break
        if not ret:
            continue
        for a in c.args:
            a.expr = expr_simp(a.expr)
        c.b = cls.getbytes(bs, offset_o, c.l)
        c.offset = offset_o
        c = c.post_dis()
        if c is None:
            continue
        c_args = [a.expr for a in c.args]
        instr = cls.instruction(c.name, mode, c_args,
                                additional_info=c.additional_info())
        instr.l = prefix_len + total_l / 8
        instr.b = cls.getbytes(bs, offset_o, instr.l)
        instr.offset = offset_o
        instr.get_info(c)
        if c.alias:
            alias = True
        out.append(instr)
        out_c.append(c)
    bs_o.leave_atomic_mode()
    if not out:
        raise Disasm_Exception('cannot disasm at %X' % offset_o)
    if len(out) != 1:
        if not alias:
            log.warning('dis multiple args ret default')
        for i, o in enumerate(out_c):
            if o.alias:
                return out[i]
        raise NotImplementedError('Multiple disas: \n' +
                                  "\n".join([str(x) for x in out]))
    return out[0]

def dup_info(

self, infos)

def dup_info(self, infos):
    return

def encodefields(

self, decoded)

def encodefields(self, decoded):
    bits = bitobj()
    for _, f in decoded:
        setattr(self, f.fname, f)
        if f.value is None:
            continue
        bits.putbits(f.value, f.l)
    return bits.tostring()

def endian_offset(

cls, attrib, offset)

@classmethod
def endian_offset(cls, attrib, offset):
    if attrib == "l":
        return (offset & ~3) + 3 - offset % 4
    elif attrib == "b":
        return offset
    else:
        raise NotImplementedError('bad attrib')

def filter_asm_candidates(

cls, instr, candidates)

@classmethod
def filter_asm_candidates(cls, instr, candidates):
    o = []
    for _, v in candidates:
        o += v
    o.sort(key=len)
    return o

def fromstring(

cls, text, loc_db, mode=None)

@classmethod
def fromstring(cls, text, loc_db, mode = None):
    global total_scans
    name = re.search('(\S+)', text).groups()
    if not name:
        raise ValueError('cannot find name', text)
    name = name[0]
    if not name in cls.all_mn_name:
        raise ValueError('unknown name', name)
    clist = [x for x in cls.all_mn_name[name]]
    out = []
    out_args = []
    parsers = defaultdict(dict)
    for cc in clist:
        for c in cls.get_cls_instance(cc, mode):
            args_expr = []
            args_str = text[len(name):].strip(' ')
            start = 0
            cannot_parse = False
            len_o = len(args_str)
            for i, f in enumerate(c.args):
                start_i = len_o - len(args_str)
                if type(f.parser) == tuple:
                    parser = f.parser
                else:
                    parser = (f.parser,)
                for p in parser:
                    if p in parsers[(i, start_i)]:
                        continue
                    try:
                        total_scans += 1
                        v, start, stop = p.scanString(args_str).next()
                    except StopIteration:
                        v, start, stop = [None], None, None
                    if start != 0:
                        v, start, stop = [None], None, None
                    if v != [None]:
                        v = f.asm_ast_to_expr(v[0], loc_db)
                    if v is None:
                        v, start, stop = [None], None, None
                    parsers[(i, start_i)][p] = v, start, stop
                start, stop = f.fromstring(args_str, loc_db, parsers[(i, start_i)])
                if start != 0:
                    log.debug("cannot fromstring %r", args_str)
                    cannot_parse = True
                    break
                if f.expr is None:
                    raise NotImplementedError('not fully functional')
                f.expr = expr_simp(f.expr)
                args_expr.append(f.expr)
                args_str = args_str[stop:].strip(' ')
                if args_str.startswith(','):
                    args_str = args_str[1:]
                args_str = args_str.strip(' ')
            if args_str:
                cannot_parse = True
            if cannot_parse:
                continue
            out.append(c)
            out_args.append(args_expr)
            break
    if len(out) == 0:
        raise ValueError('cannot fromstring %r' % text)
    if len(out) != 1:
        log.debug('fromstring multiple args ret default')
    c = out[0]
    c_args = out_args[0]
    instr = cls.instruction(c.name, mode, c_args,
                            additional_info=c.additional_info())
    return instr

def gen_args(

self, args)

def gen_args(self, args):
    out = ', '.join([str(x) for x in args])
    return out

def gen_modes(

cls, subcls, name, bases, dct, fields)

@classmethod
def gen_modes(cls, subcls, name, bases, dct, fields):
    dct['mode'] = None
    return [(subcls, name, bases, dct, fields)]

def get_cls_instance(

cls, cc, mode, infos=None)

@classmethod
def get_cls_instance(cls, cc, mode, infos=None):
    c = cls.all_mn_inst[cc][0]
    c.reset_class()
    c.add_pre_dis_info()
    c.dup_info(infos)
    c.mode = mode
    yield c

def get_symbol_size(

self, symbol, loc_db, mode)

def get_symbol_size(self, symbol, loc_db, mode):
    return 32

def getbits(

cls, bs, attrib, start, n)

@classmethod
def getbits(cls, bs, attrib, start, n):
    if not n:
        return 0
    o = 0
    if n > bs.getlen() * 8:
        raise ValueError('not enought bits %r %r' % (n, len(bs.bin) * 8))
    while n:
        offset = start / 8
        n_offset = cls.endian_offset(attrib, offset)
        c = cls.getbytes(bs, n_offset, 1)
        if not c:
            raise IOError
        c = ord(c)
        r = 8 - start % 8
        c &= (1 << r) - 1
        l = min(r, n)
        c >>= (r - l)
        o <<= l
        o |= c
        n -= l
        start += l
    return o

def getbytes(

cls, bs, offset, l)

@classmethod
def getbytes(cls, bs, offset, l):
    return bs.getbytes(offset, l)

def getdstflow(

self, loc_db)

def getdstflow(self, loc_db):
    return [self.args[0].expr]

def getmn(

cls, name)

@classmethod
def getmn(cls, name):
    return name.upper()

def getpc(

cls, attrib=None)

@classmethod
def getpc(cls, attrib = None):
    return PC

def getsp(

cls, attrib=None)

@classmethod
def getsp(cls, attrib = None):
    return SP

def guess_mnemo(

cls, bs, attrib, pre_dis_info, offset)

@classmethod
def guess_mnemo(cls, bs, attrib, pre_dis_info, offset):
    candidates = []
    candidates = set()
    fname_values = pre_dis_info
    todo = [(dict(fname_values), branch, offset * 8)
            for branch in cls.bintree.items()]
    for fname_values, branch, offset_b in todo:
        (l, fmask, fbits, fname, flen), vals = branch
        if flen is not None:
            l = flen(attrib, fname_values)
        if l is not None:
            try:
                v = cls.getbits(bs, attrib, offset_b, l)
            except IOError:
                # Raised if offset is out of bound
                continue
            offset_b += l
            if v & fmask != fbits:
                continue
            if fname is not None and not fname in fname_values:
                fname_values[fname] = v
        for nb, v in vals.items():
            if 'mn' in nb:
                candidates.update(v)
            else:
                todo.append((dict(fname_values), (nb, v), offset_b))
    return [c for c in candidates]

def init_class(

self)

def init_class(self):
    args = []
    fields_order = []
    to_decode = []
    off = 0
    for i, fc in enumerate(self.fields):
        f = fc.gen(self)
        f.offset = off
        off += f.l
        fields_order.append(f)
        to_decode.append((i, f))
        if isinstance(f, m_arg):
            args.append(f)
        if f.fname:
            setattr(self, f.fname, f)
    if hasattr(self, 'args_permut'):
        args = [args[self.args_permut[i]]
                for i in xrange(len(self.args_permut))]
    to_decode.sort(key=lambda x: (x[1].order, x[0]))
    to_decode = [fields_order.index(f[1]) for f in to_decode]
    self.args = args
    self.fields_order = fields_order
    self.to_decode = to_decode

def mod_fields(

cls, fields)

@classmethod
def mod_fields(cls, fields):
    l = sum([x.l for x in fields])
    if l == 32:
        return fields
    return [bm_cond] + fields

def parse_prefix(

self, v)

def parse_prefix(self, v):
    return 0

def post_dis(

self)

def post_dis(self):
    return self

def pre_dis(

cls, v_o, attrib, offset)

@classmethod
def pre_dis(cls, v_o, attrib, offset):
    return {}, v_o, attrib, offset, 0

def reset_class(

self)

def reset_class(self):
    for f in self.fields_order:
        if f.strbits and isbin(f.strbits):
            f.value = int(f.strbits, 2)
        elif 'default_val' in f.kargs:
            f.value = int(f.kargs['default_val'], 2)
        else:
            f.value = None
        if f.fname:
            setattr(self, f.fname, f)

def set_dst_symbol(

self, loc_db)

def set_dst_symbol(self, loc_db):
    dst = self.getdstflow(loc_db)
    args = []
    for d in dst:
        if isinstance(d, m2_expr.ExprInt):
            l = loc_db.get_or_create_offset_location(int(d))
            a = m2_expr.ExprId(l.name, d.size)
        else:
            a = d
        args.append(a)
    self.args_symb = args

def value(

self, mode)

def value(self, mode):
    v = super(mn_arm, self).value(mode)
    if mode == 'l':
        return [x[::-1] for x in v]
    elif mode == 'b':
        return [x for x in v]
    else:
        raise NotImplementedError('bad attrib')

class mn_armt

class mn_armt(cls_mn):
    name = "armt"
    regs = regs_module
    delayslot = 0
    bintree = {}
    num = 0
    all_mn = []
    all_mn_mode = defaultdict(list)
    all_mn_name = defaultdict(list)
    all_mn_inst = defaultdict(list)
    pc = PC
    sp = SP
    instruction = instruction_armt
    max_instruction_len = 4
    alignment = 4

    @classmethod
    def getpc(cls, attrib = None):
        return PC

    @classmethod
    def getsp(cls, attrib = None):
        return SP

    def additional_info(self):
        info = additional_info()
        info.lnk = False
        if hasattr(self, "lnk"):
            info.lnk = self.lnk.value != 0
        info.cond = 14  # COND_ALWAYS
        return info


    @classmethod
    def getbits(cls, bs, attrib, start, n):
        if not n:
            return 0
        o = 0
        if n > bs.getlen() * 8:
            raise ValueError('not enought bits %r %r' % (n, len(bs.bin) * 8))
        while n:
            offset = start / 8
            n_offset = cls.endian_offset(attrib, offset)
            c = cls.getbytes(bs, n_offset, 1)
            if not c:
                raise IOError
            c = ord(c)
            r = 8 - start % 8
            c &= (1 << r) - 1
            l = min(r, n)
            c >>= (r - l)
            o <<= l
            o |= c
            n -= l
            start += l
        return o

    @classmethod
    def endian_offset(cls, attrib, offset):
        if attrib == "l":
            return (offset & ~1) + 1 - offset % 2
        elif attrib == "b":
            return offset
        else:
            raise NotImplementedError('bad attrib')

    @classmethod
    def check_mnemo(cls, fields):
        l = sum([x.l for x in fields])
        assert l in [16, 32], "len %r" % l

    @classmethod
    def getmn(cls, name):
        return name.upper()

    @classmethod
    def mod_fields(cls, fields):
        return list(fields)

    @classmethod
    def gen_modes(cls, subcls, name, bases, dct, fields):
        dct['mode'] = None
        return [(subcls, name, bases, dct, fields)]

    def value(self, mode):
        v = super(mn_armt, self).value(mode)
        if mode == 'l':
            out = []
            for x in v:
                if len(x) == 2:
                    out.append(x[::-1])
                elif len(x) == 4:
                    out.append(x[:2][::-1] + x[2:4][::-1])
            return out
        elif mode == 'b':
            return [x for x in v]
        else:
            raise NotImplementedError('bad attrib')

    def get_args_expr(self):
        args = [a.expr for a in self.args]
        return args

    def get_symbol_size(self, symbol, loc_db, mode):
        return 32

Ancestors (in MRO)

  • mn_armt
  • miasm2.core.cpu.cls_mn
  • __builtin__.object

Class variables

var alignment

var all_mn

var all_mn_inst

var all_mn_mode

var all_mn_name

var args_symb

var bintree

var delayslot

var instruction

var max_instruction_len

var name

var num

var pc

var regs

var sp

Methods

def add_pre_dis_info(

self, prefix=None)

def add_pre_dis_info(self, prefix=None):
    return True

def additional_info(

self)

def additional_info(self):
    info = additional_info()
    info.lnk = False
    if hasattr(self, "lnk"):
        info.lnk = self.lnk.value != 0
    info.cond = 14  # COND_ALWAYS
    return info

def args2str(

self)

def args2str(self):
    args = []
    for arg in self.args:
        # XXX todo test
        if not (isinstance(arg, m2_expr.Expr) or
                isinstance(arg.expr, m2_expr.Expr)):
            raise ValueError('zarb arg type')
        x = str(arg)
        args.append(x)
    return args

def asm(

cls, instr, symbols=None)

Re asm instruction by searching mnemo using name and args. We then can modify args and get the hex of a modified instruction

@classmethod
def asm(cls, instr, symbols=None):
    """
    Re asm instruction by searching mnemo using name and args. We then
    can modify args and get the hex of a modified instruction
    """
    clist = cls.all_mn_name[instr.name]
    clist = [x for x in clist]
    vals = []
    candidates = []
    args = instr.resolve_args_with_symbols(symbols)
    for cc in clist:
        for c in cls.get_cls_instance(
            cc, instr.mode, instr.additional_info):
            cannot_parse = False
            if len(c.args) != len(instr.args):
                continue
            # only fix args expr
            for i in xrange(len(c.args)):
                c.args[i].expr = args[i]
            v = c.value(instr.mode)
            if not v:
                log.debug("cannot encode %r", c)
                cannot_parse = True
            if cannot_parse:
                continue
            vals += v
            candidates.append((c, v))
    if len(vals) == 0:
        raise ValueError('cannot asm %r %r' %
                         (instr.name, [str(x) for x in instr.args]))
    if len(vals) != 1:
        log.debug('asm multiple args ret default')
    vals = cls.filter_asm_candidates(instr, candidates)
    return vals

def check_mnemo(

cls, fields)

@classmethod
def check_mnemo(cls, fields):
    l = sum([x.l for x in fields])
    assert l in [16, 32], "len %r" % l

def decoded2bytes(

self, result)

def decoded2bytes(self, result):
    if not result:
        return []
    out = []
    for decoded in result:
        decoded.sort()
        o = self.encodefields(decoded)
        if o is None:
            continue
        out.append(o)
    out = list(set(out))
    return out

def dis(

cls, bs_o, mode_o=None, offset=0)

@classmethod
def dis(cls, bs_o, mode_o = None, offset=0):
    if not isinstance(bs_o, bin_stream):
        bs_o = bin_stream_str(bs_o)
    bs_o.enter_atomic_mode()
    offset_o = offset
    try:
        pre_dis_info, bs, mode, offset, prefix_len = cls.pre_dis(
            bs_o, mode_o, offset)
    except:
        bs_o.leave_atomic_mode()
        raise
    candidates = cls.guess_mnemo(bs, mode, pre_dis_info, offset)
    if not candidates:
        bs_o.leave_atomic_mode()
        raise Disasm_Exception('cannot disasm (guess) at %X' % offset)
    out = []
    out_c = []
    if hasattr(bs, 'getlen'):
        bs_l = bs.getlen()
    else:
        bs_l = len(bs)
    alias = False
    for c in candidates:
        log.debug("*" * 40, mode, c.mode)
        log.debug(c.fields)
        c = cls.all_mn_inst[c][0]
        c.reset_class()
        c.mode = mode
        if not c.add_pre_dis_info(pre_dis_info):
            continue
        todo = {}
        getok = True
        fname_values = dict(pre_dis_info)
        offset_b = offset * 8
        total_l = 0
        for i, f in enumerate(c.fields_order):
            if f.flen is not None:
                l = f.flen(mode, fname_values)
            else:
                l = f.l
            if l is not None:
                total_l += l
                f.l = l
                f.is_present = True
                log.debug("FIELD %s %s %s %s", f.__class__, f.fname,
                          offset_b, l)
                if bs_l * 8 - offset_b < l:
                    getok = False
                    break
                try:
                    bv = cls.getbits(bs, mode, offset_b, l)
                except:
                    bs_o.leave_atomic_mode()
                    raise
                offset_b += l
                if not f.fname in fname_values:
                    fname_values[f.fname] = bv
                todo[i] = bv
            else:
                f.is_present = False
                todo[i] = None
        if not getok:
            continue
        c.l = prefix_len + total_l / 8
        for i in c.to_decode:
            f = c.fields_order[i]
            if f.is_present:
                ret = f.decode(todo[i])
                if not ret:
                    log.debug("cannot decode %r", f)
                    break
        if not ret:
            continue
        for a in c.args:
            a.expr = expr_simp(a.expr)
        c.b = cls.getbytes(bs, offset_o, c.l)
        c.offset = offset_o
        c = c.post_dis()
        if c is None:
            continue
        c_args = [a.expr for a in c.args]
        instr = cls.instruction(c.name, mode, c_args,
                                additional_info=c.additional_info())
        instr.l = prefix_len + total_l / 8
        instr.b = cls.getbytes(bs, offset_o, instr.l)
        instr.offset = offset_o
        instr.get_info(c)
        if c.alias:
            alias = True
        out.append(instr)
        out_c.append(c)
    bs_o.leave_atomic_mode()
    if not out:
        raise Disasm_Exception('cannot disasm at %X' % offset_o)
    if len(out) != 1:
        if not alias:
            log.warning('dis multiple args ret default')
        for i, o in enumerate(out_c):
            if o.alias:
                return out[i]
        raise NotImplementedError('Multiple disas: \n' +
                                  "\n".join([str(x) for x in out]))
    return out[0]

def dup_info(

self, infos)

def dup_info(self, infos):
    return

def encodefields(

self, decoded)

def encodefields(self, decoded):
    bits = bitobj()
    for _, f in decoded:
        setattr(self, f.fname, f)
        if f.value is None:
            continue
        bits.putbits(f.value, f.l)
    return bits.tostring()

def endian_offset(

cls, attrib, offset)

@classmethod
def endian_offset(cls, attrib, offset):
    if attrib == "l":
        return (offset & ~1) + 1 - offset % 2
    elif attrib == "b":
        return offset
    else:
        raise NotImplementedError('bad attrib')

def filter_asm_candidates(

cls, instr, candidates)

@classmethod
def filter_asm_candidates(cls, instr, candidates):
    o = []
    for _, v in candidates:
        o += v
    o.sort(key=len)
    return o

def fromstring(

cls, text, loc_db, mode=None)

@classmethod
def fromstring(cls, text, loc_db, mode = None):
    global total_scans
    name = re.search('(\S+)', text).groups()
    if not name:
        raise ValueError('cannot find name', text)
    name = name[0]
    if not name in cls.all_mn_name:
        raise ValueError('unknown name', name)
    clist = [x for x in cls.all_mn_name[name]]
    out = []
    out_args = []
    parsers = defaultdict(dict)
    for cc in clist:
        for c in cls.get_cls_instance(cc, mode):
            args_expr = []
            args_str = text[len(name):].strip(' ')
            start = 0
            cannot_parse = False
            len_o = len(args_str)
            for i, f in enumerate(c.args):
                start_i = len_o - len(args_str)
                if type(f.parser) == tuple:
                    parser = f.parser
                else:
                    parser = (f.parser,)
                for p in parser:
                    if p in parsers[(i, start_i)]:
                        continue
                    try:
                        total_scans += 1
                        v, start, stop = p.scanString(args_str).next()
                    except StopIteration:
                        v, start, stop = [None], None, None
                    if start != 0:
                        v, start, stop = [None], None, None
                    if v != [None]:
                        v = f.asm_ast_to_expr(v[0], loc_db)
                    if v is None:
                        v, start, stop = [None], None, None
                    parsers[(i, start_i)][p] = v, start, stop
                start, stop = f.fromstring(args_str, loc_db, parsers[(i, start_i)])
                if start != 0:
                    log.debug("cannot fromstring %r", args_str)
                    cannot_parse = True
                    break
                if f.expr is None:
                    raise NotImplementedError('not fully functional')
                f.expr = expr_simp(f.expr)
                args_expr.append(f.expr)
                args_str = args_str[stop:].strip(' ')
                if args_str.startswith(','):
                    args_str = args_str[1:]
                args_str = args_str.strip(' ')
            if args_str:
                cannot_parse = True
            if cannot_parse:
                continue
            out.append(c)
            out_args.append(args_expr)
            break
    if len(out) == 0:
        raise ValueError('cannot fromstring %r' % text)
    if len(out) != 1:
        log.debug('fromstring multiple args ret default')
    c = out[0]
    c_args = out_args[0]
    instr = cls.instruction(c.name, mode, c_args,
                            additional_info=c.additional_info())
    return instr

def gen_args(

self, args)

def gen_args(self, args):
    out = ', '.join([str(x) for x in args])
    return out

def gen_modes(

cls, subcls, name, bases, dct, fields)

@classmethod
def gen_modes(cls, subcls, name, bases, dct, fields):
    dct['mode'] = None
    return [(subcls, name, bases, dct, fields)]

def get_args_expr(

self)

def get_args_expr(self):
    args = [a.expr for a in self.args]
    return args

def get_cls_instance(

cls, cc, mode, infos=None)

@classmethod
def get_cls_instance(cls, cc, mode, infos=None):
    c = cls.all_mn_inst[cc][0]
    c.reset_class()
    c.add_pre_dis_info()
    c.dup_info(infos)
    c.mode = mode
    yield c

def get_symbol_size(

self, symbol, loc_db, mode)

def get_symbol_size(self, symbol, loc_db, mode):
    return 32

def getbits(

cls, bs, attrib, start, n)

@classmethod
def getbits(cls, bs, attrib, start, n):
    if not n:
        return 0
    o = 0
    if n > bs.getlen() * 8:
        raise ValueError('not enought bits %r %r' % (n, len(bs.bin) * 8))
    while n:
        offset = start / 8
        n_offset = cls.endian_offset(attrib, offset)
        c = cls.getbytes(bs, n_offset, 1)
        if not c:
            raise IOError
        c = ord(c)
        r = 8 - start % 8
        c &= (1 << r) - 1
        l = min(r, n)
        c >>= (r - l)
        o <<= l
        o |= c
        n -= l
        start += l
    return o

def getbytes(

cls, bs, offset, l)

@classmethod
def getbytes(cls, bs, offset, l):
    return bs.getbytes(offset, l)

def getdstflow(

self, loc_db)

def getdstflow(self, loc_db):
    return [self.args[0].expr]

def getmn(

cls, name)

@classmethod
def getmn(cls, name):
    return name.upper()

def getpc(

cls, attrib=None)

@classmethod
def getpc(cls, attrib = None):
    return PC

def getsp(

cls, attrib=None)

@classmethod
def getsp(cls, attrib = None):
    return SP

def guess_mnemo(

cls, bs, attrib, pre_dis_info, offset)

@classmethod
def guess_mnemo(cls, bs, attrib, pre_dis_info, offset):
    candidates = []
    candidates = set()
    fname_values = pre_dis_info
    todo = [(dict(fname_values), branch, offset * 8)
            for branch in cls.bintree.items()]
    for fname_values, branch, offset_b in todo:
        (l, fmask, fbits, fname, flen), vals = branch
        if flen is not None:
            l = flen(attrib, fname_values)
        if l is not None:
            try:
                v = cls.getbits(bs, attrib, offset_b, l)
            except IOError:
                # Raised if offset is out of bound
                continue
            offset_b += l
            if v & fmask != fbits:
                continue
            if fname is not None and not fname in fname_values:
                fname_values[fname] = v
        for nb, v in vals.items():
            if 'mn' in nb:
                candidates.update(v)
            else:
                todo.append((dict(fname_values), (nb, v), offset_b))
    return [c for c in candidates]

def init_class(

self)

def init_class(self):
    args = []
    fields_order = []
    to_decode = []
    off = 0
    for i, fc in enumerate(self.fields):
        f = fc.gen(self)
        f.offset = off
        off += f.l
        fields_order.append(f)
        to_decode.append((i, f))
        if isinstance(f, m_arg):
            args.append(f)
        if f.fname:
            setattr(self, f.fname, f)
    if hasattr(self, 'args_permut'):
        args = [args[self.args_permut[i]]
                for i in xrange(len(self.args_permut))]
    to_decode.sort(key=lambda x: (x[1].order, x[0]))
    to_decode = [fields_order.index(f[1]) for f in to_decode]
    self.args = args
    self.fields_order = fields_order
    self.to_decode = to_decode

def mod_fields(

cls, fields)

@classmethod
def mod_fields(cls, fields):
    return list(fields)

def parse_prefix(

self, v)

def parse_prefix(self, v):
    return 0

def post_dis(

self)

def post_dis(self):
    return self

def pre_dis(

cls, v_o, attrib, offset)

@classmethod
def pre_dis(cls, v_o, attrib, offset):
    return {}, v_o, attrib, offset, 0

def reset_class(

self)

def reset_class(self):
    for f in self.fields_order:
        if f.strbits and isbin(f.strbits):
            f.value = int(f.strbits, 2)
        elif 'default_val' in f.kargs:
            f.value = int(f.kargs['default_val'], 2)
        else:
            f.value = None
        if f.fname:
            setattr(self, f.fname, f)

def set_dst_symbol(

self, loc_db)

def set_dst_symbol(self, loc_db):
    dst = self.getdstflow(loc_db)
    args = []
    for d in dst:
        if isinstance(d, m2_expr.ExprInt):
            l = loc_db.get_or_create_offset_location(int(d))
            a = m2_expr.ExprId(l.name, d.size)
        else:
            a = d
        args.append(a)
    self.args_symb = args

def value(

self, mode)

def value(self, mode):
    v = super(mn_armt, self).value(mode)
    if mode == 'l':
        out = []
        for x in v:
            if len(x) == 2:
                out.append(x[::-1])
            elif len(x) == 4:
                out.append(x[:2][::-1] + x[2:4][::-1])
        return out
    elif mode == 'b':
        return [x for x in v]
    else:
        raise NotImplementedError('bad attrib')

class mul_part_x

class mul_part_x(bs_mod_name):
    prio = 5
    mn_mod = ['B', 'T']

Ancestors (in MRO)

  • mul_part_x
  • miasm2.core.cpu.bs_mod_name
  • miasm2.core.cpu.bs_divert
  • __builtin__.object

Class variables

var mn_mod

var prio

Methods

def __init__(

self, **kargs)

def __init__(self, **kargs):
    self.args = kargs

def divert(

self, i, candidates)

def divert(self, i, candidates):
    out = []
    for cls, _, bases, dct, fields in candidates:
        tab = self.args['mn_mod']
        if isinstance(tab, list):
            tmp = {}
            for j, v in enumerate(tab):
                tmp[j] = v
            tab = tmp
        for value, new_name in tab.iteritems():
            nfields = fields[:]
            s = int2bin(value, self.args['l'])
            args = dict(self.args)
            args.update({'strbits': s})
            f = bs(**args)
            nfields[i] = f
            ndct = dict(dct)
            ndct['name'] = self.modname(ndct['name'], value)
            out.append((cls, new_name, bases, ndct, nfields))
    return out

def modname(

self, name, i)

def modname(self, name, i):
    return name + self.args['mn_mod'][i]

class mul_part_y

class mul_part_y(bs_mod_name):
    prio = 6
    mn_mod = ['B', 'T']

Ancestors (in MRO)

  • mul_part_y
  • miasm2.core.cpu.bs_mod_name
  • miasm2.core.cpu.bs_divert
  • __builtin__.object

Class variables

var mn_mod

var prio

Methods

def __init__(

self, **kargs)

def __init__(self, **kargs):
    self.args = kargs

def divert(

self, i, candidates)

def divert(self, i, candidates):
    out = []
    for cls, _, bases, dct, fields in candidates:
        tab = self.args['mn_mod']
        if isinstance(tab, list):
            tmp = {}
            for j, v in enumerate(tab):
                tmp[j] = v
            tab = tmp
        for value, new_name in tab.iteritems():
            nfields = fields[:]
            s = int2bin(value, self.args['l'])
            args = dict(self.args)
            args.update({'strbits': s})
            f = bs(**args)
            nfields[i] = f
            ndct = dict(dct)
            ndct['name'] = self.modname(ndct['name'], value)
            out.append((cls, new_name, bases, ndct, nfields))
    return out

def modname(

self, name, i)

def modname(self, name, i):
    return name + self.args['mn_mod'][i]

class ppi_b_nosp_mn

class ppi_b_nosp_mn(bs_mod_name):
    prio = 5
    mn_mod = ['A', 'B']

Ancestors (in MRO)

  • ppi_b_nosp_mn
  • miasm2.core.cpu.bs_mod_name
  • miasm2.core.cpu.bs_divert
  • __builtin__.object

Class variables

var mn_mod

var prio

Methods

def __init__(

self, **kargs)

def __init__(self, **kargs):
    self.args = kargs

def divert(

self, i, candidates)

def divert(self, i, candidates):
    out = []
    for cls, _, bases, dct, fields in candidates:
        tab = self.args['mn_mod']
        if isinstance(tab, list):
            tmp = {}
            for j, v in enumerate(tab):
                tmp[j] = v
            tab = tmp
        for value, new_name in tab.iteritems():
            nfields = fields[:]
            s = int2bin(value, self.args['l'])
            args = dict(self.args)
            args.update({'strbits': s})
            f = bs(**args)
            nfields[i] = f
            ndct = dict(dct)
            ndct['name'] = self.modname(ndct['name'], value)
            out.append((cls, new_name, bases, ndct, nfields))
    return out

def modname(

self, name, i)

def modname(self, name, i):
    return name + self.args['mn_mod'][i]

class ppi_b_sp_mn

class ppi_b_sp_mn(bs_mod_name):
    mn_mod = ['F', 'E']

    def modname(self, name, f_i):
        if name.startswith("STM"):
            f_i = [1, 0][f_i]
        return name + self.args['mn_mod'][f_i]

Ancestors (in MRO)

  • ppi_b_sp_mn
  • miasm2.core.cpu.bs_mod_name
  • miasm2.core.cpu.bs_divert
  • __builtin__.object

Class variables

var mn_mod

var prio

Methods

def __init__(

self, **kargs)

def __init__(self, **kargs):
    self.args = kargs

def divert(

self, i, candidates)

def divert(self, i, candidates):
    out = []
    for cls, _, bases, dct, fields in candidates:
        tab = self.args['mn_mod']
        if isinstance(tab, list):
            tmp = {}
            for j, v in enumerate(tab):
                tmp[j] = v
            tab = tmp
        for value, new_name in tab.iteritems():
            nfields = fields[:]
            s = int2bin(value, self.args['l'])
            args = dict(self.args)
            args.update({'strbits': s})
            f = bs(**args)
            nfields[i] = f
            ndct = dict(dct)
            ndct['name'] = self.modname(ndct['name'], value)
            out.append((cls, new_name, bases, ndct, nfields))
    return out

def modname(

self, name, f_i)

def modname(self, name, f_i):
    if name.startswith("STM"):
        f_i = [1, 0][f_i]
    return name + self.args['mn_mod'][f_i]

class updown_b_nosp_mn

class updown_b_nosp_mn(bs_mod_name):
    mn_mod = ['D', 'I']

    def modname(self, name, f_i):
        return name + self.args['mn_mod'][f_i]

Ancestors (in MRO)

  • updown_b_nosp_mn
  • miasm2.core.cpu.bs_mod_name
  • miasm2.core.cpu.bs_divert
  • __builtin__.object

Class variables

var mn_mod

var prio

Methods

def __init__(

self, **kargs)

def __init__(self, **kargs):
    self.args = kargs

def divert(

self, i, candidates)

def divert(self, i, candidates):
    out = []
    for cls, _, bases, dct, fields in candidates:
        tab = self.args['mn_mod']
        if isinstance(tab, list):
            tmp = {}
            for j, v in enumerate(tab):
                tmp[j] = v
            tab = tmp
        for value, new_name in tab.iteritems():
            nfields = fields[:]
            s = int2bin(value, self.args['l'])
            args = dict(self.args)
            args.update({'strbits': s})
            f = bs(**args)
            nfields[i] = f
            ndct = dict(dct)
            ndct['name'] = self.modname(ndct['name'], value)
            out.append((cls, new_name, bases, ndct, nfields))
    return out

def modname(

self, name, f_i)

def modname(self, name, f_i):
    return name + self.args['mn_mod'][f_i]

class updown_b_sp_mn

class updown_b_sp_mn(bs_mod_name):
    mn_mod = ['A', 'D']

    def modname(self, name, f_i):
        if name.startswith("STM"):
            f_i = [1, 0][f_i]
        return name + self.args['mn_mod'][f_i]

Ancestors (in MRO)

  • updown_b_sp_mn
  • miasm2.core.cpu.bs_mod_name
  • miasm2.core.cpu.bs_divert
  • __builtin__.object

Class variables

var mn_mod

var prio

Methods

def __init__(

self, **kargs)

def __init__(self, **kargs):
    self.args = kargs

def divert(

self, i, candidates)

def divert(self, i, candidates):
    out = []
    for cls, _, bases, dct, fields in candidates:
        tab = self.args['mn_mod']
        if isinstance(tab, list):
            tmp = {}
            for j, v in enumerate(tab):
                tmp[j] = v
            tab = tmp
        for value, new_name in tab.iteritems():
            nfields = fields[:]
            s = int2bin(value, self.args['l'])
            args = dict(self.args)
            args.update({'strbits': s})
            f = bs(**args)
            nfields[i] = f
            ndct = dict(dct)
            ndct['name'] = self.modname(ndct['name'], value)
            out.append((cls, new_name, bases, ndct, nfields))
    return out

def modname(

self, name, f_i)

def modname(self, name, f_i):
    if name.startswith("STM"):
        f_i = [1, 0][f_i]
    return name + self.args['mn_mod'][f_i]