Top

miasm2.arch.msp430.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.msp430.regs as regs_module
from miasm2.arch.msp430.regs import *
from miasm2.core.asm_ast import AstInt, AstId, AstMem, AstOp

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

conditional_branch = ['jnz', 'jz', 'jnc', 'jc',
                      'jn', 'jge', 'jl']
unconditional_branch = ['jmp']

def cb_deref_nooff(tokens):
    assert len(tokens) == 1
    result = AstMem(tokens[0], 16)
    return result


def cb_deref_pinc(tokens):
    assert len(tokens) == 1

    result = AstOp('autoinc', *tokens)
    return result


def cb_deref_off(tokens):
    assert len(tokens) == 2
    result = AstMem(tokens[1] + tokens[0], 16)
    return result


def cb_expr(tokens):
    assert(len(tokens) == 1)
    result = tokens[0]
    return result


ARO = Suppress("@")
LPARENT = Suppress("(")
RPARENT = Suppress(")")

PINC = Suppress("+")

deref_nooff = (ARO + base_expr).setParseAction(cb_deref_nooff)
deref_pinc = (ARO + base_expr + PINC).setParseAction(cb_deref_pinc)
deref_off = (base_expr + LPARENT + gpregs.parser + RPARENT).setParseAction(cb_deref_off)
sreg_p = (deref_pinc | deref_nooff | deref_off | base_expr).setParseAction(cb_expr)



class msp430_arg(m_arg):
    def asm_ast_to_expr(self, value, loc_db):
        if isinstance(value, AstId):
            name = value.name
            if isinstance(name, Expr):
                return name
            assert isinstance(name, str)
            if name in gpregs.str:
                index = gpregs.str.index(name)
                reg = gpregs.expr[index]
                return reg
            loc_key = loc_db.get_or_create_name_location(value.name)
            return ExprLoc(loc_key, 16)
        if isinstance(value, AstOp):
            args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in value.args]
            if None in args:
                return None
            return ExprOp(value.op, *args)
        if isinstance(value, AstInt):
            return ExprInt(value.value, 16)
        if isinstance(value, AstMem):
            ptr = self.asm_ast_to_expr(value.ptr, loc_db)
            if ptr is None:
                return None
            return ExprMem(ptr, value.size)
        return None


class additional_info:

    def __init__(self):
        self.except_on_instr = False


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

    def dstflow(self):
        if self.name.startswith('j'):
            return True
        return self.name in ['call']

    @staticmethod
    def arg2str(expr, index=None, loc_db=None):
        if isinstance(expr, ExprId):
            o = str(expr)
        elif isinstance(expr, ExprInt):
            o = str(expr)
        elif expr.is_loc():
            if loc_db is not None:
                return loc_db.pretty_str(expr.loc_key)
            else:
                return str(expr)
        elif isinstance(expr, ExprOp) and expr.op == "autoinc":
            o = "@%s+" % str(expr.args[0])
        elif isinstance(expr, ExprMem):
            if isinstance(expr.arg, ExprId):
                if index == 0:
                    o = "@%s" % expr.arg
                else:
                    o = "0x0(%s)" % expr.arg
            elif isinstance(expr.arg, ExprInt):
                o = "@%s" % expr.arg
            elif isinstance(expr.arg, ExprOp):
                o = "%s(%s)" % (expr.arg.args[1], expr.arg.args[0])
        else:
            raise NotImplementedError('unknown instance expr = %s' % type(expr))
        return o


    def dstflow2label(self, loc_db):
        expr = self.args[0]
        if not isinstance(expr, ExprInt):
            return
        if self.name == "call":
            addr = expr.arg
        else:
            addr = expr.arg + int(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.name in conditional_branch + unconditional_branch:
            return True
        if self.name.startswith('ret'):
            return True
        if self.name.startswith('int'):
            return True
        if self.name.startswith('mov') and self.args[1] == PC:
            return True
        return self.name in ['call']

    def splitflow(self):
        if self.name in conditional_branch:
            return True
        if self.name in unconditional_branch:
            return False
        return self.name in ['call']

    def setdstflow(self, a):
        return

    def is_subcall(self):
        return self.name in ['call']

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

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

    def fixDstOffset(self):
        e = self.args[0]
        if self.offset is None:
            raise ValueError('symbol not resolved %s' % l)
        if not isinstance(e, ExprInt):
            # raise ValueError('dst must be int or label')
            log.warning('dynamic dst %r', e)
            return

        # Call argument is an absolute offset
        # Other offsets are relative to instruction offset
        if self.name != "call":
            self.args[0] =  ExprInt(int(e) - self.offset, 16)

    def get_info(self, c):
        pass

    def __str__(self):
        o = super(instruction_msp430, self).__str__()
        return o

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


mode_msp430 = None


class mn_msp430(cls_mn):
    name = "msp430"
    regs = regs_module
    all_mn = []
    bintree = {}
    num = 0
    delayslot = 0
    pc = {None: PC}
    sp = {None: SP}
    all_mn_mode = defaultdict(list)
    all_mn_name = defaultdict(list)
    all_mn_inst = defaultdict(list)
    instruction = instruction_msp430
    max_instruction_len = 8

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

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

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

    @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:
            i = start / 8
            c = cls.getbytes(bs, i)
            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 getbytes(cls, bs, offset, l=1):
        out = ""
        for _ in xrange(l):
            n_offset = (offset & ~1) + 1 - offset % 2
            out += bs.getbytes(n_offset, 1)
            offset += 1
        return out

    def decoded2bytes(self, result):
        tmp = super(mn_msp430, self).decoded2bytes(result)
        out = []
        for x in tmp:
            o = ""
            while x:
                o += x[:2][::-1]
                x = x[2:]
            out.append(o)
        return out

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

    def additional_info(self):
        info = additional_info()
        return info

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

    def reset_class(self):
        super(mn_msp430, self).reset_class()

    def getnextflow(self, loc_db):
        raise NotImplementedError('not fully functional')


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


class bw_mn(bs_mod_name):
    prio = 5
    mn_mod = ['.w', '.b']


class msp430_sreg_arg(reg_noarg, msp430_arg):
    prio = default_prio + 1
    reg_info = gpregs
    parser = sreg_p

    def decode(self, v):
        size = 16
        if hasattr(self.parent, 'size'):
            size = [16, 8][self.parent.size.value]
        v = v & self.lmask
        e = self.reg_info.expr[v]
        if self.parent.a_s.value == 0b00:
            if e == R3:
                self.expr = ExprInt(0, size)
            else:
                self.expr = e
        elif self.parent.a_s.value == 0b01:
            if e == SR:
                self.expr = ExprMem(ExprInt(self.parent.off_s.value, 16), size)
            elif e == R3:
                self.expr = ExprInt(1, size)
            else:
                self.expr = ExprMem(
                    e + ExprInt(self.parent.off_s.value, 16), size)
        elif self.parent.a_s.value == 0b10:
            if e == SR:
                self.expr = ExprInt(4, size)
            elif e == R3:
                self.expr = ExprInt(2, size)
            else:
                self.expr = ExprMem(e, size)
        elif self.parent.a_s.value == 0b11:
            if e == SR:
                self.expr = ExprInt(8, size)
            elif e == R3:
                if self.parent.size.value == 0:
                    self.expr = ExprInt(0xffff, size)
                else:
                    self.expr = ExprInt(0xff, size)
            elif e == PC:
                self.expr = ExprInt(self.parent.off_s.value, size)
            else:
                self.expr = ExprOp('autoinc', e)
        else:
            raise NotImplementedError(
                "unknown value self.parent.a_s.value = " +
                "%d" % self.parent.a_s.value)
        return True

    def encode(self):
        e = self.expr
        if e in self.reg_info.expr:
            self.parent.a_s.value = 0
            self.value = self.reg_info.expr.index(e)
        elif isinstance(e, ExprInt):
            v = int(e)
            if v == 0xffff and self.parent.size.value == 0:
                self.parent.a_s.value = 0b11
                self.value = 3
            elif v == 0xff and self.parent.size.value == 1:
                self.parent.a_s.value = 0b11
                self.value = 3
            elif v == 2:
                self.parent.a_s.value = 0b10
                self.value = 3
            elif v == 1:
                self.parent.a_s.value = 0b01
                self.value = 3
            elif v == 8:
                self.parent.a_s.value = 0b11
                self.value = 2
            elif v == 4:
                self.parent.a_s.value = 0b10
                self.value = 2
            elif v == 0:
                self.parent.a_s.value = 0b00
                self.value = 3
            else:
                self.parent.a_s.value = 0b11
                self.value = 0
                self.parent.off_s.value = v
        elif isinstance(e, ExprMem):
            if isinstance(e.arg, ExprId):
                self.parent.a_s.value = 0b10
                self.value = self.reg_info.expr.index(e.arg)
            elif isinstance(e.arg, ExprInt):
                self.parent.a_s.value = 0b01
                self.value = self.reg_info.expr.index(SR)
                self.parent.off_s.value = int(e.arg)
            elif isinstance(e.arg, ExprOp):
                self.parent.a_s.value = 0b01
                self.value = self.reg_info.expr.index(e.arg.args[0])
                self.parent.off_s.value = int(e.arg.args[1])
            else:
                raise NotImplementedError(
                    'unknown instance e.arg = %s' % type(e.arg))
        elif isinstance(e, ExprOp) and e.op == "autoinc":
            self.parent.a_s.value = 0b11
            self.value = self.reg_info.expr.index(e.args[0])
        else:
            raise NotImplementedError('unknown instance e = %s' % type(e))
        return True


class msp430_dreg_arg(msp430_sreg_arg):
    prio = default_prio + 1
    reg_info = gpregs
    parser = sreg_p

    def decode(self, v):
        if hasattr(self.parent, 'size'):
            size = [16, 8][self.parent.size.value]
        else:
            size = 16

        v = v & self.lmask
        e = self.reg_info.expr[v]
        if self.parent.a_d.value == 0:
            self.expr = e
        elif self.parent.a_d.value == 1:
            if e == SR:
                x = ExprInt(self.parent.off_d.value, 16)
            else:
                x = e + ExprInt(self.parent.off_d.value, 16)
            self.expr = ExprMem(x, size)
        else:
            raise NotImplementedError(
                "unknown value self.parent.a_d.value = " +
                "%d" % self.parent.a_d.value)
        return True

    def encode(self):
        e = self.expr
        if e in self.reg_info.expr:
            self.parent.a_d.value = 0
            self.value = self.reg_info.expr.index(e)
        elif isinstance(e, ExprMem):
            if isinstance(e.arg, ExprId):
                r, i = e.arg, ExprInt(0, 16)
            elif isinstance(e.arg, ExprOp):
                r, i = e.arg.args[0], e.arg.args[1]
            elif isinstance(e.arg, ExprInt):
                r, i = SR, e.arg
            else:
                raise NotImplementedError(
                    'unknown instance e.arg = %s' % type(e.arg))
            self.parent.a_d.value = 1
            self.value = self.reg_info.expr.index(r)
            self.parent.off_d.value = int(i)
        else:
            raise NotImplementedError('unknown instance e = %s' % type(e))
        return True

class bs_cond_off_s(bs_cond):

    @classmethod
    def flen(cls, mode, v):
        if v['a_s'] == 0b00:
            return None
        elif v['a_s'] == 0b01:
            if v['sreg'] in [3]:
                return None
            else:
                return 16
        elif v['a_s'] == 0b10:
            return None
        elif v['a_s'] == 0b11:
            """
            if v['sreg'] in [2, 3]:
                return None
            else:
                return 16
            """
            if v['sreg'] in [0]:
                return 16
            else:
                return None
        else:
            raise NotImplementedError("unknown value v[a_s] = %d" % v['a_s'])

    def encode(self):
        return super(bs_cond_off_s, self).encode()

    def decode(self, v):
        if self.l == 0:
            self.value = None
        self.value = v
        return True


class bs_cond_off_d(bs_cond_off_s):

    @classmethod
    def flen(cls, mode, v):
        if v['a_d'] == 0:
            return None
        elif v['a_d'] == 1:
            return 16
        else:
            raise NotImplementedError("unknown value v[a_d] = %d" % v['a_d'])


class msp430_offs(imm_noarg, msp430_arg):
    parser = base_expr

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

    def decodeval(self, v):
        v <<= 1
        v += self.parent.l
        return v

    def encodeval(self, v):
        plen = self.parent.l + self.l
        assert(plen % 8 == 0)
        v -= plen / 8
        if v % 2 != 0:
            return False
        return v >> 1

    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, 16)
        return True

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


off_s = bs(l=16, order=-10, cls=(bs_cond_off_s,), fname = "off_s")
off_d = bs(l=16, order=-10, cls=(bs_cond_off_d,), fname = "off_d")

a_s = bs(l=2, order=-4, fname='a_s')
a_d = bs(l=1, order=-6, fname='a_d')

a_d2 = bs(l=2, order=-2, fname='a_d')

sreg = bs(l=4, order=-3, cls=(msp430_sreg_arg,), fname='sreg')
dreg = bs(l=4, order=-5, cls=(msp430_dreg_arg,), fname='dreg')

bw = bw_mn(l=1, order=-10, mn_mod=['.w', '.b'], fname='size')

bs_f1 = bs_name(
    l=4, name={
        'mov': 4, 'add': 5, 'addc': 6, 'subc': 7, 'sub': 8, 'cmp': 9,
        'dadd': 10, 'bit': 11, 'bic': 12, 'bis': 13, 'xor': 14, 'and': 15})
addop("f1", [bs_f1, sreg, a_d, bw, a_s, dreg, off_s, off_d])

bs_f2 = bs_name(l=3, name={'rrc': 0, 'rra': 2,
                           'push': 4})
addop("f2_1", [bs('000100'), bs_f2, bw, a_s, sreg, off_s])


bs_f2_nobw = bs_name(l=3, name={'swpb': 1, 'sxt': 3,
                                'call': 5})
addop("f2_2", [bs('000100'), bs_f2_nobw, bs('0'), a_s, sreg, off_s])

# Offset must be decoded in last position to have final instruction len
offimm = bs(l=10, cls=(msp430_offs,), fname="offs", order=-1)

bs_f2_jcc = bs_name(l=3, name={'jnz': 0, 'jz': 1, 'jnc': 2, 'jc': 3, 'jn': 4,
                               'jge': 5, 'jl': 6, 'jmp': 7})
addop("f2_3", [bs('001'), bs_f2_jcc, offimm])

Module variables

var ARO

var EXPRAFF

var EXPRCOMPOSE

var EXPRCOND

var EXPRID

var EXPRINT

var EXPRLOC

var EXPRMEM

var EXPROP

var EXPRSLICE

var EXPR_ORDER_DICT

var LPARENT

var PINC

var PRIORITY_MAX

var RPARENT

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 a_d

var a_d2

var a_s

var all_regs_ids

var all_regs_ids_byname

var all_regs_ids_init

var all_regs_ids_no_alias

var alphanums

var alphas

var alphas8bit

var attrib_to_regs

var bs_f1

var bs_f2

var bs_f2_jcc

var bs_f2_nobw

var bw

var conditional_branch

var console_handler

var default_prio

var deref_nooff

var deref_off

var deref_pinc

var dreg

var hexnums

var i

var log

var mod_size2uint

var mode_msp430

var nums

var off_d

var off_s

var offimm

var printables

var priorities

var priorities_list

var punc8bit

var reg_cf

var reg_cpuoff

var reg_gie

var reg_nf

var reg_of

var reg_osc

var reg_res

var reg_scg0

var reg_scg1

var reg_zf

var regs16_expr

var regs16_str

var regs_flt_expr

var regs_init

var size_to_IEEE754_info

var sreg

var sreg_p

var total_scans

var unconditional_branch

Functions

def addop(

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

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

def cb_deref_nooff(

tokens)

def cb_deref_nooff(tokens):
    assert len(tokens) == 1
    result = AstMem(tokens[0], 16)
    return result

def cb_deref_off(

tokens)

def cb_deref_off(tokens):
    assert len(tokens) == 2
    result = AstMem(tokens[1] + tokens[0], 16)
    return result

def cb_deref_pinc(

tokens)

def cb_deref_pinc(tokens):
    assert len(tokens) == 1

    result = AstOp('autoinc', *tokens)
    return result

def cb_expr(

tokens)

def cb_expr(tokens):
    assert(len(tokens) == 1)
    result = tokens[0]
    return result

Classes

class additional_info

class additional_info:

    def __init__(self):
        self.except_on_instr = False

Ancestors (in MRO)

Instance variables

var except_on_instr

Methods

def __init__(

self)

def __init__(self):
    self.except_on_instr = False

class bs_cond_off_d

class bs_cond_off_d(bs_cond_off_s):

    @classmethod
    def flen(cls, mode, v):
        if v['a_d'] == 0:
            return None
        elif v['a_d'] == 1:
            return 16
        else:
            raise NotImplementedError("unknown value v[a_d] = %d" % v['a_d'])

Ancestors (in MRO)

Instance variables

var lmask

Inheritance: bs_cond_off_s.lmask

Methods

def __init__(

self, parent, strbits, l, cls, fname, order, lmask, fbits, fmask, value, flen, **kargs)

Inheritance: bs_cond_off_s.__init__

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)

Inheritance: bs_cond_off_s.clone

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)

Inheritance: bs_cond_off_s.decode

def decode(self, v):
    if self.l == 0:
        self.value = None
    self.value = v
    return True

def encode(

self)

Inheritance: bs_cond_off_s.encode

def encode(self):
    return super(bs_cond_off_s, self).encode()

def flen(

cls, mode, v)

Inheritance: bs_cond_off_s.flen

@classmethod
def flen(cls, mode, v):
    if v['a_d'] == 0:
        return None
    elif v['a_d'] == 1:
        return 16
    else:
        raise NotImplementedError("unknown value v[a_d] = %d" % v['a_d'])

class bs_cond_off_s

class bs_cond_off_s(bs_cond):

    @classmethod
    def flen(cls, mode, v):
        if v['a_s'] == 0b00:
            return None
        elif v['a_s'] == 0b01:
            if v['sreg'] in [3]:
                return None
            else:
                return 16
        elif v['a_s'] == 0b10:
            return None
        elif v['a_s'] == 0b11:
            """
            if v['sreg'] in [2, 3]:
                return None
            else:
                return 16
            """
            if v['sreg'] in [0]:
                return 16
            else:
                return None
        else:
            raise NotImplementedError("unknown value v[a_s] = %d" % v['a_s'])

    def encode(self):
        return super(bs_cond_off_s, self).encode()

    def decode(self, v):
        if self.l == 0:
            self.value = None
        self.value = v
        return True

Ancestors (in MRO)

  • bs_cond_off_s
  • miasm2.core.cpu.bs_cond
  • 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 self.l == 0:
        self.value = None
    self.value = v
    return True

def encode(

self)

def encode(self):
    return super(bs_cond_off_s, self).encode()

def flen(

cls, mode, v)

@classmethod
def flen(cls, mode, v):
    if v['a_s'] == 0b00:
        return None
    elif v['a_s'] == 0b01:
        if v['sreg'] in [3]:
            return None
        else:
            return 16
    elif v['a_s'] == 0b10:
        return None
    elif v['a_s'] == 0b11:
        """
        if v['sreg'] in [2, 3]:
            return None
        else:
            return 16
        """
        if v['sreg'] in [0]:
            return 16
        else:
            return None
    else:
        raise NotImplementedError("unknown value v[a_s] = %d" % v['a_s'])

class bw_mn

class bw_mn(bs_mod_name):
    prio = 5
    mn_mod = ['.w', '.b']

Ancestors (in MRO)

  • bw_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 instruction_msp430

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

    def dstflow(self):
        if self.name.startswith('j'):
            return True
        return self.name in ['call']

    @staticmethod
    def arg2str(expr, index=None, loc_db=None):
        if isinstance(expr, ExprId):
            o = str(expr)
        elif isinstance(expr, ExprInt):
            o = str(expr)
        elif expr.is_loc():
            if loc_db is not None:
                return loc_db.pretty_str(expr.loc_key)
            else:
                return str(expr)
        elif isinstance(expr, ExprOp) and expr.op == "autoinc":
            o = "@%s+" % str(expr.args[0])
        elif isinstance(expr, ExprMem):
            if isinstance(expr.arg, ExprId):
                if index == 0:
                    o = "@%s" % expr.arg
                else:
                    o = "0x0(%s)" % expr.arg
            elif isinstance(expr.arg, ExprInt):
                o = "@%s" % expr.arg
            elif isinstance(expr.arg, ExprOp):
                o = "%s(%s)" % (expr.arg.args[1], expr.arg.args[0])
        else:
            raise NotImplementedError('unknown instance expr = %s' % type(expr))
        return o


    def dstflow2label(self, loc_db):
        expr = self.args[0]
        if not isinstance(expr, ExprInt):
            return
        if self.name == "call":
            addr = expr.arg
        else:
            addr = expr.arg + int(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.name in conditional_branch + unconditional_branch:
            return True
        if self.name.startswith('ret'):
            return True
        if self.name.startswith('int'):
            return True
        if self.name.startswith('mov') and self.args[1] == PC:
            return True
        return self.name in ['call']

    def splitflow(self):
        if self.name in conditional_branch:
            return True
        if self.name in unconditional_branch:
            return False
        return self.name in ['call']

    def setdstflow(self, a):
        return

    def is_subcall(self):
        return self.name in ['call']

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

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

    def fixDstOffset(self):
        e = self.args[0]
        if self.offset is None:
            raise ValueError('symbol not resolved %s' % l)
        if not isinstance(e, ExprInt):
            # raise ValueError('dst must be int or label')
            log.warning('dynamic dst %r', e)
            return

        # Call argument is an absolute offset
        # Other offsets are relative to instruction offset
        if self.name != "call":
            self.args[0] =  ExprInt(int(e) - self.offset, 16)

    def get_info(self, c):
        pass

    def __str__(self):
        o = super(instruction_msp430, self).__str__()
        return o

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

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):
    if isinstance(expr, ExprId):
        o = str(expr)
    elif isinstance(expr, ExprInt):
        o = str(expr)
    elif expr.is_loc():
        if loc_db is not None:
            return loc_db.pretty_str(expr.loc_key)
        else:
            return str(expr)
    elif isinstance(expr, ExprOp) and expr.op == "autoinc":
        o = "@%s+" % str(expr.args[0])
    elif isinstance(expr, ExprMem):
        if isinstance(expr.arg, ExprId):
            if index == 0:
                o = "@%s" % expr.arg
            else:
                o = "0x0(%s)" % expr.arg
        elif isinstance(expr.arg, ExprInt):
            o = "@%s" % expr.arg
        elif isinstance(expr.arg, ExprOp):
            o = "%s(%s)" % (expr.arg.args[1], expr.arg.args[0])
    else:
        raise NotImplementedError('unknown instance expr = %s' % type(expr))
    return o

Methods

def __init__(

self, name, mode, args, additional_info=None)

def __init__(self, name, mode, args, additional_info=None):
    self.name = name
    self.mode = mode
    self.args = args
    self.additional_info = additional_info
    self.offset = None
    self.l = None
    self.b = None

def breakflow(

self)

def breakflow(self):
    if self.name in conditional_branch + unconditional_branch:
        return True
    if self.name.startswith('ret'):
        return True
    if self.name.startswith('int'):
        return True
    if self.name.startswith('mov') and self.args[1] == PC:
        return True
    return self.name in ['call']

def dstflow(

self)

def dstflow(self):
    if self.name.startswith('j'):
        return True
    return self.name in ['call']

def dstflow2label(

self, loc_db)

def dstflow2label(self, loc_db):
    expr = self.args[0]
    if not isinstance(expr, ExprInt):
        return
    if self.name == "call":
        addr = expr.arg
    else:
        addr = expr.arg + int(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):
        # raise ValueError('dst must be int or label')
        log.warning('dynamic dst %r', e)
        return
    # Call argument is an absolute offset
    # Other offsets are relative to instruction offset
    if self.name != "call":
        self.args[0] =  ExprInt(int(e) - self.offset, 16)

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 = []
    for a in self.args:
        args.append(a)
    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):
    return m2_expr.ExprInt(self.offset, expr.size)

def get_info(

self, c)

def get_info(self, c):
    pass

def get_symbol_size(

self, symbol, loc_db)

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

def getdstflow(

self, loc_db)

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

def is_subcall(

self)

def is_subcall(self):
    return self.name in ['call']

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

self, a)

def setdstflow(self, a):
    return

def splitflow(

self)

def splitflow(self):
    if self.name in conditional_branch:
        return True
    if self.name in unconditional_branch:
        return False
    return self.name in ['call']

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 mn_msp430

class mn_msp430(cls_mn):
    name = "msp430"
    regs = regs_module
    all_mn = []
    bintree = {}
    num = 0
    delayslot = 0
    pc = {None: PC}
    sp = {None: SP}
    all_mn_mode = defaultdict(list)
    all_mn_name = defaultdict(list)
    all_mn_inst = defaultdict(list)
    instruction = instruction_msp430
    max_instruction_len = 8

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

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

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

    @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:
            i = start / 8
            c = cls.getbytes(bs, i)
            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 getbytes(cls, bs, offset, l=1):
        out = ""
        for _ in xrange(l):
            n_offset = (offset & ~1) + 1 - offset % 2
            out += bs.getbytes(n_offset, 1)
            offset += 1
        return out

    def decoded2bytes(self, result):
        tmp = super(mn_msp430, self).decoded2bytes(result)
        out = []
        for x in tmp:
            o = ""
            while x:
                o += x[:2][::-1]
                x = x[2:]
            out.append(o)
        return out

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

    def additional_info(self):
        info = additional_info()
        return info

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

    def reset_class(self):
        super(mn_msp430, self).reset_class()

    def getnextflow(self, loc_db):
        raise NotImplementedError('not fully functional')

Ancestors (in MRO)

  • mn_msp430
  • 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()
    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 % 16 == 00, "len %r" % l

def decoded2bytes(

self, result)

def decoded2bytes(self, result):
    tmp = super(mn_msp430, self).decoded2bytes(result)
    out = []
    for x in tmp:
        o = ""
        while x:
            o += x[:2][::-1]
            x = x[2:]
        out.append(o)
    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 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 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:
        i = start / 8
        c = cls.getbytes(bs, i)
        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=1)

@classmethod
def getbytes(cls, bs, offset, l=1):
    out = ""
    for _ in xrange(l):
        n_offset = (offset & ~1) + 1 - offset % 2
        out += bs.getbytes(n_offset, 1)
        offset += 1
    return out

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

self, loc_db)

def getnextflow(self, loc_db):
    raise NotImplementedError('not fully functional')

def getpc(

cls, attrib)

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

def getsp(

cls, attrib)

@classmethod
def getsp(cls, attrib):
    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 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):
    super(mn_msp430, self).reset_class()

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):
    todo = [(0, 0, [(x, self.fields_order[x]) for x in self.to_decode[::-1]])]
    result = []
    done = []
    while todo:
        index, cur_len, to_decode = todo.pop()
        # TEST XXX
        for _, f in to_decode:
            setattr(self, f.fname, f)
        if (index, [x[1].value for x in to_decode]) in done:
            continue
        done.append((index, [x[1].value for x in to_decode]))
        can_encode = True
        for i, f in to_decode[index:]:
            f.parent.l = cur_len
            ret = f.encode()
            if not ret:
                log.debug('cannot encode %r', f)
                can_encode = False
                break
            if f.value is not None and f.l:
                assert f.value <= f.lmask
                cur_len += f.l
            index += 1
            if ret is True:
                continue
            for _ in ret:
                o = []
                if ((index, cur_len, [xx[1].value for xx in to_decode]) in todo or
                    (index, cur_len, [xx[1].value for xx in to_decode]) in done):
                    raise NotImplementedError('not fully functional')
                for p, f in to_decode:
                    fnew = f.clone()
                    o.append((p, fnew))
                todo.append((index, cur_len, o))
            can_encode = False
            break
        if not can_encode:
            continue
        result.append(to_decode)
    return self.decoded2bytes(result)

class msp430_arg

class msp430_arg(m_arg):
    def asm_ast_to_expr(self, value, loc_db):
        if isinstance(value, AstId):
            name = value.name
            if isinstance(name, Expr):
                return name
            assert isinstance(name, str)
            if name in gpregs.str:
                index = gpregs.str.index(name)
                reg = gpregs.expr[index]
                return reg
            loc_key = loc_db.get_or_create_name_location(value.name)
            return ExprLoc(loc_key, 16)
        if isinstance(value, AstOp):
            args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in value.args]
            if None in args:
                return None
            return ExprOp(value.op, *args)
        if isinstance(value, AstInt):
            return ExprInt(value.value, 16)
        if isinstance(value, AstMem):
            ptr = self.asm_ast_to_expr(value.ptr, loc_db)
            if ptr is None:
                return None
            return ExprMem(ptr, value.size)
        return None

Ancestors (in MRO)

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

Methods

def asm_ast_to_expr(

self, value, loc_db)

def asm_ast_to_expr(self, value, loc_db):
    if isinstance(value, AstId):
        name = value.name
        if isinstance(name, Expr):
            return name
        assert isinstance(name, str)
        if name in gpregs.str:
            index = gpregs.str.index(name)
            reg = gpregs.expr[index]
            return reg
        loc_key = loc_db.get_or_create_name_location(value.name)
        return ExprLoc(loc_key, 16)
    if isinstance(value, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in value.args]
        if None in args:
            return None
        return ExprOp(value.op, *args)
    if isinstance(value, AstInt):
        return ExprInt(value.value, 16)
    if isinstance(value, AstMem):
        ptr = self.asm_ast_to_expr(value.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, value.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 msp430_dreg_arg

class msp430_dreg_arg(msp430_sreg_arg):
    prio = default_prio + 1
    reg_info = gpregs
    parser = sreg_p

    def decode(self, v):
        if hasattr(self.parent, 'size'):
            size = [16, 8][self.parent.size.value]
        else:
            size = 16

        v = v & self.lmask
        e = self.reg_info.expr[v]
        if self.parent.a_d.value == 0:
            self.expr = e
        elif self.parent.a_d.value == 1:
            if e == SR:
                x = ExprInt(self.parent.off_d.value, 16)
            else:
                x = e + ExprInt(self.parent.off_d.value, 16)
            self.expr = ExprMem(x, size)
        else:
            raise NotImplementedError(
                "unknown value self.parent.a_d.value = " +
                "%d" % self.parent.a_d.value)
        return True

    def encode(self):
        e = self.expr
        if e in self.reg_info.expr:
            self.parent.a_d.value = 0
            self.value = self.reg_info.expr.index(e)
        elif isinstance(e, ExprMem):
            if isinstance(e.arg, ExprId):
                r, i = e.arg, ExprInt(0, 16)
            elif isinstance(e.arg, ExprOp):
                r, i = e.arg.args[0], e.arg.args[1]
            elif isinstance(e.arg, ExprInt):
                r, i = SR, e.arg
            else:
                raise NotImplementedError(
                    'unknown instance e.arg = %s' % type(e.arg))
            self.parent.a_d.value = 1
            self.value = self.reg_info.expr.index(r)
            self.parent.off_d.value = int(i)
        else:
            raise NotImplementedError('unknown instance e = %s' % type(e))
        return True

Ancestors (in MRO)

Class variables

var parser

Inheritance: msp430_sreg_arg.parser

var prio

Inheritance: msp430_sreg_arg.prio

var reg_info

Inheritance: msp430_sreg_arg.reg_info

Methods

def asm_ast_to_expr(

self, value, loc_db)

Inheritance: msp430_sreg_arg.asm_ast_to_expr

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

def check_fbits(

self, v)

Inheritance: msp430_sreg_arg.check_fbits

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

def decode(

self, v)

Inheritance: msp430_sreg_arg.decode

def decode(self, v):
    if hasattr(self.parent, 'size'):
        size = [16, 8][self.parent.size.value]
    else:
        size = 16
    v = v & self.lmask
    e = self.reg_info.expr[v]
    if self.parent.a_d.value == 0:
        self.expr = e
    elif self.parent.a_d.value == 1:
        if e == SR:
            x = ExprInt(self.parent.off_d.value, 16)
        else:
            x = e + ExprInt(self.parent.off_d.value, 16)
        self.expr = ExprMem(x, size)
    else:
        raise NotImplementedError(
            "unknown value self.parent.a_d.value = " +
            "%d" % self.parent.a_d.value)
    return True

def encode(

self)

Inheritance: msp430_sreg_arg.encode

def encode(self):
    e = self.expr
    if e in self.reg_info.expr:
        self.parent.a_d.value = 0
        self.value = self.reg_info.expr.index(e)
    elif isinstance(e, ExprMem):
        if isinstance(e.arg, ExprId):
            r, i = e.arg, ExprInt(0, 16)
        elif isinstance(e.arg, ExprOp):
            r, i = e.arg.args[0], e.arg.args[1]
        elif isinstance(e.arg, ExprInt):
            r, i = SR, e.arg
        else:
            raise NotImplementedError(
                'unknown instance e.arg = %s' % type(e.arg))
        self.parent.a_d.value = 1
        self.value = self.reg_info.expr.index(r)
        self.parent.off_d.value = int(i)
    else:
        raise NotImplementedError('unknown instance e = %s' % type(e))
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: msp430_sreg_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 msp430_offs

class msp430_offs(imm_noarg, msp430_arg):
    parser = base_expr

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

    def decodeval(self, v):
        v <<= 1
        v += self.parent.l
        return v

    def encodeval(self, v):
        plen = self.parent.l + self.l
        assert(plen % 8 == 0)
        v -= plen / 8
        if v % 2 != 0:
            return False
        return v >> 1

    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, 16)
        return True

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

Ancestors (in MRO)

Class variables

var intmask

var intsize

var parser

Methods

def asm_ast_to_expr(

self, value, loc_db)

Inheritance: msp430_arg.asm_ast_to_expr

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

def decode(

self, v)

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, 16)
    return True

def decodeval(

self, v)

def decodeval(self, v):
    v <<= 1
    v += self.parent.l
    return v

def encode(

self)

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

def encodeval(

self, v)

def encodeval(self, v):
    plen = self.parent.l + self.l
    assert(plen % 8 == 0)
    v -= plen / 8
    if v % 2 != 0:
        return False
    return v >> 1

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: msp430_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 ExprInt(v, 16)

class msp430_sreg_arg

class msp430_sreg_arg(reg_noarg, msp430_arg):
    prio = default_prio + 1
    reg_info = gpregs
    parser = sreg_p

    def decode(self, v):
        size = 16
        if hasattr(self.parent, 'size'):
            size = [16, 8][self.parent.size.value]
        v = v & self.lmask
        e = self.reg_info.expr[v]
        if self.parent.a_s.value == 0b00:
            if e == R3:
                self.expr = ExprInt(0, size)
            else:
                self.expr = e
        elif self.parent.a_s.value == 0b01:
            if e == SR:
                self.expr = ExprMem(ExprInt(self.parent.off_s.value, 16), size)
            elif e == R3:
                self.expr = ExprInt(1, size)
            else:
                self.expr = ExprMem(
                    e + ExprInt(self.parent.off_s.value, 16), size)
        elif self.parent.a_s.value == 0b10:
            if e == SR:
                self.expr = ExprInt(4, size)
            elif e == R3:
                self.expr = ExprInt(2, size)
            else:
                self.expr = ExprMem(e, size)
        elif self.parent.a_s.value == 0b11:
            if e == SR:
                self.expr = ExprInt(8, size)
            elif e == R3:
                if self.parent.size.value == 0:
                    self.expr = ExprInt(0xffff, size)
                else:
                    self.expr = ExprInt(0xff, size)
            elif e == PC:
                self.expr = ExprInt(self.parent.off_s.value, size)
            else:
                self.expr = ExprOp('autoinc', e)
        else:
            raise NotImplementedError(
                "unknown value self.parent.a_s.value = " +
                "%d" % self.parent.a_s.value)
        return True

    def encode(self):
        e = self.expr
        if e in self.reg_info.expr:
            self.parent.a_s.value = 0
            self.value = self.reg_info.expr.index(e)
        elif isinstance(e, ExprInt):
            v = int(e)
            if v == 0xffff and self.parent.size.value == 0:
                self.parent.a_s.value = 0b11
                self.value = 3
            elif v == 0xff and self.parent.size.value == 1:
                self.parent.a_s.value = 0b11
                self.value = 3
            elif v == 2:
                self.parent.a_s.value = 0b10
                self.value = 3
            elif v == 1:
                self.parent.a_s.value = 0b01
                self.value = 3
            elif v == 8:
                self.parent.a_s.value = 0b11
                self.value = 2
            elif v == 4:
                self.parent.a_s.value = 0b10
                self.value = 2
            elif v == 0:
                self.parent.a_s.value = 0b00
                self.value = 3
            else:
                self.parent.a_s.value = 0b11
                self.value = 0
                self.parent.off_s.value = v
        elif isinstance(e, ExprMem):
            if isinstance(e.arg, ExprId):
                self.parent.a_s.value = 0b10
                self.value = self.reg_info.expr.index(e.arg)
            elif isinstance(e.arg, ExprInt):
                self.parent.a_s.value = 0b01
                self.value = self.reg_info.expr.index(SR)
                self.parent.off_s.value = int(e.arg)
            elif isinstance(e.arg, ExprOp):
                self.parent.a_s.value = 0b01
                self.value = self.reg_info.expr.index(e.arg.args[0])
                self.parent.off_s.value = int(e.arg.args[1])
            else:
                raise NotImplementedError(
                    'unknown instance e.arg = %s' % type(e.arg))
        elif isinstance(e, ExprOp) and e.op == "autoinc":
            self.parent.a_s.value = 0b11
            self.value = self.reg_info.expr.index(e.args[0])
        else:
            raise NotImplementedError('unknown instance e = %s' % type(e))
        return True

Ancestors (in MRO)

Class variables

var parser

var prio

var reg_info

Methods

def asm_ast_to_expr(

self, value, loc_db)

Inheritance: msp430_arg.asm_ast_to_expr

def asm_ast_to_expr(self, value, loc_db):
    if isinstance(value, AstId):
        name = value.name
        if isinstance(name, Expr):
            return name
        assert isinstance(name, str)
        if name in gpregs.str:
            index = gpregs.str.index(name)
            reg = gpregs.expr[index]
            return reg
        loc_key = loc_db.get_or_create_name_location(value.name)
        return ExprLoc(loc_key, 16)
    if isinstance(value, AstOp):
        args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in value.args]
        if None in args:
            return None
        return ExprOp(value.op, *args)
    if isinstance(value, AstInt):
        return ExprInt(value.value, 16)
    if isinstance(value, AstMem):
        ptr = self.asm_ast_to_expr(value.ptr, loc_db)
        if ptr is None:
            return None
        return ExprMem(ptr, value.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):
    size = 16
    if hasattr(self.parent, 'size'):
        size = [16, 8][self.parent.size.value]
    v = v & self.lmask
    e = self.reg_info.expr[v]
    if self.parent.a_s.value == 0b00:
        if e == R3:
            self.expr = ExprInt(0, size)
        else:
            self.expr = e
    elif self.parent.a_s.value == 0b01:
        if e == SR:
            self.expr = ExprMem(ExprInt(self.parent.off_s.value, 16), size)
        elif e == R3:
            self.expr = ExprInt(1, size)
        else:
            self.expr = ExprMem(
                e + ExprInt(self.parent.off_s.value, 16), size)
    elif self.parent.a_s.value == 0b10:
        if e == SR:
            self.expr = ExprInt(4, size)
        elif e == R3:
            self.expr = ExprInt(2, size)
        else:
            self.expr = ExprMem(e, size)
    elif self.parent.a_s.value == 0b11:
        if e == SR:
            self.expr = ExprInt(8, size)
        elif e == R3:
            if self.parent.size.value == 0:
                self.expr = ExprInt(0xffff, size)
            else:
                self.expr = ExprInt(0xff, size)
        elif e == PC:
            self.expr = ExprInt(self.parent.off_s.value, size)
        else:
            self.expr = ExprOp('autoinc', e)
    else:
        raise NotImplementedError(
            "unknown value self.parent.a_s.value = " +
            "%d" % self.parent.a_s.value)
    return True

def encode(

self)

def encode(self):
    e = self.expr
    if e in self.reg_info.expr:
        self.parent.a_s.value = 0
        self.value = self.reg_info.expr.index(e)
    elif isinstance(e, ExprInt):
        v = int(e)
        if v == 0xffff and self.parent.size.value == 0:
            self.parent.a_s.value = 0b11
            self.value = 3
        elif v == 0xff and self.parent.size.value == 1:
            self.parent.a_s.value = 0b11
            self.value = 3
        elif v == 2:
            self.parent.a_s.value = 0b10
            self.value = 3
        elif v == 1:
            self.parent.a_s.value = 0b01
            self.value = 3
        elif v == 8:
            self.parent.a_s.value = 0b11
            self.value = 2
        elif v == 4:
            self.parent.a_s.value = 0b10
            self.value = 2
        elif v == 0:
            self.parent.a_s.value = 0b00
            self.value = 3
        else:
            self.parent.a_s.value = 0b11
            self.value = 0
            self.parent.off_s.value = v
    elif isinstance(e, ExprMem):
        if isinstance(e.arg, ExprId):
            self.parent.a_s.value = 0b10
            self.value = self.reg_info.expr.index(e.arg)
        elif isinstance(e.arg, ExprInt):
            self.parent.a_s.value = 0b01
            self.value = self.reg_info.expr.index(SR)
            self.parent.off_s.value = int(e.arg)
        elif isinstance(e.arg, ExprOp):
            self.parent.a_s.value = 0b01
            self.value = self.reg_info.expr.index(e.arg.args[0])
            self.parent.off_s.value = int(e.arg.args[1])
        else:
            raise NotImplementedError(
                'unknown instance e.arg = %s' % type(e.arg))
    elif isinstance(e, ExprOp) and e.op == "autoinc":
        self.parent.a_s.value = 0b11
        self.value = self.reg_info.expr.index(e.args[0])
    else:
        raise NotImplementedError('unknown instance e = %s' % type(e))
    return True

def fromstring(

self, text, loc_db, parser_result=None)

Inheritance: msp430_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