about summary refs log tree commit diff stats
path: root/src/miasm/jitter/Jitllvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/miasm/jitter/Jitllvm.c')
-rw-r--r--src/miasm/jitter/Jitllvm.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/src/miasm/jitter/Jitllvm.c b/src/miasm/jitter/Jitllvm.c
new file mode 100644
index 00000000..3420c254
--- /dev/null
+++ b/src/miasm/jitter/Jitllvm.c
@@ -0,0 +1,96 @@
+#include <Python.h>
+
+#include <inttypes.h>
+
+#include <stdint.h>
+#include "compat_py23.h"
+#include "queue.h"
+#include "vm_mngr.h"
+#include "bn.h"
+#include "vm_mngr_py.h"
+#include "JitCore.h"
+// Needed to get the JitCpu.cpu offset, arch independent
+#include "arch/JitCore_x86.h"
+
+PyObject* llvm_exec_block(PyObject* self, PyObject* args)
+{
+	uint64_t (*func)(void*, void*, void*, uint8_t*);
+	struct vm_cpu* cpu;
+	vm_mngr_t* vm;
+	uint64_t ret;
+	JitCpu* jitcpu;
+	uint8_t status;
+	PyObject* func_py;
+	PyObject* lbl2ptr;
+	PyObject* stop_offsets;
+	PyObject* retaddr = NULL;
+	uint64_t max_exec_per_call = 0;
+	uint64_t cpt;
+	int do_cpt;
+
+	if (!PyArg_ParseTuple(args, "OOOO|K",
+			      &retaddr, &jitcpu, &lbl2ptr, &stop_offsets,
+			      &max_exec_per_call))
+		return NULL;
+
+	cpu = jitcpu->cpu;
+	vm = &(jitcpu->pyvm->vm_mngr);
+	/* The loop will decref retaddr always once */
+	Py_INCREF(retaddr);
+
+	if (max_exec_per_call == 0) {
+		do_cpt = 0;
+		cpt = 1;
+	} else {
+		do_cpt = 1;
+		cpt = max_exec_per_call;
+	}
+
+	for (;;) {
+		// Handle cpt
+		if (cpt == 0)
+			return retaddr;
+		if (do_cpt)
+			cpt --;
+
+		// Get the expected jitted function address
+		func_py = PyDict_GetItem(lbl2ptr, retaddr);
+		if (func_py)
+			func = PyLong_AsVoidPtr((PyObject*) func_py);
+		else
+			// retaddr is not jitted yet
+			return retaddr;
+
+		// Execute it
+		ret = func((void*) jitcpu, (void*)(intptr_t) cpu, (void*)(intptr_t) vm, &status);
+		Py_DECREF(retaddr);
+		retaddr = PyLong_FromUnsignedLongLong(ret);
+
+		// Check exception
+		if (status)
+			return retaddr;
+
+		// Check stop offsets
+		if (PySet_Contains(stop_offsets, retaddr))
+			return retaddr;
+	}
+}
+
+
+static PyMethodDef LLVMMethods[] = {
+    {"llvm_exec_block",  llvm_exec_block, METH_VARARGS,
+     "llvm exec block"},
+    {NULL, NULL, 0, NULL}        /* Sentinel */
+};
+
+
+
+
+MOD_INIT(Jitllvm)
+{
+	PyObject *module = NULL;
+
+	MOD_DEF(module, "Jitllvm", "llvm module", LLVMMethods);
+
+	RET_MODULE;
+}