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
|
#-*- coding:utf-8 -*-
import os
import tempfile
import ctypes
import _ctypes
from subprocess import check_call
from miasm2.jitter import Jitgcc
from miasm2.jitter.jitcore_cc_base import JitCore_Cc_Base, gen_core
class JitCore_Gcc(JitCore_Cc_Base):
"JiT management, using a C compiler as backend"
def __init__(self, ir_arch, bs=None):
super(JitCore_Gcc, self).__init__(ir_arch, bs)
self.exec_wrapper = Jitgcc.gcc_exec_bloc
def deleteCB(self, offset):
"""Free the state associated to @offset and delete it
@offset: gcc state offset
"""
_ctypes.dlclose(self.states[offset]._handle)
del self.states[offset]
def load_code(self, label, fname_so):
f_name = self.label2fname(label)
lib = ctypes.cdll.LoadLibrary(fname_so)
func = getattr(lib, f_name)
addr = ctypes.cast(func, ctypes.c_void_p).value
self.lbl2jitbloc[label.offset] = addr
self.states[label.offset] = lib
def add_bloc(self, block):
"""Add a bloc to JiT and JiT it.
@block: block to jit
"""
block_hash = self.hash_block(block)
fname_out = os.path.join(self.tempdir, "%s.so" % block_hash)
if not os.access(fname_out, os.R_OK | os.X_OK):
func_code = self.gen_c_code(block.label, block)
# Create unique C file
fdesc, fname_in = tempfile.mkstemp(suffix=".c")
os.write(fdesc, func_code)
os.close(fdesc)
# Create unique SO file
fdesc, fname_tmp = tempfile.mkstemp(suffix=".so")
os.close(fdesc)
inc_dir = ["-I%s" % inc for inc in self.include_files]
libs = ["%s" % lib for lib in self.libs]
args = ["cc"] + ["-O3"] + [
"-shared", "-fPIC", fname_in, '-o', fname_tmp] + inc_dir + libs
check_call(args)
# Move temporary file to final file
os.rename(fname_tmp, fname_out)
os.remove(fname_in)
self.load_code(block.label, fname_out)
@staticmethod
def gen_C_source(ir_arch, func_code):
c_source = ""
c_source += "\n".join(func_code)
c_source = gen_core(ir_arch.arch, ir_arch.attrib) + c_source
c_source = "#include <Python.h>\n" + c_source
return c_source
|