diff options
| -rw-r--r-- | miasm2/arch/arm/arch.py | 64 | ||||
| -rw-r--r-- | miasm2/arch/arm/sem.py | 13 | ||||
| -rw-r--r-- | miasm2/ir/translators/C.py | 3 | ||||
| -rw-r--r-- | miasm2/jitter/arch/JitCore_arm.c | 11 | ||||
| -rw-r--r-- | miasm2/jitter/arch/JitCore_arm.h | 2 | ||||
| -rw-r--r-- | test/arch/arm/arch.py | 6 |
6 files changed, 99 insertions, 0 deletions
diff --git a/miasm2/arch/arm/arch.py b/miasm2/arch/arm/arch.py index 7dc5d959..e14549ec 100644 --- a/miasm2/arch/arm/arch.py +++ b/miasm2/arch/arm/arch.py @@ -39,6 +39,9 @@ gpregs_sp = reg_info(regs_str[13:14], regs_expr[13:14]) gpregs_nosppc = reg_info(regs_str[:13] + [str(reg_dum), regs_str[14]], regs_expr[:13] + [reg_dum, regs_expr[14]]) +gpregs_nopc = reg_info(regs_str[:14], + regs_expr[:14]) + # psr sr_flags = "cxsf" @@ -106,9 +109,18 @@ def check_bounds(left_bound, right_bound, value): else: raise ValueError('shift operator immediate value out of bound') + +def check_values(values, value): + if value in values: + return ExprInt32(value) + else: + raise ValueError('shift operator immediate value out of bound') + int_1_31 = str_int.copy().setParseAction(lambda v: check_bounds(1, 31, v[0])) int_1_32 = str_int.copy().setParseAction(lambda v: check_bounds(1, 32, v[0])) +int_8_16_24 = str_int.copy().setParseAction(lambda v: check_values([8, 16, 24], v[0])) + def reglistparse(s, l, t): t = t[0] @@ -145,6 +157,9 @@ all_binaryop_1_32_shifts_t = literal_list( ['LSR', 'ASR']).setParseAction(op_shift2expr) all_unaryop_shifts_t = literal_list(['RRX']).setParseAction(op_shift2expr) +ror_shifts_t = literal_list(['ROR']).setParseAction(op_shift2expr) + + allshifts_t_armt = literal_list( ['LSL', 'LSR', 'ASR', 'ROR', 'RRX']).setParseAction(op_shift2expr) @@ -190,6 +205,12 @@ shift_off = (gpregs.parser + Optional( shift_off |= base_expr +rot2_expr = (gpregs.parser + Optional( + (ror_shifts_t + (int_8_16_24)) +)).setParseAction(shift2expr) + + + def deref2expr_nooff(s, l, t): t = t[0] # XXX default @@ -1595,12 +1616,54 @@ class arm_widthm1(arm_imm, m_arg): return True +class arm_rm_rot2(m_arg): + parser = rot2_expr + def decode(self, v): + expr = gpregs.expr[v] + shift_value = self.parent.rot2.value + if shift_value: + expr = ExprOp(allshifts[3], expr, ExprInt32(shift_value * 8)) + self.expr = expr + return True + def encode(self): + if self.expr in gpregs.expr: + self.value = gpregs.expr.index(self.expr) + self.parent.rot2.value = 0 + elif (isinstance(self.expr, ExprOp) and + self.expr.op == allshifts[3]): + reg, value = self.expr.args + if reg not in gpregs.expr: + return False + self.value = gpregs.expr.index(reg) + if not isinstance(value, ExprInt): + return False + value = int(value.arg) + if not value in [8, 16, 24]: + return False + self.parent.rot2.value = value / 8 + return True + +class arm_gpreg_nopc(arm_reg): + reg_info = gpregs_nopc + parser = reg_info.parser + + +rm_rot2 = bs(l=4, cls=(arm_rm_rot2,), fname="rm") +rot2 = bs(l=2, fname="rot2") + widthm1 = bs(l=5, cls=(arm_widthm1, m_arg)) lsb = bs(l=5, cls=(arm_imm, m_arg)) +rn_nopc = bs(l=4, cls=(arm_gpreg_nopc,), fname="rn") + armop("ubfx", [bs('0111111'), widthm1, rd, lsb, bs('101'), rn], [rd, rn, lsb, widthm1]) armop("bfc", [bs('0111110'), widthm1, rd, lsb, bs('001'), bs('1111')], [rd, lsb, widthm1]) + +armop("uxtab", [bs('01101110'), rn_nopc, rd, rot2, bs('000111'), rm_rot2], [rd, rn_nopc, rm_rot2]) + + + # # thumnb ####################### # @@ -2080,6 +2143,7 @@ class arm_gpreg_nosppc(arm_reg): reg_info = gpregs_nosppc + class armt_gpreg_rm_shift_off(arm_reg): parser = armt_gpreg_shift_off diff --git a/miasm2/arch/arm/sem.py b/miasm2/arch/arm/sem.py index 5bd4db24..be44061e 100644 --- a/miasm2/arch/arm/sem.py +++ b/miasm2/arch/arm/sem.py @@ -937,6 +937,17 @@ def pld(ir, instr, a): return [] +def clz(ir, instr, a, b): + e = [] + e.append(ExprAff(a, ExprOp('clz', b))) + return e + +def uxtab(ir, instr, a, b, c): + e = [] + e.append(ExprAff(a, b + (c & ExprInt32(0xff)))) + return e + + COND_EQ = 0 COND_NE = 1 @@ -1080,6 +1091,8 @@ mnemo_condm0 = {'add': add, 'ubfx': ubfx, 'bfc': bfc, 'rev': rev, + 'clz': clz, + 'uxtab': uxtab, } mnemo_condm1 = {'adds': add, diff --git a/miasm2/ir/translators/C.py b/miasm2/ir/translators/C.py index 2c44d9e1..340fbfec 100644 --- a/miasm2/ir/translators/C.py +++ b/miasm2/ir/translators/C.py @@ -50,6 +50,9 @@ class TranslatorC(Translator): return "x86_%s(%s, 0x%x)" % (expr.op, self.from_expr(expr.args[0]), expr.args[0].size) + elif expr.op in ['clz']: + return "%s(%s)" % (expr.op, + self.from_expr(expr.args[0])) elif expr.op == '!': return "(~ %s)&0x%x" % (self.from_expr(expr.args[0]), size2mask(expr.args[0].size)) diff --git a/miasm2/jitter/arch/JitCore_arm.c b/miasm2/jitter/arch/JitCore_arm.c index a7ed67d0..0d7caeec 100644 --- a/miasm2/jitter/arch/JitCore_arm.c +++ b/miasm2/jitter/arch/JitCore_arm.c @@ -201,6 +201,17 @@ void MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src) } +uint32_t clz(uint32_t arg) +{ + + int i; + + for (i=0; i<32; i++) { + if (arg & (1 << (31-i))) + break; + } + return i; +} diff --git a/miasm2/jitter/arch/JitCore_arm.h b/miasm2/jitter/arch/JitCore_arm.h index 9fde5e93..dda8a65d 100644 --- a/miasm2/jitter/arch/JitCore_arm.h +++ b/miasm2/jitter/arch/JitCore_arm.h @@ -32,3 +32,5 @@ typedef struct { void dump_gpregs(vm_cpu_t* vmcpu); #define RETURN_PC return BlockDst; + +uint32_t clz(uint32_t arg); diff --git a/test/arch/arm/arch.py b/test/arch/arm/arch.py index a00fe3d6..6b010d20 100644 --- a/test/arch/arm/arch.py +++ b/test/arch/arm/arch.py @@ -250,6 +250,12 @@ reg_tests_arm = [ ('XXXXXXXX PLD [R1, 0x1C]', '1CF0D1F5'), + ('XXXXXXXX UXTAB R5, R2, R8', + '7850e2e6'), + + ('XXXXXXXX UXTAB R5, R2, R8 ROR 0x8', + '7854e2e6'), + ] ts = time.time() |