diff options
Diffstat (limited to 'miasm/arch')
| -rw-r--r-- | miasm/arch/aarch64/arch.py | 28 | ||||
| -rw-r--r-- | miasm/arch/aarch64/sem.py | 12 | ||||
| -rw-r--r-- | miasm/arch/arm/arch.py | 93 | ||||
| -rw-r--r-- | miasm/arch/arm/regs.py | 65 | ||||
| -rw-r--r-- | miasm/arch/arm/sem.py | 243 | ||||
| -rw-r--r-- | miasm/arch/mep/arch.py | 40 | ||||
| -rw-r--r-- | miasm/arch/mep/sem.py | 8 | ||||
| -rw-r--r-- | miasm/arch/mips32/arch.py | 94 | ||||
| -rw-r--r-- | miasm/arch/mips32/regs.py | 28 | ||||
| -rw-r--r-- | miasm/arch/mips32/sem.py | 141 | ||||
| -rw-r--r-- | miasm/arch/msp430/arch.py | 2 | ||||
| -rw-r--r-- | miasm/arch/ppc/arch.py | 62 | ||||
| -rw-r--r-- | miasm/arch/ppc/regs.py | 12 | ||||
| -rw-r--r-- | miasm/arch/ppc/sem.py | 66 | ||||
| -rw-r--r-- | miasm/arch/x86/arch.py | 21 | ||||
| -rw-r--r-- | miasm/arch/x86/sem.py | 15 |
16 files changed, 773 insertions, 157 deletions
diff --git a/miasm/arch/aarch64/arch.py b/miasm/arch/aarch64/arch.py index 10e94517..768f1b03 100644 --- a/miasm/arch/aarch64/arch.py +++ b/miasm/arch/aarch64/arch.py @@ -330,19 +330,19 @@ class instruction_aarch64(instruction): op_str = expr.op return "%s %s %s" % (expr.args[0], op_str, expr.args[1]) elif isinstance(expr, m2_expr.ExprOp) and expr.op == "postinc": - if expr.args[1].arg != 0: + if int(expr.args[1]) != 0: return "[%s], %s" % (expr.args[0], expr.args[1]) else: return "[%s]" % (expr.args[0]) elif isinstance(expr, m2_expr.ExprOp) and expr.op == "preinc_wb": - if expr.args[1].arg != 0: + if int(expr.args[1]) != 0: return "[%s, %s]!" % (expr.args[0], expr.args[1]) else: return "[%s]" % (expr.args[0]) elif isinstance(expr, m2_expr.ExprOp) and expr.op == "preinc": if len(expr.args) == 1: return "[%s]" % (expr.args[0]) - elif not isinstance(expr.args[1], m2_expr.ExprInt) or expr.args[1].arg != 0: + elif not isinstance(expr.args[1], m2_expr.ExprInt) or int(expr.args[1]) != 0: return "[%s, %s]" % (expr.args[0], expr.args[1]) else: return "[%s]" % (expr.args[0]) @@ -350,7 +350,7 @@ class instruction_aarch64(instruction): arg = expr.args[1] if isinstance(arg, m2_expr.ExprId): arg = str(arg) - elif arg.op == 'LSL' and arg.args[1].arg == 0: + elif arg.op == 'LSL' and int(arg.args[1]) == 0: arg = str(arg.args[0]) else: arg = "%s %s %s" % (arg.args[0], arg.op, arg.args[1]) @@ -375,7 +375,7 @@ class instruction_aarch64(instruction): expr = self.args[index] if not expr.is_int(): return - 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[index] = m2_expr.ExprLoc(loc_key, expr.size) @@ -403,7 +403,7 @@ class instruction_aarch64(instruction): if not isinstance(e, m2_expr.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[index] = m2_expr.ExprInt(int(off), 64) @@ -643,7 +643,7 @@ class aarch64_gpreg0(bsi, aarch64_arg): def encode(self): if isinstance(self.expr, m2_expr.ExprInt): - if self.expr.arg == 0: + if int(self.expr) == 0: self.value = 0x1F return True return False @@ -793,7 +793,7 @@ def set_imm_to_size(size, expr): if size > expr.size: expr = m2_expr.ExprInt(int(expr), size) else: - if expr.arg > (1 << size) - 1: + if int(expr) > (1 << size) - 1: return None expr = m2_expr.ExprInt(int(expr), size) return expr @@ -954,11 +954,11 @@ class aarch64_gpreg_ext2(reg_noarg, aarch64_arg): if arg1.op not in EXT2_OP_INV: return False self.parent.option.value = EXT2_OP_INV[arg1.op] - if arg1.args[1].arg == 0: + if int(arg1.args[1]) == 0: self.parent.shift.value = 0 return True - if arg1.args[1].arg != self.get_size(): + if int(arg1.args[1]) != self.get_size(): return False self.parent.shift.value = 1 @@ -1273,7 +1273,7 @@ class aarch64_imm_nsr(aarch64_imm_sf, aarch64_arg): return False if not test_set_sf(self.parent, self.expr.size): return False - value = self.expr.arg + value = int(self.expr) if value == 0: return False @@ -1376,7 +1376,7 @@ class aarch64_imm_hw_sc(aarch64_arg): def encode(self): if isinstance(self.expr, m2_expr.ExprInt): - if self.expr.arg > 0xFFFF: + if int(self.expr) > 0xFFFF: return False self.value = int(self.expr) self.parent.hw.value = 0 @@ -1498,7 +1498,7 @@ class aarch64_deref(aarch64_arg): def decode(self, v): reg = gpregs64_info.expr[v] - off = self.parent.imm.expr.arg + off = int(self.parent.imm.expr) op = self.get_postpre(self.parent) off = self.decode_w_size(off) self.expr = m2_expr.ExprOp(op, reg, m2_expr.ExprInt(off, 64)) @@ -1568,7 +1568,7 @@ class aarch64_deref_nooff(aarch64_deref): reg, off = expr.args if not isinstance(off, m2_expr.ExprInt): return False - if off.arg != 0: + if int(off) != 0: return False else: return False diff --git a/miasm/arch/aarch64/sem.py b/miasm/arch/aarch64/sem.py index e9088bde..2761aed4 100644 --- a/miasm/arch/aarch64/sem.py +++ b/miasm/arch/aarch64/sem.py @@ -401,7 +401,7 @@ def movk(ir, instr, arg1, arg2): assert(arg2.op == 'slice_at' and isinstance(arg2.args[0], ExprInt) and isinstance(arg2.args[1], ExprInt)) - value, shift = int(arg2.args[0].arg), int(arg2.args[1]) + value, shift = int(arg2.args[0]), int(arg2.args[1]) e.append( ExprAssign(arg1[shift:shift + 16], ExprInt(value, 16))) else: @@ -434,7 +434,7 @@ def csel(arg1, arg2, arg3, arg4): def ccmp(ir, instr, arg1, arg2, arg3, arg4): e = [] if(arg2.is_int()): - arg2=ExprInt(arg2.arg.arg,arg1.size) + arg2=ExprInt(int(arg2),arg1.size) default_nf = arg3[0:1] default_zf = arg3[1:2] default_cf = arg3[2:3] @@ -697,7 +697,7 @@ def ldp(ir, instr, arg1, arg2, arg3): def sbfm(ir, instr, arg1, arg2, arg3, arg4): e = [] - rim, sim = int(arg3.arg), int(arg4) + 1 + rim, sim = int(arg3), int(arg4) + 1 if sim > rim: res = arg2[rim:sim].signExtend(arg1.size) else: @@ -709,7 +709,7 @@ def sbfm(ir, instr, arg1, arg2, arg3, arg4): def ubfm(ir, instr, arg1, arg2, arg3, arg4): e = [] - rim, sim = int(arg3.arg), int(arg4) + 1 + rim, sim = int(arg3), int(arg4) + 1 if sim != arg1.size - 1 and rim == sim: # Simple case: lsl value = int(rim) @@ -733,7 +733,7 @@ def ubfm(ir, instr, arg1, arg2, arg3, arg4): def bfm(ir, instr, arg1, arg2, arg3, arg4): e = [] - rim, sim = int(arg3.arg), int(arg4) + 1 + rim, sim = int(arg3), int(arg4) + 1 if sim > rim: res = arg2[rim:sim] e.append(ExprAssign(arg1[:sim-rim], res)) @@ -1038,7 +1038,7 @@ def rev16(ir, instr, arg1, arg2): @sbuild.parse def extr(arg1, arg2, arg3, arg4): compose = ExprCompose(arg2, arg3) - arg1 = compose[int(arg4.arg):int(arg4)+arg1.size] + arg1 = compose[int(arg4):int(arg4)+arg1.size] @sbuild.parse 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]) diff --git a/miasm/arch/arm/regs.py b/miasm/arch/arm/regs.py index 63caada3..2b24b0d5 100644 --- a/miasm/arch/arm/regs.py +++ b/miasm/arch/arm/regs.py @@ -2,7 +2,7 @@ from builtins import range from miasm.expression.expression import * - +from miasm.core.cpu import gen_reg, gen_regs # GP @@ -111,4 +111,67 @@ regs_init = {} for i, r in enumerate(all_regs_ids): regs_init[r] = all_regs_ids_init[i] +coproc_reg_str = [ + "MIDR", "CTR", "TCMTR", "TLBTR", "MIDR", "MPIDR", "REVIDR", + "ID_PFR0", "ID_PFR1", "ID_DFR0", "ID_AFR0", "ID_MMFR0", "ID_MMFR1", "ID_MMFR2", "ID_MMFR3", + "ID_ISAR0", "ID_ISAR1", "ID_ISAR2", "ID_ISAR3", "ID_ISAR4", "ID_ISAR5", + "CCSIDR", "CLIDR", "AIDR", + "CSSELR", + "VPIDR", "VMPIDR", + "SCTLR", "ACTLR", "CPACR", + "SCR", "SDER", "NSACR", + "HSCTLR", "HACTLR", + "HCR", "HDCR", "HCPTR", "HSTR", "HACR", + "TTBR0", "TTBR1", "TTBCR", + "HTCR", "VTCR", + "DACR", + "DFSR", "IFSR", + "ADFSR", "AIFSR", + "HADFSR", "HAIFSR", + "HSR", + "DFAR", "IFAR", + "HDFAR", "HIFAR", "HPFAR", + "ICIALLUIS", "BPIALLIS", + "PAR", + "ICIALLU", "ICIMVAU", "CP15ISB", "BPIALL", "BPIMVA", + "DCIMVAC", "DCISW", + "ATS1CPR", "ATS1CPW", "ATS1CUR", "ATS1CUW", "ATS12NSOPR", "ATS12NSOPW", "ATS12NSOUR", "ATS12NSOUW", + "DCCMVAC", "DCCSW", "CP15DSB", "CP15DMB", + "DCCMVAU", + "DCCIMVAC", "DCCISW", + "ATS1HR", "ATS1HW", + "TLBIALLIS", "TLBIMVAIS", "TLBIASIDIS", "TLBIMVAAIS", + "ITLBIALL", "ITLBIMVA", "ITLBIASID", + "DTLBIALL", "DTLBIMVA", "DTLBIASID", + "TLBIALL", "TLBIMVA", "TLBIASID", "TLBIMVAA", + "TLBIALLHIS", "TLBIMVAHIS", "TLBIALLNSNHIS", + "TLBIALLH", "TLBIMVAH", "TLBIALLNSNH", + "PMCR", "PMCNTENSET", "PMCNTENCLR", "PMOVSR", "PMSWINC", "PMSELR", "PMCEID0", "PMCEID1", + "PMCCNTR", "PMXEVTYPER", "PMXEVCNTR", + "PMUSERENR", "PMINTENSET", "PMINTENCLR", "PMOVSSET", + "PRRR", "NMRR", + "AMAIR0", "AMAIR1", + "HMAIR0", "HMAIR1", + "HAMAIR0", "HAMAIR1", + "VBAR", "MVBAR", + "ISR", + "HVBAR", + "FCSEIDR", "CONTEXTIDR", "TPIDRURW", "TPIDRURO", "TPIDRPRW", + "HTPIDR", + "CNTFRQ", + "CNTKCTL", + "CNTP_TVAL", "CNTP_CTL", + "CNTV_TVAL", "CNTV_CTL", + "CNTHCTL", + "CNTHP_TVAL", "CNTHP_CTL" + ] +coproc_reg_expr, coproc_reg_init, coproc_reg_info = gen_regs(coproc_reg_str, globals(), 32) + +all_regs_ids = all_regs_ids + coproc_reg_expr +all_regs_ids_byname.update(dict([(x.name, x) for x in coproc_reg_expr])) +all_regs_ids_init = all_regs_ids_init + coproc_reg_init + +for i, r in enumerate(coproc_reg_expr): + regs_init[r] = coproc_reg_init[i] + regs_flt_expr = [] diff --git a/miasm/arch/arm/sem.py b/miasm/arch/arm/sem.py index 981a5060..027c3a6a 100644 --- a/miasm/arch/arm/sem.py +++ b/miasm/arch/arm/sem.py @@ -8,6 +8,219 @@ from miasm.arch.arm.regs import * from miasm.jitter.csts import EXCEPT_DIV_BY_ZERO, EXCEPT_INT_XX +coproc_reg_dict = { + ("p15", "c0", 0, "c0", 0): MIDR, + ("p15", "c0", 0, "c0", 1): CTR, + ("p15", "c0", 0, "c0", 2): TCMTR, + ("p15", "c0", 0, "c0", 3): TLBTR, + ("p15", "c0", 0, "c0", 4): MIDR, + ("p15", "c0", 0, "c0", 5): MPIDR, + ("p15", "c0", 0, "c0", 6): REVIDR, + ("p15", "c0", 0, "c0", 7): MIDR, + + ("p15", "c0", 0, "c1", 0): ID_PFR0, + ("p15", "c0", 0, "c1", 1): ID_PFR1, + ("p15", "c0", 0, "c1", 2): ID_DFR0, + ("p15", "c0", 0, "c1", 3): ID_AFR0, + ("p15", "c0", 0, "c1", 4): ID_MMFR0, + ("p15", "c0", 0, "c1", 5): ID_MMFR1, + ("p15", "c0", 0, "c1", 6): ID_MMFR2, + ("p15", "c0", 0, "c1", 7): ID_MMFR3, + + ("p15", "c0", 0, "c2", 0): ID_ISAR0, + ("p15", "c0", 0, "c2", 1): ID_ISAR1, + ("p15", "c0", 0, "c2", 2): ID_ISAR2, + ("p15", "c0", 0, "c2", 3): ID_ISAR3, + ("p15", "c0", 0, "c2", 4): ID_ISAR4, + ("p15", "c0", 0, "c2", 5): ID_ISAR5, + + ("p15", "c0", 1, "c0", 0): CCSIDR, + ("p15", "c0", 1, "c0", 1): CLIDR, + ("p15", "c0", 1, "c0", 7): AIDR, + + ("p15", "c0", 2, "c0", 0): CSSELR, + + ("p15", "c0", 4, "c0", 0): VPIDR, + ("p15", "c0", 4, "c0", 5): VMPIDR, + + ("p15", "c1", 0, "c0", 0): SCTLR, + ("p15", "c1", 0, "c0", 1): ACTLR, + ("p15", "c1", 0, "c0", 2): CPACR, + + ("p15", "c1", 0, "c1", 0): SCR, + ("p15", "c1", 0, "c1", 1): SDER, + ("p15", "c1", 0, "c1", 2): NSACR, + + ("p15", "c1", 4, "c0", 0): HSCTLR, + ("p15", "c1", 4, "c0", 1): HACTLR, + + ("p15", "c1", 4, "c1", 0): HCR, + ("p15", "c1", 4, "c1", 1): HDCR, + ("p15", "c1", 4, "c1", 2): HCPTR, + ("p15", "c1", 4, "c1", 3): HSTR, + ("p15", "c1", 4, "c1", 7): HACR, + + # TODO: TTBRO/TTBR1 64-bit + ("p15", "c2", 0, "c0", 0): TTBR0, + ("p15", "c2", 0, "c0", 1): TTBR1, + ("p15", "c2", 0, "c0", 2): TTBCR, + + ("p15", "c2", 4, "c0", 2): HTCR, + + ("p15", "c2", 4, "c1", 2): VTCR, + + # TODO: HTTBR, VTTBR + + ("p15", "c3", 0, "c0", 0): DACR, + + ("p15", "c5", 0, "c0", 0): DFSR, + ("p15", "c5", 0, "c0", 1): IFSR, + + ("p15", "c5", 0, "c1", 0): ADFSR, + ("p15", "c5", 0, "c1", 1): AIFSR, + + ("p15", "c5", 4, "c1", 0): HADFSR, + ("p15", "c5", 4, "c1", 1): HAIFSR, + + ("p15", "c5", 4, "c2", 0): HSR, + + ("p15", "c6", 0, "c1", 0): DFAR, + ("p15", "c6", 0, "c1", 2): IFAR, + + ("p15", "c6", 4, "c0", 0): HDFAR, + ("p15", "c6", 4, "c0", 2): HIFAR, + ("p15", "c6", 4, "c0", 4): HPFAR, + + ("p15", "c7", 0, "c1", 0): ICIALLUIS, + ("p15", "c7", 0, "c1", 6): BPIALLIS, + + ("p15", "c7", 0, "c4", 0): PAR, + + # TODO: PAR 64-bit + + ("p15", "c7", 0, "c5", 0): ICIALLU, + ("p15", "c7", 0, "c5", 1): ICIMVAU, + ("p15", "c7", 0, "c5", 4): CP15ISB, + ("p15", "c7", 0, "c5", 6): BPIALL, + ("p15", "c7", 0, "c5", 7): BPIMVA, + + ("p15", "c7", 0, "c6", 1): DCIMVAC, + ("p15", "c7", 0, "c6", 2): DCISW, + + ("p15", "c7", 0, "c8", 0): ATS1CPR, + ("p15", "c7", 0, "c8", 1): ATS1CPW, + ("p15", "c7", 0, "c8", 2): ATS1CUR, + ("p15", "c7", 0, "c8", 3): ATS1CUW, + ("p15", "c7", 0, "c8", 4): ATS12NSOPR, + ("p15", "c7", 0, "c8", 5): ATS12NSOPW, + ("p15", "c7", 0, "c8", 6): ATS12NSOUR, + ("p15", "c7", 0, "c8", 7): ATS12NSOUW, + + ("p15", "c7", 0, "c10", 1): DCCMVAC, + ("p15", "c7", 0, "c10", 2): DCCSW, + ("p15", "c7", 0, "c10", 4): CP15DSB, + ("p15", "c7", 0, "c10", 5): CP15DMB, + + ("p15", "c7", 0, "c11", 1): DCCMVAU, + + ("p15", "c7", 0, "c14", 1): DCCIMVAC, + ("p15", "c7", 0, "c14", 2): DCCISW, + + ("p15", "c7", 4, "c8", 0): ATS1HR, + ("p15", "c7", 4, "c8", 1): ATS1HW, + + ("p15", "c8", 0, "c3", 0): TLBIALLIS, + ("p15", "c8", 0, "c3", 1): TLBIMVAIS, + ("p15", "c8", 0, "c3", 2): TLBIASIDIS, + ("p15", "c8", 0, "c3", 3): TLBIMVAAIS, + + ("p15", "c8", 0, "c5", 0): ITLBIALL, + ("p15", "c8", 0, "c5", 1): ITLBIMVA, + ("p15", "c8", 0, "c5", 2): ITLBIASID, + + ("p15", "c8", 0, "c6", 0): DTLBIALL, + ("p15", "c8", 0, "c6", 1): DTLBIMVA, + ("p15", "c8", 0, "c6", 2): DTLBIASID, + + ("p15", "c8", 0, "c7", 0): TLBIALL, + ("p15", "c8", 0, "c7", 1): TLBIMVA, + ("p15", "c8", 0, "c7", 2): TLBIASID, + ("p15", "c8", 0, "c7", 3): TLBIMVAA, + + ("p15", "c8", 4, "c3", 0): TLBIALLHIS, + ("p15", "c8", 4, "c3", 1): TLBIMVAHIS, + ("p15", "c8", 4, "c3", 4): TLBIALLNSNHIS, + + ("p15", "c8", 4, "c7", 0): TLBIALLH, + ("p15", "c8", 4, "c7", 1): TLBIMVAH, + ("p15", "c8", 4, "c7", 2): TLBIALLNSNH, + + ("p15", "c9", 0, "c12", 0): PMCR, + ("p15", "c9", 0, "c12", 1): PMCNTENSET, + ("p15", "c9", 0, "c12", 2): PMCNTENCLR, + ("p15", "c9", 0, "c12", 3): PMOVSR, + ("p15", "c9", 0, "c12", 4): PMSWINC, + ("p15", "c9", 0, "c12", 5): PMSELR, + ("p15", "c9", 0, "c12", 6): PMCEID0, + ("p15", "c9", 0, "c12", 7): PMCEID1, + + ("p15", "c9", 0, "c13", 0): PMCCNTR, + ("p15", "c9", 0, "c13", 1): PMXEVTYPER, + ("p15", "c9", 0, "c13", 2): PMXEVCNTR, + + ("p15", "c9", 0, "c14", 0): PMUSERENR, + ("p15", "c9", 0, "c14", 1): PMINTENSET, + ("p15", "c9", 0, "c14", 2): PMINTENCLR, + ("p15", "c9", 0, "c14", 3): PMOVSSET, + + ("p15", "c10", 0, "c2", 0): PRRR, # ALIAS MAIR0 + ("p15", "c10", 0, "c2", 1): NMRR, # ALIAS MAIR1 + + ("p15", "c10", 0, "c3", 0): AMAIR0, + ("p15", "c10", 0, "c3", 1): AMAIR1, + + ("p15", "c10", 4, "c2", 0): HMAIR0, + ("p15", "c10", 4, "c2", 1): HMAIR1, + + ("p15", "c10", 4, "c3", 0): HAMAIR0, + ("p15", "c10", 4, "c3", 1): HAMAIR1, + + ("p15", "c12", 0, "c0", 0): VBAR, + ("p15", "c12", 0, "c0", 1): MVBAR, + + ("p15", "c12", 0, "c1", 0): ISR, + + ("p15", "c12", 4, "c0", 0): HVBAR, + + ("p15", "c13", 0, "c0", 0): FCSEIDR, + ("p15", "c13", 0, "c0", 1): CONTEXTIDR, + ("p15", "c13", 0, "c0", 2): TPIDRURW, + ("p15", "c13", 0, "c0", 3): TPIDRURO, + ("p15", "c13", 0, "c0", 4): TPIDRPRW, + + ("p15", "c13", 4, "c0", 2): HTPIDR, + + ("p15", "c14", 0, "c0", 0): CNTFRQ, + # TODO: CNTPCT 64-bit + + ("p15", "c14", 0, "c1", 0): CNTKCTL, + + ("p15", "c14", 0, "c2", 0): CNTP_TVAL, + ("p15", "c14", 0, "c2", 1): CNTP_CTL, + + ("p15", "c14", 0, "c3", 0): CNTV_TVAL, + ("p15", "c14", 0, "c3", 1): CNTV_CTL, + + # TODO: CNTVCT, CNTP_CVAL, CNTV_CVAL, CNTVOFF 64-bit + + ("p15", "c14", 4, "c1", 0): CNTHCTL, + + ("p15", "c14", 4, "c2", 0): CNTHP_TVAL, + ("p15", "c14", 4, "c2", 0): CNTHP_CTL + + # TODO: CNTHP_CVAL 64-bit + } + # liris.cnrs.fr/~mmrissa/lib/exe/fetch.php?media=armv7-a-r-manual.pdf EXCEPT_SOFT_BP = (1 << 1) @@ -762,7 +975,6 @@ def blx(ir, instr, a): def st_ld_r(ir, instr, a, a2, b, store=False, size=32, s_ext=False, z_ext=False): e = [] wb = False - b = b.copy() postinc = False b = b.ptr if isinstance(b, ExprOp): @@ -1320,6 +1532,10 @@ def dsb(ir, instr, a): e = [] return e, [] +def isb(ir, instr, a): + # XXX TODO + e = [] + return e, [] def cpsie(ir, instr, a): # XXX TODO @@ -1377,6 +1593,25 @@ def pkhtb(ir, instr, arg1, arg2, arg3): ) return e, [] +def mrc(ir, insr, arg1, arg2, arg3, arg4, arg5, arg6): + e = [] + sreg = (str(arg1), str(arg4), int(arg2), str(arg5), int(arg6)) + if sreg in coproc_reg_dict: + e.append(ExprAssign(arg3, coproc_reg_dict[sreg])) + else: + raise NotImplementedError("Unknown coprocessor register: %s %s %d %s %d" % (str(arg1), str(arg4), int(arg2), str(arg5), int(arg6))) + + return e, [] + +def mcr(ir, insr, arg1, arg2, arg3, arg4, arg5, arg6): + e = [] + sreg = (str(arg1), str(arg4), int(arg2), str(arg5), int(arg6)) + if sreg in coproc_reg_dict: + e.append(ExprAssign(coproc_reg_dict[sreg], arg3)) + else: + raise NotImplementedError("Unknown coprocessor register: %s %s %d %s %d" % (str(arg1), str(arg4), int(arg2), str(arg5), int(arg6))) + + return e, [] COND_EQ = 0 COND_NE = 1 @@ -1517,6 +1752,9 @@ mnemo_condm0 = {'add': add, 'sdiv': sdiv, 'udiv': udiv, + 'mrc': mrc, + 'mcr': mcr, + 'mul': mul, 'umull': umull, 'umlal': umlal, @@ -1630,6 +1868,7 @@ mnemo_nocond = {'lsr': lsr, 'tbh': tbh, 'nop': nop, 'dsb': dsb, + 'isb': isb, 'cpsie': cpsie, 'cpsid': cpsid, 'wfe': wfe, @@ -1775,7 +2014,7 @@ class ir_arml(IntermediateRepresentation): index += 1 instr = block.lines[index] - # Add conditionnal jump to current irblock + # Add conditional jump to current irblock loc_do = self.loc_db.add_location() loc_next = self.get_next_loc_key(instr) diff --git a/miasm/arch/mep/arch.py b/miasm/arch/mep/arch.py index d06a93ca..073acc57 100644 --- a/miasm/arch/mep/arch.py +++ b/miasm/arch/mep/arch.py @@ -4,8 +4,8 @@ from builtins import range from miasm.core.cpu import * from miasm.core.utils import Disasm_Exception -from miasm.expression.expression import Expr, ExprId, ExprInt, ExprLoc, \ - ExprMem, ExprOp +from miasm.expression.expression import ExprId, ExprInt, ExprLoc, \ + ExprMem, ExprOp, is_expr from miasm.core.asm_ast import AstId, AstMem from miasm.arch.mep.regs import * @@ -35,7 +35,7 @@ def ExprInt2SignedString(expr, pos_fmt="%d", neg_fmt="%d", size=None, offset=0): else: mask_length = size mask = (1 << mask_length) - 1 - value = int(expr.arg) & mask + value = int(expr) & mask # Return a signed integer if necessary if (value >> mask_length - 1) == 1: @@ -90,7 +90,7 @@ class instruction_mep(instruction): return "(%s)" % expr.ptr elif isinstance(expr, ExprMem) and isinstance(expr.ptr, ExprOp): - return "0x%X(%s)" % (expr.ptr.args[1].arg, expr.ptr.args[0]) + return "0x%X(%s)" % (int(expr.ptr.args[1]), expr.ptr.args[0]) # Raise an exception if the expression type was not processed message = "instruction_mep.arg2str(): don't know what \ @@ -111,13 +111,13 @@ class instruction_mep(instruction): if self.name == "SSARB": # The first operand is displayed in decimal, not in hex - o += " %d" % self.args[0].arg + o += " %d" % int(self.args[0]) o += self.arg2str(self.args[1]) elif self.name in ["MOV", "ADD"] and isinstance(self.args[1], ExprInt): # The second operand is displayed in decimal, not in hex o += " " + self.arg2str(self.args[0]) - o += ", %s" % ExprInt2SignedString(self.args[1].arg) + o += ", %s" % ExprInt2SignedString(self.args[1]) elif "CPI" in self.name: # The second operand ends with the '+' sign @@ -131,7 +131,7 @@ class instruction_mep(instruction): deref_reg_str = self.arg2str(self.args[1]) o += ", %s+)" % deref_reg_str[:-1] # GV: looks ugly # The third operand is displayed in decimal, not in hex - o += ", %s" % ExprInt2SignedString(self.args[2].arg) + o += ", %s" % ExprInt2SignedString(self.args[2]) elif len(self.args) == 2 and self.name in ["SB", "SH", "LBU", "LB", "LH", "LW"] and \ isinstance(self.args[1], ExprMem) and isinstance(self.args[1].ptr, ExprOp): # Major Opcodes #12 @@ -150,13 +150,13 @@ class instruction_mep(instruction): elif self.name == "SLL" and isinstance(self.args[1], ExprInt): # Major Opcodes #6 # The second operand is displayed in hex, not in decimal o += " " + self.arg2str(self.args[0]) - o += ", 0x%X" % self.args[1].arg + o += ", 0x%X" % int(self.args[1]) elif self.name in ["ADD3", "SLT3"] and isinstance(self.args[2], ExprInt): o += " %s" % self.arg2str(self.args[0]) o += ", %s" % self.arg2str(self.args[1]) # The third operand is displayed in decimal, not in hex - o += ", %s" % ExprInt2SignedString(self.args[2].arg, pos_fmt="0x%X") + o += ", %s" % ExprInt2SignedString(self.args[2], pos_fmt="0x%X") elif self.name == "(RI)": return o @@ -166,7 +166,7 @@ class instruction_mep(instruction): if self.args: o += " " for i, arg in enumerate(self.args): - if not isinstance(arg, Expr): + if not is_expr(arg): raise ValueError('zarb arg type') x = self.arg2str(arg, pos=i) args.append(x) @@ -218,7 +218,7 @@ class instruction_mep(instruction): # Compute the correct address num = self.get_dst_num() - addr = self.args[num].arg + addr = int(self.args[num]) if not self.name == "JMP": addr += self.offset @@ -671,7 +671,7 @@ class mep_deref_reg_offset(mep_arg): return False # Get the integer and check the upper bound - v = int(self.expr.ptr.args[1].arg & 0xFFFF) + v = int(self.expr.ptr.args[1]) & 0xFFFF # Encode the values self.parent.reg04_deref.value = gpr_exprs.index(self.expr.ptr.args[0]) @@ -845,7 +845,7 @@ class mep_int32_noarg(int32_noarg): def encode(self): if not isinstance(self.expr, ExprInt): return False - v = int(self.expr.arg) + v = int(self.expr) # Note: the following lines were commented on purpose #if sign_ext(v & self.lmask, self.l, self.intsize) != v: # return False @@ -923,7 +923,7 @@ class mep_target24(mep_imm): return False # Get the integer and apply a mask - v = int(self.expr.arg) & 0x00FFFFFF + v = int(self.expr) & 0x00FFFFFF # Encode the value into two parts self.parent.imm7.value = (v & 0xFF) >> 1 @@ -940,7 +940,7 @@ class mep_target24_signed(mep_target24): """ mep_target24.decode(self, v) - v = int(self.expr.arg) + v = int(self.expr) self.expr = ExprInt(sign_ext(v, 24, 32), 32) return True @@ -1046,7 +1046,7 @@ class mep_imm7_align4(mep_imm): return False # Get the integer and check the upper bound - v = int(self.expr.arg) + v = int(self.expr) if v > 0x80: return False @@ -1129,7 +1129,7 @@ class mep_disp7_align2(mep_imm): return False # Get the integer - v = int(self.expr.arg) & self.upper_bound + v = int(self.expr) & self.upper_bound # Encode the value self.value = (v >> self.bits_shift) & self.upper_bound @@ -1161,7 +1161,7 @@ class mep_disp12_align2_signed(mep_disp12_align2): """Perform sign extension. """ mep_disp12_align2.decode(self, v) - v = int(self.expr.arg) + v = int(self.expr) self.expr = ExprInt(sign_ext(v, 12, 32), 32) return True @@ -1198,7 +1198,7 @@ class mep_imm24(mep_imm): return False # Get the integer and check the upper bound - v = int(self.expr.arg) + v = int(self.expr) if v > 0xFFFFFF: return False @@ -1236,7 +1236,7 @@ class mep_abs24(mep_imm): return False # Get the integer and check the upper bound - v = int(self.expr.ptr.arg) + v = int(self.expr.ptr) if v > 0xffffff: return False diff --git a/miasm/arch/mep/sem.py b/miasm/arch/mep/sem.py index 1736b139..df484ab5 100644 --- a/miasm/arch/mep/sem.py +++ b/miasm/arch/mep/sem.py @@ -239,7 +239,7 @@ def add3(ir, instr, reg_dst, reg_src, reg_or_imm): result = ExprOp("+", reg_src, reg_or_imm) else: # Rn <- Rm + SignExt(imm16) - value = int(reg_or_imm.arg) + value = int(reg_or_imm) result = ExprOp("+", reg_src, ExprInt(value, 32)) return [ExprAssign(reg_dst, result)], [] @@ -334,7 +334,7 @@ if False: def sltu3(r0, rn, rm_or_imm5): """SLTU3 - Set on less than (unsigned).""" - # if (Rn<Rm) R0<-1 else R0<-0 (Unigned) + # if (Rn<Rm) R0<-1 else R0<-0 (Unsigned) # if (Rn<ZeroExt(imm5)) R0<-1 else R0<-0(Unsigned) r0 = i32(1) if compute_u_inf(rn, rm_or_imm5) else i32(0) @@ -645,7 +645,7 @@ def repeat(rn, disp17): # RPB <- pc+4 // Repeat Begin RPB = PC + i32(4) # RPE <- pc+SignExt((disp17)16..1||0)) // Repeat End - RPE = PC + i32(disp17.arg & 0xFFFFFFFE) + RPE = PC + i32(int(disp17) & 0xFFFFFFFE) # RPC <- Rn RPC = rn in_erepeat = ExprInt(0, 32) @@ -660,7 +660,7 @@ def erepeat(disp17): # RPB <- pc+4 // Repeat Begin RPB = PC + i32(4) # RPE <- pc+SignExt((disp17)16..1||1)) (EREPEAT) - RPE = PC + i32(disp17.arg + 1) + RPE = PC + i32(int(disp17) + 1) # RPC <- undefined in_erepeat = ExprInt(1, 32) diff --git a/miasm/arch/mips32/arch.py b/miasm/arch/mips32/arch.py index 09ff0a24..0398be37 100644 --- a/miasm/arch/mips32/arch.py +++ b/miasm/arch/mips32/arch.py @@ -47,8 +47,8 @@ class additional_info(object): self.except_on_instr = False br_0 = ['B', 'J', 'JR', 'BAL', 'JAL', 'JALR'] -br_1 = ['BGEZ', 'BLTZ', 'BGTZ', 'BLEZ', 'BC1T', 'BC1F'] -br_2 = ['BEQ', 'BEQL', 'BNE'] +br_1 = ['BGEZ', 'BLTZ', 'BGTZ', 'BGTZL', 'BLEZ', 'BLEZL', 'BC1T', 'BC1TL', 'BC1F', 'BC1FL'] +br_2 = ['BEQ', 'BEQL', 'BNE', 'BNEL'] class instruction_mips32(cpu.instruction): @@ -95,8 +95,9 @@ class instruction_mips32(cpu.instruction): def dstflow2label(self, loc_db): if self.name in ["J", 'JAL']: - expr = self.args[0].arg - addr = (self.offset & (0xFFFFFFFF ^ ((1<< 28)-1))) + expr + expr = self.args[0] + offset = int(expr) + addr = ((self.offset & (0xFFFFFFFF ^ ((1<< 28)-1))) + offset) & int(expr.mask) loc_key = loc_db.get_or_create_offset_location(addr) self.args[0] = ExprLoc(loc_key, expr.size) return @@ -106,7 +107,7 @@ class instruction_mips32(cpu.instruction): if not isinstance(expr, ExprInt): return - 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[ndx] = ExprLoc(loc_key, expr.size) @@ -157,7 +158,7 @@ class instruction_mips32(cpu.instruction): raise ValueError('symbol not resolved %s' % self.l) if not isinstance(e, ExprInt): 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[ndx] = ExprInt(off, 32) @@ -312,7 +313,7 @@ class mips32_s16imm_noarg(mips32_imm): def encode(self): if not isinstance(self.expr, ExprInt): return False - v = self.expr.arg.arg + v = int(self.expr) if v & 0x80000000: nv = v & ((1 << 16) - 1) assert( v == cpu.sign_ext(nv, 16, 32)) @@ -320,6 +321,26 @@ class mips32_s16imm_noarg(mips32_imm): self.value = v return True + +class mips32_s09imm_noarg(mips32_imm): + def decode(self, v): + v = v & self.lmask + v = cpu.sign_ext(v, 9, 32) + self.expr = ExprInt(v, 32) + return True + + def encode(self): + if not isinstance(self.expr, ExprInt): + return False + v = int(self.expr) + if v & 0x80000000: + nv = v & ((1 << 9) - 1) + assert( v == cpu.sign_ext(nv, 9, 32)) + v = nv + self.value = v + return True + + class mips32_soff_noarg(mips32_imm): def decode(self, v): v = v & self.lmask @@ -333,7 +354,7 @@ class mips32_soff_noarg(mips32_imm): if not isinstance(self.expr, ExprInt): return False # Remove pipeline offset - v = int(self.expr.arg - 4) + v = (int(self.expr) - 4) & 0xFFFFFFFF if v & 0x80000000: nv = v & ((1 << 16+2) - 1) assert( v == cpu.sign_ext(nv, 16+2, 32)) @@ -345,6 +366,9 @@ class mips32_soff_noarg(mips32_imm): class mips32_s16imm(mips32_s16imm_noarg, mips32_arg): pass +class mips32_s09imm(mips32_s09imm_noarg, mips32_arg): + pass + class mips32_soff(mips32_soff_noarg, mips32_arg): pass @@ -358,7 +382,7 @@ class mips32_instr_index(mips32_imm, mips32_arg): def encode(self): if not isinstance(self.expr, ExprInt): return False - v = self.expr.arg.arg + v = int(self.expr) if v & 3: return False v>>=2 @@ -377,7 +401,7 @@ class mips32_u16imm(mips32_imm, mips32_arg): def encode(self): if not isinstance(self.expr, ExprInt): return False - v = self.expr.arg.arg + v = int(self.expr) assert(v < (1<<16)) self.value = v return True @@ -424,7 +448,7 @@ class mips32_esize(mips32_imm, mips32_arg): def encode(self): if not isinstance(self.expr, ExprInt): return False - v = self.expr.arg.arg -1 + v = int(self.expr) -1 assert(v < (1<<16)) self.value = v return True @@ -437,7 +461,7 @@ class mips32_eposh(mips32_imm, mips32_arg): def encode(self): if not isinstance(self.expr, ExprInt): return False - v = int(self.expr.arg) + int(self.parent.epos.expr) -1 + v = int(self.expr) + int(self.parent.epos.expr) -1 self.value = v return True @@ -470,16 +494,22 @@ fd = cpu.bs(l=5, cls=(mips32_fltpreg,)) s16imm = cpu.bs(l=16, cls=(mips32_s16imm,)) u16imm = cpu.bs(l=16, cls=(mips32_u16imm,)) +s09imm = cpu.bs(l=9, cls=(mips32_s09imm,)) sa = cpu.bs(l=5, cls=(mips32_u16imm,)) base = cpu.bs(l=5, cls=(mips32_dreg_imm,)) soff = cpu.bs(l=16, cls=(mips32_soff,)) +oper = cpu.bs(l=5, cls=(mips32_u16imm,)) cpr0 = cpu.bs(l=5, cls=(mips32_imm,), fname="cpr0") cpr = cpu.bs(l=3, cls=(mips32_cpr,)) +stype = cpu.bs(l=5, cls=(mips32_u16imm,)) +hint_pref = cpu.bs(l=5, cls=(mips32_u16imm,)) s16imm_noarg = cpu.bs(l=16, cls=(mips32_s16imm_noarg,), fname="imm", order=-1) +s09imm_noarg = cpu.bs(l=9, cls=(mips32_s09imm_noarg,), fname="imm", + order=-1) hint = cpu.bs(l=5, default_val="00000") fcc = cpu.bs(l=3, cls=(mips32_fccreg,)) @@ -668,13 +698,18 @@ mips32op("mfhi", [cpu.bs('000000'), cpu.bs('0000000000'), rd, mips32op("b", [cpu.bs('000100'), cpu.bs('00000'), cpu.bs('00000'), soff], alias = True) mips32op("bne", [cpu.bs('000101'), rs, rt, soff]) +mips32op("bnel", [cpu.bs('010101'), rs, rt, soff]) + mips32op("beq", [cpu.bs('000100'), rs, rt, soff]) +mips32op("beql", [cpu.bs('010100'), rs, rt, soff]) mips32op("blez", [cpu.bs('000110'), rs, cpu.bs('00000'), soff]) +mips32op("blezl", [cpu.bs('010110'), rs, cpu.bs('00000'), soff]) mips32op("bcc", [cpu.bs('000001'), rs, bs_bcc, soff]) mips32op("bgtz", [cpu.bs('000111'), rs, cpu.bs('00000'), soff]) +mips32op("bgtzl", [cpu.bs('010111'), rs, cpu.bs('00000'), soff]) mips32op("bal", [cpu.bs('000001'), cpu.bs('00000'), cpu.bs('10001'), soff], alias = True) @@ -697,7 +732,6 @@ mips32op("mtc0", [cpu.bs('010000'), cpu.bs('00100'), rt, cpr0, cpu.bs('00000000'), cpr]) mips32op("mtc1", [cpu.bs('010001'), cpu.bs('00100'), rt, fs, cpu.bs('00000000000')]) - # XXXX TODO CFC1 mips32op("cfc1", [cpu.bs('010001'), cpu.bs('00010'), rt, fs, cpu.bs('00000000000')]) @@ -715,8 +749,12 @@ mips32op("c", [cpu.bs('010001'), bs_fmt, ft, fs, fcc, cpu.bs('0'), mips32op("bc1t", [cpu.bs('010001'), cpu.bs('01000'), fcc, cpu.bs('0'), cpu.bs('1'), soff]) +mips32op("bc1tl", [cpu.bs('010001'), cpu.bs('01000'), fcc, cpu.bs('1'), + cpu.bs('1'), soff]) mips32op("bc1f", [cpu.bs('010001'), cpu.bs('01000'), fcc, cpu.bs('0'), cpu.bs('0'), soff]) +mips32op("bc1fl", [cpu.bs('010001'), cpu.bs('01000'), fcc, cpu.bs('1'), + cpu.bs('0'), soff]) mips32op("swc1", [cpu.bs('111001'), base, ft, s16imm_noarg], [ft, base]) @@ -753,3 +791,33 @@ mips32op("tlbwi", [cpu.bs('010000'), cpu.bs('1'), cpu.bs('0'*19), mips32op("teq", [cpu.bs('000000'), rs, rt, bs_code, cpu.bs('110100')], [rs, rt]) +mips32op("tne", [cpu.bs('000000'), rs, rt, bs_code, cpu.bs('110110')], + [rs, rt]) + +mips32op("clz", [cpu.bs('011100'), rs, rt, rd, cpu.bs('00000'), cpu.bs('100000')], + [rd, rs]) +mips32op("clz", [cpu.bs('000000'), rs, cpu.bs('00000'), rd, cpu.bs('00001010000')], + [rd, rs]) + +mips32op("ll", [cpu.bs('110000'), base, rt, s16imm_noarg], [rt, base]) +mips32op("ll", [cpu.bs('011111'), base, rt, s09imm_noarg, cpu.bs('0110110')], [rt, base]) + +mips32op("sc", [cpu.bs('111000'), base, rt, s16imm_noarg], [rt, base]) +mips32op("sc", [cpu.bs('011111'), base, rt, s09imm_noarg, cpu.bs('0'), cpu.bs('100110')], [rt, base]) + +mips32op("sync", [cpu.bs('000000000000000000000'), stype, cpu.bs('001111')], [stype]) + +mips32op("pref", [cpu.bs('110011'), base, hint_pref, s16imm_noarg], [hint_pref, base]) +mips32op("pref", [cpu.bs('011111'), base, hint_pref, s09imm_noarg, cpu.bs('0110101')], [hint_pref, base]) + +mips32op("tlbwr", [cpu.bs('01000010000000000000000000000110')], []) +mips32op("tlbr", [cpu.bs('01000010000000000000000000000001')], []) + +mips32op("cache", [cpu.bs('101111'), base, oper, s16imm_noarg], [oper, base]) +mips32op("cache", [cpu.bs('011111'), base, oper, s09imm_noarg, cpu.bs('0100101')], [oper, base]) + +mips32op("eret", [cpu.bs('01000010000000000000000000011000')], []) + +mips32op("mtlo", [cpu.bs('000000'), rs, cpu.bs('000000000000000'), cpu.bs('010011')], [rs]) +mips32op("mthi", [cpu.bs('000000'), rs, cpu.bs('000000000000000'), cpu.bs('010001')], [rs]) + diff --git a/miasm/arch/mips32/regs.py b/miasm/arch/mips32/regs.py index 1513e989..967b7458 100644 --- a/miasm/arch/mips32/regs.py +++ b/miasm/arch/mips32/regs.py @@ -40,15 +40,43 @@ R_HI_init = ExprId('R_HI_init', 32) cpr0_str = ["CPR0_%d"%x for x in range(0x100)] cpr0_str[0] = "INDEX" +cpr0_str[8] = "RANDOM" cpr0_str[16] = "ENTRYLO0" cpr0_str[24] = "ENTRYLO1" +cpr0_str[32] = "CONTEXT" +cpr0_str[33] = "CONTEXTCONFIG" cpr0_str[40] = "PAGEMASK" +cpr0_str[41] = "PAGEGRAIN" +cpr0_str[42] = "SEGCTL0" +cpr0_str[43] = "SEGCTL1" +cpr0_str[44] = "SEGCTL2" +cpr0_str[45] = "PWBASE" +cpr0_str[46] = "PWFIELD" +cpr0_str[47] = "PWSIZE" +cpr0_str[48] = "WIRED" +cpr0_str[54] = "PWCTL" +cpr0_str[64] = "BADVADDR" +cpr0_str[65] = "BADINSTR" +cpr0_str[66] = "BADINSTRP" cpr0_str[72] = "COUNT" cpr0_str[80] = "ENTRYHI" cpr0_str[104] = "CAUSE" cpr0_str[112] = "EPC" +cpr0_str[120] = "PRID" +cpr0_str[121] = "EBASE" cpr0_str[128] = "CONFIG" +cpr0_str[129] = "CONFIG1" +cpr0_str[130] = "CONFIG2" +cpr0_str[131] = "CONFIG3" +cpr0_str[132] = "CONFIG4" +cpr0_str[133] = "CONFIG5" cpr0_str[152] = "WATCHHI" +cpr0_str[250] = "KSCRATCH" +cpr0_str[251] = "KSCRATCH1" +cpr0_str[252] = "KSCRATCH2" +cpr0_str[253] = "KSCRATCH3" +cpr0_str[254] = "KSCRATCH4" +cpr0_str[255] = "KSCRATCH5" regs_cpr0_expr, regs_cpr0_init, regs_cpr0_info = gen_regs(cpr0_str, globals()) diff --git a/miasm/arch/mips32/sem.py b/miasm/arch/mips32/sem.py index 5fc491a7..23684a8d 100644 --- a/miasm/arch/mips32/sem.py +++ b/miasm/arch/mips32/sem.py @@ -67,6 +67,12 @@ def lbu(arg1, arg2): arg1 = mem8[arg2.ptr].zeroExtend(32) @sbuild.parse +def lh(arg1, arg2): + """A word is loaded into a register @arg1 from the + specified address @arg2.""" + arg1 = mem16[arg2.ptr].signExtend(32) + +@sbuild.parse def lhu(arg1, arg2): """A word is loaded (unsigned extended) into a register @arg1 from the specified address @arg2.""" @@ -78,6 +84,11 @@ def lb(arg1, arg2): arg1 = mem8[arg2.ptr].signExtend(32) @sbuild.parse +def ll(arg1, arg2): + "To load a word from memory for an atomic read-modify-write" + arg1 = arg2 + +@sbuild.parse def beq(arg1, arg2, arg3): "Branches on @arg3 if the quantities of two registers @arg1, @arg2 are eq" dst = arg3 if ExprOp(m2_expr.TOK_EQUAL, arg1, arg2) else ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) @@ -85,6 +96,13 @@ def beq(arg1, arg2, arg3): ir.IRDst = dst @sbuild.parse +def beql(arg1, arg2, arg3): + "Branches on @arg3 if the quantities of two registers @arg1, @arg2 are eq" + dst = arg3 if ExprOp(m2_expr.TOK_EQUAL, arg1, arg2) else ExprLoc(ir.get_next_delay_loc_key(instr), ir.IRDst.size) + PC = dst + ir.IRDst = dst + +@sbuild.parse def bgez(arg1, arg2): """Branches on @arg2 if the quantities of register @arg1 is greater than or equal to zero""" @@ -93,6 +111,14 @@ def bgez(arg1, arg2): ir.IRDst = dst @sbuild.parse +def bgezl(arg1, arg2): + """Branches on @arg2 if the quantities of register @arg1 is greater than or + equal to zero""" + dst = ExprLoc(ir.get_next_delay_loc_key(instr), ir.IRDst.size) if ExprOp(m2_expr.TOK_INF_SIGNED, arg1, ExprInt(0, arg1.size)) else arg2 + PC = dst + ir.IRDst = dst + +@sbuild.parse def bne(arg1, arg2, arg3): """Branches on @arg3 if the quantities of two registers @arg1, @arg2 are NOT equal""" @@ -101,6 +127,14 @@ def bne(arg1, arg2, arg3): ir.IRDst = dst @sbuild.parse +def bnel(arg1, arg2, arg3): + """Branches on @arg3 if the quantities of two registers @arg1, @arg2 are NOT + equal""" + dst = ExprLoc(ir.get_next_delay_loc_key(instr), ir.IRDst.size) if ExprOp(m2_expr.TOK_EQUAL, arg1, arg2) else arg3 + PC = dst + ir.IRDst = dst + +@sbuild.parse def lui(arg1, arg2): """The immediate value @arg2 is shifted left 16 bits and stored in the register @arg1. The lower 16 bits are zeroes.""" @@ -111,6 +145,14 @@ def nop(): """Do nothing""" @sbuild.parse +def sync(arg1): + """Synchronize Shared Memory""" + +@sbuild.parse +def pref(arg1, arg2): + """To move data between memory and cache""" + +@sbuild.parse def j(arg1): """Jump to an address @arg1""" PC = arg1 @@ -248,6 +290,13 @@ def bltz(arg1, arg2): ir.IRDst = dst_o @sbuild.parse +def bltzl(arg1, arg2): + """Branches on @arg2 if the register @arg1 is less than zero""" + dst_o = arg2 if ExprOp(m2_expr.TOK_INF_SIGNED, arg1, ExprInt(0, arg1.size)) else ExprLoc(ir.get_next_delay_loc_key(instr), ir.IRDst.size) + PC = dst_o + ir.IRDst = dst_o + +@sbuild.parse def blez(arg1, arg2): """Branches on @arg2 if the register @arg1 is less than or equal to zero""" cond = ExprOp(m2_expr.TOK_INF_EQUAL_SIGNED, arg1, ExprInt(0, arg1.size)) @@ -256,6 +305,14 @@ def blez(arg1, arg2): ir.IRDst = dst_o @sbuild.parse +def blezl(arg1, arg2): + """Branches on @arg2 if the register @arg1 is less than or equal to zero""" + cond = ExprOp(m2_expr.TOK_INF_EQUAL_SIGNED, arg1, ExprInt(0, arg1.size)) + dst_o = arg2 if cond else ExprLoc(ir.get_next_delay_loc_key(instr), ir.IRDst.size) + PC = dst_o + ir.IRDst = dst_o + +@sbuild.parse def bgtz(arg1, arg2): """Branches on @arg2 if the register @arg1 is greater than zero""" cond = ExprOp(m2_expr.TOK_INF_EQUAL_SIGNED, arg1, ExprInt(0, arg1.size)) @@ -264,6 +321,14 @@ def bgtz(arg1, arg2): ir.IRDst = dst_o @sbuild.parse +def bgtzl(arg1, arg2): + """Branches on @arg2 if the register @arg1 is greater than zero""" + cond = ExprOp(m2_expr.TOK_INF_EQUAL_SIGNED, arg1, ExprInt(0, arg1.size)) + dst_o = ExprLoc(ir.get_next_delay_loc_key(instr), ir.IRDst.size) if cond else arg2 + PC = dst_o + ir.IRDst = dst_o + +@sbuild.parse def wsbh(arg1, arg2): arg1 = ExprCompose(arg2[8:16], arg2[0:8], arg2[24:32], arg2[16:24]) @@ -320,6 +385,14 @@ def tlbwi(): def tlbp(): "TODO XXX" +@sbuild.parse +def tlbwr(): + "TODO XXX" + +@sbuild.parse +def tlbr(): + "TODO XXX" + def ins(ir, instr, a, b, c, d): e = [] pos = int(c) @@ -327,12 +400,12 @@ def ins(ir, instr, a, b, c, d): my_slices = [] if pos != 0: - my_slices.append((a[:pos], 0, pos)) + my_slices.append(a[:pos]) if l != 0: - my_slices.append((b[:l], pos, pos+l)) + my_slices.append(b[:l]) if pos + l != 32: - my_slices.append((a[pos+l:], pos+l, 32)) - r = m2_expr.ExprCompose(my_slices) + my_slices.append(a[pos+l:]) + r = m2_expr.ExprCompose(*my_slices) e.append(m2_expr.ExprAssign(a, r)) return e, [] @@ -364,12 +437,24 @@ def bc1t(arg1, arg2): ir.IRDst = dst_o @sbuild.parse +def bc1tl(arg1, arg2): + dst_o = arg2 if arg1 else ExprLoc(ir.get_next_delay_loc_key(instr), ir.IRDst.size) + PC = dst_o + ir.IRDst = dst_o + +@sbuild.parse def bc1f(arg1, arg2): dst_o = ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) if arg1 else arg2 PC = dst_o ir.IRDst = dst_o @sbuild.parse +def bc1fl(arg1, arg2): + dst_o = ExprLoc(ir.get_next_delay_loc_key(instr), ir.IRDst.size) if arg1 else arg2 + PC = dst_o + ir.IRDst = dst_o + +@sbuild.parse def cvt_d_w(arg1, arg2): # TODO XXX arg1 = 'flt_d_w'(arg2) @@ -424,6 +509,23 @@ def ei(arg1): def ehb(arg1): "NOP" +@sbuild.parse +def sc(arg1, arg2): + arg2 = arg1; + arg1 = ExprInt(0x1, 32) + +@sbuild.parse +def mthi(arg1): + R_HI = arg1 + +@sbuild.parse +def mtlo(arg1): + R_LOW = arg1 + +def clz(ir, instr, rs, rd): + e = [] + e.append(ExprAssign(rd, ExprOp('cntleadzeros', rs))) + return e, [] def teq(ir, instr, arg1, arg2): e = [] @@ -436,7 +538,7 @@ def teq(ir, instr, arg1, arg2): do_except.append(m2_expr.ExprAssign(exception_flags, m2_expr.ExprInt( EXCEPT_DIV_BY_ZERO, exception_flags.size))) do_except.append(m2_expr.ExprAssign(ir.IRDst, loc_next_expr)) - blk_except = IRBlock(loc_except.index, [AssignBlock(do_except, instr)]) + blk_except = IRBlock(loc_except, [AssignBlock(do_except, instr)]) cond = arg1 - arg2 @@ -447,6 +549,28 @@ def teq(ir, instr, arg1, arg2): return e, [blk_except] +def tne(ir, instr, arg1, arg2): + e = [] + + loc_except, loc_except_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) + loc_next = ir.get_next_loc_key(instr) + loc_next_expr = m2_expr.ExprLoc(loc_next, ir.IRDst.size) + + do_except = [] + do_except.append(m2_expr.ExprAssign(exception_flags, m2_expr.ExprInt( + EXCEPT_DIV_BY_ZERO, exception_flags.size))) + do_except.append(m2_expr.ExprAssign(ir.IRDst, loc_next_expr)) + blk_except = IRBlock(loc_except, [AssignBlock(do_except, instr)]) + + cond = arg1 ^ arg2 + + + e = [] + e.append(m2_expr.ExprAssign(ir.IRDst, + m2_expr.ExprCond(cond, loc_next_expr, loc_except_expr))) + + return e, [blk_except] + mnemo_func = sbuild.functions mnemo_func.update({ @@ -473,8 +597,10 @@ mnemo_func.update({ 'subu': l_sub, 'xor': l_xor, 'xori': l_xor, + 'clz': clz, 'teq': teq, -}) + 'tne': tne + }) def get_mnemo_expr(ir, instr, *args): instr, extra_ir = mnemo_func[instr.name.lower()](ir, instr, *args) @@ -511,6 +637,9 @@ class ir_mips32l(IntermediateRepresentation): def get_next_break_loc_key(self, instr): return self.loc_db.get_or_create_offset_location(instr.offset + 8) + def get_next_delay_loc_key(self, instr): + return self.loc_db.get_or_create_offset_location(instr.offset + 16) + class ir_mips32b(ir_mips32l): def __init__(self, loc_db=None): self.addrsize = 32 diff --git a/miasm/arch/msp430/arch.py b/miasm/arch/msp430/arch.py index a700b04a..93854153 100644 --- a/miasm/arch/msp430/arch.py +++ b/miasm/arch/msp430/arch.py @@ -64,7 +64,7 @@ class msp430_arg(m_arg): def asm_ast_to_expr(self, value, loc_db): if isinstance(value, AstId): name = value.name - if isinstance(name, Expr): + if is_expr(name): return name assert isinstance(name, str) if name in gpregs.str: diff --git a/miasm/arch/ppc/arch.py b/miasm/arch/ppc/arch.py index 29550931..2b951027 100644 --- a/miasm/arch/ppc/arch.py +++ b/miasm/arch/ppc/arch.py @@ -129,9 +129,9 @@ class instruction_ppc(instruction): if not isinstance(e, ExprInt): return if name[-1] != 'A': - ad = e.arg + self.offset + ad = (int(e) + self.offset) & 0xFFFFFFFF else: - ad = e.arg + ad = int(e) loc_key = loc_db.get_or_create_offset_location(ad) s = ExprLoc(loc_key, e.size) self.args[address_index] = s @@ -175,11 +175,11 @@ class instruction_ppc(instruction): if self.name[-1] != 'A': if self.offset is None: raise ValueError('symbol not resolved %s' % self.l) - off = e.arg - (self.offset + self.l) + off = (int(e) + 0x100000000 - (self.offset + self.l)) & 0xFFFFFFFF if int(off % 4): raise ValueError('Offset %r must be a multiple of four' % off) else: - off = e.arg + off = int(e) self.args[0] = ExprInt(off, 32) def get_args_expr(self): @@ -343,7 +343,7 @@ class ppc_s14imm_branch(ppc_imm): def encode(self): if not isinstance(self.expr, ExprInt): return False - v = self.expr.arg.arg + v = int(self.expr) if v & 0x3: return False v = v >> 2 @@ -362,7 +362,7 @@ class ppc_s24imm_branch(ppc_imm): def encode(self): if not isinstance(self.expr, ExprInt): return False - v = self.expr.arg.arg + v = int(self.expr) if v & 0x3: return False v = v >> 2 @@ -381,7 +381,7 @@ class ppc_s16imm(ppc_imm): def encode(self): if not isinstance(self.expr, ExprInt): return False - v = self.expr.arg.arg + v = int(self.expr) if sign_ext(v & self.lmask, 16, 32) != v: return False self.value = v & self.lmask @@ -398,7 +398,7 @@ class ppc_u16imm(ppc_imm): def encode(self): if not isinstance(self.expr, ExprInt): return False - v = self.expr.arg.arg + v = int(self.expr) if v & self.lmask != v: return False self.value = v & self.lmask @@ -416,7 +416,7 @@ class ppc_spr(ppc_imm): def encode(self, e): if not isinstance(e, ExprInt): return False - self.value = ppc_swap_10(e.arg) + self.value = ppc_swap_10(int(e)) return True class ppc_tbr(ppc_imm): @@ -428,7 +428,7 @@ class ppc_tbr(ppc_imm): def encode(self, e): if not isinstance(e, ExprInt): return False - self.value = ppc_swap_10(e.arg) + self.value = ppc_swap_10(int(e)) return True class ppc_u08imm(ppc_u16imm): @@ -443,6 +443,13 @@ class ppc_u04imm(ppc_u16imm): class ppc_u02imm_noarg(imm_noarg): pass +class ppc_float(ppc_reg): + reg_info = floatregs + parser = reg_info.parser + +class ppc_vex(ppc_reg): + reg_info = vexregs + parser = reg_info.parser def ppc_bo_bi_to_mnemo(bo, bi, prefer_taken=True, default_taken=True): bo2mnemo = { 0: 'DNZF', 2: 'DZF', 4: 'F', 8: 'DNZT', @@ -520,7 +527,7 @@ class ppc_deref32(ppc_arg): if len(addr.args) != 2: return False reg, disp = addr.args[0], addr.args[1] - v = int(disp.arg) + v = int(disp) if sign_ext(v & 0xFFFF, 16, 32) != v: return False v &= 0xFFFF @@ -566,6 +573,16 @@ dregimm = bs(l=16, cls=(ppc_deref32,)) rc_mod = bs_mod_name(l=1, mn_mod=['', '.'], fname='rc') +frd = bs(l=5, cls=(ppc_float,)) +frb = bs(l=5, cls=(ppc_float,)) +frs = bs(l=5, cls=(ppc_float,)) +fm = bs(l=8, cls=(ppc_u08imm,)) + +va = bs(l=5, cls=(ppc_vex,)) +vb = bs(l=5, cls=(ppc_vex,)) +vd = bs(l=5, cls=(ppc_vex,)) +rb_noarg = bs(l=5, cls=(ppc_gpreg_noarg,), fname="rb") + arith1_name = {"MULLI": 0b000111, "SUBFIC": 0b001000, "ADDIC": 0b001100, "ADDIC.": 0b001101 } @@ -636,6 +653,17 @@ dcb_name = {"DCBST": 0b00001, "DCBF": 0b00010, "DCBI": 0b01110, "DCBA": 0b10111, "ICBI": 0b11110, "DCBZ": 0b11111 } + +load1_name_float = {"LFS": 0b110000, "LFD": 0b110010 } +load1_name_float_u = {"LFSU": 0b110001, "LFDU": 0b110011 } +store1_name_float = {"STFS": 0b110100, "STFD": 0b110110 } +store1_name_float_u = {"STFSU": 0b110101, "STFDU": 0b110111 } + +load1_name_vex = {"LVEBX": 0b0000000111, "LVEHX": 0b0000100111, + "LVEWX": 0b0001000111, "LVSL": 0b0000000110, + "LVSR": 0b0000100110, "LVX": 0b0001100111, + "LVXL": 0b0101100111 } + class bs_mod_name_prio4(bs_mod_name): prio = 4 @@ -762,3 +790,15 @@ ppcop("SRAWI", [bs('011111'), rs, ra, sh, bs('1100111000'), rc_mod], [ra, rs, sh]) ppcop("EIEIO", [bs('011111'), bs('000000000000000'), bs('11010101100')]) + +ppcop("load1f", [bs_name(l=6, name=load1_name_float), frd, ra_noarg, dregimm]) +ppcop("load1fu", [bs_name(l=6, name=load1_name_float_u), frd, ra_noarg, dregimm]) +ppcop("store1f", [bs_name(l=6, name=store1_name_float), frd, ra_noarg, dregimm]) +ppcop("store1fu", [bs_name(l=6, name=store1_name_float_u), frd, ra_noarg, dregimm]) +ppcop("MTFSF", [bs('111111'), bs('0'), fm, bs('0'), frb, bs('10110001110')]) +ppcop("MTFSF.", [bs('111111'), bs('0'), fm, bs('0'), frb, bs('10110001111')]) +ppcop("MFFS", [bs('111111'), frd, bs('00000000001001000111'), bs('0')]) +ppcop("MFFS.", [bs('111111'), frd, bs('00000000001001000111'), bs('1')]) + +ppcop("load1vex", [bs('011111'), vd, ra, rb, bs_name(l=10, name=load1_name_vex), bs('0')]) +ppcop("mtvscr", [bs('0001000000000000'), vb, bs('11001000100')]) diff --git a/miasm/arch/ppc/regs.py b/miasm/arch/ppc/regs.py index 4b710045..00781d6a 100644 --- a/miasm/arch/ppc/regs.py +++ b/miasm/arch/ppc/regs.py @@ -35,7 +35,7 @@ xerbcreg_expr, xerbcreg_init, xerbcreg = gen_regs(xerbcreg_str, globals(), 7) -otherregs_str = ["PC", "CTR", "LR" ] +otherregs_str = ["PC", "CTR", "LR", "FPSCR", "VRSAVE", "VSCR" ] otherregs_expr, otherregs_init, otherregs = gen_regs(otherregs_str, globals(), 32) @@ -55,10 +55,18 @@ mmuregs_str = (["SR%d" % i for i in range(16)] + mmuregs_expr, mmuregs_init, mmuregs = gen_regs(mmuregs_str, globals(), 32) +floatregs_str = (["FPR%d" % i for i in range(32)]) +floatregs_expr, floatregs_init, floatregs = gen_regs(floatregs_str, + globals(), 64) + +vexregs_str = (["VR%d" % i for i in range(32)]) +vexregs_expr, vexregs_init, vexregs = gen_regs(vexregs_str, + globals(), 128) + regs_flt_expr = [] all_regs_ids = (gpregs_expr + crfbitregs_expr + xerbitregs_expr + - xerbcreg_expr + otherregs_expr + superregs_expr + mmuregs_expr + + xerbcreg_expr + otherregs_expr + superregs_expr + mmuregs_expr + floatregs_expr + vexregs_expr + [ exception_flags, spr_access, reserve, reserve_address ]) all_regs_ids_byname = dict([(x.name, x) for x in all_regs_ids]) all_regs_ids_init = [ExprId("%s_init" % x.name, x.size) for x in all_regs_ids] diff --git a/miasm/arch/ppc/sem.py b/miasm/arch/ppc/sem.py index fd6db8f3..7ca7e3e1 100644 --- a/miasm/arch/ppc/sem.py +++ b/miasm/arch/ppc/sem.py @@ -25,6 +25,20 @@ sr_dict = { 12: SR12, 13: SR13, 14: SR14, 15: SR15 } +float_dict = { + 0: FPR0, 1: FPR1, 2: FPR2, 3: FPR3, 4: FPR4, 5: FPR5, 6: FPR6, 7: FPR7, 8: FPR8, + 9: FPR9, 10: FPR10, 11: FPR11, 12: FPR12, 13: FPR13, 14: FPR14, 15: FPR15, 16: FPR16, + 17: FPR17, 18: FPR18, 19: FPR19, 20: FPR20, 21: FPR21, 22: FPR22, 23: FPR23, 24: FPR24, + 25: FPR25, 26: FPR26, 27: FPR27, 28: FPR28, 29: FPR29, 30: FPR30, 31: FPR31 +} + +vex_dict = { + 0: VR0, 1: VR1, 2: VR2, 3: VR3, 4: VR4, 5: VR5, 6: VR6, 7: VR7, 8: VR8, + 9: VR9, 10: VR10, 11: VR11, 12: VR12, 13: VR13, 14: VR14, 15: VR15, 16: VR16, + 17: VR17, 18: VR18, 19: VR19, 20: VR20, 21: VR21, 22: VR22, 23: VR23, 24: VR24, + 25: VR25, 26: VR26, 27: VR27, 28: VR28, 29: VR29, 30: VR30, 31: VR31, +} + crf_dict = dict((ExprId("CR%d" % i, 4), dict( (bit, ExprId("CR%d_%s" % (i, bit), 1)) for bit in ['LT', 'GT', 'EQ', 'SO' ] )) @@ -34,6 +48,8 @@ ctx = { 'crf_dict': crf_dict, 'spr_dict': spr_dict, 'sr_dict': sr_dict, + 'float_dict': float_dict, + 'vex_dict': vex_dict, 'expr': expr, } @@ -125,7 +141,7 @@ def mn_do_cntlzw(ir, instr, ra, rs): return ret, [] def crbit_to_reg(bit): - bit = bit.arg.arg + bit = int(bit) crid = bit // 4 bitname = [ 'LT', 'GT', 'EQ', 'SO' ][bit % 4] return all_regs_ids_byname["CR%d_%s" % (crid, bitname)] @@ -232,8 +248,8 @@ def mn_do_exts(ir, instr, ra, rs): def byte_swap(expr): nbytes = expr.size // 8 - bytes = [ expr[i*8:i*8+8] for i in range(nbytes - 1, -1, -1) ] - return ExprCompose(bytes) + lbytes = [ expr[i*8:i*8+8] for i in range(nbytes - 1, -1, -1) ] + return ExprCompose(*lbytes) def mn_do_load(ir, instr, arg1, arg2, arg3=None): assert instr.name[0] == 'L' @@ -244,6 +260,12 @@ def mn_do_load(ir, instr, arg1, arg2, arg3=None): return mn_do_lmw(ir, instr, arg1, arg2) elif instr.name[1] == 'S': raise RuntimeError("LSWI, and LSWX need implementing") + elif instr.name[1] == 'F': + print("Warning, instruction %s implemented as NOP" % instr) + return [], [] + elif instr.name[1] == 'V': + print("Warning, instruction %s implemented as NOP" % instr) + return [], [] size = {'B': 8, 'H': 16, 'W': 32}[instr.name[1]] @@ -298,7 +320,7 @@ def mn_do_load(ir, instr, arg1, arg2, arg3=None): def mn_do_lmw(ir, instr, rd, src): ret = [] - address = src.arg + address = src.ptr ri = int(rd.name[1:],10) i = 0 while ri <= 31: @@ -348,7 +370,7 @@ def mn_mfmsr(rd): rd = MSR def mn_mfspr(ir, instr, arg1, arg2): - sprid = arg2.arg.arg + sprid = int(arg2) gprid = int(arg1.name[1:]) if sprid in spr_dict: return [ ExprAssign(arg1, spr_dict[sprid]) ], [] @@ -365,7 +387,7 @@ def mn_mtcrf(ir, instr, crm, rs): ret = [] for i in range(8): - if crm.arg.arg & (1 << (7 - i)): + if int(crm) & (1 << (7 - i)): j = (28 - 4 * i) + 3 for b in ['LT', 'GT', 'EQ', 'SO']: ret.append(ExprAssign(all_regs_ids_byname["CR%d_%s" % (i, b)], @@ -379,7 +401,7 @@ def mn_mtmsr(ir, instr, rs): return [ ExprAssign(MSR, rs) ], [] def mn_mtspr(ir, instr, arg1, arg2): - sprid = arg1.arg.arg + sprid = int(arg1) gprid = int(arg2.name[1:]) if sprid in spr_dict: return [ ExprAssign(spr_dict[sprid], arg2) ], [] @@ -505,7 +527,7 @@ def mn_do_rfi(ir, instr): ret = [ ExprAssign(MSR, (MSR & ~ExprInt(0b1111111101110011, 32) | ExprCompose(SRR1[0:2], ExprInt(0, 2), - SRR1[4:7], ExprInt(0, 1), + SRR1[4:7], ExprInt(0, 1), SRR1[8:16], ExprInt(0, 16)))), ExprAssign(PC, dest), ExprAssign(ir.IRDst, dest) ] @@ -562,7 +584,7 @@ def mn_do_srawi(ir, instr, ra, rs, imm): if instr.name[-1] == '.': ret += mn_compute_flags(rvalue) - mask = ExprInt(0xFFFFFFFF >> (32 - imm.arg.arg), 32) + mask = ExprInt(0xFFFFFFFF >> (32 - int(imm)), 32) ret.append(ExprAssign(XER_CA, rs.msb() & ExprCond(rs & mask, ExprInt(1, 1), ExprInt(0, 1)))) @@ -580,7 +602,7 @@ def mn_do_srw(ir, instr, ra, rs, rb): def mn_do_stmw(ir, instr, rs, dest): ret = [] - address = dest.arg + address = dest.ptr ri = int(rs.name[1:],10) i = 0 while ri <= 31: @@ -599,6 +621,9 @@ def mn_do_store(ir, instr, arg1, arg2, arg3=None): if instr.name[2] == 'S': raise RuntimeError("STSWI, and STSWX need implementing") + elif instr.name[2] == 'F': + print("Warning, instruction %s implemented as NOP" % instr) + return [], [] size = {'B': 8, 'H': 16, 'W': 32}[instr.name[2]] @@ -650,8 +675,8 @@ def mn_do_store(ir, instr, arg1, arg2, arg3=None): ret.append(ExprAssign(ir.IRDst, loc_next)) dont = flags + [ ExprAssign(CR0_EQ, ExprInt(0,1)), ExprAssign(ir.IRDst, loc_next) ] - additional_ir = [ IRBlock(loc_do, [ AssignBlock(ret) ]), - IRBlock(loc_dont, [ AssignBlock(dont) ]) ] + additional_ir = [ IRBlock(loc_do.loc_key, [ AssignBlock(ret) ]), + IRBlock(loc_dont.loc_key, [ AssignBlock(dont) ]) ] ret = [ ExprAssign(reserve, ExprInt(0, 1)), ExprAssign(ir.IRDst, ExprCond(reserve, loc_do, loc_dont)) ] @@ -834,16 +859,21 @@ sem_dir = { 'MCRF': mn_do_mcrf, 'MCRXR': mn_do_mcrxr, 'MFCR': mn_do_mfcr, + 'MFFS': mn_do_nop_warn, + 'MFFS.': mn_do_nop_warn, 'MFMSR': mn_mfmsr, 'MFSPR': mn_mfspr, 'MFSR': mn_mfsr, 'MFSRIN': mn_do_nop_warn, - 'MFTB': mn_mfmsr, + 'MTFSF': mn_do_nop_warn, + 'MTFSF.': mn_do_nop_warn, + 'MFTB': mn_mfspr, 'MTCRF': mn_mtcrf, 'MTMSR': mn_mtmsr, 'MTSPR': mn_mtspr, 'MTSR': mn_mtsr, 'MTSRIN': mn_do_nop_warn, + 'MTVSCR': mn_do_nop_warn, 'NAND': mn_do_nand, 'NAND.': mn_do_nand, 'NOR': mn_do_nor, @@ -879,7 +909,7 @@ class ir_ppc32b(IntermediateRepresentation): def get_ir(self, instr): args = instr.args[:] if instr.name[0:5] in [ 'ADDIS', 'ORIS', 'XORIS', 'ANDIS' ]: - args[2] = ExprInt(args[2].arg << 16, 32) + args[2] = ExprInt(int(args[2]) << 16, 32) if instr.name[0:3] == 'ADD': if instr.name[0:4] == 'ADDZ': last_arg = ExprInt(0, 32) @@ -920,17 +950,17 @@ class ir_ppc32b(IntermediateRepresentation): instr_ir, extra_ir = mn_do_or(self, instr, *args) elif instr.name[0:2] == 'RL': instr_ir, extra_ir = mn_do_rotate(self, instr, args[0], args[1], - args[2], args[3].arg.arg, - args[4].arg.arg) + args[2], int(args[3]), + int(args[4])) elif instr.name == 'STMW': instr_ir, extra_ir = mn_do_stmw(self, instr, *args) elif instr.name[0:2] == 'ST': instr_ir, extra_ir = mn_do_store(self, instr, *args) elif instr.name[0:4] == 'SUBF': if instr.name[0:5] == 'SUBFZ': - last_arg = ExprInt(0) + last_arg = ExprInt(0, 32) elif instr.name[0:5] == 'SUBFM': - last_arg = ExprInt(0xFFFFFFFF) + last_arg = ExprInt(0xFFFFFFFF, 32) else: last_arg = args[2] instr_ir, extra_ir = mn_do_sub(self, instr, args[0], args[1], diff --git a/miasm/arch/x86/arch.py b/miasm/arch/x86/arch.py index 33b41236..127dded4 100644 --- a/miasm/arch/x86/arch.py +++ b/miasm/arch/x86/arch.py @@ -278,7 +278,7 @@ class x86_arg(m_arg): if value.name in ["FAR"]: return None - loc_key = loc_db.get_or_create_name_location(value.name.encode()) + loc_key = loc_db.get_or_create_name_location(value.name) return ExprLoc(loc_key, size_hint) if isinstance(value, AstOp): # First pass to retrieve fixed_size @@ -481,7 +481,7 @@ class instruction_x86(instruction): expr = self.args[0] if not expr.is_int(): return - addr = expr.arg + int(self.offset) + addr = (int(expr) + int(self.offset)) & int(expr.mask) loc_key = loc_db.get_or_create_offset_location(addr) self.args[0] = ExprLoc(loc_key, expr.size) @@ -547,7 +547,7 @@ class instruction_x86(instruction): def __str__(self): return self.to_string() - + def to_string(self, loc_db=None): o = super(instruction_x86, self).to_string(loc_db) if self.additional_info.g1.value & 1: @@ -1706,7 +1706,7 @@ def exprfindmod(e, o=None): def test_addr_size(ptr, size): if isinstance(ptr, ExprInt): - return ptr.arg < (1 << size) + return int(ptr) < (1 << size) else: return ptr.size == size @@ -1767,13 +1767,13 @@ def parse_mem(expr, parent, w8, sx=0, xmm=0, mm=0, bnd=0): value = ExprInt(int(disp), cast_size) if admode < value.size: if signed: - if int(disp.arg) != sign_ext(int(value), admode, disp.size): + if int(disp) != sign_ext(int(value), admode, disp.size): continue else: - if int(disp.arg) != int(value): + if int(disp) != int(value): continue else: - if int(disp.arg) != sign_ext(int(value), value.size, admode): + if int(disp) != sign_ext(int(value), value.size, admode): continue x1 = dict(dct_expr) x1[f_imm] = (encoding, value) @@ -1913,7 +1913,10 @@ def modrm2expr(modrm, parent, w8, sx=0, xmm=0, mm=0, bnd=0): if parent.disp.value is None: return None o.append(ExprInt(int(parent.disp.expr), admode)) - expr = ExprOp('+', *o) + if len(o) == 1: + expr = o[0] + else: + expr = ExprOp('+', *o) if w8 == 0: opmode = 8 elif sx == 1: @@ -2918,7 +2921,7 @@ class bs_rel_off(bs_cond_imm): parent_len = len(prefix) * 8 + self.parent.l + self.l assert(parent_len % 8 == 0) - v = int(self.expr.arg) - parent_len // 8 + v = int(self.expr) - parent_len // 8 if prefix is None: return mask = ((1 << self.l) - 1) diff --git a/miasm/arch/x86/sem.py b/miasm/arch/x86/sem.py index cf3539e2..86a933a0 100644 --- a/miasm/arch/x86/sem.py +++ b/miasm/arch/x86/sem.py @@ -28,7 +28,8 @@ from miasm.arch.x86.arch import mn_x86, repeat_mn, replace_regs from miasm.ir.ir import IntermediateRepresentation, IRBlock, AssignBlock from miasm.core.sembuilder import SemBuilder from miasm.jitter.csts import EXCEPT_DIV_BY_ZERO, EXCEPT_ILLEGAL_INSN, \ - EXCEPT_PRIV_INSN, EXCEPT_SOFT_BP, EXCEPT_INT_XX, EXCEPT_INT_1 + EXCEPT_PRIV_INSN, EXCEPT_SOFT_BP, EXCEPT_INT_XX, EXCEPT_INT_1, \ + EXCEPT_SYSCALL import math import struct @@ -1161,7 +1162,9 @@ def setalc(_, instr): def bswap(_, instr, dst): e = [] if dst.size == 16: - result = m2_expr.ExprCompose(dst[8:16], dst[:8]) + # BSWAP referencing a 16-bit register is undefined + # Seems to return 0 actually + result = m2_expr.ExprInt(0, 16) elif dst.size == 32: result = m2_expr.ExprCompose( dst[24:32], dst[16:24], dst[8:16], dst[:8]) @@ -3386,9 +3389,11 @@ def icebp(_, instr): def l_int(_, instr, src): e = [] # XXX - if src.arg == 1: + assert src.is_int() + value = int(src) + if value == 1: except_int = EXCEPT_INT_1 - elif src.arg == 3: + elif value == 3: except_int = EXCEPT_SOFT_BP else: except_int = EXCEPT_INT_XX @@ -3408,7 +3413,7 @@ def l_sysenter(_, instr): def l_syscall(_, instr): e = [] e.append(m2_expr.ExprAssign(exception_flags, - m2_expr.ExprInt(EXCEPT_PRIV_INSN, 32))) + m2_expr.ExprInt(EXCEPT_SYSCALL, 32))) return e, [] # XXX |