about summary refs log tree commit diff stats
path: root/miasm2/jitter/Jitllvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'miasm2/jitter/Jitllvm.c')
-rw-r--r--miasm2/jitter/Jitllvm.c63
1 files changed, 55 insertions, 8 deletions
diff --git a/miasm2/jitter/Jitllvm.c b/miasm2/jitter/Jitllvm.c
index c176a4b2..b46f88e3 100644
--- a/miasm2/jitter/Jitllvm.c
+++ b/miasm2/jitter/Jitllvm.c
@@ -12,19 +12,66 @@
 
 PyObject* llvm_exec_bloc(PyObject* self, PyObject* args)
 {
-	uint64_t func_addr;
 	uint64_t (*func)(void*, void*, void*, uint8_t*);
-	uint64_t vm;
+	vm_cpu_t* cpu;
+	vm_mngr_t* vm;
 	uint64_t ret;
 	JitCpu* jitcpu;
 	uint8_t status;
-	
-	if (!PyArg_ParseTuple(args, "KOK", &func_addr, &jitcpu, &vm))
+	PyObject* func_py;
+	PyObject* lbl2ptr;
+	PyObject* breakpoints;
+	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, &breakpoints,
+			      &max_exec_per_call))
 		return NULL;
-	vm_cpu_t* cpu = jitcpu->cpu;
-	func = (void *) (intptr_t) func_addr;
-	ret = func((void*) jitcpu, (void*)(intptr_t) cpu, (void*)(intptr_t) vm, &status);
-	return PyLong_FromUnsignedLongLong(ret);
+
+	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 breakpoint
+		if (PyDict_Contains(breakpoints, retaddr))
+			return retaddr;
+	}
 }