diff options
| author | Camille Mougey <commial@gmail.com> | 2017-05-16 17:40:49 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-05-16 17:40:49 +0200 |
| commit | d3e5587207f68763ea483c0deeef160b3ebec155 (patch) | |
| tree | 51580d83ad4a574350975494d577fcc7b1fbcf7f | |
| parent | 627669759b4bdcfb220f098a141c183621477cd6 (diff) | |
| parent | 09f7c519d4c3249736a16ce36be9b6c3f135d6a8 (diff) | |
| download | miasm-d3e5587207f68763ea483c0deeef160b3ebec155.tar.gz miasm-d3e5587207f68763ea483c0deeef160b3ebec155.zip | |
Merge pull request #551 from serpilliere/instr_except
IR: explicit exception for div
| -rw-r--r-- | miasm2/arch/aarch64/sem.py | 12 | ||||
| -rw-r--r-- | miasm2/arch/x86/sem.py | 66 | ||||
| -rw-r--r-- | miasm2/jitter/codegen.py | 20 | ||||
| -rw-r--r-- | miasm2/jitter/llvmconvert.py | 43 | ||||
| -rw-r--r-- | miasm2/jitter/vm_mngr.h | 80 |
5 files changed, 111 insertions, 110 deletions
diff --git a/miasm2/arch/aarch64/sem.py b/miasm2/arch/aarch64/sem.py index 599cdc98..79c72d32 100644 --- a/miasm2/arch/aarch64/sem.py +++ b/miasm2/arch/aarch64/sem.py @@ -3,8 +3,8 @@ from miasm2.ir.ir import IntermediateRepresentation, IRBlock, AssignBlock from miasm2.arch.aarch64.arch import mn_aarch64, conds_expr, replace_regs from miasm2.arch.aarch64.regs import * from miasm2.core.sembuilder import SemBuilder +from miasm2.jitter.csts import EXCEPT_DIV_BY_ZERO -EXCEPT_PRIV_INSN = (1 << 17) # CPSR: N Z C V @@ -136,7 +136,9 @@ ctx = {"PC": PC, "of": of, "cond2expr": cond2expr, "extend_arg": extend_arg, - "m2_expr":m2_expr + "m2_expr":m2_expr, + "exception_flags": exception_flags, + "EXCEPT_DIV_BY_ZERO": EXCEPT_DIV_BY_ZERO, } sbuild = SemBuilder(ctx) @@ -528,7 +530,11 @@ def msub(arg1, arg2, arg3, arg4): @sbuild.parse def udiv(arg1, arg2, arg3): - arg1 = m2_expr.ExprOp('udiv', arg2, arg3) + if arg3: + arg1 = m2_expr.ExprOp('udiv', arg2, arg3) + else: + exception_flags = m2_expr.ExprInt(EXCEPT_DIV_BY_ZERO, + exception_flags.size) @sbuild.parse diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py index 0312891b..e32b8001 100644 --- a/miasm2/arch/x86/sem.py +++ b/miasm2/arch/x86/sem.py @@ -23,6 +23,8 @@ from miasm2.arch.x86.arch import mn_x86, repeat_mn, replace_regs from miasm2.expression.expression_helper import expr_cmps, expr_cmpu from miasm2.ir.ir import IntermediateRepresentation, IRBlock, AssignBlock from miasm2.core.sembuilder import SemBuilder +from miasm2.jitter.csts import EXCEPT_DIV_BY_ZERO, EXCEPT_ILLEGAL_INSN, \ + EXCEPT_PRIV_INSN, EXCEPT_SOFT_BP, EXCEPT_INT_XX import math import struct @@ -36,22 +38,6 @@ ctx = {'mRAX': mRAX, } sbuild = SemBuilder(ctx) -# interrupt with eip update after instr -EXCEPT_SOFT_BP = (1 << 1) -EXCEPT_INT_XX = (1 << 2) - -EXCEPT_BREAKPOINT_INTERN = (1 << 10) - -EXCEPT_NUM_UPDT_EIP = (1 << 11) -# interrupt with eip at instr -EXCEPT_UNK_MEM_AD = (1 << 12) -EXCEPT_THROW_SEH = (1 << 13) -EXCEPT_UNK_EIP = (1 << 14) -EXCEPT_ACCESS_VIOL = (1 << 14) -EXCEPT_INT_DIV_BY_ZERO = (1 << 16) -EXCEPT_PRIV_INSN = (1 << 17) -EXCEPT_ILLEGAL_INSN = (1 << 18) -EXCEPT_UNK_MNEMO = (1 << 19) """ @@ -1441,7 +1427,7 @@ def loope(ir, instr, dst): # XXX size to do; eflag -def div(_, instr, src1): +def div(ir, instr, src1): e = [] size = src1.size if size == 8: @@ -1461,12 +1447,32 @@ def div(_, instr, src1): else: e.append(m2_expr.ExprAff(s1, c_r[:size])) e.append(m2_expr.ExprAff(s2, c_d[:size])) - return e, [] + + lbl_div = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size) + lbl_except = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size) + lbl_next = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size) + + do_div = [] + do_div += e + do_div.append(m2_expr.ExprAff(ir.IRDst, lbl_next)) + blk_div = IRBlock(lbl_div.name, [do_div]) + + do_except = [] + do_except.append(m2_expr.ExprAff(exception_flags, m2_expr.ExprInt( + EXCEPT_DIV_BY_ZERO, exception_flags.size))) + do_except.append(m2_expr.ExprAff(ir.IRDst, lbl_next)) + blk_except = IRBlock(lbl_except.name, [do_except]) + + e = [] + e.append(m2_expr.ExprAff(ir.IRDst, + m2_expr.ExprCond(src1, lbl_div, lbl_except))) + + return e, [blk_div, blk_except] # XXX size to do; eflag -def idiv(_, instr, src1): +def idiv(ir, instr, src1): e = [] size = src1.size @@ -1487,7 +1493,27 @@ def idiv(_, instr, src1): else: e.append(m2_expr.ExprAff(s1, c_r[:size])) e.append(m2_expr.ExprAff(s2, c_d[:size])) - return e, [] + + lbl_div = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size) + lbl_except = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size) + lbl_next = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size) + + do_div = [] + do_div += e + do_div.append(m2_expr.ExprAff(ir.IRDst, lbl_next)) + blk_div = IRBlock(lbl_div.name, [do_div]) + + do_except = [] + do_except.append(m2_expr.ExprAff(exception_flags, m2_expr.ExprInt( + EXCEPT_DIV_BY_ZERO, exception_flags.size))) + do_except.append(m2_expr.ExprAff(ir.IRDst, lbl_next)) + blk_except = IRBlock(lbl_except.name, [do_except]) + + e = [] + e.append(m2_expr.ExprAff(ir.IRDst, + m2_expr.ExprCond(src1, lbl_div, lbl_except))) + + return e, [blk_div, blk_except] # XXX size to do; eflag diff --git a/miasm2/jitter/codegen.py b/miasm2/jitter/codegen.py index b2398dd2..15f172ee 100644 --- a/miasm2/jitter/codegen.py +++ b/miasm2/jitter/codegen.py @@ -25,7 +25,6 @@ class Attributes(object): self.mem_read = False self.mem_write = False self.set_exception = False - self.op_set_exception = False self.log_mn = log_mn self.log_regs = log_regs self.instr = None @@ -36,8 +35,6 @@ class CGen(object): Helper to generate C code for a given AsmBlock """ - IMPLICIT_EXCEPTION_OP = set(['umod', 'udiv']) - """ Translate native assembly block to C """ @@ -325,7 +322,7 @@ class CGen(object): out = [] if attrib.mem_read | attrib.mem_write: out += (self.CODE_VM_EXCEPTION_POST_INSTR % (self.C_PC)).split('\n') - if attrib.set_exception or attrib.op_set_exception: + if attrib.set_exception: out += (self.CODE_CPU_EXCEPTION_POST_INSTR % (self.C_PC)).split('\n') if attrib.mem_read | attrib.mem_write: @@ -437,10 +434,6 @@ class CGen(object): if c_prefetch: out += self.gen_check_memory_exception(attrib.instr.offset) - # Check if operator raised exception flags - if attrib.op_set_exception: - out += self.gen_check_cpu_exception(attrib.instr.offset) - out.append("// Mem updt") out += c_mem @@ -462,12 +455,6 @@ class CGen(object): return out - def is_exception_operator(self, operator): - """Return True if the @op operator can raise a runtime exception""" - - return any(operator.startswith(except_op) - for except_op in self.IMPLICIT_EXCEPTION_OP) - def get_caracteristics(self, assignblk, attrib): """ Set the carateristics in @attrib according to the @assignblk @@ -479,10 +466,6 @@ class CGen(object): attrib.set_exception = self.ir_arch.arch.regs.exception_flags in assignblk element_read = assignblk.get_r(mem_read=True) - # Check implicit exception raising - attrib.op_set_exception = any(self.is_exception_operator(operator) - for elem in assignblk.values() - for operator in m2_expr.get_expr_ops(elem)) # Check mem read attrib.mem_read = any(isinstance(expr, m2_expr.ExprMem) for expr in element_read) @@ -513,7 +496,6 @@ class CGen(object): attrib.instr = instr instr_attrib.mem_read |= attrib.mem_read instr_attrib.mem_write |= attrib.mem_write - instr_attrib.op_set_exception |= attrib.op_set_exception instr_attrib.set_exception |= attrib.set_exception return instr_attrib, irblocks_attributes diff --git a/miasm2/jitter/llvmconvert.py b/miasm2/jitter/llvmconvert.py index e7a1d6bc..ae018c18 100644 --- a/miasm2/jitter/llvmconvert.py +++ b/miasm2/jitter/llvmconvert.py @@ -242,23 +242,6 @@ class LLVMContext_JIT(LLVMContext): "args": [LLVMType.IntType(k), LLVMType.IntType(k)]}}) - for k in [16, 32, 64]: - self.add_fc({"imod%s" % k: {"ret": LLVMType.IntType(k), - "args": [p8, - LLVMType.IntType(k), - LLVMType.IntType(k)]}}) - self.add_fc({"idiv%s" % k: {"ret": LLVMType.IntType(k), - "args": [p8, - LLVMType.IntType(k), - LLVMType.IntType(k)]}}) - self.add_fc({"umod%s" % k: {"ret": LLVMType.IntType(k), - "args": [p8, - LLVMType.IntType(k), - LLVMType.IntType(k)]}}) - self.add_fc({"udiv%s" % k: {"ret": LLVMType.IntType(k), - "args": [p8, - LLVMType.IntType(k), - LLVMType.IntType(k)]}}) def add_log_functions(self): "Add functions for state logging" @@ -745,11 +728,21 @@ class LLVMFunction(): return ret if op in ["imod", "idiv", "umod", "udiv"]: - fc_ptr = self.mod.get_global( - "%s%s" % (op, expr.args[0].size)) - args_casted = [self.add_ir(arg) for arg in expr.args] - args = [self.local_vars["vmcpu"]] + args_casted - ret = builder.call(fc_ptr, args) + assert len(expr.args) == 2 + + arg_b = self.add_ir(expr.args[1]) + arg_a = self.add_ir(expr.args[0]) + + if op == "imod": + callback = builder.srem + elif op == "idiv": + callback = builder.sdiv + elif op == "umod": + callback = builder.urem + elif op == "udiv": + callback = builder.udiv + + ret = callback(arg_a, arg_b) self.update_cache(expr, ret) return ret @@ -1020,8 +1013,6 @@ class LLVMFunction(): fc_ptr = self.mod.get_global("check_invalid_code_blocs") self.builder.call(fc_ptr, [self.local_vars["vmmngr"]]) self.check_memory_exception(next_instr, restricted_exception=False) - if attrib.set_exception or attrib.op_set_exception: - self.check_cpu_exception(next_instr, restricted_exception=False) if attrib.mem_read | attrib.mem_write: fc_ptr = self.mod.get_global("reset_memory_access") @@ -1146,10 +1137,6 @@ class LLVMFunction(): self.check_memory_exception(instr.offset, restricted_exception=True) - # Check operation exception - if attributes[index].op_set_exception: - self.check_cpu_exception(instr.offset, restricted_exception=True) - # Update the memory for dst, src in values.iteritems(): if isinstance(dst, m2_expr.ExprMem): diff --git a/miasm2/jitter/vm_mngr.h b/miasm2/jitter/vm_mngr.h index 912b105e..74ad49ad 100644 --- a/miasm2/jitter/vm_mngr.h +++ b/miasm2/jitter/vm_mngr.h @@ -224,55 +224,55 @@ unsigned int rcr_rez_op(unsigned int size, unsigned int a, unsigned int b, unsig #define UDIV(sizeA) \ - uint ## sizeA ## _t udiv ## sizeA (vm_cpu_t* vmcpu, uint ## sizeA ## _t a, uint ## sizeA ## _t b) \ - { \ - uint ## sizeA ## _t r; \ - if (b == 0) { \ - vmcpu->exception_flags |= EXCEPT_INT_DIV_BY_ZERO; \ - return 0; \ - } \ - r = a/b; \ - return r; \ - } + uint ## sizeA ## _t udiv ## sizeA (vm_cpu_t* vmcpu, uint ## sizeA ## _t a, uint ## sizeA ## _t b) \ + { \ + uint ## sizeA ## _t r; \ + if (b == 0) { \ + fprintf(stderr, "Should not happen\n"); \ + exit(0); \ + } \ + r = a/b; \ + return r; \ + } #define UMOD(sizeA) \ - uint ## sizeA ## _t umod ## sizeA (vm_cpu_t* vmcpu, uint ## sizeA ## _t a, uint ## sizeA ## _t b) \ - { \ - uint ## sizeA ## _t r; \ - if (b == 0) { \ - vmcpu->exception_flags |= EXCEPT_INT_DIV_BY_ZERO; \ - return 0; \ - } \ - r = a%b; \ - return r; \ - } + uint ## sizeA ## _t umod ## sizeA (vm_cpu_t* vmcpu, uint ## sizeA ## _t a, uint ## sizeA ## _t b) \ + { \ + uint ## sizeA ## _t r; \ + if (b == 0) { \ + fprintf(stderr, "Should not happen\n"); \ + exit(0); \ + } \ + r = a%b; \ + return r; \ + } #define IDIV(sizeA) \ - int ## sizeA ## _t idiv ## sizeA (vm_cpu_t* vmcpu, int ## sizeA ## _t a, int ## sizeA ## _t b) \ - { \ - int ## sizeA ## _t r; \ - if (b == 0) { \ - vmcpu->exception_flags |= EXCEPT_INT_DIV_BY_ZERO; \ - return 0; \ - } \ - r = a/b; \ - return r; \ - } + int ## sizeA ## _t idiv ## sizeA (vm_cpu_t* vmcpu, int ## sizeA ## _t a, int ## sizeA ## _t b) \ + { \ + int ## sizeA ## _t r; \ + if (b == 0) { \ + fprintf(stderr, "Should not happen\n"); \ + exit(0); \ + } \ + r = a/b; \ + return r; \ + } #define IMOD(sizeA) \ - int ## sizeA ## _t imod ## sizeA (vm_cpu_t* vmcpu, int ## sizeA ## _t a, int ## sizeA ## _t b) \ - { \ - int ## sizeA ## _t r; \ - if (b == 0) { \ - vmcpu->exception_flags |= EXCEPT_INT_DIV_BY_ZERO; \ - return 0; \ - } \ - r = a%b; \ - return r; \ - } + int ## sizeA ## _t imod ## sizeA (vm_cpu_t* vmcpu, int ## sizeA ## _t a, int ## sizeA ## _t b) \ + { \ + int ## sizeA ## _t r; \ + if (b == 0) { \ + fprintf(stderr, "Should not happen\n"); \ + exit(0); \ + } \ + r = a%b; \ + return r; \ + } void memory_access_list_init(struct memory_access_list * access); |