diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-03 16:43:42 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-03 16:43:42 +0100 |
| commit | f4829a8ce42b1abbcc8621802d6c6fad3a56cd5d (patch) | |
| tree | 211276c3587721126ded00be46487bf23b605591 /src/tools/callback.c | |
| parent | f73fbd3cee38b4c0086c934d73972375c9c8c7d6 (diff) | |
| download | box64-f4829a8ce42b1abbcc8621802d6c6fad3a56cd5d.tar.gz box64-f4829a8ce42b1abbcc8621802d6c6fad3a56cd5d.zip | |
More infrastructure added to elf and x64 emu
Diffstat (limited to 'src/tools/callback.c')
| -rwxr-xr-x | src/tools/callback.c | 86 |
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; +} |