diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2025-05-11 14:01:46 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2025-05-11 14:01:46 +0200 |
| commit | b1eabd758349fafb92871254c34ff7e207b508be (patch) | |
| tree | 1631b1c827fe67494d6e4dbc1c788b98f15256e9 /src/tools/callback.c | |
| parent | 7a2d9967f5aba185ea641cee996310187002fa24 (diff) | |
| download | box64-b1eabd758349fafb92871254c34ff7e207b508be.tar.gz box64-b1eabd758349fafb92871254c34ff7e207b508be.zip | |
[WRAPPER] Added more wrapped function to ffmpeg, and disable it with NOGTK=1, as wrapping needs more work on structure callbacks
Diffstat (limited to 'src/tools/callback.c')
| -rw-r--r-- | src/tools/callback.c | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/src/tools/callback.c b/src/tools/callback.c index f7e914b4..e5a8148c 100644 --- a/src/tools/callback.c +++ b/src/tools/callback.c @@ -14,6 +14,7 @@ #include "box64cpu_util.h" #ifdef BOX32 #include "box32.h" +#include "emu/x87emu_private.h" #endif EXPORTDYN @@ -251,6 +252,178 @@ uint64_t RunFunctionFmt(uintptr_t fnc, const char* fmt, ...) } EXPORTDYN +double RunFunctionFmtD(uintptr_t fnc, const char* fmt, ...) +{ + x64emu_t *emu = thread_get_emu(); + int nargs = 0; + int ni = 0; + int ndf = 0; + for (int i=0; fmt[i]; ++i) { + #ifdef BOX32 + if(box64_is32bits) + switch(fmt[i]) { + case 'd': + case 'I': + case 'U': nargs+=2; break; + case 'p': + case 'L': + case 'l': + case 'f': + case 'i': + case 'u': + case 'w': + case 'W': + case 'c': + case 'C': ++nargs; break; + default: + ++nargs; break; + } + else + #endif + switch(fmt[i]) { + case 'f': + case 'd': if(ndf<8) ++ndf; else ++nargs; break; + case 'p': + case 'i': + case 'u': + case 'I': + case 'U': + case 'L': + case 'l': + case 'w': + case 'W': + case 'c': + case 'C': if(ni<6) ++ni; else ++nargs; break; + default: + if(ni<6) ++ni; else ++nargs; break; + } + } + ni = 0; + ndf = 0; + int align = nargs&1; + int stackn = align + nargs; + int sizeof_ptr = sizeof(void*); + #ifdef BOX32 + if(box64_is32bits) { + Push_32(emu, R_EBP); // push ebp + R_RBP = R_ESP; // mov ebp, esp + sizeof_ptr = sizeof(ptr_t); + align = (4-(nargs&3))&3; + } else + #endif + { + Push64(emu, R_RBP); // push rbp + R_RBP = R_RSP; // mov rbp, rsp + } + + R_RSP -= stackn*sizeof_ptr; // need to push in reverse order + + #ifdef BOX32 + if(box64_is32bits) { + ptr_t *p = (ptr_t*)from_ptrv(R_ESP); + + #define GO(c, B, B2, N) case c: *((B*)p) = va_arg(va, B2); p+=N; break + va_list va; + va_start (va, fmt); + for (int i=0; fmt[i]; ++i) { + switch(fmt[i]) { + GO('f', float, double, 1); + GO('d', double, double, 2); + case 'p': *((ptr_t*)p) = to_ptrv(va_arg(va, void*)); p+=1; break; + GO('i', int, int, 1); + GO('u', uint32_t, uint32_t, 1); + GO('I', int64_t, int64_t, 2); + GO('U', uint64_t, uint64_t, 2); + GO('L', uint32_t, uint64_t, 1); // long are 64bits on 64bits system + GO('l', int32_t, int64_t, 1); // but 32bits on 32bits system + GO('w', int16_t, int, 1); + GO('W', uint16_t, int, 1); + GO('c', int8_t, int, 1); + GO('C', uint8_t, int, 1); + default: + printf_log(LOG_NONE, "Error, unhandled arg %d: '%c' in RunFunctionFmt\n", i, fmt[i]); + *p = va_arg(va, uint32_t); + ++p; + break; + } + } + #undef GO + va_end (va); + } else + #endif + { + uint64_t *p = (uint64_t*)R_RSP; + + static const int nn[] = {_DI, _SI, _DX, _CX, _R8, _R9}; + #define GO(c, A, B, B2, C) case c: if(ni<6) emu->regs[nn[ni++]].A[0] = C va_arg(va, B2); else {*p = 0; *((B*)p) = va_arg(va, B2); ++p;}; break; + va_list va; + va_start (va, fmt); + for (int i=0; fmt[i]; ++i) { + switch(fmt[i]) { + case 'f': if(ndf<8) + emu->xmm[ndf++].f[0] = va_arg(va, double); // float are promoted to double in ... + else { + *p = 0; + *((float*)p) = va_arg(va, double); + ++p; + } + break; + case 'd': if(ndf<8) + emu->xmm[ndf++].d[0] = va_arg(va, double); + else { + *((double*)p) = va_arg(va, double); + ++p; + } + break; + GO('p', q, void*, void*, (uintptr_t)) + GO('i', sdword, int, int, ) + GO('u', dword, uint32_t, uint32_t, ) + GO('I', sq, int64_t, int64_t, ) + GO('U', q, uint64_t, uint64_t, ) + GO('L', q, uint64_t, uint64_t, ) + GO('l', sq, int64_t, int64_t, ) + GO('w', sword, int16_t, int, ) + GO('W', word, uint16_t, int, ) + GO('c', sbyte, int8_t, int, ) + GO('C', byte, uint8_t, int, ) + default: + printf_log(LOG_NONE, "Error, unhandled arg %d: '%c' in RunFunctionFmt\n", i, fmt[i]); + if(ni<6) emu->regs[nn[ni++]].q[0] = va_arg(va, uint64_t); else {*p = va_arg(va, uint64_t); ++p;}; + break; + } + } + #undef GO + va_end (va); + } + + uintptr_t oldip = R_RIP; + DynaCall(emu, fnc); + + if(oldip==R_RIP) { + #ifdef BOX32 + if(box64_is32bits) { + R_RSP = R_EBP; // mov esp, ebp + R_RBP = Pop_32(emu); // pop ebp + } else + #endif + { + R_RSP = R_RBP; // mov rsp, rbp + R_RBP = Pop64(emu); // pop rbp + } + } + double ret; + #ifdef BOX32 + if(box64_is32bits) { + ret = ST0.d; + fpu_do_pop(emu); + } else + #endif + ret = emu->xmm[0].d[0]; + + return ret; +} + +EXPORTDYN uint64_t RunSafeFunction(uintptr_t fnc, int nargs, ...) { x64emu_t * emu = thread_get_emu(); |