Skip to content

Commit

Permalink
Add more armt instrs
Browse files Browse the repository at this point in the history
  • Loading branch information
b14aa178 committed Sep 7, 2021
1 parent 2bc3b28 commit 3a0d417
Show file tree
Hide file tree
Showing 2 changed files with 230 additions and 4 deletions.
197 changes: 193 additions & 4 deletions miasm/arch/arm/arch.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,21 @@
regs_expr[:13] + [reg_dum, regs_expr[14], regs_expr[15]])


# Single-Precision
spregs_str = ['S%d' % r for r in range(32)]
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(32)]
dpregs_expr = [ExprId(x, 64) for x in dpregs_str]
dpregs = reg_info(dpregs_str, dpregs_expr)

# Quadword
qpregs_str = ['Q%d' % r for r in range(16)]
qpregs_expr = [ExprId(x, 128) for x in qpregs_str]
qpregs = reg_info(qpregs_str, qpregs_expr)

# psr
sr_flags = "cxsf"
cpsr_regs_str = []
Expand Down Expand Up @@ -2037,11 +2052,16 @@ 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]
# We should not use regs_expr direct
# subclass overwrite reg_info in some case
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 @@ -3336,9 +3356,72 @@ def encode(self):
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])
class armt_rn_deref_up(arm_arg):
parser = deref_reg_imm

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

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

class arm_nopc_deref(arm_deref_reg_imm):
reg_info = gpregs_nopc

class armt_pc_deref_up(armt_rn_deref_up):
parser = deref_pc

class armt_nopc_deref_up(armt_rn_deref_up):
pass

rn_nopc_noarg = bs(l=4, cls=(arm_gpreg_nopc_noarg,), fname="rn")
rn_nopc_deref = bs(l=4, cls=(arm_nopc_deref,), fname="rt")
rn_nopc_deref_up = bs(l=4, cls=(armt_nopc_deref_up,))
pc_deref_up = bs("1111", l=4, cls=(armt_pc_deref_up,))

armtop("ldr", [bs('11111000'), updown, bs('101'), pc_deref_up, rt, off12], [rt, pc_deref_up])
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])
Expand All @@ -3356,3 +3439,109 @@ def encode(self):
armtop("dsb", [bs('111100111011'), bs('1111'), bs('1000'), bs('1111'), bs('0100'), barrier_option])

armtop("adr", [bs('11110'), imm12_1, bs('100000'), bs('1111'), bs('0'), imm12_3, rd, imm12_8_t4], [rd, imm12_8_t4])

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_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)
round_zero = bs('1', l=1, fname="round_zero")
vunsigned = bs(l=1, fname="unsigned")

rt2_nopc = bs(l=4, cls=(arm_gpreg_nopc, arm_arg), fname="rt")
rn_sp_nowb = bs("1101", cls=(arm_gpreg,), fname='rnsp')

off8r2 = bs(l=8, cls=(arm_off7,), fname="off", order=-1)
off8_ = bs(l=8, cls=(arm_off,), fname="off", order=-1)

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("btransfersp", [bs('1110100010'), wback, bs_tbtransfer_name, rn_wb, pc_in, lr_in, bs('0'), trlist13pclr])
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("strb", [bs('111110000000'), rn_noarg, rt, bs('000000'), imm2_noarg, rm_deref_reg], [rt, rm_deref_reg])
armtop("strex", [bs('111010000100'), rn_deref, rt, rd, off8_], [rd, rt, rn_deref])
armtop("ldrex",[bs('111010000101'), rn_deref, rt, bs('1111'), off8_], [rt, rn_deref])

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

# DDI0406C.d, 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])

# DDI0406C.d, A8.8.310
armtop("vcvt", [bs('111011101'), sn_x_1, bs('111'), bs("101"), sn_4_1, bs('101'), bs('1'), round_zero, 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'), round_zero, 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'), round_zero, 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'), round_zero, bs('1'), sm_x_1, bs('0'), sm_4_1], [sn_4_1, sm_4_1])
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])
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])

# DDI0406C.d, A8.8.414
armtop("vstr", [bs('11101101'), updown, dn_1_x, bs('00'), rn_nopc_deref_up, dn_1_4, bs('1011'), off8r2], [dn_1_4, rn_nopc_deref_up])
armtop("vstr", [bs('11101101'), updown, sn_x_1, bs('00'), rn_nopc_deref_up, sn_4_1, bs('1010'), off8r2], [sn_4_1, rn_nopc_deref_up])
37 changes: 37 additions & 0 deletions miasm/arch/arm/sem.py
Original file line number Diff line number Diff line change
Expand Up @@ -971,6 +971,36 @@ 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 vstr(ir, instr, a, b):
e = []
return e, []

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

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


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

# todo:
def dmb(ir, instr, a):
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 @@ -1797,6 +1827,8 @@ def add_condition_expr(ir, instr, cond, instr_ir, extra_ir):
'pkhtb': pkhtb,
'pkhbt': pkhbt,

'ldrex': ldrex,
'strex': strex,
}

mnemo_condm1 = {'adds': add,
Expand Down Expand Up @@ -1826,6 +1858,10 @@ def add_condition_expr(ir, instr, cond, instr_ir, extra_ir):
'ldrb': ldrb,
'ldsb': ldrsb,
'strb': strb,

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

mnemo_condm2 = {'ldmia': ldmia,
Expand Down Expand Up @@ -1881,6 +1917,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

0 comments on commit 3a0d417

Please sign in to comment.