about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2022-03-04 14:41:17 +0100
committerptitSeb <sebastien.chev@gmail.com>2022-03-04 14:41:17 +0100
commit9d65062d35381320c4b0b82b012936ecf97f8ba3 (patch)
treea5666b024e6f8b67305c305fb8a7146b6ecd6cec
parent2bd78e25fd992f0e1f4f98d1ab0c2027d60def7f (diff)
downloadbox64-9d65062d35381320c4b0b82b012936ecf97f8ba3.tar.gz
box64-9d65062d35381320c4b0b82b012936ecf97f8ba3.zip
Various changes and improvement centered around steam (but still not good enough)
-rwxr-xr-xCMakeLists.txt4
-rwxr-xr-xsrc/elfs/elfloader.c14
-rwxr-xr-xsrc/elfs/elfloader_private.h1
-rwxr-xr-xsrc/include/box64context.h2
-rwxr-xr-xsrc/include/elfloader.h2
-rwxr-xr-xsrc/include/librarian.h2
-rwxr-xr-xsrc/librarian/librarian.c38
-rwxr-xr-xsrc/librarian/library.c64
-rwxr-xr-xsrc/librarian/library_private.h16
-rwxr-xr-xsrc/library_list.h2
-rwxr-xr-xsrc/main.c1
-rw-r--r--src/wrapped/generated/functions_list.txt21
-rw-r--r--src/wrapped/generated/wrappedlibctypes.h6
-rw-r--r--src/wrapped/generated/wrappedlibusb1defs.h8
-rw-r--r--src/wrapped/generated/wrappedlibusb1types.h24
-rw-r--r--src/wrapped/generated/wrappedlibusb1undefs.h8
-rw-r--r--src/wrapped/generated/wrapper.c19
-rw-r--r--src/wrapped/generated/wrapper.h7
-rwxr-xr-xsrc/wrapped/wrappedlibc.c68
-rwxr-xr-xsrc/wrapped/wrappedlibc_private.h8
-rwxr-xr-xsrc/wrapped/wrappedlibdl.c58
-rwxr-xr-xsrc/wrapped/wrappedlibusb1.c196
-rwxr-xr-xsrc/wrapped/wrappedlibusb1_private.h85
23 files changed, 614 insertions, 40 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 051cf2ac..2d41fe79 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -311,6 +311,7 @@ set(WRAPPEDS
     "${BOX64_ROOT}/src/wrapped/wrappedlibssl.c"
     "${BOX64_ROOT}/src/wrapped/wrappedlibtinfo.c"
     "${BOX64_ROOT}/src/wrapped/wrappedlibtinfo6.c"
+    "${BOX64_ROOT}/src/wrapped/wrappedlibusb1.c"
     "${BOX64_ROOT}/src/wrapped/wrappedlibuuid.c"
     "${BOX64_ROOT}/src/wrapped/wrappedlibvorbis.c"
     "${BOX64_ROOT}/src/wrapped/wrappedlibx11.c"
@@ -520,7 +521,8 @@ add_executable(${BOX64} ${ELFLOADER_SRC} ${WRAPPEDS} "${BOX64_ROOT}/src/git_head
 set_target_properties(${BOX64} PROPERTIES ENABLE_EXPORTS ON)
 add_dependencies(${BOX64} WRAPPERS)
 #add_dependencies(${BOX64} PRINTER)
-target_link_libraries(${BOX64} c m dl rt pthread)
+#target_link_libraries(${BOX64} c m dl rt pthread resolv)
+set_target_properties(${BOX64} PROPERTIES LINK_FLAGS "-Wl,--no-as-need -lc -lm -ldl -lrt -lpthread -lresolv -Wl,--as-need")
 if(DYNAREC)
     target_link_libraries(${BOX64} dynarec)
 endif()
diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c
index afd9002d..c5f59375 100755
--- a/src/elfs/elfloader.c
+++ b/src/elfs/elfloader.c
@@ -1081,6 +1081,20 @@ int LoadNeededLibs(elfheader_t* h, lib_t *maplib, needed_libs_t* neededlibs, lib
                 rpath = tmp;
                 free(origin);
             }
+            while(strstr(rpath, "${PLATFORM}")) {
+                char* platform = strdup("x86_64");
+                char* p = strrchr(platform, '/');
+                if(p) *p = '\0';    // remove file name to have only full path, without last '/'
+                char* tmp = (char*)calloc(1, strlen(rpath)-strlen("${PLATFORM}")+strlen(platform)+1);
+                p = strstr(rpath, "${PLATFORM}");
+                memcpy(tmp, rpath, p-rpath);
+                strcat(tmp, platform);
+                strcat(tmp, p+strlen("${PLATFORM}"));
+                if(rpath!=rpathref)
+                    free(rpath);
+                rpath = tmp;
+                free(platform);
+            }
             if(strchr(rpath, '$')) {
                 printf_log(LOG_INFO, "BOX64: Warning, RPATH with $ variable not supported yet (%s)\n", rpath);
             } else {
diff --git a/src/elfs/elfloader_private.h b/src/elfs/elfloader_private.h
index 97319305..c1c34d0c 100755
--- a/src/elfs/elfloader_private.h
+++ b/src/elfs/elfloader_private.h
@@ -8,7 +8,6 @@ typedef struct dynablocklist_s dynablocklist_t;
 typedef struct library_s library_t;
 typedef struct needed_libs_s needed_libs_t;
 
-#include <pthread.h>
 #include <elf.h>
 #include "elfloader.h"
 
diff --git a/src/include/box64context.h b/src/include/box64context.h
index 9d660664..371fdce3 100755
--- a/src/include/box64context.h
+++ b/src/include/box64context.h
@@ -15,6 +15,7 @@ typedef struct bridge_s bridge_t;
 typedef struct dlprivate_s dlprivate_t;
 typedef struct kh_symbolmap_s kh_symbolmap_t;
 typedef struct library_s library_t;
+typedef struct linkmap_s linkmap_t;
 typedef struct kh_threadstack_s kh_threadstack_t;
 typedef struct atfork_fnc_s {
     uintptr_t prepare;
@@ -154,6 +155,7 @@ typedef struct box64context_s {
     library_t           *pulse;
     library_t           *d3dadapter9;
     library_t           *libglu;
+    linkmap_t           *linkmap;
 
     int                 deferedInit;
     elfheader_t         **deferedInitList;
diff --git a/src/include/elfloader.h b/src/include/elfloader.h
index 4e06546b..86efe061 100755
--- a/src/include/elfloader.h
+++ b/src/include/elfloader.h
@@ -64,4 +64,6 @@ int SameVersionnedSymbol(const char* name1, int ver1, const char* vername1, cons
 
 void* GetNativeSymbolUnversionned(void* lib, const char* name);
 
+void AddMainElfToLinkmap(elfheader_t* lib);
+
 #endif //__ELF_LOADER_H_
diff --git a/src/include/librarian.h b/src/include/librarian.h
index a135edf5..d2f0740c 100755
--- a/src/include/librarian.h
+++ b/src/include/librarian.h
@@ -37,7 +37,7 @@ int GetNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, u
 elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, const char* vername);
 int IsGlobalNoWeakSymbolInNative(lib_t *maplib, const char* name, int version, const char* vername);
 
-const char* FindSymbolName(lib_t *maplib, void* p, void** start, uint64_t* sz, const char** libname, void** base);
+const char* FindSymbolName(lib_t *maplib, void* p, void** start, uint64_t* sz, const char** libname, void** base, library_t** lib);
 
 void AddOffsetSymbol(lib_t *maplib, void* offs, const char* name);
 const char* GetNameOffset(lib_t *maplib, void* offs);
diff --git a/src/librarian/librarian.c b/src/librarian/librarian.c
index b9f1be5a..a0419132 100755
--- a/src/librarian/librarian.c
+++ b/src/librarian/librarian.c
@@ -285,6 +285,19 @@ int AddNeededLib_add(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib
         printf_log(LOG_DEBUG, "Failure to Add lib => fail\n");
         return 1;
     }
+
+    if (lib->type == 1) {
+        // Need to add library to the linkmap (put here so the link is ordered)
+        linkmap_t *lm = addLinkMapLib(lib);
+        if(!lm) {
+            // Crashed already
+            printf_log(LOG_DEBUG, "Failure to add lib linkmap\n");
+            return 1;
+        }
+        lm->l_addr = (Elf64_Addr)GetBaseAddress(my_context->elfs[lib->priv.n.elf_index]);
+        lm->l_name = lib->name;
+        lm->l_ld = GetDynamicSection(my_context->elfs[lib->priv.n.elf_index]);
+    }
     return 0;
 }
 
@@ -588,7 +601,7 @@ int GetNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, u
     }
     return 0;
 }
-const char* FindSymbolName(lib_t *maplib, void* p, void** start, uint64_t* sz, const char** libname, void** base)
+const char* FindSymbolName(lib_t *maplib, void* p, void** start, uint64_t* sz, const char** libname, void** base, library_t** lib)
 {
     // first, search in self...
     const char* ret = NULL;
@@ -597,8 +610,7 @@ const char* FindSymbolName(lib_t *maplib, void* p, void** start, uint64_t* sz, c
     elfheader_t* h = FindElfAddress(my_context, (uintptr_t)p);
     if(h) {
         ret = FindNearestSymbolName(h, p, &offs, &size);
-    }
-    if(h) {
+
         if(start)
             *start = (void*)offs;
         if(sz)
@@ -607,6 +619,26 @@ const char* FindSymbolName(lib_t *maplib, void* p, void** start, uint64_t* sz, c
             *libname = ElfName(h);
         if(base)
             *base = GetBaseAddress(h);
+        if(lib) {
+            if(h == my_context->elfs[0])
+                *lib = NULL;    // main elf
+            else {
+                for(int i=0; i<my_context->maplib->libsz; ++i) {
+                    int idx = GetElfIndex(my_context->maplib->libraries[i]);
+                    if((idx!=-1) && (my_context->elfs[idx]==h)) {
+                        *lib = my_context->maplib->libraries[i];
+                        return ret;
+                    }
+                }
+                for(int i=0; i<my_context->local_maplib->libsz; ++i) {
+                    int idx = GetElfIndex(my_context->local_maplib->libraries[i]);
+                    if((idx!=-1) && (my_context->elfs[idx]==h)) {
+                        *lib = my_context->local_maplib->libraries[i];
+                        return ret;
+                    }
+                }
+            }
+        }
         return ret;
     }
     // TODO: find if cyclic references exists (should also fix MapLibAddMapLib)
diff --git a/src/librarian/library.c b/src/librarian/library.c
index 647d014c..e390ebe6 100755
--- a/src/librarian/library.c
+++ b/src/librarian/library.c
@@ -9,6 +9,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 #include <errno.h>
+#include <link.h>
 
 #include "debug.h"
 #include "library.h"
@@ -191,7 +192,9 @@ static void initNativeLib(library_t *lib, box64context_t* context) {
         if(strcmp(lib->name, wrappedlibs[i].name)==0) {
             if(wrappedlibs[i].init(lib, context)) {
                 // error!
-                printf_log(LOG_NONE, "Error initializing native %s (last dlerror is %s)\n", lib->name, dlerror());
+                const char* error_str = dlerror();
+                if(error_str)   // don't print the message if there is no error string from last error
+                    printf_log(LOG_NONE, "Error initializing native %s (last dlerror is %s)\n", lib->name, error_str);
                 return; // non blocker...
             }
             printf_log(LOG_INFO, "Using native(wrapped) %s\n", lib->name);
@@ -207,6 +210,20 @@ static void initNativeLib(library_t *lib, box64context_t* context) {
                 printf_log(LOG_NONE, "Error: loading a needed libs in elf %s\n", lib->name);
                 return;
             }
+
+            linkmap_t *lm = addLinkMapLib(lib);
+            if(!lm) {
+                // Crashed already
+                printf_log(LOG_DEBUG, "Failure to add lib %s linkmap\n", lib->name);
+                break;
+            }
+            struct link_map real_lm;
+            if(dlinfo(lib->priv.w.lib, RTLD_DI_LINKMAP, &real_lm)) {
+                printf_log(LOG_DEBUG, "Failed to dlinfo lib %s\n", lib->name);
+            }
+            lm->l_addr = real_lm.l_addr;
+            lm->l_name = real_lm.l_name;
+            lm->l_ld = real_lm.l_ld;
             break;
         }
     }
@@ -836,3 +853,48 @@ lib_t* GetMaplib(library_t* lib)
         return NULL;
     return lib->maplib;
 }
+
+linkmap_t* getLinkMapLib(library_t* lib)
+{
+    linkmap_t* lm = my_context->linkmap;
+    while(lm) {
+        if(lm->l_lib == lib)
+            return lm;
+        lm = lm->l_next;
+    }
+    return NULL;
+}
+linkmap_t* addLinkMapLib(library_t* lib)
+{
+    if(!my_context->linkmap) {
+        my_context->linkmap = (linkmap_t*)calloc(1, sizeof(linkmap_t));
+        my_context->linkmap->l_lib = lib;
+        return my_context->linkmap;
+    }
+    linkmap_t* lm = my_context->linkmap;
+    while(lm->l_next)
+        lm = lm->l_next;
+    lm->l_next = (linkmap_t*)calloc(1, sizeof(linkmap_t));
+    lm->l_next->l_lib = lib;
+    lm->l_next->l_prev = lm;
+    return lm->l_next;
+}
+void removeLinkMapLib(library_t* lib)
+{
+    linkmap_t* lm = getLinkMapLib(lib);
+    if(!lm) return;
+    if(lm->l_next)
+        lm->l_next->l_prev = lm->l_prev;
+    if(lm->l_prev)
+        lm->l_prev->l_next = lm->l_next;
+    free(lm);
+}
+
+void AddMainElfToLinkmap(elfheader_t* elf)
+{
+    linkmap_t* lm = addLinkMapLib(NULL);    // main elf will have a null lib link
+
+    lm->l_addr = (Elf64_Addr)GetBaseAddress(elf);
+    lm->l_name = my_context->fullpath;
+    lm->l_ld = GetDynamicSection(elf);
+}
diff --git a/src/librarian/library_private.h b/src/librarian/library_private.h
index ebbe1529..9e1d3381 100755
--- a/src/librarian/library_private.h
+++ b/src/librarian/library_private.h
@@ -1,6 +1,7 @@
 #ifndef __LIBRARY_PRIVATE_H_
 #define __LIBRARY_PRIVATE_H_
 #include <stdint.h>
+#include <elf.h>
 
 #include "custommem.h"
 #include "khash.h"
@@ -100,4 +101,19 @@ typedef struct map_onedata_s {
 
 int getSymbolInMaps(library_t *lib, const char* name, int noweak, uintptr_t *addr, uintptr_t *size, int version, const char* vername, int local);  // Add bridges to functions
 
+typedef struct linkmap_s {
+    // actual struct link_map
+    Elf64_Addr  l_addr;
+    char*       l_name;
+    Elf64_Dyn*  l_ld;
+    struct linkmap_s *l_next, *l_prev;
+    // custom
+    library_t*  l_lib;
+
+} linkmap_t;
+
+linkmap_t* getLinkMapLib(library_t* lib);
+linkmap_t* addLinkMapLib(library_t* lib);
+void removeLinkMapLib(library_t* lib);
+
 #endif //__LIBRARY_PRIVATE_H_
diff --git a/src/library_list.h b/src/library_list.h
index a93f8119..9f6203dc 100755
--- a/src/library_list.h
+++ b/src/library_list.h
@@ -134,7 +134,7 @@ GO("libbz2.so.1", bz2)
 GO("liblzma.so.5", lzma)
 GO("libSM.so.6", libsm)
 GO("libICE.so.6", libice)
-//GO("libusb-1.0.so.0", libusb1)
+GO("libusb-1.0.so.0", libusb1)
 GO("libncursesw.so.5", libncursesw)
 GO("libncursesw.so.6", libncursesw6)
 GO("libform.so.5", libform)
diff --git a/src/main.c b/src/main.c
index 316c31af..f6bd9538 100755
--- a/src/main.c
+++ b/src/main.c
@@ -1260,6 +1260,7 @@ int main(int argc, const char **argv, const char **env) {
         dynarec_wine_prereserve();
         #endif
     }
+    AddMainElfToLinkmap(elf_header);
     // pre-load lib if needed
     if(ld_preload.size) {
         if(AddNeededLib(NULL, NULL, NULL, 0, 0, (const char**)ld_preload.paths, ld_preload.size, my_context, emu)) {
diff --git a/src/wrapped/generated/functions_list.txt b/src/wrapped/generated/functions_list.txt
index 25f672bb..435c44db 100644
--- a/src/wrapped/generated/functions_list.txt
+++ b/src/wrapped/generated/functions_list.txt
@@ -376,6 +376,7 @@
 #() iFpip
 #() iFpIi
 #() iFpII
+#() iFpCp
 #() iFpui
 #() iFpuu
 #() iFpuU
@@ -513,6 +514,7 @@
 #() pFpip
 #() pFpCC
 #() pFpCu
+#() pFpWW
 #() pFpui
 #() pFpuu
 #() pFpuL
@@ -732,6 +734,7 @@
 #() iFpipV
 #() iFpIip
 #() iFpCCC
+#() iFpCpi
 #() iFpWWu
 #() iFpuwp
 #() iFpuiL
@@ -778,6 +781,7 @@
 #() iFppLL
 #() iFppLp
 #() iFpppi
+#() iFpppC
 #() iFpppu
 #() iFpppU
 #() iFpppL
@@ -1377,6 +1381,7 @@
 #() iFpippip
 #() iFpipppL
 #() iFpipppp
+#() iFpCpipu
 #() iFpWpppp
 #() iFpuiCpp
 #() iFpuippp
@@ -1723,6 +1728,7 @@
 #() iFuipuuluf
 #() iFuuuuuuuu
 #() iFullfpppp
+#() iFpCCWWpWu
 #() iFpWCuWCuu
 #() iFpWWipppp
 #() iFpuiipppp
@@ -1887,6 +1893,7 @@
 #() vFppuuuuiiuu
 #() vFppdddddddd
 #() vFpppppppppp
+#() iFEpiiiiippp
 #() iFEpupppLppL
 #() iFEppppppipp
 #() iFEppppppppp
@@ -2645,6 +2652,7 @@ wrappedlibc:
   - _ITM_registerTMCloneTable
 - vFpp:
   - __register_frame_info
+  - tdestroy
 - vFpV:
   - warn
   - warnx
@@ -2747,6 +2755,8 @@ wrappedlibc:
   - readlink
 - pFpip:
   - fts_open
+- pFppp:
+  - tsearch
 - vFiipV:
   - __syslog_chk
 - vFiipA:
@@ -2812,6 +2822,9 @@ wrappedlibc:
 - iFpLiLpV:
   - __snprintf_chk
   - __swprintf_chk
+- iFpppppp:
+  - posix_spawn
+  - posix_spawnp
 - pFpLiiil:
   - mmap
   - mmap64
@@ -3078,6 +3091,14 @@ wrappedlibtinfo:
 wrappedlibtinfo6:
 - iFpip:
   - tputs
+wrappedlibusb1:
+- iFp:
+  - libusb_cancel_transfer
+  - libusb_submit_transfer
+- pFi:
+  - libusb_alloc_transfer
+- iFpiiiiippp:
+  - libusb_hotplug_register_callback
 wrappedlibuuid:
 wrappedlibvorbis:
 wrappedlibx11:
diff --git a/src/wrapped/generated/wrappedlibctypes.h b/src/wrapped/generated/wrappedlibctypes.h
index 688beb6c..9fa403f3 100644
--- a/src/wrapped/generated/wrappedlibctypes.h
+++ b/src/wrapped/generated/wrappedlibctypes.h
@@ -49,6 +49,7 @@ typedef int64_t (*iFppA_t)(void*, void*, va_list);
 typedef int64_t (*iFpOu_t)(void*, int32_t, uint64_t);
 typedef intptr_t (*lFppL_t)(void*, void*, uintptr_t);
 typedef void* (*pFpip_t)(void*, int64_t, void*);
+typedef void* (*pFppp_t)(void*, void*, void*);
 typedef void (*vFiipV_t)(int64_t, int64_t, void*, ...);
 typedef void (*vFiipA_t)(int64_t, int64_t, void*, va_list);
 typedef void (*vFpLLp_t)(void*, uintptr_t, uintptr_t, void*);
@@ -74,6 +75,7 @@ typedef void* (*pFpLLiN_t)(void*, uintptr_t, uintptr_t, int64_t, ...);
 typedef void* (*pFppLLp_t)(void*, void*, uintptr_t, uintptr_t, void*);
 typedef void* (*pFpppLp_t)(void*, void*, void*, uintptr_t, void*);
 typedef int64_t (*iFpLiLpV_t)(void*, uintptr_t, int64_t, uintptr_t, void*, ...);
+typedef int64_t (*iFpppppp_t)(void*, void*, void*, void*, void*, void*);
 typedef void* (*pFpLiiil_t)(void*, uintptr_t, int64_t, int64_t, int64_t, intptr_t);
 typedef int64_t (*iFpippppp_t)(void*, int64_t, void*, void*, void*, void*, void*);
 
@@ -102,6 +104,7 @@ typedef int64_t (*iFpippppp_t)(void*, int64_t, void*, void*, void*, void*, void*
 	GO(siglongjmp, vFpi_t) \
 	GO(_ITM_registerTMCloneTable, vFpu_t) \
 	GO(__register_frame_info, vFpp_t) \
+	GO(tdestroy, vFpp_t) \
 	GO(warn, vFpV_t) \
 	GO(warnx, vFpV_t) \
 	GO(__sigsetjmp, iFpi_t) \
@@ -178,6 +181,7 @@ typedef int64_t (*iFpippppp_t)(void*, int64_t, void*, void*, void*, void*, void*
 	GO(open64, iFpOu_t) \
 	GO(readlink, lFppL_t) \
 	GO(fts_open, pFpip_t) \
+	GO(tsearch, pFppp_t) \
 	GO(__syslog_chk, vFiipV_t) \
 	GO(__vsyslog_chk, vFiipA_t) \
 	GO(qsort, vFpLLp_t) \
@@ -218,6 +222,8 @@ typedef int64_t (*iFpippppp_t)(void*, int64_t, void*, void*, void*, void*, void*
 	GO(lsearch, pFpppLp_t) \
 	GO(__snprintf_chk, iFpLiLpV_t) \
 	GO(__swprintf_chk, iFpLiLpV_t) \
+	GO(posix_spawn, iFpppppp_t) \
+	GO(posix_spawnp, iFpppppp_t) \
 	GO(mmap, pFpLiiil_t) \
 	GO(mmap64, pFpLiiil_t) \
 	GO(__libc_start_main, iFpippppp_t)
diff --git a/src/wrapped/generated/wrappedlibusb1defs.h b/src/wrapped/generated/wrappedlibusb1defs.h
new file mode 100644
index 00000000..1a892ff8
--- /dev/null
+++ b/src/wrapped/generated/wrappedlibusb1defs.h
@@ -0,0 +1,8 @@
+/*******************************************************************
+ * File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
+ *******************************************************************/
+#ifndef __wrappedlibusb1DEFS_H_
+#define __wrappedlibusb1DEFS_H_
+
+
+#endif // __wrappedlibusb1DEFS_H_
diff --git a/src/wrapped/generated/wrappedlibusb1types.h b/src/wrapped/generated/wrappedlibusb1types.h
new file mode 100644
index 00000000..8450870d
--- /dev/null
+++ b/src/wrapped/generated/wrappedlibusb1types.h
@@ -0,0 +1,24 @@
+/*******************************************************************
+ * File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
+ *******************************************************************/
+#ifndef __wrappedlibusb1TYPES_H_
+#define __wrappedlibusb1TYPES_H_
+
+#ifndef LIBNAME
+#error You should only #include this file inside a wrapped*.c file
+#endif
+#ifndef ADDED_FUNCTIONS
+#define ADDED_FUNCTIONS() 
+#endif
+
+typedef int64_t (*iFp_t)(void*);
+typedef void* (*pFi_t)(int64_t);
+typedef int64_t (*iFpiiiiippp_t)(void*, int64_t, int64_t, int64_t, int64_t, int64_t, void*, void*, void*);
+
+#define SUPER() ADDED_FUNCTIONS() \
+	GO(libusb_cancel_transfer, iFp_t) \
+	GO(libusb_submit_transfer, iFp_t) \
+	GO(libusb_alloc_transfer, pFi_t) \
+	GO(libusb_hotplug_register_callback, iFpiiiiippp_t)
+
+#endif // __wrappedlibusb1TYPES_H_
diff --git a/src/wrapped/generated/wrappedlibusb1undefs.h b/src/wrapped/generated/wrappedlibusb1undefs.h
new file mode 100644
index 00000000..7352fe1e
--- /dev/null
+++ b/src/wrapped/generated/wrappedlibusb1undefs.h
@@ -0,0 +1,8 @@
+/*******************************************************************
+ * File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
+ *******************************************************************/
+#ifndef __wrappedlibusb1UNDEFS_H_
+#define __wrappedlibusb1UNDEFS_H_
+
+
+#endif // __wrappedlibusb1UNDEFS_H_
diff --git a/src/wrapped/generated/wrapper.c b/src/wrapped/generated/wrapper.c
index 0afca20a..0ab204a9 100644
--- a/src/wrapped/generated/wrapper.c
+++ b/src/wrapped/generated/wrapper.c
@@ -410,6 +410,7 @@ typedef int64_t (*iFpiL_t)(void*, int64_t, uintptr_t);
 typedef int64_t (*iFpip_t)(void*, int64_t, void*);
 typedef int64_t (*iFpIi_t)(void*, int64_t, int64_t);
 typedef int64_t (*iFpII_t)(void*, int64_t, int64_t);
+typedef int64_t (*iFpCp_t)(void*, uint8_t, void*);
 typedef int64_t (*iFpui_t)(void*, uint64_t, int64_t);
 typedef int64_t (*iFpuu_t)(void*, uint64_t, uint64_t);
 typedef int64_t (*iFpuU_t)(void*, uint64_t, uint64_t);
@@ -547,6 +548,7 @@ typedef void* (*pFpiL_t)(void*, int64_t, uintptr_t);
 typedef void* (*pFpip_t)(void*, int64_t, void*);
 typedef void* (*pFpCC_t)(void*, uint8_t, uint8_t);
 typedef void* (*pFpCu_t)(void*, uint8_t, uint64_t);
+typedef void* (*pFpWW_t)(void*, uint16_t, uint16_t);
 typedef void* (*pFpui_t)(void*, uint64_t, int64_t);
 typedef void* (*pFpuu_t)(void*, uint64_t, uint64_t);
 typedef void* (*pFpuL_t)(void*, uint64_t, uintptr_t);
@@ -766,6 +768,7 @@ typedef int64_t (*iFpipp_t)(void*, int64_t, void*, void*);
 typedef int64_t (*iFpipV_t)(void*, int64_t, void*, void*);
 typedef int64_t (*iFpIip_t)(void*, int64_t, int64_t, void*);
 typedef int64_t (*iFpCCC_t)(void*, uint8_t, uint8_t, uint8_t);
+typedef int64_t (*iFpCpi_t)(void*, uint8_t, void*, int64_t);
 typedef int64_t (*iFpWWu_t)(void*, uint16_t, uint16_t, uint64_t);
 typedef int64_t (*iFpuwp_t)(void*, uint64_t, int16_t, void*);
 typedef int64_t (*iFpuiL_t)(void*, uint64_t, int64_t, uintptr_t);
@@ -812,6 +815,7 @@ typedef int64_t (*iFppLi_t)(void*, void*, uintptr_t, int64_t);
 typedef int64_t (*iFppLL_t)(void*, void*, uintptr_t, uintptr_t);
 typedef int64_t (*iFppLp_t)(void*, void*, uintptr_t, void*);
 typedef int64_t (*iFpppi_t)(void*, void*, void*, int64_t);
+typedef int64_t (*iFpppC_t)(void*, void*, void*, uint8_t);
 typedef int64_t (*iFpppu_t)(void*, void*, void*, uint64_t);
 typedef int64_t (*iFpppU_t)(void*, void*, void*, uint64_t);
 typedef int64_t (*iFpppL_t)(void*, void*, void*, uintptr_t);
@@ -1411,6 +1415,7 @@ typedef int64_t (*iFpipipi_t)(void*, int64_t, void*, int64_t, void*, int64_t);
 typedef int64_t (*iFpippip_t)(void*, int64_t, void*, void*, int64_t, void*);
 typedef int64_t (*iFpipppL_t)(void*, int64_t, void*, void*, void*, uintptr_t);
 typedef int64_t (*iFpipppp_t)(void*, int64_t, void*, void*, void*, void*);
+typedef int64_t (*iFpCpipu_t)(void*, uint8_t, void*, int64_t, void*, uint64_t);
 typedef int64_t (*iFpWpppp_t)(void*, uint16_t, void*, void*, void*, void*);
 typedef int64_t (*iFpuiCpp_t)(void*, uint64_t, int64_t, uint8_t, void*, void*);
 typedef int64_t (*iFpuippp_t)(void*, uint64_t, int64_t, void*, void*, void*);
@@ -1757,6 +1762,7 @@ typedef int64_t (*iFiiupiupi_t)(int64_t, int64_t, uint64_t, void*, int64_t, uint
 typedef int64_t (*iFuipuuluf_t)(uint64_t, int64_t, void*, uint64_t, uint64_t, intptr_t, uint64_t, float);
 typedef int64_t (*iFuuuuuuuu_t)(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t);
 typedef int64_t (*iFullfpppp_t)(uint64_t, intptr_t, intptr_t, float, void*, void*, void*, void*);
+typedef int64_t (*iFpCCWWpWu_t)(void*, uint8_t, uint8_t, uint16_t, uint16_t, void*, uint16_t, uint64_t);
 typedef int64_t (*iFpWCuWCuu_t)(void*, uint16_t, uint8_t, uint64_t, uint16_t, uint8_t, uint64_t, uint64_t);
 typedef int64_t (*iFpWWipppp_t)(void*, uint16_t, uint16_t, int64_t, void*, void*, void*, void*);
 typedef int64_t (*iFpuiipppp_t)(void*, uint64_t, int64_t, int64_t, void*, void*, void*, void*);
@@ -1921,6 +1927,7 @@ typedef void (*vFppipppiiii_t)(void*, void*, int64_t, void*, void*, void*, int64
 typedef void (*vFppuuuuiiuu_t)(void*, void*, uint64_t, uint64_t, uint64_t, uint64_t, int64_t, int64_t, uint64_t, uint64_t);
 typedef void (*vFppdddddddd_t)(void*, void*, double, double, double, double, double, double, double, double);
 typedef void (*vFpppppppppp_t)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
+typedef int64_t (*iFEpiiiiippp_t)(x64emu_t*, void*, int64_t, int64_t, int64_t, int64_t, int64_t, void*, void*, void*);
 typedef int64_t (*iFEpupppLppL_t)(x64emu_t*, void*, uint64_t, void*, void*, void*, uintptr_t, void*, void*, uintptr_t);
 typedef int64_t (*iFEppppppipp_t)(x64emu_t*, void*, void*, void*, void*, void*, void*, int64_t, void*, void*);
 typedef int64_t (*iFEppppppppp_t)(x64emu_t*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
@@ -2456,6 +2463,7 @@ void iFpiL(x64emu_t *emu, uintptr_t fcn) { iFpiL_t fn = (iFpiL_t)fcn; R_RAX=(int
 void iFpip(x64emu_t *emu, uintptr_t fcn) { iFpip_t fn = (iFpip_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (int64_t)R_RSI, (void*)R_RDX); }
 void iFpIi(x64emu_t *emu, uintptr_t fcn) { iFpIi_t fn = (iFpIi_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (int64_t)R_RSI, (int64_t)R_RDX); }
 void iFpII(x64emu_t *emu, uintptr_t fcn) { iFpII_t fn = (iFpII_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (int64_t)R_RSI, (int64_t)R_RDX); }
+void iFpCp(x64emu_t *emu, uintptr_t fcn) { iFpCp_t fn = (iFpCp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint8_t)R_RSI, (void*)R_RDX); }
 void iFpui(x64emu_t *emu, uintptr_t fcn) { iFpui_t fn = (iFpui_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint64_t)R_RSI, (int64_t)R_RDX); }
 void iFpuu(x64emu_t *emu, uintptr_t fcn) { iFpuu_t fn = (iFpuu_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint64_t)R_RSI, (uint64_t)R_RDX); }
 void iFpuU(x64emu_t *emu, uintptr_t fcn) { iFpuU_t fn = (iFpuU_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint64_t)R_RSI, (uint64_t)R_RDX); }
@@ -2593,6 +2601,7 @@ void pFpiL(x64emu_t *emu, uintptr_t fcn) { pFpiL_t fn = (pFpiL_t)fcn; R_RAX=(uin
 void pFpip(x64emu_t *emu, uintptr_t fcn) { pFpip_t fn = (pFpip_t)fcn; R_RAX=(uintptr_t)fn((void*)R_RDI, (int64_t)R_RSI, (void*)R_RDX); }
 void pFpCC(x64emu_t *emu, uintptr_t fcn) { pFpCC_t fn = (pFpCC_t)fcn; R_RAX=(uintptr_t)fn((void*)R_RDI, (uint8_t)R_RSI, (uint8_t)R_RDX); }
 void pFpCu(x64emu_t *emu, uintptr_t fcn) { pFpCu_t fn = (pFpCu_t)fcn; R_RAX=(uintptr_t)fn((void*)R_RDI, (uint8_t)R_RSI, (uint64_t)R_RDX); }
+void pFpWW(x64emu_t *emu, uintptr_t fcn) { pFpWW_t fn = (pFpWW_t)fcn; R_RAX=(uintptr_t)fn((void*)R_RDI, (uint16_t)R_RSI, (uint16_t)R_RDX); }
 void pFpui(x64emu_t *emu, uintptr_t fcn) { pFpui_t fn = (pFpui_t)fcn; R_RAX=(uintptr_t)fn((void*)R_RDI, (uint64_t)R_RSI, (int64_t)R_RDX); }
 void pFpuu(x64emu_t *emu, uintptr_t fcn) { pFpuu_t fn = (pFpuu_t)fcn; R_RAX=(uintptr_t)fn((void*)R_RDI, (uint64_t)R_RSI, (uint64_t)R_RDX); }
 void pFpuL(x64emu_t *emu, uintptr_t fcn) { pFpuL_t fn = (pFpuL_t)fcn; R_RAX=(uintptr_t)fn((void*)R_RDI, (uint64_t)R_RSI, (uintptr_t)R_RDX); }
@@ -2812,6 +2821,7 @@ void iFpipp(x64emu_t *emu, uintptr_t fcn) { iFpipp_t fn = (iFpipp_t)fcn; R_RAX=(
 void iFpipV(x64emu_t *emu, uintptr_t fcn) { iFpipV_t fn = (iFpipV_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (int64_t)R_RSI, (void*)R_RDX, (void*)(R_RSP + 8)); }
 void iFpIip(x64emu_t *emu, uintptr_t fcn) { iFpIip_t fn = (iFpIip_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (int64_t)R_RSI, (int64_t)R_RDX, (void*)R_RCX); }
 void iFpCCC(x64emu_t *emu, uintptr_t fcn) { iFpCCC_t fn = (iFpCCC_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint8_t)R_RSI, (uint8_t)R_RDX, (uint8_t)R_RCX); }
+void iFpCpi(x64emu_t *emu, uintptr_t fcn) { iFpCpi_t fn = (iFpCpi_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint8_t)R_RSI, (void*)R_RDX, (int64_t)R_RCX); }
 void iFpWWu(x64emu_t *emu, uintptr_t fcn) { iFpWWu_t fn = (iFpWWu_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint16_t)R_RSI, (uint16_t)R_RDX, (uint64_t)R_RCX); }
 void iFpuwp(x64emu_t *emu, uintptr_t fcn) { iFpuwp_t fn = (iFpuwp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint64_t)R_RSI, (int16_t)R_RDX, (void*)R_RCX); }
 void iFpuiL(x64emu_t *emu, uintptr_t fcn) { iFpuiL_t fn = (iFpuiL_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint64_t)R_RSI, (int64_t)R_RDX, (uintptr_t)R_RCX); }
@@ -2858,6 +2868,7 @@ void iFppLi(x64emu_t *emu, uintptr_t fcn) { iFppLi_t fn = (iFppLi_t)fcn; R_RAX=(
 void iFppLL(x64emu_t *emu, uintptr_t fcn) { iFppLL_t fn = (iFppLL_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (uintptr_t)R_RDX, (uintptr_t)R_RCX); }
 void iFppLp(x64emu_t *emu, uintptr_t fcn) { iFppLp_t fn = (iFppLp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (uintptr_t)R_RDX, (void*)R_RCX); }
 void iFpppi(x64emu_t *emu, uintptr_t fcn) { iFpppi_t fn = (iFpppi_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (int64_t)R_RCX); }
+void iFpppC(x64emu_t *emu, uintptr_t fcn) { iFpppC_t fn = (iFpppC_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uint8_t)R_RCX); }
 void iFpppu(x64emu_t *emu, uintptr_t fcn) { iFpppu_t fn = (iFpppu_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uint64_t)R_RCX); }
 void iFpppU(x64emu_t *emu, uintptr_t fcn) { iFpppU_t fn = (iFpppU_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uint64_t)R_RCX); }
 void iFpppL(x64emu_t *emu, uintptr_t fcn) { iFpppL_t fn = (iFpppL_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uintptr_t)R_RCX); }
@@ -3457,6 +3468,7 @@ void iFpipipi(x64emu_t *emu, uintptr_t fcn) { iFpipipi_t fn = (iFpipipi_t)fcn; R
 void iFpippip(x64emu_t *emu, uintptr_t fcn) { iFpippip_t fn = (iFpippip_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (int64_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (int64_t)R_R8, (void*)R_R9); }
 void iFpipppL(x64emu_t *emu, uintptr_t fcn) { iFpipppL_t fn = (iFpipppL_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (int64_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (uintptr_t)R_R9); }
 void iFpipppp(x64emu_t *emu, uintptr_t fcn) { iFpipppp_t fn = (iFpipppp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (int64_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9); }
+void iFpCpipu(x64emu_t *emu, uintptr_t fcn) { iFpCpipu_t fn = (iFpCpipu_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint8_t)R_RSI, (void*)R_RDX, (int64_t)R_RCX, (void*)R_R8, (uint64_t)R_R9); }
 void iFpWpppp(x64emu_t *emu, uintptr_t fcn) { iFpWpppp_t fn = (iFpWpppp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint16_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9); }
 void iFpuiCpp(x64emu_t *emu, uintptr_t fcn) { iFpuiCpp_t fn = (iFpuiCpp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint64_t)R_RSI, (int64_t)R_RDX, (uint8_t)R_RCX, (void*)R_R8, (void*)R_R9); }
 void iFpuippp(x64emu_t *emu, uintptr_t fcn) { iFpuippp_t fn = (iFpuippp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint64_t)R_RSI, (int64_t)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9); }
@@ -3803,6 +3815,7 @@ void iFiiupiupi(x64emu_t *emu, uintptr_t fcn) { iFiiupiupi_t fn = (iFiiupiupi_t)
 void iFuipuuluf(x64emu_t *emu, uintptr_t fcn) { iFuipuuluf_t fn = (iFuipuuluf_t)fcn; R_RAX=(int64_t)fn((uint64_t)R_RDI, (int64_t)R_RSI, (void*)R_RDX, (uint64_t)R_RCX, (uint64_t)R_R8, (intptr_t)R_R9, *(uint64_t*)(R_RSP + 8), emu->xmm[0].f[0]); }
 void iFuuuuuuuu(x64emu_t *emu, uintptr_t fcn) { iFuuuuuuuu_t fn = (iFuuuuuuuu_t)fcn; R_RAX=(int64_t)fn((uint64_t)R_RDI, (uint64_t)R_RSI, (uint64_t)R_RDX, (uint64_t)R_RCX, (uint64_t)R_R8, (uint64_t)R_R9, *(uint64_t*)(R_RSP + 8), *(uint64_t*)(R_RSP + 16)); }
 void iFullfpppp(x64emu_t *emu, uintptr_t fcn) { iFullfpppp_t fn = (iFullfpppp_t)fcn; R_RAX=(int64_t)fn((uint64_t)R_RDI, (intptr_t)R_RSI, (intptr_t)R_RDX, emu->xmm[0].f[0], (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8)); }
+void iFpCCWWpWu(x64emu_t *emu, uintptr_t fcn) { iFpCCWWpWu_t fn = (iFpCCWWpWu_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint8_t)R_RSI, (uint8_t)R_RDX, (uint16_t)R_RCX, (uint16_t)R_R8, (void*)R_R9, *(uint16_t*)(R_RSP + 8), *(uint64_t*)(R_RSP + 16)); }
 void iFpWCuWCuu(x64emu_t *emu, uintptr_t fcn) { iFpWCuWCuu_t fn = (iFpWCuWCuu_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint16_t)R_RSI, (uint8_t)R_RDX, (uint64_t)R_RCX, (uint16_t)R_R8, (uint8_t)R_R9, *(uint64_t*)(R_RSP + 8), *(uint64_t*)(R_RSP + 16)); }
 void iFpWWipppp(x64emu_t *emu, uintptr_t fcn) { iFpWWipppp_t fn = (iFpWWipppp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint16_t)R_RSI, (uint16_t)R_RDX, (int64_t)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16)); }
 void iFpuiipppp(x64emu_t *emu, uintptr_t fcn) { iFpuiipppp_t fn = (iFpuiipppp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint64_t)R_RSI, (int64_t)R_RDX, (int64_t)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16)); }
@@ -3967,6 +3980,7 @@ void vFppipppiiii(x64emu_t *emu, uintptr_t fcn) { vFppipppiiii_t fn = (vFppipppi
 void vFppuuuuiiuu(x64emu_t *emu, uintptr_t fcn) { vFppuuuuiiuu_t fn = (vFppuuuuiiuu_t)fcn; fn((void*)R_RDI, (void*)R_RSI, (uint64_t)R_RDX, (uint64_t)R_RCX, (uint64_t)R_R8, (uint64_t)R_R9, *(int64_t*)(R_RSP + 8), *(int64_t*)(R_RSP + 16), *(uint64_t*)(R_RSP + 24), *(uint64_t*)(R_RSP + 32)); }
 void vFppdddddddd(x64emu_t *emu, uintptr_t fcn) { vFppdddddddd_t fn = (vFppdddddddd_t)fcn; fn((void*)R_RDI, (void*)R_RSI, emu->xmm[0].d[0], emu->xmm[1].d[0], emu->xmm[2].d[0], emu->xmm[3].d[0], emu->xmm[4].d[0], emu->xmm[5].d[0], emu->xmm[6].d[0], emu->xmm[7].d[0]); }
 void vFpppppppppp(x64emu_t *emu, uintptr_t fcn) { vFpppppppppp_t fn = (vFpppppppppp_t)fcn; fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32)); }
+void iFEpiiiiippp(x64emu_t *emu, uintptr_t fcn) { iFEpiiiiippp_t fn = (iFEpiiiiippp_t)fcn; R_RAX=(int64_t)fn(emu, (void*)R_RDI, (int64_t)R_RSI, (int64_t)R_RDX, (int64_t)R_RCX, (int64_t)R_R8, (int64_t)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24)); }
 void iFEpupppLppL(x64emu_t *emu, uintptr_t fcn) { iFEpupppLppL_t fn = (iFEpupppLppL_t)fcn; R_RAX=(int64_t)fn(emu, (void*)R_RDI, (uint64_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (uintptr_t)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(uintptr_t*)(R_RSP + 24)); }
 void iFEppppppipp(x64emu_t *emu, uintptr_t fcn) { iFEppppppipp_t fn = (iFEppppppipp_t)fcn; R_RAX=(int64_t)fn(emu, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(int64_t*)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24)); }
 void iFEppppppppp(x64emu_t *emu, uintptr_t fcn) { iFEppppppppp_t fn = (iFEppppppppp_t)fcn; R_RAX=(int64_t)fn(emu, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24)); }
@@ -4458,6 +4472,7 @@ int isSimpleWrapper(wrapper_t fun) {
 	if (fun == &iFpip) return 1;
 	if (fun == &iFpIi) return 1;
 	if (fun == &iFpII) return 1;
+	if (fun == &iFpCp) return 1;
 	if (fun == &iFpui) return 1;
 	if (fun == &iFpuu) return 1;
 	if (fun == &iFpuU) return 1;
@@ -4575,6 +4590,7 @@ int isSimpleWrapper(wrapper_t fun) {
 	if (fun == &pFpip) return 1;
 	if (fun == &pFpCC) return 1;
 	if (fun == &pFpCu) return 1;
+	if (fun == &pFpWW) return 1;
 	if (fun == &pFpui) return 1;
 	if (fun == &pFpuu) return 1;
 	if (fun == &pFpuL) return 1;
@@ -4758,6 +4774,7 @@ int isSimpleWrapper(wrapper_t fun) {
 	if (fun == &iFpipp) return 1;
 	if (fun == &iFpIip) return 1;
 	if (fun == &iFpCCC) return 1;
+	if (fun == &iFpCpi) return 1;
 	if (fun == &iFpWWu) return 1;
 	if (fun == &iFpuwp) return 1;
 	if (fun == &iFpuiL) return 1;
@@ -4802,6 +4819,7 @@ int isSimpleWrapper(wrapper_t fun) {
 	if (fun == &iFppLL) return 1;
 	if (fun == &iFppLp) return 1;
 	if (fun == &iFpppi) return 1;
+	if (fun == &iFpppC) return 1;
 	if (fun == &iFpppu) return 1;
 	if (fun == &iFpppU) return 1;
 	if (fun == &iFpppL) return 1;
@@ -5306,6 +5324,7 @@ int isSimpleWrapper(wrapper_t fun) {
 	if (fun == &iFpippip) return 1;
 	if (fun == &iFpipppL) return 1;
 	if (fun == &iFpipppp) return 1;
+	if (fun == &iFpCpipu) return 1;
 	if (fun == &iFpWpppp) return 1;
 	if (fun == &iFpuiCpp) return 1;
 	if (fun == &iFpuippp) return 1;
diff --git a/src/wrapped/generated/wrapper.h b/src/wrapped/generated/wrapper.h
index 360bc132..2ee93023 100644
--- a/src/wrapped/generated/wrapper.h
+++ b/src/wrapped/generated/wrapper.h
@@ -409,6 +409,7 @@ void iFpiL(x64emu_t *emu, uintptr_t fnc);
 void iFpip(x64emu_t *emu, uintptr_t fnc);
 void iFpIi(x64emu_t *emu, uintptr_t fnc);
 void iFpII(x64emu_t *emu, uintptr_t fnc);
+void iFpCp(x64emu_t *emu, uintptr_t fnc);
 void iFpui(x64emu_t *emu, uintptr_t fnc);
 void iFpuu(x64emu_t *emu, uintptr_t fnc);
 void iFpuU(x64emu_t *emu, uintptr_t fnc);
@@ -546,6 +547,7 @@ void pFpiL(x64emu_t *emu, uintptr_t fnc);
 void pFpip(x64emu_t *emu, uintptr_t fnc);
 void pFpCC(x64emu_t *emu, uintptr_t fnc);
 void pFpCu(x64emu_t *emu, uintptr_t fnc);
+void pFpWW(x64emu_t *emu, uintptr_t fnc);
 void pFpui(x64emu_t *emu, uintptr_t fnc);
 void pFpuu(x64emu_t *emu, uintptr_t fnc);
 void pFpuL(x64emu_t *emu, uintptr_t fnc);
@@ -765,6 +767,7 @@ void iFpipp(x64emu_t *emu, uintptr_t fnc);
 void iFpipV(x64emu_t *emu, uintptr_t fnc);
 void iFpIip(x64emu_t *emu, uintptr_t fnc);
 void iFpCCC(x64emu_t *emu, uintptr_t fnc);
+void iFpCpi(x64emu_t *emu, uintptr_t fnc);
 void iFpWWu(x64emu_t *emu, uintptr_t fnc);
 void iFpuwp(x64emu_t *emu, uintptr_t fnc);
 void iFpuiL(x64emu_t *emu, uintptr_t fnc);
@@ -811,6 +814,7 @@ void iFppLi(x64emu_t *emu, uintptr_t fnc);
 void iFppLL(x64emu_t *emu, uintptr_t fnc);
 void iFppLp(x64emu_t *emu, uintptr_t fnc);
 void iFpppi(x64emu_t *emu, uintptr_t fnc);
+void iFpppC(x64emu_t *emu, uintptr_t fnc);
 void iFpppu(x64emu_t *emu, uintptr_t fnc);
 void iFpppU(x64emu_t *emu, uintptr_t fnc);
 void iFpppL(x64emu_t *emu, uintptr_t fnc);
@@ -1410,6 +1414,7 @@ void iFpipipi(x64emu_t *emu, uintptr_t fnc);
 void iFpippip(x64emu_t *emu, uintptr_t fnc);
 void iFpipppL(x64emu_t *emu, uintptr_t fnc);
 void iFpipppp(x64emu_t *emu, uintptr_t fnc);
+void iFpCpipu(x64emu_t *emu, uintptr_t fnc);
 void iFpWpppp(x64emu_t *emu, uintptr_t fnc);
 void iFpuiCpp(x64emu_t *emu, uintptr_t fnc);
 void iFpuippp(x64emu_t *emu, uintptr_t fnc);
@@ -1756,6 +1761,7 @@ void iFiiupiupi(x64emu_t *emu, uintptr_t fnc);
 void iFuipuuluf(x64emu_t *emu, uintptr_t fnc);
 void iFuuuuuuuu(x64emu_t *emu, uintptr_t fnc);
 void iFullfpppp(x64emu_t *emu, uintptr_t fnc);
+void iFpCCWWpWu(x64emu_t *emu, uintptr_t fnc);
 void iFpWCuWCuu(x64emu_t *emu, uintptr_t fnc);
 void iFpWWipppp(x64emu_t *emu, uintptr_t fnc);
 void iFpuiipppp(x64emu_t *emu, uintptr_t fnc);
@@ -1920,6 +1926,7 @@ void vFppipppiiii(x64emu_t *emu, uintptr_t fnc);
 void vFppuuuuiiuu(x64emu_t *emu, uintptr_t fnc);
 void vFppdddddddd(x64emu_t *emu, uintptr_t fnc);
 void vFpppppppppp(x64emu_t *emu, uintptr_t fnc);
+void iFEpiiiiippp(x64emu_t *emu, uintptr_t fnc);
 void iFEpupppLppL(x64emu_t *emu, uintptr_t fnc);
 void iFEppppppipp(x64emu_t *emu, uintptr_t fnc);
 void iFEppppppppp(x64emu_t *emu, uintptr_t fnc);
diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c
index e2ae9c76..e73e32cf 100755
--- a/src/wrapped/wrappedlibc.c
+++ b/src/wrapped/wrappedlibc.c
@@ -238,6 +238,29 @@ static void* findgloberrFct(void* fct)
     printf_log(LOG_NONE, "Warning, no more slot for libc globerr callback\n");
     return NULL;
 }
+// free
+#define GO(A)   \
+static uintptr_t my_free_fct_##A = 0;               \
+static void my_free_##A(void* p)                    \
+{                                                   \
+    RunFunction(my_context, my_free_fct_##A, 1, p); \
+}
+SUPER()
+#undef GO
+static void* findfreeFct(void* fct)
+{
+    if(!fct) return NULL;
+    void* p;
+    if((p = GetNativeFnc((uintptr_t)fct))) return p;
+    #define GO(A) if(my_free_fct_##A == (uintptr_t)fct) return my_free_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_free_fct_##A == 0) {my_free_fct_##A = (uintptr_t)fct; return my_free_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for libc free callback\n");
+    return NULL;
+}
 
 #if 0
 #undef dirent
@@ -1138,6 +1161,17 @@ EXPORT void* my_lsearch(x64emu_t* emu, void* key, void* base, size_t* nmemb, siz
     (void)emu;
     return lsearch(key, base, nmemb, size, findcompareFct(fnc));
 }
+
+EXPORT void* my_tsearch(x64emu_t* emu, void* key, void* root, void* fnc)
+{
+    (void)emu;
+    return tsearch(key, root, findcompareFct(fnc));
+}
+EXPORT void my_tdestroy(x64emu_t* emu, void* root, void* fnc)
+{
+    (void)emu;
+    return tdestroy(root, findfreeFct(fnc));
+}
 EXPORT void* my_lfind(x64emu_t* emu, void* key, void* base, size_t* nmemb, size_t size, void* fnc)
 {
     (void)emu;
@@ -1780,7 +1814,32 @@ EXPORT int32_t my_execlp(x64emu_t* emu, const char* path)
     return ret;
 }
 
-#if 0
+EXPORT int32_t my_posix_spawn(x64emu_t* emu, pid_t* pid, const char* fullpath, 
+    const posix_spawn_file_actions_t *actions, const posix_spawnattr_t* attrp,  char* const argv[], char* const envp[])
+{
+    int self = isProcSelf(fullpath, "exe");
+    int x64 = FileIsX64ELF(fullpath);
+    int x86 = my_context->box86path?FileIsX86ELF(fullpath):0;
+    printf_log(/*LOG_DEBUG*/LOG_INFO, "posix_spawn(%p, \"%s\", %p, %p, %p, %p), IsX86=%d\n", pid, fullpath, actions, attrp, argv, envp, x64);
+    if (x64 || x86 || self) {
+        // count argv...
+        int i=0;
+        while(argv[i]) ++i;
+        char** newargv = (char**)calloc(i+2, sizeof(char*));
+        newargv[0] = x86?emu->context->box86path:emu->context->box64path;
+        for (int j=0; j<i; ++j)
+            newargv[j+1] = argv[j];
+        if(self) newargv[1] = emu->context->fullpath;
+        printf_log(/*LOG_DEBUG*/LOG_INFO, " => posix_spawn(%p, \"%s\", %p, %p, %p [\"%s\", \"%s\"...:%d], %p)\n", pid, newargv[0], actions, attrp, newargv, newargv[1], i?newargv[2]:"", i, envp);
+        int ret = posix_spawn(pid, newargv[0], actions, attrp, newargv, envp);
+        printf_log(/*LOG_DEBUG*/LOG_INFO, "posix_spawn returned %d\n", ret);
+        //free(newargv);
+        return ret;
+    }
+    // fullpath is gone, so the search will only be on PATH, not on BOX64_PATH (is that an issue?)
+    return posix_spawn(pid, fullpath, actions, attrp, argv, envp);
+}
+
 // execvp should use PATH to search for the program first
 EXPORT int32_t my_posix_spawnp(x64emu_t* emu, pid_t* pid, const char* path, 
     const posix_spawn_file_actions_t *actions, const posix_spawnattr_t* attrp,  char* const argv[], char* const envp[])
@@ -1791,7 +1850,7 @@ EXPORT int32_t my_posix_spawnp(x64emu_t* emu, pid_t* pid, const char* path,
     int self = isProcSelf(fullpath, "exe");
     int x64 = FileIsX64ELF(fullpath);
     int x86 = my_context->box86path?FileIsX86ELF(path):0;
-    printf_log(LOG_DEBUG, "posix_spawnp(%p, \"%s\", %p, %p, %p, %p), IsX86=%d / fullpath=\"%s\"\n", pid, path, actions, attrp, argv, envp, x64, fullpath);
+    printf_log(/*LOG_DEBUG*/LOG_INFO, "posix_spawnp(%p, \"%s\", %p, %p, %p, %p), IsX86=%d / fullpath=\"%s\"\n", pid, path, actions, attrp, argv, envp, x64, fullpath);
     free(fullpath);
     if (x64 || x86 || self) {
         // count argv...
@@ -1802,16 +1861,15 @@ EXPORT int32_t my_posix_spawnp(x64emu_t* emu, pid_t* pid, const char* path,
         for (int j=0; j<i; ++j)
             newargv[j+1] = argv[j];
         if(self) newargv[1] = emu->context->fullpath;
-        printf_log(LOG_DEBUG, " => posix_spawnp(%p, \"%s\", %p, %p, %p [\"%s\", \"%s\"...:%d], %p)\n", pid, newargv[0], actions, attrp, newargv, newargv[1], i?newargv[2]:"", i, envp);
+        printf_log(/*LOG_DEBUG*/LOG_INFO, " => posix_spawnp(%p, \"%s\", %p, %p, %p [\"%s\", \"%s\"...:%d], %p)\n", pid, newargv[0], actions, attrp, newargv, newargv[1], i?newargv[2]:"", i, envp);
         int ret = posix_spawnp(pid, newargv[0], actions, attrp, newargv, envp);
-        printf_log(LOG_DEBUG, "posix_spawnp returned %d\n", ret);
+        printf_log(/*LOG_DEBUG*/LOG_INFO, "posix_spawnp returned %d\n", ret);
         //free(newargv);
         return ret;
     }
     // fullpath is gone, so the search will only be on PATH, not on BOX64_PATH (is that an issue?)
     return posix_spawnp(pid, path, actions, attrp, argv, envp);
 }
-#endif
 
 EXPORT void my__Jv_RegisterClasses() {}
 
diff --git a/src/wrapped/wrappedlibc_private.h b/src/wrapped/wrappedlibc_private.h
index 36ef89b4..bdcca88d 100755
--- a/src/wrapped/wrappedlibc_private.h
+++ b/src/wrapped/wrappedlibc_private.h
@@ -1325,7 +1325,7 @@ GO(posix_fallocate64, iFill)
 GO(posix_madvise, iFpLi)
 GOW(posix_memalign, iFpLL)
 GOW(posix_openpt, iFi)
-GO(posix_spawn, iFpppppp) // Need wrapping?
+GOM(posix_spawn, iFEpppppp)
 GOW(posix_spawnattr_destroy, iFp)
 GO(posix_spawnattr_getflags, iFpp)
 //GO(posix_spawnattr_getpgroup, iF!p)
@@ -1347,7 +1347,7 @@ GOW(posix_spawn_file_actions_adddup2, iFpii)
 //GOW(posix_spawn_file_actions_addopen, iF!ipiu)
 GOW(posix_spawn_file_actions_destroy, iFp)
 GOW(posix_spawn_file_actions_init, iFp)
-GO(posix_spawnp, iFpppppp)
+GOM(posix_spawnp, iFEpppppp)
 GO(ppoll, iFpLpp)
 //GO(__ppoll_chk, 
 GOW(prctl, iFiLLLL)
@@ -1942,7 +1942,7 @@ GO(tcsetattr, iFiip)
 GO(tcsetpgrp, iFii)
 //GO(__tdelete, 
 //GOW(tdelete, pFpp@)
-//GOW(tdestroy, vFp@)
+GOWM(tdestroy, vFEpp)
 GO(tee, lFiiLu)
 GO(telldir, lFp)
 GO(tempnam, pFpp)
@@ -1992,7 +1992,7 @@ GOW(towupper_l, uFup)
 GOW(truncate, iFpl)
 GOW(truncate64, iFpl)
 //GO(__tsearch, 
-//GOW(tsearch, pFpp@)
+GOWM(tsearch, pFEppp)
 GO(ttyname, pFi)
 GOW(ttyname_r, iFipL)
 //GO(__ttyname_r_chk, 
diff --git a/src/wrapped/wrappedlibdl.c b/src/wrapped/wrappedlibdl.c
index dffc9fa9..d8582536 100755
--- a/src/wrapped/wrappedlibdl.c
+++ b/src/wrapped/wrappedlibdl.c
@@ -65,7 +65,8 @@ void* my_dlopen(x64emu_t* emu, void *filename, int flag)
     int is_local = (flag&0x100)?0:1;  // if not global, then local, and that means symbols are not put in the global "pot" for pther libs
     CLEARERR
     if(filename) {
-        char* rfilename = (char*)filename;
+        char* rfilename = (char*)alloca(MAX_PATH);
+        strcpy(rfilename, (char*)filename);
         if(box64_zoom && rfilename && strstr(rfilename, "/libturbojpeg.so")) {
             void* sys = my_dlopen(emu, "libturbojpeg.so.0", flag);
             if(sys)
@@ -74,6 +75,33 @@ void* my_dlopen(x64emu_t* emu, void *filename, int flag)
         if(dlsym_error || box64_log>=LOG_DEBUG) {
             printf_log(LOG_NONE, "Call to dlopen(\"%s\"/%p, %X)\n", rfilename, filename, flag);
         }
+        // Transform any ${...} that maight be present
+        while(strstr(rfilename, "${ORIGIN}")) {
+            char* origin = strdup(my_context->fullpath);
+            char* p = strrchr(origin, '/');
+            if(p) *p = '\0';    // remove file name to have only full path, without last '/'
+            char* tmp = (char*)calloc(1, strlen(rfilename)-strlen("${ORIGIN}")+strlen(origin)+1);
+            p = strstr(rfilename, "${ORIGIN}");
+            memcpy(tmp, rfilename, p-rfilename);
+            strcat(tmp, origin);
+            strcat(tmp, p+strlen("${ORIGIN}"));
+            strcpy(rfilename, tmp);
+            free(tmp);
+            free(origin);
+        }
+        while(strstr(rfilename, "${PLATFORM}")) {
+            char* platform = strdup("x86_64");
+            char* p = strrchr(platform, '/');
+            if(p) *p = '\0';    // remove file name to have only full path, without last '/'
+            char* tmp = (char*)calloc(1, strlen(rfilename)-strlen("${PLATFORM}")+strlen(platform)+1);
+            p = strstr(rfilename, "${PLATFORM}");
+            memcpy(tmp, rfilename, p-rfilename);
+            strcat(tmp, platform);
+            strcat(tmp, p+strlen("${PLATFORM}"));
+            strcpy(rfilename, tmp);
+            free(tmp);
+            free(platform);
+        }
         // check if alread dlopenned...
         for (size_t i=0; i<dl->lib_sz; ++i) {
             if(IsSameLib(dl->libs[i], rfilename)) {
@@ -349,22 +377,16 @@ int my_dladdr1(x64emu_t* emu, void *addr, void *i, void** extra_info, int flags)
     printf_log(LOG_DEBUG, "Warning: partially unimplement call to dladdr/dladdr1(%p, %p, %p, %d)\n", addr, info, extra_info, flags);
     
     //emu->quit = 1;
+    library_t* lib = NULL;
     info->dli_saddr = NULL;
     info->dli_fname = NULL;
-    info->dli_sname = FindSymbolName(emu->context->maplib, addr, &info->dli_saddr, NULL, &info->dli_fname, &info->dli_fbase);
+    info->dli_sname = FindSymbolName(emu->context->maplib, addr, &info->dli_saddr, NULL, &info->dli_fname, &info->dli_fbase, &lib);
     printf_log(LOG_DEBUG, "     dladdr return saddr=%p, fname=\"%s\", sname=\"%s\"\n", info->dli_saddr, info->dli_sname?info->dli_sname:"", info->dli_fname?info->dli_fname:"");
     if(flags==RTLD_DL_SYMENT) {
         printf_log(LOG_INFO, "Warning, unimplement call to dladdr1 with RTLD_DL_SYMENT flags\n");
     } else if (flags==RTLD_DL_LINKMAP) {
-        printf_log(LOG_INFO, "Warning, partially unimplement call to dladdr1 with RTLD_DL_LINKMAP flags\n");
-        static struct link_map my_map = {0};
-        elfheader_t* elf = FindElfAddress(my_context, (uintptr_t)addr);
-        if(elf) {
-            my_map.l_addr = (uintptr_t)GetElfDelta(elf);
-            my_map.l_name = (char*)ElfPath(elf);
-            my_map.l_ld = GetDynamicSection(elf);
-        }
-        *extra_info = &my_map;
+        printf_log(LOG_INFO, "Warning, partially unimplemented call to dladdr1 with RTLD_DL_LINKMAP flags\n");
+        *(linkmap_t**)extra_info = getLinkMapLib(lib);
     }
     return (info->dli_sname)?1:0;   // success is non-null here...
 }
@@ -485,12 +507,6 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername)
     return (void*)start;
 }
 
-typedef struct link_map_s {
-    uintptr_t   l_addr;
-    char*       l_name;
-    Elf64_Dyn*  l_ld;
-} link_map_t;
-
 int my_dlinfo(x64emu_t* emu, void* handle, int request, void* info)
 {
     (void)emu;
@@ -521,15 +537,11 @@ int my_dlinfo(x64emu_t* emu, void* handle, int request, void* info)
         return -1;
     }
     library_t *lib = dl->libs[nlib];
-    elfheader_t *h = (GetElfIndex(lib)>-1)?my_context->elfs[GetElfIndex(lib)]:NULL;
+    //elfheader_t *h = (GetElfIndex(lib)>-1)?my_context->elfs[GetElfIndex(lib)]:NULL;
     switch(request) {
         case 2: // RTLD_DI_LINKMAP
             {
-                static link_map_t map = {0};   //cheating, creating a structure on demand...
-                *(link_map_t**)info = &map;
-                map.l_addr = h?h->delta:0;
-                map.l_name = lib->path;
-                map.l_ld = h?h->Dynamic:NULL;
+                *(linkmap_t**)info = getLinkMapLib(lib);
             }
             return 0;
         default:
diff --git a/src/wrapped/wrappedlibusb1.c b/src/wrapped/wrappedlibusb1.c
new file mode 100755
index 00000000..9d4b21d4
--- /dev/null
+++ b/src/wrapped/wrappedlibusb1.c
@@ -0,0 +1,196 @@
+#define _GNU_SOURCE         /* See feature_test_macros(7) */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+
+#include "wrappedlibs.h"
+
+#include "debug.h"
+#include "wrapper.h"
+#include "bridge.h"
+#include "librarian/library_private.h"
+#include "x64emu.h"
+#include "emu/x64emu_private.h"
+#include "callback.h"
+#include "librarian.h"
+#include "box64context.h"
+#include "emu/x64emu_private.h"
+#include "myalign.h"
+
+const char* libusb1Name = "libusb-1.0.so.0";
+#define LIBNAME libusb1
+
+typedef void*   (*pFi_t)            (int);
+typedef int     (*iFp_t)            (void*);
+typedef void    (*vFpu_t)           (void*, uint32_t);
+typedef int     (*iFpiiiiippp_t)    (void*, int, int, int, int, int, void*, void*, void*);
+
+static library_t* my_lib = NULL;
+
+#define SUPER() \
+    GO(libusb_hotplug_register_callback, iFpiiiiippp_t) \
+    GO(libusb_alloc_transfer, pFi_t)                    \
+    GO(libusb_submit_transfer, iFp_t)                   \
+    GO(libusb_cancel_transfer, iFp_t)                   \
+
+typedef struct libusb1_my_s {
+    // functions
+    #define GO(A, B)    B   A;
+    SUPER()
+    #undef GO
+} libusb1_my_t;
+
+void* getUsb1My(library_t* lib)
+{
+    libusb1_my_t* my = (libusb1_my_t*)calloc(1, sizeof(libusb1_my_t));
+    #define GO(A, W) my->A = (W)dlsym(lib->priv.w.lib, #A);
+    SUPER()
+    #undef GO
+    return my;
+}
+#undef SUPER
+
+void freeUsb1My(void* lib)
+{
+//    libusb1_my_t *my = (libusb1_my_t *)lib;
+}
+
+#define SUPER() \
+GO(0)   \
+GO(1)   \
+GO(2)   \
+GO(3)   \
+GO(4)   \
+GO(5)   \
+GO(6)   \
+GO(7)   \
+GO(8)   \
+GO(9)   \
+
+
+// hotplug
+#define GO(A)   \
+static uintptr_t my_hotplug_fct_##A = 0;                                                    \
+static int my_hotplug_##A(void* ctx, void* device, int event, void* data)                   \
+{                                                                                           \
+    return (int)RunFunction(my_context, my_hotplug_fct_##A, 4, ctx, device, event, data);   \
+}
+SUPER()
+#undef GO
+static void* findhotplugFct(void* fct)
+{
+    if(!fct) return fct;
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_hotplug_fct_##A == (uintptr_t)fct) return my_hotplug_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_hotplug_fct_##A == 0) {my_hotplug_fct_##A = (uintptr_t)fct; return my_hotplug_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for libusb-1.0 hotplug callback (%p)\n", fct);
+    return NULL;
+}
+// transfert
+#define GO(A)   \
+static uintptr_t my_transfert_fct_##A = 0;                      \
+static void my_transfert_##A(void* ctx)                         \
+{                                                               \
+    RunFunction(my_context, my_transfert_fct_##A, 1, ctx);      \
+}
+SUPER()
+#undef GO
+static void* findtransfertFct(void* fct)
+{
+    if(!fct) return fct;
+    #define GO(A) if(my_transfert_##A == fct) return my_transfert_##A;
+    SUPER()
+    #undef GO
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_transfert_fct_##A == (uintptr_t)fct) return my_transfert_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_transfert_fct_##A == 0) {my_transfert_fct_##A = (uintptr_t)fct; return my_transfert_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for libusb-1.0 transfert callback (%p)\n", fct);
+    return NULL;
+}
+static void* reverse_transfert_Fct(void* fct)
+{
+    if(!fct) return fct;
+    if(CheckBridged(my_lib->priv.w.bridge, fct))
+        return (void*)CheckBridged(my_lib->priv.w.bridge, fct);
+    #define GO(A) if(my_transfert_##A == fct) return (void*)my_transfert_fct_##A;
+    SUPER()
+    #undef GO
+    return (void*)AddBridge(my_lib->priv.w.bridge, vFp, fct, 0, NULL);
+}
+
+#undef SUPER
+
+EXPORT int my_libusb_hotplug_register_callback(x64emu_t* emu, void* ctx, int event, int flags, int vendor, int product, int dev_class, void* f, void* data, void* handle)
+{
+    libusb1_my_t *my = (libusb1_my_t*)my_lib->priv.w.p2;
+
+    return my->libusb_hotplug_register_callback(ctx, event, flags, vendor, product, dev_class, findhotplugFct(f), data, handle);
+}
+
+struct my_libusb_iso_packet_descriptor {
+    unsigned int length;
+    unsigned int actual_length;
+    int status;
+};
+
+typedef struct my_libusb_transfer_s {
+    void* dev_handle;
+    uint8_t flags;
+    unsigned char endpoint;
+    unsigned char type;
+    unsigned int timeout;
+    int status;
+    int length;
+    int actual_length;
+    void* callback;
+    void* user_data;
+    unsigned char *buffer;
+    int num_iso_packets;
+    struct my_libusb_iso_packet_descriptor iso_packet_desc[0];
+} my_libusb_transfer_t;
+
+EXPORT void* my_libusb_alloc_transfer(x64emu_t* emu, int num)
+{
+    libusb1_my_t *my = (libusb1_my_t*)my_lib->priv.w.p2;
+
+    my_libusb_transfer_t* ret = (my_libusb_transfer_t*)my->libusb_alloc_transfer(num);
+    if(ret)
+        ret->callback = reverse_transfert_Fct(ret->callback);
+    return ret;
+}
+
+EXPORT int my_libusb_submit_transfer(x64emu_t* emu, my_libusb_transfer_t* t)
+{
+    libusb1_my_t *my = (libusb1_my_t*)my_lib->priv.w.p2;
+    
+    t->callback = findtransfertFct(t->callback);
+    return my->libusb_submit_transfer(t); // don't put back callback, it's unknown if it's safe
+} 
+
+EXPORT int my_libusb_cancel_transfer(x64emu_t* emu, my_libusb_transfer_t* t)
+{
+    libusb1_my_t *my = (libusb1_my_t*)my_lib->priv.w.p2;
+    
+    t->callback = findtransfertFct(t->callback);
+    return my->libusb_cancel_transfer(t);
+}
+
+#define CUSTOM_INIT \
+    my_lib = lib;   \
+    lib->priv.w.p2 = getUsb1My(lib);
+
+#define CUSTOM_FINI \
+    freeUsb1My(lib->priv.w.p2); \
+    free(lib->priv.w.p2);
+
+#include "wrappedlib_init.h"
+
diff --git a/src/wrapped/wrappedlibusb1_private.h b/src/wrapped/wrappedlibusb1_private.h
new file mode 100755
index 00000000..6aa06dbf
--- /dev/null
+++ b/src/wrapped/wrappedlibusb1_private.h
@@ -0,0 +1,85 @@
+#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))
+#error meh!
+#endif
+
+GOM(libusb_alloc_transfer, pFEi)
+GO(libusb_attach_kernel_driver, iFpi)
+GO(libusb_bulk_transfer, iFpCpipu)
+GOM(libusb_cancel_transfer, iFEp)
+GO(libusb_claim_interface, iFpi)
+GO(libusb_clear_halt, iFpC)
+GO(libusb_close, vFp)
+GO(libusb_control_transfer, iFpCCWWpWu)
+GO(libusb_detach_kernel_driver, iFpi)
+GO(libusb_error_name, pFi)
+GO(libusb_event_handler_active, iFp)
+GO(libusb_event_handling_ok, iFp)
+GO(libusb_exit, vFp)
+GO(libusb_free_bos_descriptor, vFp)
+GO(libusb_free_config_descriptor, vFp)
+GO(libusb_free_container_id_descriptor, vFp)
+GO(libusb_free_device_list, vFpi)
+GO(libusb_free_ss_endpoint_companion_descriptor, vFp)
+GO(libusb_free_ss_usb_device_capability_descriptor, iFppp)
+GO(libusb_free_transfer, vFp)
+GO(libusb_free_usb_2_0_extension_descriptor, vFp)
+GO(libusb_get_active_config_descriptor, iFpp)
+GO(libusb_get_bos_descriptor, iFpp)
+GO(libusb_get_bus_number, CFp)
+GO(libusb_get_config_descriptor, iFpCp)
+GO(libusb_get_config_descriptor_by_value, iFpCp)
+GO(libusb_get_configuration, iFpp)
+GO(libusb_get_container_id_descriptor, iFppp)
+GO(libusb_get_device, pFp)
+GO(libusb_get_device_address, CFp)
+GO(libusb_get_device_descriptor, iFpp)
+GO(libusb_get_device_list, lFpp)
+GO(libusb_get_device_speed, iFp)
+GO(libusb_get_max_iso_packet_size, iFpC)
+GO(libusb_get_max_packet_size, iFpC)
+GO(libusb_get_next_timeout, iFpp)
+GO(libusb_get_parent, pFp)
+GO(libusb_get_pollfds, pFp)
+GO(libusb_get_port_number, CFp)
+GO(libusb_get_port_numbers, iFppi)
+GO(libusb_get_port_path, iFpppC)
+GO(libusb_get_ss_endpoint_companion_descriptor, iFppp)
+GO(libusb_get_ss_usb_device_capability_descriptor, iFppp)
+GO(libusb_get_string_descriptor_ascii, iFpCpi)
+GO(libusb_get_usb_2_0_extension_descriptor, iFppp)
+GO(libusb_get_version, pFv)
+GO(libusb_handle_events, iFp)
+GO(libusb_handle_events_completed, iFpp)
+GO(libusb_handle_events_locked, iFpp)
+GO(libusb_handle_events_timeout, iFpp)
+GO(libusb_handle_events_timeout_completed, iFppp)
+GO(libusb_has_capability, iFu)
+GO(libusb_hotplug_deregister_callback, vFpi)
+GOM(libusb_hotplug_register_callback, iFEpiiiiippp)
+GO(libusb_init, iFp)
+GO(libusb_interrupt_transfer, iFpCpipu)
+GO(libusb_interrupt_event_handler, iFp) // since 1.0.21 (API_VERSION > 0x01000105)
+GO(libusb_kernel_driver_active, iFpi)
+GO(libusb_lock_events, vFp)
+GO(libusb_lock_event_waiters, vFp)
+GO(libusb_open, iFpp)
+GO(libusb_open_device_with_vid_pid, pFpWW)
+GO(libusb_pollfds_handle_timeouts, iFp)
+GO(libusb_ref_device, pFp)
+GO(libusb_release_interface, iFpi)
+GO(libusb_reset_device, iFp)
+GO(libusb_set_auto_detach_kernel_driver, iFpi)
+GO(libusb_set_configuration, iFpi)
+GO(libusb_set_debug, vFpi)
+GO(libusb_set_interface_alt_setting, iFpii)
+GO(libusb_setlocale, iFp)
+//GOM(libusb_set_pollfd_notifiers, vFpppp)
+GO(libusb_strerror, pFi)
+GOM(libusb_submit_transfer, iFEp)
+GO(libusb_transfer_get_stream_id, uFp)  //v1.0.19+ , no need to wrap callback here
+GO(libusb_transfer_set_stream_id, vFpu) //v1.0.19+ , no need to wrap callback here
+GO(libusb_try_lock_events, iFp)
+GO(libusb_unlock_events, vFp)
+GO(libusb_unlock_event_waiters, vFp)
+GO(libusb_unref_device, vFp)
+GO(libusb_wait_for_event, iFpp)