about summary refs log tree commit diff stats
path: root/src/tools/callback.c
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-03 16:43:42 +0100
committerptitSeb <sebastien.chev@gmail.com>2021-03-03 16:43:42 +0100
commitf4829a8ce42b1abbcc8621802d6c6fad3a56cd5d (patch)
tree211276c3587721126ded00be46487bf23b605591 /src/tools/callback.c
parentf73fbd3cee38b4c0086c934d73972375c9c8c7d6 (diff)
downloadbox64-f4829a8ce42b1abbcc8621802d6c6fad3a56cd5d.tar.gz
box64-f4829a8ce42b1abbcc8621802d6c6fad3a56cd5d.zip
More infrastructure added to elf and x64 emu
Diffstat (limited to 'src/tools/callback.c')
-rwxr-xr-xsrc/tools/callback.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/src/tools/callback.c b/src/tools/callback.c
new file mode 100755
index 00000000..8c46139e
--- /dev/null
+++ b/src/tools/callback.c
@@ -0,0 +1,86 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include "debug.h"
+#include "x64emu.h"
+#include "x64run.h"
+#include "emu/x64emu_private.h"
+#include "emu/x64run_private.h"
+#include "box64context.h"
+#include "box64stack.h"
+#include "dynarec.h"
+
+EXPORTDYN
+uint64_t RunFunction(box64context_t *context, uintptr_t fnc, int nargs, ...)
+{
+    x64emu_t *emu = thread_get_emu();
+
+    if(nargs>6)
+        R_ESP -= (nargs-6)*4;   // need to push in reverse order
+
+    uint64_t *p = (uint64_t*)R_RSP;
+
+    va_list va;
+    va_start (va, nargs);
+    for (int i=0; i<nargs; ++i) {
+        if(i<6) {
+            int nn[] = {_DI, _SI, _DX, _CX, _R8, _R9};
+            emu->regs[nn[i]].q[0] = va_arg(va, uint64_t);
+        } else {
+            *p = va_arg(va, uint64_t);
+            p++;
+        }
+    }
+    va_end (va);
+
+    DynaCall(emu, fnc);
+    if(nargs>6)
+        R_ESP+=((nargs-6)*4);
+
+    uint64_t ret = R_RAX;
+
+    return ret;
+}
+
+EXPORTDYN
+uint64_t RunFunctionWithEmu(x64emu_t *emu, int QuitOnLongJump, uintptr_t fnc, int nargs, ...)
+{
+    if(nargs>6)
+        R_ESP -= (nargs-6)*4;   // need to push in reverse order
+
+    uint64_t *p = (uint64_t*)R_RSP;
+
+    va_list va;
+    va_start (va, nargs);
+    for (int i=0; i<nargs; ++i) {
+        if(i<6) {
+            int nn[] = {_DI, _SI, _DX, _CX, _R8, _R9};
+            emu->regs[nn[i]].q[0] = va_arg(va, uint64_t);
+        } else {
+            *p = va_arg(va, uint64_t);
+            p++;
+        }
+    }
+    va_end (va);
+
+    uintptr_t oldip = R_RIP;
+    int old_quit = emu->quit;
+    int oldlong = emu->quitonlongjmp;
+
+    emu->quit = 0;
+    emu->quitonlongjmp = QuitOnLongJump;
+
+    DynaCall(emu, fnc);
+
+    if(oldip==R_RIP && nargs>6)
+        R_ESP+=((nargs-6)*4);   // restore stack only if EIP is the one expected (else, it means return value is not the one expected)
+
+    emu->quit = old_quit;
+    emu->quitonlongjmp = oldlong;
+
+
+    return R_RAX;
+}