diff options
Diffstat (limited to 'miasm/arch/arm/arch.py')
| -rw-r--r-- | miasm/arch/arm/arch.py | 93 |
1 files changed, 48 insertions, 45 deletions
diff --git a/miasm/arch/arm/arch.py b/miasm/arch/arm/arch.py index fc6a0527..2b4476f0 100644 --- a/miasm/arch/arm/arch.py +++ b/miasm/arch/arm/arch.py @@ -413,10 +413,10 @@ class instruction_arm(instruction): if isinstance(expr, ExprOp) and expr.op == 'postinc': o = '[%s]' % r - if s and not (isinstance(s, ExprInt) and s.arg == 0): + if s and not (isinstance(s, ExprInt) and int(s) == 0): o += ', %s' % s else: - if s and not (isinstance(s, ExprInt) and s.arg == 0): + if s and not (isinstance(s, ExprInt) and int(s) == 0): o = '[%s, %s]' % (r, s) else: o = '[%s]' % (r) @@ -437,9 +437,9 @@ class instruction_arm(instruction): if not isinstance(expr, ExprInt): return if self.name == 'BLX': - addr = expr.arg + self.offset + addr = (int(expr) + self.offset) & int(expr.mask) else: - addr = expr.arg + self.offset + addr = (int(expr) + self.offset) & int(expr.mask) loc_key = loc_db.get_or_create_offset_location(addr) self.args[0] = ExprLoc(loc_key, expr.size) @@ -481,7 +481,7 @@ class instruction_arm(instruction): if not isinstance(e, ExprInt): log.debug('dyn dst %r', e) return - off = e.arg - self.offset + off = (int(e) - self.offset) & int(e.mask) if int(off % 4): raise ValueError('strange offset! %r' % off) self.args[0] = ExprInt(off, 32) @@ -514,15 +514,15 @@ class instruction_armt(instruction_arm): if not isinstance(expr, ExprInt): return if self.name == 'BLX': - addr = expr.arg + (self.offset & 0xfffffffc) + addr = (int(expr) + (self.offset & 0xfffffffc)) & int(expr.mask) elif self.name == 'BL': - addr = expr.arg + self.offset + addr = (int(expr) + self.offset) & int(expr.mask) elif self.name.startswith('BP'): - addr = expr.arg + self.offset + addr = (int(expr) + self.offset) & int(expr.mask) elif self.name.startswith('CB'): - addr = expr.arg + self.offset + self.l + 2 + addr = (int(expr) + self.offset + self.l + 2) & int(expr.mask) else: - addr = expr.arg + self.offset + addr = (int(expr) + self.offset) & int(expr.mask) loc_key = loc_db.get_or_create_offset_location(addr) dst = ExprLoc(loc_key, expr.size) @@ -564,7 +564,7 @@ class instruction_armt(instruction_arm): # The first +2 is to compensate instruction len, but strangely, 32 bits # thumb2 instructions len is 2... For the second +2, didn't find it in # the doc. - off = e.arg - self.offset + off = (int(e) - self.offset) & int(e.mask) if int(off % 2): raise ValueError('strange offset! %r' % off) self.args[0] = ExprInt(off, 32) @@ -798,6 +798,9 @@ class arm_arg(m_arg): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args] if None in args: return None + if arg.op == "-": + assert len(args) == 2 + return args[0] - args[1] return ExprOp(arg.op, *args) if isinstance(arg, AstInt): return ExprInt(arg.value, 32) @@ -1345,7 +1348,7 @@ class arm_offs_blx(arm_imm): if not isinstance(self.expr, ExprInt): return False # Remove pipeline offset - v = int(self.expr.arg - 8) + v = (int(self.expr) - 8) & int(self.expr.mask) if v & 0x80000000: v &= (1 << 26) - 1 self.parent.lowb.value = (v >> 1) & 1 @@ -1657,6 +1660,33 @@ bs_mr_name = bs_name(l=1, name=mr_name) bs_addi = bs(l=1, fname="add_imm") bs_rw = bs_mod_name(l=1, fname='rw', mn_mod=['W', '']) +class armt_barrier_option(reg_noarg, arm_arg): + reg_info = barrier_info + parser = reg_info.parser + + def decode(self, v): + v = v & self.lmask + if v not in self.reg_info.dct_expr: + return False + self.expr = self.reg_info.dct_expr[v] + return True + + def encode(self): + if not self.expr in self.reg_info.dct_expr_inv: + log.debug("cannot encode reg %r", self.expr) + return False + self.value = self.reg_info.dct_expr_inv[self.expr] + if self.value > self.lmask: + log.debug("cannot encode field value %x %x", + self.value, self.lmask) + return False + return True + + def check_fbits(self, v): + return v & self.fmask == self.fbits + +barrier_option = bs(l=4, cls=(armt_barrier_option,)) + armop("mul", [bs('000000'), bs('0'), scc, rd, bs('0000'), rs, bs('1001'), rm], [rd, rm, rs]) armop("umull", [bs('000010'), bs('0'), scc, rd, rdl, rs, bs('1001'), rm], [rdl, rd, rm, rs]) armop("umlal", [bs('000010'), bs('1'), scc, rd, rdl, rs, bs('1001'), rm], [rdl, rd, rm, rs]) @@ -1706,7 +1736,8 @@ armop("rev16", [bs('01101011'), bs('1111'), rd, bs('1111'), bs('1011'), rm]) armop("pld", [bs8(0xF5), bs_addi, bs_rw, bs('01'), mem_rn_imm, bs('1111'), imm12_off]) -armop("isb", [bs8(0xF5), bs8(0x7F), bs8(0xF0), bs8(0x6F)]) +armop("dsb", [bs('111101010111'), bs('1111'), bs('1111'), bs('0000'), bs('0100'), barrier_option]) +armop("isb", [bs('111101010111'), bs('1111'), bs('1111'), bs('0000'), bs('0110'), barrier_option]) armop("nop", [bs8(0xE3), bs8(0x20), bs8(0xF0), bs8(0)]) class arm_widthm1(arm_imm, m_arg): @@ -2323,7 +2354,6 @@ class arm_sp(arm_reg): reg_info = gpregs_sp parser = reg_info.parser - off5 = bs(l=5, cls=(arm_imm,), fname="off") off3 = bs(l=3, cls=(arm_imm,), fname="off") off8 = bs(l=8, cls=(arm_imm,), fname="off") @@ -2738,7 +2768,7 @@ class armt2_imm10l(arm_imm): def encode(self): if not isinstance(self.expr, ExprInt): return False - v = self.expr.arg.arg + v = int(self.expr) s = 0 if v & 0x80000000: s = 1 @@ -2775,7 +2805,7 @@ class armt2_imm11l(arm_imm): def encode(self): if not isinstance(self.expr, ExprInt): return False - v = self.expr.arg.arg - 4 + v = (int(self.expr) - 4) & int(self.expr.mask) s = 0 if v & 0x80000000: s = 1 @@ -2813,7 +2843,7 @@ class armt2_imm6_11l(arm_imm): def encode(self): if not isinstance(self.expr, ExprInt): return False - v = self.expr.arg.arg - 4 + v = (int(self.expr) - 4) & int(self.expr.mask) s = 0 if v != sign_ext(v & ((1 << 22) - 1), 21, 32): return False @@ -2881,7 +2911,7 @@ class armt_imm5_1(arm_imm): def encode(self): if not isinstance(self.expr, ExprInt): return False - v = self.expr.arg.arg + v = int(self.expr) if v & 0x1: return False self.parent.imm1.value = (v >> 6) & 1 @@ -3227,33 +3257,6 @@ bs_deref_reg_reg = bs(l=4, cls=(armt_deref_reg_reg,)) bs_deref_reg_reg_lsl_1 = bs(l=4, cls=(armt_deref_reg_reg_lsl_1,)) -class armt_barrier_option(reg_noarg, arm_arg): - reg_info = barrier_info - parser = reg_info.parser - - def decode(self, v): - v = v & self.lmask - if v not in self.reg_info.dct_expr: - return False - self.expr = self.reg_info.dct_expr[v] - return True - - def encode(self): - if not self.expr in self.reg_info.dct_expr_inv: - log.debug("cannot encode reg %r", self.expr) - return False - self.value = self.reg_info.dct_expr_inv[self.expr] - if self.value > self.lmask: - log.debug("cannot encode field value %x %x", - self.value, self.lmask) - return False - return True - - def check_fbits(self, v): - return v & self.fmask == self.fbits - -barrier_option = bs(l=4, cls=(armt_barrier_option,)) - armtop("adc", [bs('11110'), imm12_1, bs('0'), bs('1010'), scc, rn_nosppc, bs('0'), imm12_3, rd_nosppc, imm12_8]) armtop("adc", [bs('11101'), bs('01'), bs('1010'), scc, rn_nosppc, bs('0'), imm5_3, rd_nosppc, imm5_2, imm_stype, rm_sh]) armtop("bl", [bs('11110'), tsign, timm10H, bs('11'), tj1, bs('1'), tj2, timm11L]) |