1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
# Toshiba MeP-c4 - miasm jitter
# Guillaume Valadon <guillaume@valadon.net>
# 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
|