diff options
| author | serpilliere <devnull@localhost> | 2014-06-03 10:27:56 +0200 |
|---|---|---|
| committer | serpilliere <devnull@localhost> | 2014-06-03 10:27:56 +0200 |
| commit | ed5c3668cc9f545b52674ad699fc2b0ed1ccb575 (patch) | |
| tree | 07faf97d7e4d083173a1f7e1bfd249baed2d74f9 /miasm2/jitter/jitcore_llvm.py | |
| parent | a183e1ebd525453710306695daa8c410fd0cb2af (diff) | |
| download | miasm-ed5c3668cc9f545b52674ad699fc2b0ed1ccb575.tar.gz miasm-ed5c3668cc9f545b52674ad699fc2b0ed1ccb575.zip | |
Miasm v2
* API has changed, so old scripts need updates * See example for API usage * Use tcc or llvm for jit emulation * Go to test and run test_all.py to check install Enjoy !
Diffstat (limited to 'miasm2/jitter/jitcore_llvm.py')
| -rw-r--r-- | miasm2/jitter/jitcore_llvm.py | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/miasm2/jitter/jitcore_llvm.py b/miasm2/jitter/jitcore_llvm.py new file mode 100644 index 00000000..f081d281 --- /dev/null +++ b/miasm2/jitter/jitcore_llvm.py @@ -0,0 +1,157 @@ +import os +import importlib +import hashlib +try: + from llvmconvert import * +except ImportError: + pass +import jitcore +import Jitllvm + + +class JitCore_LLVM(jitcore.JitCore): + + "JiT management, using LLVM as backend" + + # Architecture dependant libraries + arch_dependent_libs = {"x86": "arch/JitCore_x86.so"} + + def __init__(self, my_ir, bs=None): + super(JitCore_LLVM, self).__init__(my_ir, bs) + + self.options.update({"safe_mode": False, # Verify each function + "optimise": False, # Optimise functions + "log_func": False, # Print LLVM functions + "log_assembly": False, # Print assembly executed + "cache_ir": None # SaveDir for cached .ll + }) + + self.exec_wrapper = Jitllvm.llvm_exec_bloc + self.exec_engines = [] + + def load(self, arch): + + # Library to load within Jit context + libs_to_load = [] + + # Get the vm_mngr librairy + lib_dir = os.path.dirname(os.path.realpath(__file__)) + vm_mngr_path = os.path.join(lib_dir, 'vm_mngr.so') + libs_to_load.append(vm_mngr_path) + + # Get architecture dependant Jitcore library (if any) + try: + jit_lib = os.path.join( + lib_dir, self.arch_dependent_libs[arch.name]) + libs_to_load.append(jit_lib) + except KeyError: + pass + + # Create a context + self.context = LLVMContext_JIT(libs_to_load) + + # Set the optimisation level + self.context.optimise_level() + + # Save the current architecture parameters + self.arch = arch + + # Get the correspondance between registers and vmcpu struct + mod_name = "miasm2.jitter.arch.JitCore_%s" % (arch.name) + mod = importlib.import_module(mod_name) + self.context.set_vmcpu(mod.get_gpreg_offset_all()) + + # Save module base + self.mod_base_str = str(self.context.mod) + + # Set IRs transformation to apply + self.context.set_IR_transformation(self.my_ir.expr_fix_regs_for_mode) + + def add_bloc(self, bloc): + + # Search in IR cache + if self.options["cache_ir"] is not None: + + # /!\ This part is under development + # Use it at your own risk + + # Compute Hash : label + bloc binary + func_name = bloc.label.name + to_hash = func_name + + # Get binary from bloc + for line in bloc.lines: + b = line.b + to_hash += b + + # Compute Hash + md5 = hashlib.md5(to_hash).hexdigest() + + # Try to load the function from cache + filename = self.options["cache_ir"] + md5 + ".ll" + + try: + fcontent = open(filename) + content = fcontent.read() + fcontent.close() + + except IOError: + content = None + + if content is None: + # Compute the IR + super(JitCore_LLVM, self).add_bloc(bloc) + + # Save it + fdest = open(filename, "w") + dump = str(self.context.mod.get_function_named(func_name)) + my = "declare i16 @llvm.bswap.i16(i16) nounwind readnone\n" + + fdest.write(self.mod_base_str + my + dump) + fdest.close() + + else: + import llvm.core as llvm_c + import llvm.ee as llvm_e + my_mod = llvm_c.Module.from_assembly(content) + func = my_mod.get_function_named(func_name) + exec_en = llvm_e.ExecutionEngine.new(my_mod) + self.exec_engines.append(exec_en) + + # We can use the same exec_engine + ptr = self.exec_engines[0].get_pointer_to_function(func) + + # Store a pointer on the function jitted code + self.lbl2jitbloc[bloc.label.offset] = ptr + + else: + super(JitCore_LLVM, self).add_bloc(bloc) + + def jitirblocs(self, label, irblocs): + + # Build a function in the context + func = LLVMFunction(self.context, label.name) + + # Set log level + func.log_regs = self.log_regs + func.log_mn = self.log_mn + + # Import irblocs + func.from_blocs(irblocs) + + # Verify + if self.options["safe_mode"] is True: + func.verify() + + # Optimise + if self.options["optimise"] is True: + func.optimise() + + # Log + if self.options["log_func"] is True: + print func + if self.options["log_assembly"] is True: + print func.get_assembly() + + # Store a pointer on the function jitted code + self.lbl2jitbloc[label.offset] = func.get_function_pointer() |