Skip to content

Commit

Permalink
more instrs
Browse files Browse the repository at this point in the history
  • Loading branch information
b14aa178 committed Feb 9, 2020
1 parent f847fcc commit 5025f4f
Show file tree
Hide file tree
Showing 4 changed files with 251 additions and 7 deletions.
176 changes: 172 additions & 4 deletions miasm/arch/arm/arch.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@
regs_str[15] = 'PC'
regs_expr = [ExprId(x, 32) for x in regs_str]

# Single-Precision
spregs_str = ['S%d' % r for r in range(0x20)]
spregs_expr = [ExprId(x, 32) for x in spregs_str]
spregs = reg_info(spregs_str, spregs_expr)

# Double-Precision
dpregs_str = ['D%d' % r for r in range(0x10)]
dpregs_expr = [ExprId(x, 32) for x in dpregs_str]
dpregs = reg_info(dpregs_str, dpregs_expr)

gpregs = reg_info(regs_str, regs_expr)

gpregs_pc = reg_info(regs_str[-1:], regs_expr[-1:])
Expand Down Expand Up @@ -812,6 +822,9 @@ def asm_ast_to_expr(self, arg, loc_db):
class arm_reg(reg_noarg, arm_arg):
pass

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

class arm_gpreg_noarg(reg_noarg):
reg_info = gpregs
Expand Down Expand Up @@ -1390,6 +1403,7 @@ def encode(self):
lnk = bs_lnk(l=1, fname='lnk', mn_mod=['', 'L'])
offs = bs(l=24, cls=(arm_offs,), fname="offs")

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

Expand All @@ -1415,6 +1429,7 @@ def encode(self):

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

Expand Down Expand Up @@ -1813,6 +1828,46 @@ def encode(self):
return True


class arm_dpregs_1_4(reg_noarg):
reg_info = dpregs
parser = reg_info.parser


def decode(self, v):
v = v & self.lmask
v = self.parent.dpregs_1_x.value << 4 | v
self.expr = self.reg_info.expr[v]
return True

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)
self.parent.dpregs_1_x.value = self.value >> 4 & self.parent.dpregs_1_x.lmask
return True


class arm_spregs_4_1(reg_noarg):
reg_info = spregs
parser = reg_info.parser


def decode(self, v):
v = v & self.lmask
v = self.parent.spregs_x_1.value | (v << 1)
self.expr = self.reg_info.expr[v]
return True

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)
self.parent.spregs_x_1.value = self.value & self.parent.spregs_x_1.lmask
return True


class arm_gpreg_nopc(reg_noarg):
reg_info = gpregs_nopc
parser = reg_info.parser
Expand Down Expand Up @@ -1854,6 +1909,7 @@ def decode(self, v):
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")
rt2_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")

Expand Down Expand Up @@ -2014,11 +2070,14 @@ def encodeval(self, v):
return v >> 2

class arm_deref_reg_imm(arm_arg):
reg_info = gpregs
parser = deref_reg_imm

def decode(self, v):
v = v & self.lmask
rbase = regs_expr[v]
if regs_expr[v] not in self.reg_info.expr:
return False
rbase = self.reg_info.expr[v]
e = ExprOp('preinc', rbase, self.parent.off.expr)
self.expr = ExprMem(e, 32)
return True
Expand Down Expand Up @@ -2049,6 +2108,8 @@ def encode(self):
class arm_derefl(arm_deref_reg_imm):
parser = deref_low

class arm_nopc_deref(arm_deref_reg_imm):
reg_info = gpregs_nopc

class arm_offbw(imm_noarg):

Expand Down Expand Up @@ -2350,6 +2411,7 @@ class arm_sp(arm_reg):
sppc = bs(l=1, cls=(arm_sppc,))

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


Expand Down Expand Up @@ -2451,6 +2513,7 @@ class arm_sp(arm_reg):
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("btransfersp", [bs('1110100010'), wback, bs_tbtransfer_name, rn_wb, pc_in, lr_in, bs('0'), trlist13pclr])
armtop("br", [bs('1101'), bs_br_name, offs8])
armtop("blx", [bs("01000111"), bs('1'), rm, bs('000')])
armtop("svc", [bs('11011111'), imm8])
Expand Down Expand Up @@ -3303,6 +3366,7 @@ def check_fbits(self, v):
armtop("sub", [bs('11110'), imm12_1, bs('01101'), scc, rn, bs('0'), imm12_3, rd_nopc, imm12_8], [rd_nopc, rn, imm12_8])
armtop("eor", [bs('11110'), imm12_1, bs('00100'), 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("add", [bs('11110'), imm12_1, bs('10000'), bs('0'), rn_sp_nowb, bs('0'), imm12_3, rd, imm12_8_t4], [rd, rn_sp_nowb, imm12_8_t4])
armtop("cmp", [bs('11110'), imm12_1, bs('01101'), bs('1'), rn, bs('0'), imm12_3, bs('1111'), imm12_8] )

armtop("cmp", [bs('11101011101'), bs('1'), rn, bs('0'), imm5_3, bs('1111'), imm5_2, imm_stype, rm_sh], [rn, rm_sh] )
Expand Down Expand Up @@ -3342,23 +3406,125 @@ def check_fbits(self, v):
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("strb", [bs('111110000000'), rn_noarg, rt, bs('000000'), imm2_noarg, rm_deref_reg], [rt, rm_deref_reg])
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])

class arm_dpregs_4_1:
reg_info = dpregs
parser = reg_info.parser

def decode(self, v):
v = v & self.lmask
v = self.parent.dpregs_x_1.value | v << 1
self.expr = self.reg_info.expr[v]
return True

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)
self.parent.dpregs_x_1.value = self.value & self.parent.dpregs_x_1.lmask
return True


sn_4_1 = bs(l=4, cls=(arm_spregs_4_1, arm_arg))
sn_x_1 = bs(l=1, fname="spregs_x_1", order=-1)
sm_4_1 = bs(l=4, cls=(arm_spregs_4_1, arm_arg))
sm_x_1 = bs(l=1, fname="spregs_x_1", order=-1)
dn_1_4 = bs(l=4, cls=(arm_dpregs_1_4, arm_arg))
dn_1_x = bs(l=1, fname="dpregs_1_x", order=-1)
dm_4_1 = bs(l=4, cls=(arm_dpregs_4_1, arm_arg))
dm_x_1 = bs(l=1, fname="dpregs_x_1", order=-1)

# DDI0406C.d
# A8.8.344
armtop("vmov", [bs('11101110000'), bs('1'), sn_4_1, rt_nopc, bs('1010'), sn_x_1, bs('0010000')], [rt_nopc, sn_4_1])
armtop("vmov", [bs('11101110000'), bs('0'), sn_4_1, rt_nopc, bs('1010'), sn_x_1, bs('0010000')], [sn_4_1, rt_nopc])

# A8.8.346
armtop("vmov", [bs('11101100010'), bs('1'), rt2_nopc, rt_nopc, bs('101100'), dn_1_x, bs('1'), dn_1_4], [rt_nopc, rt2_nopc, dn_1_4])
armtop("vmov", [bs('11101100010'), bs('0'), rt2_nopc, rt_nopc, bs('101100'), dn_1_x, bs('1'), dn_1_4], [dn_1_4, rt_nopc, rt2_nopc])

# A8.8.310
armtop("vcvt", [bs('111011101'), sn_x_1, bs('111'), bs("101"), sn_4_1, bs('101'), bs('1'), bs('0'), bs('1'), dn_1_x, bs('0'), dn_1_4], [sn_4_1, dn_1_4])
armtop("vcvt", [bs('111011101'), sn_x_1, bs('111'), bs("101"), sn_4_1, bs('101'), bs('0'), bs('0'), bs('1'), sm_x_1, bs('0'), sm_4_1], [sn_4_1, sm_4_1])
armtop("vcvt", [bs('111011101'), sn_x_1, bs('111'), bs("100"), sn_4_1, bs('101'), bs('1'), bs('0'), bs('1'), dn_1_x, bs('0'), dn_1_4], [sn_4_1, dn_1_4])
armtop("vcvt", [bs('111011101'), sn_x_1, bs('111'), bs("100"), sn_4_1, bs('101'), bs('0'), bs('0'), bs('1'), sm_x_1, bs('0'), sm_4_1], [sn_4_1, sm_4_1])
# dp_operation = true
armtop("vcvt", [bs('111011101'), dn_1_x, bs('111'), bs("000"), dn_1_4, bs('101'), bs('1'), bs('1'), bs('1'), sm_x_1, bs('0'), sm_4_1], [dn_1_4, sm_4_1])
armtop("vcvt", [bs('111011101'), dn_1_x, bs('111'), bs("000"), dn_1_4, bs('101'), bs('1'), bs('0'), bs('1'), sm_x_1, bs('0'), sm_4_1], [dn_1_4, sm_4_1])
# dp_operation = false
armtop("vcvt", [bs('111011101'), sn_x_1, bs('111'), bs("000"), sn_4_1, bs('101'), bs('0'), bs('1'), bs('1'), sm_x_1, bs('0'), sm_4_1], [sn_4_1, sm_4_1])
armtop("vcvt", [bs('111011101'), sn_x_1, bs('111'), bs("000"), sn_4_1, bs('101'), bs('0'), bs('0'), bs('1'), sm_x_1, bs('0'), sm_4_1], [sn_4_1, sm_4_1])


class armt_pc_deref(arm_arg):
parser = deref_pc

def decode(self, v):
v = v & self.lmask
rbase = regs_expr[v]
e = None
if self.parent.updown.value == 1:
e = ExprOp('preinc', rbase, self.parent.off.expr)
else:
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.ptr
if not (isinstance(e, ExprOp) and e.op == 'preinc'):
log.debug('cannot encode %r', e)
return False
off = e.args[1]

if not isinstance(off, ExprInt):
log.debug('cannot encode off %r', off)
return False

v = int(off)

if v < 0 or v & (1 << 31):
self.parent.updown.value = 0
v = (-v) & 0xFFFFFFFF
else:
self.parent.updown.value = 1

self.parent.off.expr = ExprInt(v, 32)
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


pc_deref_u = bs("1111", l=4, cls=(armt_pc_deref,))
rn_nopc_deref = bs(l=4, cls=(arm_nopc_deref,), fname="rt")

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])
# doc: ARM DDI 0406C.d A8-411
armtop("ldr", [bs('11111000'), updown, bs('101'), pc_deref_u, rt, off12], [rt, pc_deref_u])
armtop("ldr", [bs('111110001101'), rn_nopc_deref, rt, off12], [rt, rn_nopc_deref])
armtop("ldr", [bs('111110000101'), rn_nopc_noarg, rt, bs('1'), ppi, updown, wback_no_t, deref_immpuw], [rt, deref_immpuw])
armtop("ldr", [bs('111110000101'), rn_nopc_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("ldrex",[bs('111010000101'), rn_deref, rt, bs('1111'), off8_], [rt, rn_deref])
armtop("strex", [bs('111010000100'), rn_deref, rt, rd, off8_], [rd, rt, rn_deref])

armtop("pld", [bs('111110001001'), rn_deref, bs('1111'), off12], [rn_deref])
armtop("pldw", [bs('111110001011'), rn_deref, bs('1111'), off12], [rn_deref])
Expand All @@ -3367,5 +3533,7 @@ def check_fbits(self, v):
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])
armtop("dmb", [bs('111100111011'), bs('1111'), bs('1000'), bs('1111'), bs('0101'), barrier_option])
armtop("teq", [bs('111010101001'), rn_nosppc, bs('0'), imm5_3, bs('1111'), imm5_2, imm_stype, rm_sh])

armtop("adr", [bs('11110'), imm12_1, bs('100000'), bs('1111'), bs('0'), imm12_3, rd, imm12_8_t4], [rd, imm12_8_t4])
27 changes: 27 additions & 0 deletions miasm/arch/arm/sem.py
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,15 @@ def blx(ir, instr, a):
e.append(ExprAssign(LR, l))
return e, []

# todo
def vmov(ir, instr, a, b, c=None):
e = []
return e, []

# todo
def vcvt(ir, instr, a, a2):
e = []
return e, []

def st_ld_r(ir, instr, a, a2, b, store=False, size=32, s_ext=False, z_ext=False):
e = []
Expand Down Expand Up @@ -827,6 +836,10 @@ def st_ld_r(ir, instr, a, a2, b, store=False, size=32, s_ext=False, z_ext=False)
def ldr(ir, instr, a, b):
return st_ld_r(ir, instr, a, None, b, store=False)

# todo:
def ldrex(ir, instr, a, b):
e = []
return e, []

def ldrd(ir, instr, a, b, c=None):
if c is None:
Expand All @@ -840,6 +853,10 @@ def ldrd(ir, instr, a, b, c=None):
def l_str(ir, instr, a, b):
return st_ld_r(ir, instr, a, None, b, store=True)

# todo:
def strex(ir, instr, a, b, c=None):
e = []
return e, []

def l_strd(ir, instr, a, b, c=None):
if c is None:
Expand Down Expand Up @@ -1314,6 +1331,10 @@ def nop(ir, instr):
e = []
return e, []

# todo:
def dmb(ir, instr, a):
e = []
return e, []

def dsb(ir, instr, a):
# XXX TODO
Expand Down Expand Up @@ -1526,8 +1547,10 @@ def add_condition_expr(ir, instr, cond, instr_ir, extra_ir):
'ldr': ldr,
'ldrd': ldrd,
'ldrsb': ldrsb,
'ldrex': ldrex,
'str': l_str,
'strd': l_strd,
'strex': strex,
'b': b,
'bl': bl,
'svc': svc,
Expand Down Expand Up @@ -1588,6 +1611,9 @@ def add_condition_expr(ir, instr, cond, instr_ir, extra_ir):
'ldrb': ldrb,
'ldsb': ldrsb,
'strb': strb,

'vmov': vmov,
'vcvt': vcvt
}

mnemo_condm2 = {'ldmia': ldmia,
Expand Down Expand Up @@ -1642,6 +1668,7 @@ def add_condition_expr(ir, instr, cond, instr_ir, extra_ir):
'smlatt': smlatt,
'uadd8': uadd8,
'sel': sel,
'dmb': dmb
}

mn_cond_x = [mnemo_condm0,
Expand Down
4 changes: 3 additions & 1 deletion miasm/core/cpu.py
Original file line number Diff line number Diff line change
Expand Up @@ -1459,7 +1459,9 @@ def value(self, mode):
break

if f.value is not None and f.l:
assert f.value <= f.lmask
if f.value > f.lmask:
can_encode = False
break
cur_len += f.l
index += 1
if ret is True:
Expand Down
Loading

0 comments on commit 5025f4f

Please sign in to comment.