about summary refs log tree commit diff stats
path: root/src/tools/callback.c
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-05-11 14:01:46 +0200
committerptitSeb <sebastien.chev@gmail.com>2025-05-11 14:01:46 +0200
commitb1eabd758349fafb92871254c34ff7e207b508be (patch)
tree1631b1c827fe67494d6e4dbc1c788b98f15256e9 /src/tools/callback.c
parent7a2d9967f5aba185ea641cee996310187002fa24 (diff)
downloadbox64-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.c173
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();