about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-07-08 14:26:07 +0200
committerptitSeb <sebastien.chev@gmail.com>2023-07-08 14:26:07 +0200
commitaa39a923ed05ac9851e954508b34c202b099f37e (patch)
tree265007381afe7c3405592100be6dec5f4e71569b /src
parent57b7729ea7ed8da819865cbfd9c5a52815ae627f (diff)
downloadbox64-aa39a923ed05ac9851e954508b34c202b099f37e.tar.gz
box64-aa39a923ed05ac9851e954508b34c202b099f37e.zip
Improved BOX64_MALLOC_HACK=2 and the glAleternate mecanism (help steam & heroic and other libcef based software)
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/arm64/dynarec_arm64_00.c4
-rwxr-xr-xsrc/dynarec/dynablock.c2
-rwxr-xr-xsrc/dynarec/dynarec.c41
-rwxr-xr-xsrc/dynarec/dynarec_native.c18
-rwxr-xr-xsrc/dynarec/dynarec_native_pass.c4
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_3.c4
-rwxr-xr-xsrc/emu/x64run.c1
-rwxr-xr-xsrc/include/bridge.h2
-rwxr-xr-xsrc/include/dynarec_native.h2
-rw-r--r--src/mallochook.c83
-rwxr-xr-xsrc/tools/bridge.c4
-rwxr-xr-xsrc/tools/gtkclass.c2
-rwxr-xr-xsrc/wrapped/wrappedgobject2.c6
-rwxr-xr-xsrc/wrapped/wrappedlibx11.c6
14 files changed, 74 insertions, 105 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index 3269ac1b..10d4b41b 100755
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -2477,11 +2477,11 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 INST_NAME("JMP Ib");
                 i32 = F8S;
             }
-            JUMP(addr+i32, 0);
+            JUMP((uintptr_t)getAlternate((void*)(addr+i32)), 0);
             if(dyn->insts[ninst].x64.jmp_insts==-1) {
                 // out of the block
                 fpu_purgecache(dyn, ninst, 1, x1, x2, x3);
-                jump_to_next(dyn, addr+i32, 0, ninst);
+                jump_to_next(dyn, (uintptr_t)getAlternate((void*)(addr+i32)), 0, ninst);
             } else {
                 // inside the block
                 CacheTransform(dyn, ninst, CHECK_CACHE(), x1, x2, x3);
diff --git a/src/dynarec/dynablock.c b/src/dynarec/dynablock.c
index a3e46c2b..787a387c 100755
--- a/src/dynarec/dynablock.c
+++ b/src/dynarec/dynablock.c
@@ -215,7 +215,7 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t
             mutex_unlock(&my_context->mutex_dyndump);
         return NULL;
     }
-    void* ret = FillBlock64(block, filladdr, is32bits);
+    void* ret = FillBlock64(block, filladdr, (addr==filladdr)?0:1, is32bits);
     if(!ret) {
         dynarec_log(LOG_DEBUG, "Fillblock of block %p for %p returned an error\n", block, (void*)addr);
         customFree(block);
diff --git a/src/dynarec/dynarec.c b/src/dynarec/dynarec.c
index 42cc582b..0aa12c58 100755
--- a/src/dynarec/dynarec.c
+++ b/src/dynarec/dynarec.c
@@ -37,29 +37,28 @@ void* LinkNext(x64emu_t* emu, uintptr_t addr, void* x2, uintptr_t* x3)
     }
     #endif
     void * jblock;
-    dynablock_t* block = DBGetBlock(emu, addr, 1, is32bits);
+    dynablock_t* block = NULL;
+    if(hasAlternate((void*)addr)) {
+        printf_log(LOG_DEBUG, "Jmp address has alternate: %p", (void*)addr);
+        if(box64_log<LOG_DEBUG) dynarec_log(LOG_INFO, "Jmp address has alternate: %p", (void*)addr);
+        uintptr_t old_addr = addr;
+        addr = (uintptr_t)getAlternate((void*)addr);    // set new address
+        R_RIP = addr;   // but also new RIP!
+        *x3 = addr; // and the RIP in x27 register
+        printf_log(LOG_DEBUG, " -> %p\n", (void*)addr);
+        block = DBAlternateBlock(emu, old_addr, addr, is32bits);
+    } else
+        block = DBGetBlock(emu, addr, 1, is32bits);
     if(!block) {
-        // no block, let link table as is...
-        if(hasAlternate((void*)addr)) {
-            printf_log(LOG_DEBUG, "Jmp address has alternate: %p", (void*)addr);
-            if(box64_log<LOG_DEBUG) dynarec_log(LOG_INFO, "Jmp address has alternate: %p", (void*)addr);
-            addr = (uintptr_t)getAlternate((void*)addr);    // set new address
-            R_RIP = addr;   // but also new RIP!
-            *x3 = addr; // and the RIP in x27 register
-            printf_log(LOG_DEBUG, " -> %p\n", (void*)addr);
-            block = DBGetBlock(emu, addr, 1, is32bits);
-        }
-        if(!block) {
-            #ifdef HAVE_TRACE
-            if(LOG_INFO<=box64_dynarec_log) {
-                dynablock_t* db = FindDynablockFromNativeAddress(x2-4);
-                elfheader_t* h = FindElfAddress(my_context, (uintptr_t)x2-4);
-                dynarec_log(LOG_INFO, "Warning, jumping to a no-block address %p from %p (db=%p, x64addr=%p(elf=%s))\n", (void*)addr, x2-4, db, db?(void*)getX64Address(db, (uintptr_t)x2-4):NULL, h?ElfName(h):"(none)");
-            }
-            #endif
-            //tableupdate(native_epilog, addr, table);
-            return native_epilog;
+        #ifdef HAVE_TRACE
+        if(LOG_INFO<=box64_dynarec_log) {
+            dynablock_t* db = FindDynablockFromNativeAddress(x2-4);
+            elfheader_t* h = FindElfAddress(my_context, (uintptr_t)x2-4);
+            dynarec_log(LOG_INFO, "Warning, jumping to a no-block address %p from %p (db=%p, x64addr=%p(elf=%s))\n", (void*)addr, x2-4, db, db?(void*)getX64Address(db, (uintptr_t)x2-4):NULL, h?ElfName(h):"(none)");
         }
+        #endif
+        //tableupdate(native_epilog, addr, table);
+        return native_epilog;
     }
     if(!block->done) {
         // not finished yet... leave linker
diff --git a/src/dynarec/dynarec_native.c b/src/dynarec/dynarec_native.c
index fd9023ff..3ed6e003 100755
--- a/src/dynarec/dynarec_native.c
+++ b/src/dynarec/dynarec_native.c
@@ -398,10 +398,10 @@ void CancelBlock64(int need_lock)
         mutex_unlock(&my_context->mutex_dyndump);
 }
 
-uintptr_t native_pass0(dynarec_native_t* dyn, uintptr_t addr, int is32bits);
-uintptr_t native_pass1(dynarec_native_t* dyn, uintptr_t addr, int is32bits);
-uintptr_t native_pass2(dynarec_native_t* dyn, uintptr_t addr, int is32bits);
-uintptr_t native_pass3(dynarec_native_t* dyn, uintptr_t addr, int is32bits);
+uintptr_t native_pass0(dynarec_native_t* dyn, uintptr_t addr, int alternate, int is32bits);
+uintptr_t native_pass1(dynarec_native_t* dyn, uintptr_t addr, int alternate, int is32bits);
+uintptr_t native_pass2(dynarec_native_t* dyn, uintptr_t addr, int alternate, int is32bits);
+uintptr_t native_pass3(dynarec_native_t* dyn, uintptr_t addr, int alternate, int is32bits);
 
 void* CreateEmptyBlock(dynablock_t* block, uintptr_t addr) {
     block->isize = 0;
@@ -426,7 +426,7 @@ void* CreateEmptyBlock(dynablock_t* block, uintptr_t addr) {
     return block;
 }
 
-void* FillBlock64(dynablock_t* block, uintptr_t addr, int is32bits) {
+void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bits) {
     /*
         A Block must have this layout:
 
@@ -463,7 +463,7 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int is32bits) {
     helper.cap = 128;
     helper.insts = (instruction_native_t*)dynaCalloc(helper.cap, sizeof(instruction_native_t));
     // pass 0, addresses, x64 jump addresses, overall size of the block
-    uintptr_t end = native_pass0(&helper, addr, is32bits);
+    uintptr_t end = native_pass0(&helper, addr, alternate, is32bits);
     // no need for next anymore
     dynaFree(helper.next);
     helper.next_sz = helper.next_cap = 0;
@@ -514,10 +514,10 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int is32bits) {
         pos = updateNeed(&helper, pos, 0);
 
     // pass 1, float optimisations, first pass for flags
-    native_pass1(&helper, addr, is32bits);
+    native_pass1(&helper, addr, alternate, is32bits);
     
     // pass 2, instruction size
-    native_pass2(&helper, addr, is32bits);
+    native_pass2(&helper, addr, alternate, is32bits);
     // keep size of instructions for signal handling
     size_t insts_rsize = (helper.insts_size+2)*sizeof(instsize_t);
     insts_rsize = (insts_rsize+7)&~7;   // round the size...
@@ -557,7 +557,7 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int is32bits) {
     helper.native_size = 0;
     helper.table64size = 0; // reset table64 (but not the cap)
     helper.insts_size = 0;  // reset
-    native_pass3(&helper, addr, is32bits);
+    native_pass3(&helper, addr, alternate, is32bits);
     // keep size of instructions for signal handling
     block->instsize = instsize;
     // ok, free the helper now
diff --git a/src/dynarec/dynarec_native_pass.c b/src/dynarec/dynarec_native_pass.c
index 18c0f543..8ce3540b 100755
--- a/src/dynarec/dynarec_native_pass.c
+++ b/src/dynarec/dynarec_native_pass.c
@@ -26,7 +26,7 @@
 #error No STEP defined
 #endif
 
-uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int is32bits)
+uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int is32bits)
 {
     int ok = 1;
     int ninst = 0;
@@ -46,7 +46,7 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int is32bits)
     fpu_reset(dyn);
     ARCH_INIT();
     int reset_n = -1;
-    dyn->last_ip = (dyn->insts && dyn->insts[0].pred_sz)?0:ip;  // RIP is always set at start of block unless there is a predecessor!
+    dyn->last_ip = (alternate || (dyn->insts && dyn->insts[0].pred_sz))?0:ip;  // RIP is always set at start of block unless there is a predecessor!
     int stopblock = 2+(FindElfAddress(my_context, addr)?0:1); // if block is in elf_memory, it can be extended with bligblocks==2, else it needs 3
     // ok, go now
     INIT;
diff --git a/src/dynarec/rv64/dynarec_rv64_00_3.c b/src/dynarec/rv64/dynarec_rv64_00_3.c
index bf14373c..a2744912 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_3.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_3.c
@@ -744,11 +744,11 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                 INST_NAME("JMP Ib");
                 i32 = F8S;
             }
-            JUMP(addr+i32, 0);
+            JUMP((uintptr_t)getAlternate((void*)(addr+i32)), 0);
             if(dyn->insts[ninst].x64.jmp_insts==-1) {
                 // out of the block
                 fpu_purgecache(dyn, ninst, 1, x1, x2, x3);
-                jump_to_next(dyn, addr+i32, 0, ninst);
+                jump_to_next(dyn, (uintptr_t)getAlternate((void*)(addr+i32)), 0, ninst);
             } else {
                 // inside the block
                 CacheTransform(dyn, ninst, CHECK_CACHE(), x1, x2, x3);
diff --git a/src/emu/x64run.c b/src/emu/x64run.c
index 98fc4564..6465ab5e 100755
--- a/src/emu/x64run.c
+++ b/src/emu/x64run.c
@@ -1644,6 +1644,7 @@ x64emurun:
         case 0xE9:                      /* JMP Id */
             tmp32s = F32S; // jmp is relative
             addr += tmp32s;
+            addr = (uintptr_t)getAlternate((void*)addr);
             STEP2
             break;
 
diff --git a/src/include/bridge.h b/src/include/bridge.h
index 77f4e41a..0c238089 100755
--- a/src/include/bridge.h
+++ b/src/include/bridge.h
@@ -13,7 +13,7 @@ void FreeBridge(bridge_t** bridge);
 uintptr_t AddBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N, const char* name);
 uintptr_t CheckBridged(bridge_t* bridge, void* fnc);
 uintptr_t AddCheckBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N, const char* name);
-uintptr_t AddAutomaticBridge(x64emu_t* emu, bridge_t* bridge, wrapper_t w, void* fnc, int N);
+uintptr_t AddAutomaticBridge(x64emu_t* emu, bridge_t* bridge, wrapper_t w, void* fnc, int N, const char* name);
 void* GetNativeFnc(uintptr_t fnc);
 void* GetNativeFncOrFnc(uintptr_t fnc);
 
diff --git a/src/include/dynarec_native.h b/src/include/dynarec_native.h
index a956f1cc..42366858 100755
--- a/src/include/dynarec_native.h
+++ b/src/include/dynarec_native.h
@@ -21,6 +21,6 @@ typedef struct instsize_s instsize_t;
 void addInst(instsize_t* insts, size_t* size, int x64_size, int native_size);
 
 void CancelBlock64(int need_lock);
-void* FillBlock64(dynablock_t* block, uintptr_t addr, int is32bits);
+void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bits);
 
 #endif //__DYNAREC_ARM_H_
\ No newline at end of file
diff --git a/src/mallochook.c b/src/mallochook.c
index d51a1416..fd382b82 100644
--- a/src/mallochook.c
+++ b/src/mallochook.c
@@ -187,6 +187,7 @@ EXPORT void* malloc(size_t l)
 }
 
 static uintptr_t real_free = 0;
+static uintptr_t real_realloc = 0;
 EXPORT void free(void* p)
 {
     if(malloc_hack_2 && p) {
@@ -210,15 +211,20 @@ EXPORT void* realloc(void* p, size_t s)
 {
     if(malloc_hack_2)
         if(getMmapped((uintptr_t)p)) {
-            // found! Will realloc using regular malloc then copy from old address as much as possible, but need to check size first
-            void* ret = box_malloc(s);
-            printf_log(LOG_DEBUG, "Malloc_Hack_2: hacking realloc(%p, %zu)", p, s);
-            while(s && !(getProtection((uintptr_t)p+s)&PROT_READ)) {if(s>box64_pagesize) s-=box64_pagesize; else s=0;}
-            memcpy(ret, p, s);
-            printf_log(LOG_DEBUG, " -> %p (copied %zu from old)\n", ret, s);
-            // Mmaped, free with original function
-            if(real_free)
-                RunFunctionFmt(my_context, real_free, "p", p);
+            void* ret = p;
+            if(real_realloc) {
+                ret = (void*)RunFunctionFmt(my_context, real_realloc, "pL", p, s);
+            } else {
+                // found! Will realloc using regular malloc then copy from old address as much as possible, but need to check size first
+                ret = box_malloc(s);
+                printf_log(LOG_DEBUG, "Malloc_Hack_2: hacking realloc(%p, %zu)", p, s);
+                while(s && !(getProtection((uintptr_t)p+s)&PROT_READ)) {if(s>box64_pagesize) s-=box64_pagesize; else s=0;}
+                memcpy(ret, p, s);
+                printf_log(LOG_DEBUG, " -> %p (copied %zu from old)\n", ret, s);
+                // Mmaped, free with original function
+                if(real_free)
+                    RunFunctionFmt(my_context, real_free, "p", p);
+            }
             return ret;
         }
     return box_realloc(p, s);
@@ -708,42 +714,15 @@ typedef struct simple_jmp_s {
 
 static void addRelocJmp(void* offs, void* where, size_t size, const char* name, elfheader_t* h)
 {
-    if(0 && malloc_hack_2 && !strcmp(name, "free")) {
-        if(!real_free /*&& !strcmp(name, "free")*/)
-            real_free = (uintptr_t)offs;
-        // a bridge jump is roughly 32 bytes
-        ForceUpdateSymbol(h->mapsymbols, name, (uintptr_t)where, 32);
-        ForceUpdateSymbol(h->weaksymbols, name, (uintptr_t)where, 32);
-        ForceUpdateSymbol(h->localsymbols, name, (uintptr_t)where, 32);
-    } else {
-        reloc_jmp_t r_jmp = {0};
-        simple_jmp_t s_jmp = {0};
-        size_t sz = 0;
-        intptr_t off64 = (intptr_t)where - ((intptr_t)offs+5);
-        void* p = NULL;
-        int32_t off32 = (int32_t)off64;
-        if(off32 == off64) {
-            s_jmp._e9 = 0xe9;
-            s_jmp.delta = (uint32_t)off32;
-            p = &s_jmp;
-            sz = sizeof(s_jmp);
-        } else {
-            r_jmp._ff = 0xff;
-            r_jmp._25 = 0x25;
-            r_jmp.addr = where;
-            p = &r_jmp;
-            sz = sizeof(r_jmp);
-        }
-        if(size>=sz)
-            memcpy(offs, p, sz);
-        else {
-            printf_log(LOG_INFO, "Warning, cannot redirect %s, too small %zu vs %zu\n", name, size, sz);
-            // use plan-B, it might be enough
-            ForceUpdateSymbol(h->mapsymbols, name, (uintptr_t)where, 32);
-            ForceUpdateSymbol(h->weaksymbols, name, (uintptr_t)where, 32);
-            ForceUpdateSymbol(h->localsymbols, name, (uintptr_t)where, 32);
-        }
+    if(malloc_hack_2 && !real_free && !strcmp(name, "free")) {
+        real_free = (uintptr_t)offs;
+    } else if(malloc_hack_2 && !real_realloc && !strcmp(name, "realloc")) {
+        real_realloc = (uintptr_t)offs;
     }
+    AddSymbol(h->mapsymbols, name, (uintptr_t)where, size, 1, NULL);
+    AddSymbol(h->mapsymbols, name, (uintptr_t)offs, size, 0, NULL);
+    AddSymbol(h->localsymbols, name, (uintptr_t)offs, size, 0, NULL);
+    addAlternate(offs, where);
 }
 
 void checkHookedSymbols(elfheader_t* h)
@@ -761,7 +740,7 @@ void checkHookedSymbols(elfheader_t* h)
             uintptr_t offs = h->DynSym[i].st_value + h->delta;
             size_t sz = h->DynSym[i].st_size;
             if(bind!=STB_LOCAL && bind!=STB_WEAK && sz>=sizeof(reloc_jmp_t)) {
-                #define GO(A, B) if(!strcmp(symname, #A)) ++hooked; else if(!strcmp(symname, "scalable_" #A)) ++hooked; else if(!strcmp(symname, "__TBB_internal_" #A)) ++hooked;
+                #define GO(A, B) if(!strcmp(symname, #A)) ++hooked; else if(!strcmp(symname, "__libc_" #A)) ++hooked;
                 #define GO2(A, B)
                 SUPER()
                 #undef GO
@@ -784,23 +763,13 @@ void checkHookedSymbols(elfheader_t* h)
             uintptr_t offs = h->DynSym[i].st_value + h->delta;
             size_t sz = h->DynSym[i].st_size;
             if(bind!=STB_LOCAL && bind!=STB_WEAK) {
-                #define GO(A, B) if(!strcmp(symname, "__libc_" #A)) {uintptr_t alt = AddCheckBridge(my_context->system, B, A, 0, #A); printf_log(LOG_DEBUG, "Redirecting %s function from %p (%s)\n", symname, (void*)offs, ElfName(h)); addRelocJmp((void*)offs, (void*)alt, sz, #A, h);}
-                #define GO2(A, B)
-                SUPER()
-                #undef GO
-                #undef GO2
-                #define GO(A, B) if(!strcmp(symname, "scalable_" #A)) {uintptr_t alt = AddCheckBridge(my_context->system, B, A, 0, #A); printf_log(LOG_DEBUG, "Redirecting %s function from %p (%s)\n", symname, (void*)offs, ElfName(h)); addRelocJmp((void*)offs, (void*)alt, sz, #A, h);}
-                #define GO2(A, B)
-                SUPER()
-                #undef GO
-                #undef GO2
-                #define GO(A, B) if(!strcmp(symname, "__TBB_internal_" #A)) {uintptr_t alt = AddCheckBridge(my_context->system, B, A, 0, #A); printf_log(LOG_DEBUG, "Redirecting %s function from %p (%s)\n", symname, (void*)offs, ElfName(h)); addRelocJmp((void*)offs, (void*)alt, sz, #A, h);}
+                #define GO(A, B) if(!strcmp(symname, "__libc_" #A)) {uintptr_t alt = AddCheckBridge(my_context->system, B, A, 0, "__libc_" #A); printf_log(LOG_DEBUG, "Redirecting %s function from %p (%s)\n", symname, (void*)offs, ElfName(h)); addRelocJmp((void*)offs, (void*)alt, sz, "__libc_" #A, h);}
                 #define GO2(A, B)
                 SUPER()
                 #undef GO
                 #undef GO2
                 #define GO(A, B) if(!strcmp(symname, #A)) {uintptr_t alt = AddCheckBridge(my_context->system, B, A, 0, #A); printf_log(LOG_DEBUG, "Redirecting %s function from %p (%s)\n", symname, (void*)offs, ElfName(h)); addRelocJmp((void*)offs, (void*)alt, sz, #A, h);}
-                #define GO2(A, B) if(!strcmp(symname, #A)) {uintptr_t alt = AddCheckBridge(my_context->system, B, my_##A, 0, #A); printf_log(LOG_DEBUG, "Redirecting %s function from %p (%s)\n", symname, (void*)offs, ElfName(h)); addRelocJmp((void*)offs, (void*)alt, sz, #A, h);}
+                #define GO2(A, B) if(!strcmp(symname, #A)) {uintptr_t alt = AddCheckBridge(my_context->system, B, my_##A, 0, "my_" #A); printf_log(LOG_DEBUG, "Redirecting %s function from %p (%s)\n", symname, (void*)offs, ElfName(h)); addRelocJmp((void*)offs, (void*)alt, sz, "my_" #A, h);}
                 SUPER()
                 #undef GO
                 #undef GO2
diff --git a/src/tools/bridge.c b/src/tools/bridge.c
index bace21ae..220e06a1 100755
--- a/src/tools/bridge.c
+++ b/src/tools/bridge.c
@@ -152,7 +152,7 @@ uintptr_t AddCheckBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N, const
     return ret;
 }
 
-uintptr_t AddAutomaticBridge(x64emu_t* emu, bridge_t* bridge, wrapper_t w, void* fnc, int N)
+uintptr_t AddAutomaticBridge(x64emu_t* emu, bridge_t* bridge, wrapper_t w, void* fnc, int N, const char* name)
 {
     (void)emu;
 
@@ -160,7 +160,7 @@ uintptr_t AddAutomaticBridge(x64emu_t* emu, bridge_t* bridge, wrapper_t w, void*
         return 0;
     uintptr_t ret = CheckBridged(bridge, fnc);
     if(!ret)
-        ret = AddBridge(bridge, w, fnc, N, NULL);
+        ret = AddBridge(bridge, w, fnc, N, name);
     if(!hasAlternate(fnc)) {
         printf_log(LOG_DEBUG, "Adding AutomaticBridge for %p to %p\n", fnc, (void*)ret);
         addAlternate(fnc, (void*)ret);
diff --git a/src/tools/gtkclass.c b/src/tools/gtkclass.c
index c41674e6..1e78450a 100755
--- a/src/tools/gtkclass.c
+++ b/src/tools/gtkclass.c
@@ -117,7 +117,7 @@ static void autobridge_##NAME##_##A(wrapper_t W, void* fct)         \
         return;                                                     \
     Dl_info info;                                                   \
     if(dladdr(fct, &info))                                          \
-        AddAutomaticBridge(thread_get_emu(), my_bridge, W, fct, 0); \
+        AddAutomaticBridge(thread_get_emu(), my_bridge, W, fct, 0, #NAME "_" #A); \
 }
 
 #define WRAPPER(A, NAME, RET, DEF, FMT, ...)        \
diff --git a/src/wrapped/wrappedgobject2.c b/src/wrapped/wrappedgobject2.c
index d1d6cd1c..9a9df389 100755
--- a/src/wrapped/wrappedgobject2.c
+++ b/src/wrapped/wrappedgobject2.c
@@ -128,7 +128,7 @@ static void signal_delete(my_signal_t* sig, void* b)
 
 static void addGObject2Alternate(library_t* lib)
 {
-    #define GO(A, W) AddAutomaticBridge(thread_get_emu(), lib->w.bridge, W, dlsym(lib->w.lib, #A), 0)
+    #define GO(A, W) AddAutomaticBridge(thread_get_emu(), lib->w.bridge, W, dlsym(lib->w.lib, #A), 0, #A)
     GO(g_cclosure_marshal_VOID__VOID,               vFppuppp);
     GO(g_cclosure_marshal_VOID__BOOLEAN,            vFppuppp);
     GO(g_cclosure_marshal_VOID__UCHAR,              vFppuppp);
@@ -174,7 +174,7 @@ static void addGObject2Alternate(library_t* lib)
     GO(g_cclosure_marshal_BOOLEAN__FLAGSv,          vFpppppip);
     GO(g_cclosure_marshal_BOOLEAN__BOXED_BOXEDv,    vFpppppip);
     #undef GO
-    #define GO(A, W) AddAutomaticBridge(thread_get_emu(), lib->w.bridge, W, A, 0)
+    #define GO(A, W) AddAutomaticBridge(thread_get_emu(), lib->w.bridge, W, A, 0, #A)
     GO(signal_cb, iFpppp);
     GO(signal_cb_swapped, iFpppp);
     GO(signal_cb_5, iFppppp);
@@ -346,7 +346,7 @@ static void* findMarshalFct(void* fct)
     #define GO(A) if(my_marshal_fct_##A == (uintptr_t)fct) return my_marshal_##A;
     SUPER()
     #undef GO
-    #define GO(A) if(my_marshal_fct_##A == 0) {AddAutomaticBridge(thread_get_emu(), my_lib->w.bridge, vFppuppp, my_marshal_##A, 0); my_marshal_fct_##A = (uintptr_t)fct; return my_marshal_##A; }
+    #define GO(A) if(my_marshal_fct_##A == 0) {AddAutomaticBridge(thread_get_emu(), my_lib->w.bridge, vFppuppp, my_marshal_##A, 0, #A); my_marshal_fct_##A = (uintptr_t)fct; return my_marshal_##A; }
     SUPER()
     #undef GO
     printf_log(LOG_NONE, "Warning, no more slot for gobject Closure Marshal callback\n");
diff --git a/src/wrapped/wrappedlibx11.c b/src/wrapped/wrappedlibx11.c
index 4b6a6463..12071a38 100755
--- a/src/wrapped/wrappedlibx11.c
+++ b/src/wrapped/wrappedlibx11.c
@@ -757,7 +757,7 @@ void BridgeImageFunc(x64emu_t *emu, XImage *img)
 
     #define GO(A, W) \
     fnc = CheckBridged(system, img->f.A); \
-    if(!fnc) fnc = AddAutomaticBridge(emu, system, W, img->f.A, 0); \
+    if(!fnc) fnc = AddAutomaticBridge(emu, system, W, img->f.A, 0, #A); \
     img->f.A = (W##_t)fnc;
 
     uintptr_t fnc;
@@ -1108,12 +1108,12 @@ EXPORT void* my_XOpenDisplay(x64emu_t* emu, void* d)
     #define GO(A, W)\
     if(dpy->A)      \
         if(!CheckBridged(system, dpy->A)) \
-            AddAutomaticBridge(emu, system, W, dpy->A, 0); \
+            AddAutomaticBridge(emu, system, W, dpy->A, 0, #A); \
 
     #define GO2(A, B, W) \
     if(dpy->A && dpy->A->B)  \
         if(!CheckBridged(system, dpy->A->B)) \
-            AddAutomaticBridge(emu, system, W, dpy->A->B, 0); \
+            AddAutomaticBridge(emu, system, W, dpy->A->B, 0, #B "_" #A); \
 
 
     GO2(free_funcs, atoms, vFp)