# Toshiba MeP-c4 - miasm jitter # Guillaume Valadon # Note: inspiration from msp430/jit.py from miasm2.jitter.jitload import Jitter from miasm2.core.locationdb import LocationDB from miasm2.core.utils import * from miasm2.jitter.codegen import CGen from miasm2.ir.translators.C import TranslatorC from miasm2.arch.mep.sem import ir_mepl, ir_mepb import logging log = logging.getLogger("jit_mep") hnd = logging.StreamHandler() hnd.setFormatter(logging.Formatter("[%(levelname)s]: %(message)s")) log.addHandler(hnd) log.setLevel(logging.CRITICAL) class mep_CGen(CGen): """ Translate a bloc containing MeP instructions to C Note: it is used to emulate the *REPEAT instructions """ def __init__(self, ir_arch): self.ir_arch = ir_arch self.PC = self.ir_arch.arch.regs.PC self.translator = TranslatorC(self.ir_arch.loc_db) self.init_arch_C() def gen_pre_code(self, attrib): """Generate C code inserted before the current bloc""" # Call the base class method out = super(mep_CGen, self).gen_pre_code(attrib) # Set the PC register value explicitly out.append("mycpu->PC = 0x%X;" % attrib.instr.offset) out.append("mycpu->last_addr = mycpu->PC;"); return out def gen_post_code(self, attrib): """Generate C code inserted after the current bloc""" # Call the base class method out = super(mep_CGen, self).gen_post_code(attrib) # Implement the *REPEAT instructions logics tmp = r""" /* *REPEAT instructions logic */ { uint32_t is_repeat_end = mycpu->is_repeat_end; mycpu->is_repeat_end = !!(mycpu->last_addr == (mycpu->RPE&~0x1)); if (is_repeat_end && !mycpu->take_jmp && (mycpu->in_erepeat || mycpu->RPC)) { if (mycpu->RPC) mycpu->RPC --; //printf("Go repeat %X\n", mycpu->RPB); DST_value = mycpu->RPB; BlockDst->address = mycpu->RPB; return JIT_RET_NO_EXCEPTION; } } """ out += tmp.split('`\n') return out class jitter_mepl(Jitter): C_Gen = mep_CGen def __init__(self, *args, **kwargs): sp = LocationDB() Jitter.__init__(self, ir_mepl(sp), *args, **kwargs) self.vm.set_little_endian() self.ir_arch.jit_pc = self.ir_arch.arch.regs.PC def push_uint16_t(self, v): regs = self.cpu.get_gpreg() regs["SP"] -= 2 self.cpu.set_gpreg(regs) self.vm.set_mem(regs["SP"], pck16(v)) def pop_uint16_t(self): regs = self.cpu.get_gpreg() x = upck16(self.vm.get_mem(regs["SP"], 2)) regs["SP"] += 2 self.cpu.set_gpreg(regs) return x def get_stack_arg(self, n): regs = self.cpu.get_gpreg() x = upck16(self.vm.get_mem(regs["SP"] + 2 * n, 2)) return x def init_run(self, *args, **kwargs): Jitter.init_run(self, *args, **kwargs) self.cpu.PC = self.pc class jitter_mepb(jitter_mepl): def __init__(self, *args, **kwargs): sp = LocationDB() Jitter.__init__(self, ir_mepb(sp), *args, **kwargs) self.vm.set_big_endian() self.ir_arch.jit_pc = self.ir_arch.arch.regs.PC