Skip to content

Commit

Permalink
Add arm instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
b14aa178 committed May 17, 2019
1 parent 142fb34 commit d17b762
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 0 deletions.
9 changes: 9 additions & 0 deletions miasm/arch/arm/arch.py
Original file line number Diff line number Diff line change
Expand Up @@ -1415,6 +1415,7 @@ def encode(self):

sbit = bs(l=1, fname="sbit")
rn_sp = bs("1101", cls=(arm_reg_wb,), fname='rnsp')
rn_sp_ = 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 @@ -2350,6 +2351,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 +2453,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 +3306,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_, bs('0'), imm12_3, rd, imm12_8], [rd, rn_sp_, imm12_8])
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,6 +3346,7 @@ 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])

Expand All @@ -3359,6 +3364,8 @@ def check_fbits(self, v):
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 +3374,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])
88 changes: 88 additions & 0 deletions miasm/arch/arm/sem.py
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,9 @@ 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)

def ldrex(ir, instr, a, b):
return st_ld_r(ir, instr, a, None, b, store=False)


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


def strex(ir, instr, a, b, c=None):
if c is None:
a2 = ir.arch.regs.all_regs_ids[ir.arch.regs.all_regs_ids.index(a) + 1]
else:
a2 = b
b = c

s_ext=False
z_ext=False
size = 64
store = True

e = []
wb = False
b = b.copy()
postinc = False
b = b.ptr
if isinstance(b, ExprOp):
if b.op == "wback":
wb = True
b = b.args[0]
if b.op == "postinc":
postinc = True
if isinstance(b, ExprOp) and b.op in ["postinc", 'preinc']:
# XXX TODO CHECK
base, off = b.args[0], b.args[1] # ExprInt(size/8, 32)
else:
base, off = b, ExprInt(0, 32)
if postinc:
ad = base
else:
ad = base + off

# PC base lookup uses PC 4 byte alignment
ad = ad.replace_expr({PC: PC & ExprInt(0xFFFFFFFC, 32)})

dmem = False
if size in [8, 16]:
if store:
a = a[:size]
m = ExprMem(ad, size=size)
elif s_ext:
m = ExprMem(ad, size=size).signExtend(a.size)
elif z_ext:
m = ExprMem(ad, size=size).zeroExtend(a.size)
else:
raise ValueError('unhandled case')
elif size == 32:
m = ExprMem(ad, size=size)
elif size == 64:
assert a2 is not None
m = ExprMem(ad, size=32)
dmem = True
size = 32
else:
raise ValueError('the size DOES matter')
dst = None

if store:
# always 0
e.append(ExprAssign(a, ExprInt(0, 32)))
if dmem:
e.append(ExprAssign(ExprMem(ad + ExprInt(4, 32), size=size), a2))
else:
if a == PC:
dst = PC
e.append(ExprAssign(ir.IRDst, m))
e.append(ExprAssign(a, m))
if dmem:
e.append(ExprAssign(a2, ExprMem(ad + ExprInt(4, 32), size=size)))

# XXX TODO check multiple write cause by wb
if wb or postinc:
e.append(ExprAssign(base, base + off))

return e, []


def l_strd(ir, instr, a, b, c=None):
if c is None:
a2 = ir.arch.regs.all_regs_ids[ir.arch.regs.all_regs_ids.index(a) + 1]
Expand Down Expand Up @@ -1314,6 +1395,10 @@ def nop(ir, instr):
e = []
return e, []

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

def dsb(ir, instr, a):
# XXX TODO
Expand Down Expand Up @@ -1526,8 +1611,10 @@ def add_condition_expr(ir, instr, cond, instr_ir, extra_ir):
'ldr': ldr,
'ldrd': ldrd,
'ldrsb': ldrsb,
'ldrex': ldrex, # XXX TODO: check
'str': l_str,
'strd': l_strd,
'strex': strex, # XXX TODO: check
'b': b,
'bl': bl,
'svc': svc,
Expand Down Expand Up @@ -1642,6 +1729,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
25 changes: 25 additions & 0 deletions test/arch/arm/arch.py
Original file line number Diff line number Diff line change
Expand Up @@ -703,7 +703,32 @@ def u16swap(i):
("xxxxxxxx CMP R5, R0 LSR 0x8",
"B5EB102F"),

("xxxxxxxx LDMIA R0, {R2, R3, R6, R7}",
"90E8CC00"),

("xxxxxxxx DMB SY",
"BFF35F8F"),

("xxxxxxxx STRB R3, [R4, R8]",
"04F80830"),

("xxxxxxxx STRB R2, [R3, R9]",
"03F80920"),

("xxxxxxxx LDREX R3, [R1]",
"51E8003F"),

("xxxxxxxx LDREX R2, [R12]",
"5CE8002F"),

("xxxxxxxx STREX LR, R1, [R3]",
"43E8001E"),

("xxxxxxxx STREX R0, LR, [R2]",
"42E800E0"),

("xxxxxxxx TEQ R0, R1",
"90EA010F"),
]
print("#" * 40, 'armthumb', '#' * 40)

Expand Down

0 comments on commit d17b762

Please sign in to comment.