about summary refs log tree commit diff stats
path: root/miasm2/jitter/jitcore_tcc.py
diff options
context:
space:
mode:
Diffstat (limited to 'miasm2/jitter/jitcore_tcc.py')
-rw-r--r--miasm2/jitter/jitcore_tcc.py146
1 files changed, 146 insertions, 0 deletions
diff --git a/miasm2/jitter/jitcore_tcc.py b/miasm2/jitter/jitcore_tcc.py
new file mode 100644
index 00000000..ee33bcd0
--- /dev/null
+++ b/miasm2/jitter/jitcore_tcc.py
@@ -0,0 +1,146 @@
+#!/usr/bin/env python
+#-*- coding:utf-8 -*-
+
+import os
+from miasm2.ir.ir2C import irblocs2C
+from subprocess import Popen, PIPE
+import jitcore
+from distutils.sysconfig import get_python_inc
+import Jittcc
+
+
+def jit_tcc_compil(func_name, func_code):
+    global Jittcc
+    c = Jittcc.tcc_compil(func_name, func_code)
+    return c
+
+
+class jit_tcc_code():
+
+    def __init__(self, c):
+        self.c = c
+
+    def __call__(self, cpu, vm):
+        return Jittcc.tcc_exec_bloc(self.c, cpu, vm)
+
+
+def gen_core(arch, attrib):
+    lib_dir = os.path.dirname(os.path.realpath(__file__))
+
+    txt = ""
+    txt += '#include "%s/queue.h"\n' % lib_dir
+    txt += '#include "%s/vm_mngr.h"\n' % lib_dir
+    txt += '#include "%s/arch/JitCore_%s.h"\n' % (lib_dir, arch.name)
+
+    txt += r'''
+#define RAISE(errtype, msg) {PyObject* p; p = PyErr_Format( errtype, msg ); return p;}
+'''
+    return txt
+
+
+def gen_C_source(my_ir, func_code):
+    c_source = ""
+    c_source += "\n".join(func_code)
+
+    c_source = gen_core(my_ir.arch, my_ir.attrib) + c_source
+
+    c_source = """
+ #ifdef __x86_64__
+ #ifndef __LP64__
+ /*
+  for ubuntu ?!? XXX TODO
+  /!\ force 64 bit system using 64 bits libc
+  change this to __ILP32__ to do so.
+ */
+ #define __LP64__
+ #endif
+ #endif
+ """ + "#include <Python.h>\n" + c_source
+
+    return c_source
+
+
+class objref:
+
+    def __init__(self, obj):
+        self.obj = obj
+
+
+class myresolver:
+
+    def __init__(self, offset):
+        self.offset = offset
+
+    def ret(self):
+        return "return PyLong_FromUnsignedLongLong(0x%X);" % self.offset
+
+from miasm2.core.utils import keydefaultdict
+
+
+class resolver:
+
+    def __init__(self):
+        self.resolvers = keydefaultdict(myresolver)
+
+    def get_resolver(self, offset):
+        return self.resolvers[offset]
+
+
+class JitCore_Tcc(jitcore.JitCore):
+
+    "JiT management, using LibTCC as backend"
+
+    def __init__(self, my_ir, bs=None):
+        super(JitCore_Tcc, self).__init__(my_ir, bs)
+        self.resolver = resolver()
+        self.exec_wrapper = Jittcc.tcc_exec_bloc
+
+    def load(self, arch):
+        # os.path.join(os.path.dirname(os.path.realpath(__file__)), "jitter")
+        lib_dir = os.path.dirname(os.path.realpath(__file__))
+        libs = []
+        libs.append(os.path.join(lib_dir, 'vm_mngr.so'))
+        libs.append(os.path.join(lib_dir, 'arch/JitCore_%s.so' % (arch.name)))
+        libs = ';'.join(libs)
+        jittcc_path = Jittcc.__file__
+        include_dir = os.path.dirname(jittcc_path)
+        include_dir += ";" + os.path.join(include_dir, "arch")
+        # print include_dir
+
+        # XXX HACK
+        # As debian/ubuntu have moved some include files using arch directory,
+        # TCC doesn't know them, so we get the info from GCC
+        # For example /usr/include/x86_64-linux-gnu which contains limits.h
+        p = Popen(["cc", "-Wp,-v", "-E", "-"],
+                  stdout=PIPE, stderr=PIPE, stdin=PIPE)
+        p.stdin.close()
+        include_files = p.stderr.read().split('\n')
+        include_files = [x[1:]
+            for x in include_files if x.startswith(' /usr/include')]
+        include_files += [include_dir, get_python_inc()]
+
+        include_files = ";".join(include_files)
+        Jittcc.tcc_set_emul_lib_path(include_files, libs)
+
+    def jitirblocs(self, label, irblocs):
+        # irbloc = self.lbl2irbloc[lbl]
+        f_name = "bloc_%s" % label.name
+        f_declaration = \
+            'PyObject* %s(vm_cpu_t* vmcpu, vm_mngr_t* vm_mngr)' % f_name
+        out = irblocs2C(self.my_ir, self.resolver, label, irblocs,
+                        gen_exception_code=True,
+                        log_mn=self.log_mn,
+                        log_regs=self.log_regs)
+        out = [f_declaration + '{'] + out + ['}\n']
+        c_code = out
+
+        func_code = gen_C_source(self.my_ir, c_code)
+        # print func_code
+        # open('tmp_%.4d.c'%self.jitcount, "w").write(func_code)
+        self.jitcount += 1
+        mcode = jit_tcc_compil(f_name, func_code)
+        jcode = jit_tcc_code(mcode)
+        self.lbl2jitbloc[label.offset] = mcode
+        self.addr2obj[label.offset] = jcode
+        self.addr2objref[label.offset] = objref(jcode)
+        # print "ADDR2CODE", hex(b.label.offset), hex(id(jcode))