about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/elfs/elfloader.c2
-rwxr-xr-xsrc/elfs/elfparser.c76
-rw-r--r--src/emu/x64run66.c7
-rw-r--r--src/emu/x64runf0.c23
-rwxr-xr-xsrc/include/debug.h1
-rwxr-xr-xsrc/librarian/library.c15
-rwxr-xr-xsrc/library_list.h1
-rwxr-xr-xsrc/libtools/threads.c10
-rwxr-xr-xsrc/main.c21
-rw-r--r--src/wrapped/generated/functions_list.txt12
-rw-r--r--src/wrapped/generated/wrappedcurltypes.h2
-rw-r--r--src/wrapped/generated/wrappedlibctypes.h5
-rw-r--r--src/wrapped/generated/wrappedlibpthreadtypes.h2
-rw-r--r--src/wrapped/generated/wrapper.c7
-rw-r--r--src/wrapped/generated/wrapper.h3
-rwxr-xr-xsrc/wrapped/wrappedcurl.c108
-rwxr-xr-xsrc/wrapped/wrappedcurl_private.h6
-rwxr-xr-xsrc/wrapped/wrappedlibc.c22
-rwxr-xr-xsrc/wrapped/wrappedlibc_private.h5
-rwxr-xr-xsrc/wrapped/wrappedlibdl.c8
-rwxr-xr-xsrc/wrapped/wrappedlibm_private.h10
-rwxr-xr-xsrc/wrapped/wrappedlibpthread_private.h4
22 files changed, 301 insertions, 49 deletions
diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c
index eacafa0d..4f054785 100755
--- a/src/elfs/elfloader.c
+++ b/src/elfs/elfloader.c
@@ -472,7 +472,7 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t*
                     }
                     if (!offs) {
                         if(strcmp(symname, "__gmon_start__") && strcmp(symname, "data_start") && strcmp(symname, "__data_start"))
-                            printf_log(LOG_NONE, "%s: Global Symbol %s not found, cannot apply R_X86_64_GLOB_DAT @%p (%p) in %s\n", (bind==STB_WEAK)?"Warning":"Error", symname, p, *(void**)p, head->name);
+                            printf_log(LOG_NONE, "%s: Global Symbol %s (ver=%d/%s) not found, cannot apply R_X86_64_GLOB_DAT @%p (%p) in %s\n", (bind==STB_WEAK)?"Warning":"Error", symname, version, vername?vername:"(none)", p, *(void**)p, head->name);
                     } else {
                         printf_dump(LOG_NEVER, "Apply %s R_X86_64_GLOB_DAT @%p (%p -> %p) on sym=%s (ver=%d/%s)\n", (bind==STB_LOCAL)?"Local":"Global", p, (void*)(p?(*p):0), (void*)offs, symname, version, vername?vername:"(none)");
                         *p = offs;
diff --git a/src/elfs/elfparser.c b/src/elfs/elfparser.c
index c92d7e4c..d5292564 100755
--- a/src/elfs/elfparser.c
+++ b/src/elfs/elfparser.c
@@ -46,7 +46,7 @@ int FindSection(Elf64_Shdr *s, int n, char* SHStrTab, const char* name)
 void LoadNamedSection(FILE *f, Elf64_Shdr *s, int size, char* SHStrTab, const char* name, const char* clearname, uint32_t type, void** what, size_t* num)
 {
     int n = FindSection(s, size, SHStrTab, name);
-    printf_log(LOG_DEBUG, "Loading %s (idx = %d)\n", clearname, n);
+    printf_dump(LOG_DEBUG, "Loading %s (idx = %d)\n", clearname, n);
     if(n)
         LoadSH(f, s+n, what, name, type);
     if(type==SHT_SYMTAB || type==SHT_DYNSYM) {
@@ -73,7 +73,7 @@ elfheader_t* ParseElfHeader(FILE* f, const char* name, int exec)
     if(header.e_ident[EI_CLASS]!=ELFCLASS64) {
         if(strstr(name, ".so")) {
             // less naging on libs...
-            printf_log(LOG_DEBUG, "Not a 64bits ELF (%d)\n", header.e_ident[EI_CLASS]);
+            printf_dump(LOG_DEBUG, "Not a 64bits ELF (%d)\n", header.e_ident[EI_CLASS]);
             return NULL;
         }
         if(header.e_ident[EI_CLASS]==ELFCLASS32) {
@@ -129,7 +129,7 @@ elfheader_t* ParseElfHeader(FILE* f, const char* name, int exec)
     if(header.e_shentsize && header.e_shnum) {
         // special cases for nums
         if(h->numSHEntries == 0) {
-            printf_log(LOG_DEBUG, "Read number of Sections in 1st Section\n");
+            printf_dump(LOG_DEBUG, "Read number of Sections in 1st Section\n");
             // read 1st section header and grab actual number from here
             fseeko64(f, header.e_shoff, SEEK_SET);
             Elf64_Shdr section;
@@ -141,7 +141,7 @@ elfheader_t* ParseElfHeader(FILE* f, const char* name, int exec)
             h->numSHEntries = section.sh_size;
         }
         // now read all section headers
-        printf_log(LOG_DEBUG, "Read %zu Section header\n", h->numSHEntries);
+        printf_dump(LOG_DEBUG, "Read %zu Section header\n", h->numSHEntries);
         h->SHEntries = (Elf64_Shdr*)calloc(h->numSHEntries, sizeof(Elf64_Shdr));
         fseeko64(f, header.e_shoff ,SEEK_SET);
         if(fread(h->SHEntries, sizeof(Elf64_Shdr), h->numSHEntries, f)!=h->numSHEntries) {
@@ -151,13 +151,13 @@ elfheader_t* ParseElfHeader(FILE* f, const char* name, int exec)
         }
 
         if(h->numPHEntries == PN_XNUM) {
-            printf_log(LOG_DEBUG, "Read number of Program Header in 1st Section\n");
+            printf_dump(LOG_DEBUG, "Read number of Program Header in 1st Section\n");
             // read 1st section header and grab actual number from here
             h->numPHEntries = h->SHEntries[0].sh_info;
         }
     }
 
-    printf_log(LOG_DEBUG, "Read %zu Program header\n", h->numPHEntries);
+    printf_dump(LOG_DEBUG, "Read %zu Program header\n", h->numPHEntries);
     h->PHEntries = (Elf64_Phdr*)calloc(h->numPHEntries, sizeof(Elf64_Phdr));
     fseeko64(f, header.e_phoff ,SEEK_SET);
     if(fread(h->PHEntries, sizeof(Elf64_Phdr), h->numPHEntries, f)!=h->numPHEntries) {
@@ -168,7 +168,7 @@ elfheader_t* ParseElfHeader(FILE* f, const char* name, int exec)
 
     if(header.e_shentsize && header.e_shnum) {
         if(h->SHIdx == SHN_XINDEX) {
-            printf_log(LOG_DEBUG, "Read number of String Table in 1st Section\n");
+            printf_dump(LOG_DEBUG, "Read number of String Table in 1st Section\n");
             h->SHIdx = h->SHEntries[0].sh_link;
         }
         if(h->SHIdx > h->numSHEntries) {
@@ -177,7 +177,7 @@ elfheader_t* ParseElfHeader(FILE* f, const char* name, int exec)
             return NULL;
         }
         // load Section table
-        printf_log(LOG_DEBUG, "Loading Sections Table String (idx = %zu)\n", h->SHIdx);
+        printf_dump(LOG_DEBUG, "Loading Sections Table String (idx = %zu)\n", h->SHIdx);
         if(LoadSH(f, h->SHEntries+h->SHIdx, (void*)&h->SHStrTab, ".shstrtab", SHT_STRTAB)) {
             FreeElfHeader(&h);
             return NULL;
@@ -236,15 +236,15 @@ elfheader_t* ParseElfHeader(FILE* f, const char* name, int exec)
                     break;
                 case DT_INIT: // Entry point
                     h->initentry = ptr;
-                    printf_log(LOG_DEBUG, "The DT_INIT is at address %p\n", (void*)h->initentry);
+                    printf_dump(LOG_DEBUG, "The DT_INIT is at address %p\n", (void*)h->initentry);
                     break;
                 case DT_INIT_ARRAY:
                     h->initarray = ptr;
-                    printf_log(LOG_DEBUG, "The DT_INIT_ARRAY is at address %p\n", (void*)h->initarray);
+                    printf_dump(LOG_DEBUG, "The DT_INIT_ARRAY is at address %p\n", (void*)h->initarray);
                     break;
                 case DT_INIT_ARRAYSZ:
                     h->initarray_sz = val / sizeof(Elf64_Addr);
-                    printf_log(LOG_DEBUG, "The DT_INIT_ARRAYSZ is %zu\n", h->initarray_sz);
+                    printf_dump(LOG_DEBUG, "The DT_INIT_ARRAYSZ is %zu\n", h->initarray_sz);
                     break;
                 case DT_PREINIT_ARRAYSZ:
                     if(val)
@@ -252,31 +252,31 @@ elfheader_t* ParseElfHeader(FILE* f, const char* name, int exec)
                     break;
                 case DT_FINI: // Exit hook
                     h->finientry = ptr;
-                    printf_log(LOG_DEBUG, "The DT_FINI is at address %p\n", (void*)h->finientry);
+                    printf_dump(LOG_DEBUG, "The DT_FINI is at address %p\n", (void*)h->finientry);
                     break;
                 case DT_FINI_ARRAY:
                     h->finiarray = ptr;
-                    printf_log(LOG_DEBUG, "The DT_FINI_ARRAY is at address %p\n", (void*)h->finiarray);
+                    printf_dump(LOG_DEBUG, "The DT_FINI_ARRAY is at address %p\n", (void*)h->finiarray);
                     break;
                 case DT_FINI_ARRAYSZ:
                     h->finiarray_sz = val / sizeof(Elf64_Addr);
-                    printf_log(LOG_DEBUG, "The DT_FINI_ARRAYSZ is %zu\n", h->finiarray_sz);
+                    printf_dump(LOG_DEBUG, "The DT_FINI_ARRAYSZ is %zu\n", h->finiarray_sz);
                     break;
                 case DT_VERNEEDNUM:
                     h->szVerNeed = val;
-                    printf_log(LOG_DEBUG, "The DT_VERNEEDNUM is %d\n", h->szVerNeed);
+                    printf_dump(LOG_DEBUG, "The DT_VERNEEDNUM is %d\n", h->szVerNeed);
                     break;
                 case DT_VERNEED:
                     h->VerNeed = (Elf64_Verneed*)ptr;
-                    printf_log(LOG_DEBUG, "The DT_VERNEED is at address %p\n", h->VerNeed);
+                    printf_dump(LOG_DEBUG, "The DT_VERNEED is at address %p\n", h->VerNeed);
                     break;
                 case DT_VERDEFNUM:
                     h->szVerDef = val;
-                    printf_log(LOG_DEBUG, "The DT_VERDEFNUM is %d\n", h->szVerDef);
+                    printf_dump(LOG_DEBUG, "The DT_VERDEFNUM is %d\n", h->szVerDef);
                     break;
                 case DT_VERDEF:
                     h->VerDef = (Elf64_Verdef*)ptr;
-                    printf_log(LOG_DEBUG, "The DT_VERDEF is at address %p\n", h->VerDef);
+                    printf_dump(LOG_DEBUG, "The DT_VERDEF is at address %p\n", h->VerDef);
                     break;
                 }
             }
@@ -286,7 +286,7 @@ elfheader_t* ParseElfHeader(FILE* f, const char* name, int exec)
                     FreeElfHeader(&h);
                     return NULL;
                 }
-                printf_log(LOG_DEBUG, "Rel Table @%p (0x%zx/0x%x)\n", (void*)h->rel, h->relsz, h->relent);
+                printf_dump(LOG_DEBUG, "Rel Table @%p (0x%zx/0x%x)\n", (void*)h->rel, h->relsz, h->relent);
             }
             if(h->rela) {
                 if(h->relaent != sizeof(Elf64_Rela)) {
@@ -294,7 +294,7 @@ elfheader_t* ParseElfHeader(FILE* f, const char* name, int exec)
                     FreeElfHeader(&h);
                     return NULL;
                 }
-                printf_log(LOG_DEBUG, "RelA Table @%p (0x%zx/0x%x)\n", (void*)h->rela, h->relasz, h->relaent);
+                printf_dump(LOG_DEBUG, "RelA Table @%p (0x%zx/0x%x)\n", (void*)h->rela, h->relasz, h->relaent);
             }
             if(h->jmprel) {
                 if(h->pltrel == DT_REL) {
@@ -311,7 +311,7 @@ elfheader_t* ParseElfHeader(FILE* f, const char* name, int exec)
                     FreeElfHeader(&h);
                     return NULL;
                 }
-                printf_log(LOG_DEBUG, "PLT Table @%p (type=%ld 0x%zx/0x%0x)\n", (void*)h->jmprel, h->pltrel, h->pltsz, h->pltent);
+                printf_dump(LOG_DEBUG, "PLT Table @%p (type=%ld 0x%zx/0x%0x)\n", (void*)h->jmprel, h->pltrel, h->pltsz, h->pltent);
             }
             if(h->DynStrTab && h->szDynStrTab) {
                 //DumpDynamicNeeded(h); cannot dump now, it's not loaded yet
@@ -322,43 +322,43 @@ elfheader_t* ParseElfHeader(FILE* f, const char* name, int exec)
         if(ii) {
             h->gotplt = h->SHEntries[ii].sh_addr;
             h->gotplt_end = h->gotplt + h->SHEntries[ii].sh_size;
-            printf_log(LOG_DEBUG, "The GOT.PLT Table is at address %p\n", (void*)h->gotplt);
+            printf_dump(LOG_DEBUG, "The GOT.PLT Table is at address %p\n", (void*)h->gotplt);
         }
         ii = FindSection(h->SHEntries, h->numSHEntries, h->SHStrTab, ".got");
         if(ii) {
             h->got = h->SHEntries[ii].sh_addr;
             h->got_end = h->got + h->SHEntries[ii].sh_size;
-            printf_log(LOG_DEBUG, "The GOT Table is at address %p..%p\n", (void*)h->got, (void*)h->got_end);
+            printf_dump(LOG_DEBUG, "The GOT Table is at address %p..%p\n", (void*)h->got, (void*)h->got_end);
         }
         ii = FindSection(h->SHEntries, h->numSHEntries, h->SHStrTab, ".plt");
         if(ii) {
             h->plt = h->SHEntries[ii].sh_addr;
             h->plt_end = h->plt + h->SHEntries[ii].sh_size;
-            printf_log(LOG_DEBUG, "The PLT Table is at address %p..%p\n", (void*)h->plt, (void*)h->plt_end);
+            printf_dump(LOG_DEBUG, "The PLT Table is at address %p..%p\n", (void*)h->plt, (void*)h->plt_end);
         }
         // grab version of symbols
         ii = FindSection(h->SHEntries, h->numSHEntries, h->SHStrTab, ".gnu.version");
         if(ii) {
             h->VerSym = (Elf64_Half*)(h->SHEntries[ii].sh_addr);
-            printf_log(LOG_DEBUG, "The .gnu.version is at address %p\n", h->VerSym);
+            printf_dump(LOG_DEBUG, "The .gnu.version is at address %p\n", h->VerSym);
         }
         // grab .text for main code
         ii = FindSection(h->SHEntries, h->numSHEntries, h->SHStrTab, ".text");
         if(ii) {
             h->text = (uintptr_t)(h->SHEntries[ii].sh_addr);
             h->textsz = h->SHEntries[ii].sh_size;
-            printf_log(LOG_DEBUG, "The .text is at address %p, and is %zu big\n", (void*)h->text, h->textsz);
+            printf_dump(LOG_DEBUG, "The .text is at address %p, and is %zu big\n", (void*)h->text, h->textsz);
         }
         ii = FindSection(h->SHEntries, h->numSHEntries, h->SHStrTab, ".eh_frame");
         if(ii) {
             h->ehframe = (uintptr_t)(h->SHEntries[ii].sh_addr);
             h->ehframe_end = h->ehframe + h->SHEntries[ii].sh_size;
-            printf_log(LOG_DEBUG, "The .eh_frame section is at address %p..%p\n", (void*)h->ehframe, (void*)h->ehframe_end);
+            printf_dump(LOG_DEBUG, "The .eh_frame section is at address %p..%p\n", (void*)h->ehframe, (void*)h->ehframe_end);
         }
         ii = FindSection(h->SHEntries, h->numSHEntries, h->SHStrTab, ".eh_frame_hdr");
         if(ii) {
             h->ehframehdr = (uintptr_t)(h->SHEntries[ii].sh_addr);
-            printf_log(LOG_DEBUG, "The .eh_frame_hdr section is at address %p\n", (void*)h->ehframehdr);
+            printf_dump(LOG_DEBUG, "The .eh_frame_hdr section is at address %p\n", (void*)h->ehframehdr);
         }
 
         LoadNamedSection(f, h->SHEntries, h->numSHEntries, h->SHStrTab, ".dynstr", "DynSym Strings", SHT_STRTAB, (void**)&h->DynStr, NULL);
@@ -370,19 +370,23 @@ elfheader_t* ParseElfHeader(FILE* f, const char* name, int exec)
 
 const char* GetSymbolVersion(elfheader_t* h, int version)
 {
-    if(!h->VerNeed || (version<2))
+    if(version<2)
         return NULL;
     /*if(version==1)
         return "*";*/
-    Elf64_Verneed *ver = (Elf64_Verneed*)((uintptr_t)h->VerNeed + h->delta);
-    while(ver) {
-        Elf64_Vernaux *aux = (Elf64_Vernaux*)((uintptr_t)ver + ver->vn_aux);
-        for(int j=0; j<ver->vn_cnt; ++j) {
+    if(h->VerNeed) {
+        Elf64_Verneed *ver = (Elf64_Verneed*)((uintptr_t)h->VerNeed + h->delta);
+        while(ver) {
+            Elf64_Vernaux *aux = (Elf64_Vernaux*)((uintptr_t)ver + ver->vn_aux);
+            for(int j=0; j<ver->vn_cnt; ++j) {
+                if(aux->vna_other==version) 
             if(aux->vna_other==version)
-                return h->DynStr+aux->vna_name;
-            aux = (Elf64_Vernaux*)((uintptr_t)aux + aux->vna_next);
+                if(aux->vna_other==version) 
+                    return h->DynStr+aux->vna_name;
+                aux = (Elf64_Vernaux*)((uintptr_t)aux + aux->vna_next);
+            }
+            ver = ver->vn_next?((Elf64_Verneed*)((uintptr_t)ver + ver->vn_next)):NULL;
         }
-        ver = ver->vn_next?((Elf64_Verneed*)((uintptr_t)ver + ver->vn_next)):NULL;
     }
     return GetParentSymbolVersion(h, version);  // if symbol is "internal", use Def table instead
 }
diff --git a/src/emu/x64run66.c b/src/emu/x64run66.c
index eeb64827..85ce674b 100644
--- a/src/emu/x64run66.c
+++ b/src/emu/x64run66.c
@@ -697,7 +697,12 @@ int Run66(x64emu_t *emu, rex_t rex, int rep)
             case 1:                 /* DEC Ed */

                 EW->word[0] = dec16(emu, EW->word[0]);

                 break;

-            /*case 6:

+            case 2:                 /* CALL NEAR Ed */

+                tmp64u = (uintptr_t)getAlternate((void*)ED->q[0]);

+                Push(emu, R_RIP);

+                R_RIP = tmp64u;

+                break;

+           /*case 6:

                 Push16(emu, EW->word[0]);

                 break;*/

             default:

diff --git a/src/emu/x64runf0.c b/src/emu/x64runf0.c
index 8874bf2d..422cd5b3 100644
--- a/src/emu/x64runf0.c
+++ b/src/emu/x64runf0.c
@@ -886,6 +886,29 @@ int RunF0(x64emu_t *emu, rex_t rex)
             pthread_mutex_unlock(&emu->context->mutex_lock);

 #endif

             break;            

+

+        case 0xF6:                      /* GRP3 Eb(,Ib) */

+            nextop = F8;

+            tmp8u = (nextop>>3)&7;

+            GETEB((tmp8u<2)?1:0);

+            switch(tmp8u) {

+                case 2:                 /* NOT Eb */

+#ifdef DYNAREC

+                    do {

+                        tmp8u2 = native_lock_read_b(EB); 

+                        tmp8u2 = not8(emu, tmp8u2);

+                    } while(native_lock_write_b(EB, tmp8u2));

+#else

+                    pthread_mutex_lock(&emu->context->mutex_lock);

+                    EB->byte[0] = not8(emu, EB->byte[0]);

+                    pthread_mutex_unlock(&emu->context->mutex_lock);

+#endif

+                    break;

+                default:

+                    return 1;

+            }

+            break;

+

         case 0xFF:              /* GRP 5 Ed */

             nextop = F8;

             GETED(0);

diff --git a/src/include/debug.h b/src/include/debug.h
index 30ca16da..f1abbc9b 100755
--- a/src/include/debug.h
+++ b/src/include/debug.h
@@ -40,6 +40,7 @@ extern int box64_prefer_wrapped;
 extern int box64_prefer_emulated;
 extern int box64_steam;
 extern int box64_wine;
+extern int box64_musl;
 extern int box64_nopulse;   // disabling the use of wrapped pulseaudio
 extern int box64_nogtk; // disabling the use of wrapped gtk
 extern int box64_novulkan;  // disabling the use of wrapped vulkan
diff --git a/src/librarian/library.c b/src/librarian/library.c
index 2c8ebd5a..57cef4e4 100755
--- a/src/librarian/library.c
+++ b/src/librarian/library.c
@@ -279,6 +279,13 @@ static int loadEmulatedLib(const char* libname, library_t *lib, box64context_t*
         lib->priv.n.weaksymbols = kh_init(mapsymbols);
         lib->priv.n.localsymbols = kh_init(mapsymbols);
 
+        if(strcmp(lib->path, libname)) {
+            free(lib->path);
+            lib->path = realpath(libname, NULL);
+            if(!lib->path)
+                lib->path = strdup(libname);
+        }
+
         printf_log(LOG_INFO, "Using emulated %s\n", libname);
         #ifdef DYNAREC
         if(libname && strstr(libname, "libmonobdwgc-2.0.so")) {
@@ -334,7 +341,9 @@ library_t *NewLibrary(const char* path, box64context_t* context)
 {
     printf_log(LOG_DEBUG, "Trying to load \"%s\"\n", path);
     library_t *lib = (library_t*)calloc(1, sizeof(library_t));
-    lib->path = strdup(path);
+    lib->path = realpath(path, NULL);
+    if(!lib->path)
+        lib->path = strdup(path);
     if(libGL && !strcmp(path, libGL))
         lib->name = strdup("libGL.so.1");
     else
@@ -557,7 +566,9 @@ int IsSameLib(library_t* lib, const char* path)
         if(strcmp(name, lib->name)==0)
             ret=1;
     } else {
-        if(!strcmp(path, lib->path))
+        char rpath[PATH_MAX];
+        realpath(path, rpath);
+        if(!strcmp(rpath, lib->path))
             ret=1;
     }
     if(!ret) {
diff --git a/src/library_list.h b/src/library_list.h
index 7c3c41cb..1fadc421 100755
--- a/src/library_list.h
+++ b/src/library_list.h
@@ -3,6 +3,7 @@
 #endif
 
 GO("libc.so.6", libc)
+GO("libc.musl-x86_64.so.1", libdl)
 GO("libpthread.so.0", libpthread)
 GO("librt.so.1", librt)
 GO("libEGL.so.1", libegl)
diff --git a/src/libtools/threads.c b/src/libtools/threads.c
index c95fd598..684c5fdc 100755
--- a/src/libtools/threads.c
+++ b/src/libtools/threads.c
@@ -432,6 +432,16 @@ EXPORT int my_pthread_getattr_np(x64emu_t* emu, pthread_t thread_id, pthread_att
 	(void)emu;
 	return pthread_getattr_np(thread_id, getAlignedAttrWithInit(attr, 0));
 }
+EXPORT int my_pthread_getattr_default_np(x64emu_t* emu, pthread_attr_t* attr)
+{
+	(void)emu;
+	return pthread_getattr_default_np(getAlignedAttrWithInit(attr, 0));
+}
+EXPORT int my_pthread_setattr_default_np(x64emu_t* emu, pthread_attr_t* attr)
+{
+	(void)emu;
+	return pthread_setattr_default_np(getAlignedAttr(attr));
+}
 #endif
 
 EXPORT int my_pthread_create(x64emu_t *emu, void* t, void* attr, void* start_routine, void* arg)
diff --git a/src/main.c b/src/main.c
index 9cc99ddd..40b58412 100755
--- a/src/main.c
+++ b/src/main.c
@@ -83,6 +83,7 @@ int box64_mapclean = 0;
 int box64_zoom = 0;
 int box64_steam = 0;
 int box64_wine = 0;
+int box64_musl = 0;
 int box64_nopulse = 0;
 int box64_nogtk = 0;
 int box64_novulkan = 0;
@@ -1025,6 +1026,7 @@ int main(int argc, const char **argv, char **env) {
         pressure_vessel(argc, argv, nextarg+1);
     }
     #endif
+    int ld_libs_args = -1;
     // check if this is wine
     if(!strcmp(prog, "wine64")
      || !strcmp(prog, "wine64-development") 
@@ -1041,6 +1043,22 @@ int main(int argc, const char **argv, char **env) {
             exit(0);    // exiting, it doesn't work anyway
         }
         box64_wine = 1;
+    } else 
+    // check if ld-musl-x86_64.so.1 is used
+    if(strstr(prog, "ld-musl-x86_64.so.1")) {
+        printf_log(LOG_INFO, "BOX64: ld-musl detected, trying to workaround and use system ld-linux\n");
+        box64_musl = 1;
+        // skip ld-musl and go through args unti "--" is found, handling "--library-path" to add some libs to BOX64_LD_LIBRARY
+        ++nextarg;
+        while(strcmp(argv[nextarg], "--")) {
+            if(!strcmp(argv[nextarg], "--library-path")) {
+                ++nextarg;
+                ld_libs_args = nextarg;
+            }
+            ++nextarg;
+        }
+        ++nextarg;
+        prog = argv[nextarg];
     }
     // check if this is wineserver
     if(!strcmp(prog, "wineserver") || !strcmp(prog, "wineserver64") || (strlen(prog)>9 && !strcmp(prog+strlen(prog)-strlen("/wineserver"), "/wineserver"))) {
@@ -1055,6 +1073,9 @@ int main(int argc, const char **argv, char **env) {
 
     // check BOX64_LD_LIBRARY_PATH and load it
     LoadEnvVars(my_context);
+    // Append ld_list if it exist
+    if(ld_libs_args!=-1)
+        AppendList(&my_context->box64_ld_lib, argv[ld_libs_args], 1);
 
     my_context->box64path = ResolveFile(argv[0], &my_context->box64_path);
     // prepare all other env. var
diff --git a/src/wrapped/generated/functions_list.txt b/src/wrapped/generated/functions_list.txt
index 69be082b..465b9e10 100644
--- a/src/wrapped/generated/functions_list.txt
+++ b/src/wrapped/generated/functions_list.txt
@@ -685,6 +685,7 @@
 #() iFEpip
 #() iFEpiV
 #() iFEpiA
+#() iFEpup
 #() iFEpUp
 #() iFEpLi
 #() iFEpLp
@@ -815,6 +816,7 @@
 #() uFEppp
 #() uFifff
 #() uFuuuu
+#() uFpiip
 #() uFpipu
 #() uFpipp
 #() uFpCCC
@@ -852,6 +854,7 @@
 #() lFppii
 #() lFppip
 #() lFpppL
+#() LFEppL
 #() LFEppp
 #() LFippL
 #() LFippp
@@ -2138,6 +2141,8 @@ wrappedcrypto:
   - PEM_write_bio_ECPrivateKey
   - PEM_write_bio_RSAPrivateKey
 wrappedcurl:
+- iFpup:
+  - curl_multi_setopt
 - uFpup:
   - curl_easy_setopt
 wrappeddbus:
@@ -2679,6 +2684,7 @@ wrappedlibc:
   - iopl
 - iFp:
   - _setjmp
+  - atexit
   - getcontext
   - setcontext
   - setjmp
@@ -2713,6 +2719,7 @@ wrappedlibc:
 - iFpi:
   - __sigsetjmp
   - backtrace
+  - sigsetjmp
 - iFpL:
   - munmap
 - iFpp:
@@ -2813,6 +2820,9 @@ wrappedlibc:
   - __wprintf_chk
 - lFppL:
   - readlink
+- LFppL:
+  - strlcat
+  - strlcpy
 - pFpip:
   - fts_open
 - pFppp:
@@ -3058,12 +3068,14 @@ wrappedlibpthread:
   - pthread_barrierattr_init
   - pthread_condattr_destroy
   - pthread_condattr_init
+  - pthread_getattr_default_np
   - pthread_mutex_destroy
   - pthread_mutex_lock
   - pthread_mutex_trylock
   - pthread_mutex_unlock
   - pthread_mutexattr_destroy
   - pthread_mutexattr_init
+  - pthread_setattr_default_np
 - vFpi:
   - _pthread_cleanup_pop
   - _pthread_cleanup_pop_restore
diff --git a/src/wrapped/generated/wrappedcurltypes.h b/src/wrapped/generated/wrappedcurltypes.h
index e5f8c9cd..4542b673 100644
--- a/src/wrapped/generated/wrappedcurltypes.h
+++ b/src/wrapped/generated/wrappedcurltypes.h
@@ -11,9 +11,11 @@
 #define ADDED_FUNCTIONS() 
 #endif
 
+typedef int64_t (*iFpup_t)(void*, uint64_t, void*);
 typedef uint64_t (*uFpup_t)(void*, uint64_t, void*);
 
 #define SUPER() ADDED_FUNCTIONS() \
+	GO(curl_multi_setopt, iFpup_t) \
 	GO(curl_easy_setopt, uFpup_t)
 
 #endif // __wrappedcurlTYPES_H_
diff --git a/src/wrapped/generated/wrappedlibctypes.h b/src/wrapped/generated/wrappedlibctypes.h
index 2e911b45..989cdf64 100644
--- a/src/wrapped/generated/wrappedlibctypes.h
+++ b/src/wrapped/generated/wrappedlibctypes.h
@@ -50,6 +50,7 @@ typedef int64_t (*iFppA_t)(void*, void*, va_list);
 typedef int64_t (*iFpOu_t)(void*, int32_t, uint64_t);
 typedef intptr_t (*lFipV_t)(int64_t, void*, ...);
 typedef intptr_t (*lFppL_t)(void*, void*, uintptr_t);
+typedef uintptr_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*, ...);
@@ -93,6 +94,7 @@ typedef int64_t (*iFppipppp_t)(void*, void*, int64_t, void*, void*, void*, void*
 	GO(vfork, iFv_t) \
 	GO(iopl, iFi_t) \
 	GO(_setjmp, iFp_t) \
+	GO(atexit, iFp_t) \
 	GO(getcontext, iFp_t) \
 	GO(setcontext, iFp_t) \
 	GO(setjmp, iFp_t) \
@@ -117,6 +119,7 @@ typedef int64_t (*iFppipppp_t)(void*, void*, int64_t, void*, void*, void*, void*
 	GO(fstat64, iFip_t) \
 	GO(__sigsetjmp, iFpi_t) \
 	GO(backtrace, iFpi_t) \
+	GO(sigsetjmp, iFpi_t) \
 	GO(munmap, iFpL_t) \
 	GO(__vprintf_chk, iFpp_t) \
 	GO(dl_iterate_phdr, iFpp_t) \
@@ -193,6 +196,8 @@ typedef int64_t (*iFppipppp_t)(void*, void*, int64_t, void*, void*, void*, void*
 	GO(open64, iFpOu_t) \
 	GO(__wprintf_chk, lFipV_t) \
 	GO(readlink, lFppL_t) \
+	GO(strlcat, LFppL_t) \
+	GO(strlcpy, LFppL_t) \
 	GO(fts_open, pFpip_t) \
 	GO(tsearch, pFppp_t) \
 	GO(__syslog_chk, vFiipV_t) \
diff --git a/src/wrapped/generated/wrappedlibpthreadtypes.h b/src/wrapped/generated/wrappedlibpthreadtypes.h
index c22ae27b..ae6e10a3 100644
--- a/src/wrapped/generated/wrappedlibpthreadtypes.h
+++ b/src/wrapped/generated/wrappedlibpthreadtypes.h
@@ -42,12 +42,14 @@ typedef int64_t (*iFpppp_t)(void*, void*, void*, void*);
 	GO(pthread_barrierattr_init, iFp_t) \
 	GO(pthread_condattr_destroy, iFp_t) \
 	GO(pthread_condattr_init, iFp_t) \
+	GO(pthread_getattr_default_np, iFp_t) \
 	GO(pthread_mutex_destroy, iFp_t) \
 	GO(pthread_mutex_lock, iFp_t) \
 	GO(pthread_mutex_trylock, iFp_t) \
 	GO(pthread_mutex_unlock, iFp_t) \
 	GO(pthread_mutexattr_destroy, iFp_t) \
 	GO(pthread_mutexattr_init, iFp_t) \
+	GO(pthread_setattr_default_np, iFp_t) \
 	GO(_pthread_cleanup_pop, vFpi_t) \
 	GO(_pthread_cleanup_pop_restore, vFpi_t) \
 	GO(pthread_getattr_np, iFLp_t) \
diff --git a/src/wrapped/generated/wrapper.c b/src/wrapped/generated/wrapper.c
index 2a214391..f9606533 100644
--- a/src/wrapped/generated/wrapper.c
+++ b/src/wrapped/generated/wrapper.c
@@ -719,6 +719,7 @@ typedef int64_t (*iFEpii_t)(x64emu_t*, void*, int64_t, int64_t);
 typedef int64_t (*iFEpip_t)(x64emu_t*, void*, int64_t, void*);
 typedef int64_t (*iFEpiV_t)(x64emu_t*, void*, int64_t, void*);
 typedef int64_t (*iFEpiA_t)(x64emu_t*, void*, int64_t, void*);
+typedef int64_t (*iFEpup_t)(x64emu_t*, void*, uint64_t, void*);
 typedef int64_t (*iFEpUp_t)(x64emu_t*, void*, uint64_t, void*);
 typedef int64_t (*iFEpLi_t)(x64emu_t*, void*, uintptr_t, int64_t);
 typedef int64_t (*iFEpLp_t)(x64emu_t*, void*, uintptr_t, void*);
@@ -849,6 +850,7 @@ typedef uint64_t (*uFEpup_t)(x64emu_t*, void*, uint64_t, void*);
 typedef uint64_t (*uFEppp_t)(x64emu_t*, void*, void*, void*);
 typedef uint64_t (*uFifff_t)(int64_t, float, float, float);
 typedef uint64_t (*uFuuuu_t)(uint64_t, uint64_t, uint64_t, uint64_t);
+typedef uint64_t (*uFpiip_t)(void*, int64_t, int64_t, void*);
 typedef uint64_t (*uFpipu_t)(void*, int64_t, void*, uint64_t);
 typedef uint64_t (*uFpipp_t)(void*, int64_t, void*, void*);
 typedef uint64_t (*uFpCCC_t)(void*, uint8_t, uint8_t, uint8_t);
@@ -886,6 +888,7 @@ typedef intptr_t (*lFpilp_t)(void*, int64_t, intptr_t, void*);
 typedef intptr_t (*lFppii_t)(void*, void*, int64_t, int64_t);
 typedef intptr_t (*lFppip_t)(void*, void*, int64_t, void*);
 typedef intptr_t (*lFpppL_t)(void*, void*, void*, uintptr_t);
+typedef uintptr_t (*LFEppL_t)(x64emu_t*, void*, void*, uintptr_t);
 typedef uintptr_t (*LFEppp_t)(x64emu_t*, void*, void*, void*);
 typedef uintptr_t (*LFippL_t)(int64_t, void*, void*, uintptr_t);
 typedef uintptr_t (*LFippp_t)(int64_t, void*, void*, void*);
@@ -2814,6 +2817,7 @@ void iFEpii(x64emu_t *emu, uintptr_t fcn) { iFEpii_t fn = (iFEpii_t)fcn; R_RAX=(
 void iFEpip(x64emu_t *emu, uintptr_t fcn) { iFEpip_t fn = (iFEpip_t)fcn; R_RAX=(int64_t)fn(emu, (void*)R_RDI, (int64_t)R_RSI, (void*)R_RDX); }
 void iFEpiV(x64emu_t *emu, uintptr_t fcn) { iFEpiV_t fn = (iFEpiV_t)fcn; R_RAX=(int64_t)fn(emu, (void*)R_RDI, (int64_t)R_RSI, (void*)(R_RSP + 8)); }
 void iFEpiA(x64emu_t *emu, uintptr_t fcn) { iFEpiA_t fn = (iFEpiA_t)fcn; R_RAX=(int64_t)fn(emu, (void*)R_RDI, (int64_t)R_RSI, (void*)R_RDX); }
+void iFEpup(x64emu_t *emu, uintptr_t fcn) { iFEpup_t fn = (iFEpup_t)fcn; R_RAX=(int64_t)fn(emu, (void*)R_RDI, (uint64_t)R_RSI, (void*)R_RDX); }
 void iFEpUp(x64emu_t *emu, uintptr_t fcn) { iFEpUp_t fn = (iFEpUp_t)fcn; R_RAX=(int64_t)fn(emu, (void*)R_RDI, (uint64_t)R_RSI, (void*)R_RDX); }
 void iFEpLi(x64emu_t *emu, uintptr_t fcn) { iFEpLi_t fn = (iFEpLi_t)fcn; R_RAX=(int64_t)fn(emu, (void*)R_RDI, (uintptr_t)R_RSI, (int64_t)R_RDX); }
 void iFEpLp(x64emu_t *emu, uintptr_t fcn) { iFEpLp_t fn = (iFEpLp_t)fcn; R_RAX=(int64_t)fn(emu, (void*)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX); }
@@ -2944,6 +2948,7 @@ void uFEpup(x64emu_t *emu, uintptr_t fcn) { uFEpup_t fn = (uFEpup_t)fcn; R_RAX=(
 void uFEppp(x64emu_t *emu, uintptr_t fcn) { uFEppp_t fn = (uFEppp_t)fcn; R_RAX=(uint64_t)fn(emu, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX); }
 void uFifff(x64emu_t *emu, uintptr_t fcn) { uFifff_t fn = (uFifff_t)fcn; R_RAX=(uint64_t)fn((int64_t)R_RDI, emu->xmm[0].f[0], emu->xmm[1].f[0], emu->xmm[2].f[0]); }
 void uFuuuu(x64emu_t *emu, uintptr_t fcn) { uFuuuu_t fn = (uFuuuu_t)fcn; R_RAX=(uint64_t)fn((uint64_t)R_RDI, (uint64_t)R_RSI, (uint64_t)R_RDX, (uint64_t)R_RCX); }
+void uFpiip(x64emu_t *emu, uintptr_t fcn) { uFpiip_t fn = (uFpiip_t)fcn; R_RAX=(uint64_t)fn((void*)R_RDI, (int64_t)R_RSI, (int64_t)R_RDX, (void*)R_RCX); }
 void uFpipu(x64emu_t *emu, uintptr_t fcn) { uFpipu_t fn = (uFpipu_t)fcn; R_RAX=(uint64_t)fn((void*)R_RDI, (int64_t)R_RSI, (void*)R_RDX, (uint64_t)R_RCX); }
 void uFpipp(x64emu_t *emu, uintptr_t fcn) { uFpipp_t fn = (uFpipp_t)fcn; R_RAX=(uint64_t)fn((void*)R_RDI, (int64_t)R_RSI, (void*)R_RDX, (void*)R_RCX); }
 void uFpCCC(x64emu_t *emu, uintptr_t fcn) { uFpCCC_t fn = (uFpCCC_t)fcn; R_RAX=(uint64_t)fn((void*)R_RDI, (uint8_t)R_RSI, (uint8_t)R_RDX, (uint8_t)R_RCX); }
@@ -2981,6 +2986,7 @@ void lFpilp(x64emu_t *emu, uintptr_t fcn) { lFpilp_t fn = (lFpilp_t)fcn; R_RAX=(
 void lFppii(x64emu_t *emu, uintptr_t fcn) { lFppii_t fn = (lFppii_t)fcn; R_RAX=(intptr_t)fn((void*)R_RDI, (void*)R_RSI, (int64_t)R_RDX, (int64_t)R_RCX); }
 void lFppip(x64emu_t *emu, uintptr_t fcn) { lFppip_t fn = (lFppip_t)fcn; R_RAX=(intptr_t)fn((void*)R_RDI, (void*)R_RSI, (int64_t)R_RDX, (void*)R_RCX); }
 void lFpppL(x64emu_t *emu, uintptr_t fcn) { lFpppL_t fn = (lFpppL_t)fcn; R_RAX=(intptr_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uintptr_t)R_RCX); }
+void LFEppL(x64emu_t *emu, uintptr_t fcn) { LFEppL_t fn = (LFEppL_t)fcn; R_RAX=(uintptr_t)fn(emu, (void*)R_RDI, (void*)R_RSI, (uintptr_t)R_RDX); }
 void LFEppp(x64emu_t *emu, uintptr_t fcn) { LFEppp_t fn = (LFEppp_t)fcn; R_RAX=(uintptr_t)fn(emu, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX); }
 void LFippL(x64emu_t *emu, uintptr_t fcn) { LFippL_t fn = (LFippL_t)fcn; R_RAX=(uintptr_t)fn((int64_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (uintptr_t)R_RCX); }
 void LFippp(x64emu_t *emu, uintptr_t fcn) { LFippp_t fn = (LFippp_t)fcn; R_RAX=(uintptr_t)fn((int64_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX); }
@@ -4928,6 +4934,7 @@ int isSimpleWrapper(wrapper_t fun) {
 	if (fun == &IFpppp) return 1;
 	if (fun == &uFifff) return 4;
 	if (fun == &uFuuuu) return 1;
+	if (fun == &uFpiip) return 1;
 	if (fun == &uFpipu) return 1;
 	if (fun == &uFpipp) return 1;
 	if (fun == &uFpCCC) return 1;
diff --git a/src/wrapped/generated/wrapper.h b/src/wrapped/generated/wrapper.h
index 756eb081..f4aca073 100644
--- a/src/wrapped/generated/wrapper.h
+++ b/src/wrapped/generated/wrapper.h
@@ -718,6 +718,7 @@ void iFEpii(x64emu_t *emu, uintptr_t fnc);
 void iFEpip(x64emu_t *emu, uintptr_t fnc);
 void iFEpiV(x64emu_t *emu, uintptr_t fnc);
 void iFEpiA(x64emu_t *emu, uintptr_t fnc);
+void iFEpup(x64emu_t *emu, uintptr_t fnc);
 void iFEpUp(x64emu_t *emu, uintptr_t fnc);
 void iFEpLi(x64emu_t *emu, uintptr_t fnc);
 void iFEpLp(x64emu_t *emu, uintptr_t fnc);
@@ -848,6 +849,7 @@ void uFEpup(x64emu_t *emu, uintptr_t fnc);
 void uFEppp(x64emu_t *emu, uintptr_t fnc);
 void uFifff(x64emu_t *emu, uintptr_t fnc);
 void uFuuuu(x64emu_t *emu, uintptr_t fnc);
+void uFpiip(x64emu_t *emu, uintptr_t fnc);
 void uFpipu(x64emu_t *emu, uintptr_t fnc);
 void uFpipp(x64emu_t *emu, uintptr_t fnc);
 void uFpCCC(x64emu_t *emu, uintptr_t fnc);
@@ -885,6 +887,7 @@ void lFpilp(x64emu_t *emu, uintptr_t fnc);
 void lFppii(x64emu_t *emu, uintptr_t fnc);
 void lFppip(x64emu_t *emu, uintptr_t fnc);
 void lFpppL(x64emu_t *emu, uintptr_t fnc);
+void LFEppL(x64emu_t *emu, uintptr_t fnc);
 void LFEppp(x64emu_t *emu, uintptr_t fnc);
 void LFippL(x64emu_t *emu, uintptr_t fnc);
 void LFippp(x64emu_t *emu, uintptr_t fnc);
diff --git a/src/wrapped/wrappedcurl.c b/src/wrapped/wrappedcurl.c
index e9dc02fb..d13930d0 100755
--- a/src/wrapped/wrappedcurl.c
+++ b/src/wrapped/wrappedcurl.c
@@ -30,6 +30,7 @@ const char* curlName = "libcurl.so.4";
 #define FUNCTIONPOINT 20000
 #define OFF_T         30000
 #define CINIT(name,type,number) CURLOPT_ ## name = type + number
+#define CURLOPT(na,t,nu) na = t + nu
 
 typedef enum {
   CINIT(WRITEDATA, OBJECTPOINT, 1),
@@ -305,11 +306,33 @@ typedef enum {
   CINIT(ALTSVC, STRINGPOINT, 287),
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
+
+typedef enum {
+  CURLOPT(CURLMOPT_SOCKETFUNCTION, FUNCTIONPOINT, 1),
+  CURLOPT(CURLMOPT_SOCKETDATA, OBJECTPOINT, 2),
+  CURLOPT(CURLMOPT_PIPELINING, LONG, 3),
+  CURLOPT(CURLMOPT_TIMERFUNCTION, FUNCTIONPOINT, 4),
+  CURLOPT(CURLMOPT_TIMERDATA, OBJECTPOINT, 5),
+  CURLOPT(CURLMOPT_MAXCONNECTS, LONG, 6),
+  CURLOPT(CURLMOPT_MAX_HOST_CONNECTIONS, LONG, 7),
+  CURLOPT(CURLMOPT_MAX_PIPELINE_LENGTH, LONG, 8),
+  CURLOPT(CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE, OFF_T, 9),
+  CURLOPT(CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, OFF_T, 10),
+  CURLOPT(CURLMOPT_PIPELINING_SITE_BL, OBJECTPOINT, 11),
+  CURLOPT(CURLMOPT_PIPELINING_SERVER_BL, OBJECTPOINT, 12),
+  CURLOPT(CURLMOPT_MAX_TOTAL_CONNECTIONS, LONG, 13),
+  CURLOPT(CURLMOPT_PUSHFUNCTION, FUNCTIONPOINT, 14),
+  CURLOPT(CURLMOPT_PUSHDATA, OBJECTPOINT, 15),
+  CURLOPT(CURLMOPT_MAX_CONCURRENT_STREAMS, LONG, 16),
+  CURLMOPT_LASTENTRY /* the last unused */
+} CURLMoption;
+
 #undef LONG
 #undef OBJECTPOINT
 #undef STRINGPOINT
 #undef FUNCTIONPOINT
 #undef OFF_T
+#undef CURLOPT
 #undef CINIT
 
 #define SUPER() \
@@ -478,6 +501,76 @@ static void* find_progress_int_Fct(void* fct)
     printf_log(LOG_NONE, "Warning, no more slot for curl progress_int callback\n");
     return NULL;
 }
+
+// socket
+#define GO(A)   \
+static uintptr_t my_socket_fct_##A = 0;                                         \
+static int my_socket_##A(void *a, int b, int c, void* d, void* e)               \
+{                                                                               \
+    return (int)RunFunction(my_context, my_socket_fct_##A, 5, a, b, c, d, e);   \
+}
+SUPER()
+#undef GO
+static void* find_socket_Fct(void* fct)
+{
+    if(!fct) return NULL;
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_socket_fct_##A == (uintptr_t)fct) return my_socket_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_socket_fct_##A == 0) {my_socket_fct_##A = (uintptr_t)fct; return my_socket_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for curl socket callback\n");
+    return NULL;
+}
+
+// timer
+#define GO(A)   \
+static uintptr_t my_timer_fct_##A = 0;                                  \
+static int my_timer_##A(void *a, long b, void* c)                       \
+{                                                                       \
+    return (int)RunFunction(my_context, my_timer_fct_##A, 3, a, b, c);  \
+}
+SUPER()
+#undef GO
+static void* find_timer_Fct(void* fct)
+{
+    if(!fct) return NULL;
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_timer_fct_##A == (uintptr_t)fct) return my_timer_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_timer_fct_##A == 0) {my_timer_fct_##A = (uintptr_t)fct; return my_timer_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for curl timer callback\n");
+    return NULL;
+}
+
+// push
+#define GO(A)   \
+static uintptr_t my_push_fct_##A = 0;                                       \
+static int my_push_##A(void *a, void* b, size_t c, void* d, void* e)        \
+{                                                                           \
+    return (int)RunFunction(my_context, my_push_fct_##A, 5, a, b, c, d, e); \
+}
+SUPER()
+#undef GO
+static void* find_push_Fct(void* fct)
+{
+    if(!fct) return NULL;
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_push_fct_##A == (uintptr_t)fct) return my_push_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_push_fct_##A == 0) {my_push_fct_##A = (uintptr_t)fct; return my_push_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for curl push callback\n");
+    return NULL;
+}
+
 #undef SUPER
 
 EXPORT uint32_t my_curl_easy_setopt(x64emu_t* emu, void* handle, uint32_t option, void* param)
@@ -542,6 +635,21 @@ EXPORT uint32_t my_curl_easy_setopt(x64emu_t* emu, void* handle, uint32_t option
     }
 }
 
+EXPORT uint32_t my_curl_multi_setopt(x64emu_t* emu, void* handle, uint32_t option, void* param)
+{
+    (void)emu;
+
+    switch(option) {
+        case CURLMOPT_SOCKETFUNCTION:
+            return my->curl_multi_setopt(handle, option, find_socket_Fct(param));
+        case CURLMOPT_TIMERFUNCTION:
+            return my->curl_multi_setopt(handle, option, find_timer_Fct(param));
+        case CURLMOPT_PUSHFUNCTION:
+            return my->curl_multi_setopt(handle, option, find_push_Fct(param));
+        default:
+            return my->curl_multi_setopt(handle, option, param);
+    }
+}
 
 #define CUSTOM_INIT \
     getMy(lib);
diff --git a/src/wrapped/wrappedcurl_private.h b/src/wrapped/wrappedcurl_private.h
index 9d7e6cc5..ffcc1050 100755
--- a/src/wrapped/wrappedcurl_private.h
+++ b/src/wrapped/wrappedcurl_private.h
@@ -44,16 +44,16 @@ GO(curl_global_init, uFu)
 //GO(curl_msnprintf, 
 //GO(curl_msprintf, 
 GO(curl_multi_add_handle, uFpp)
-//GO(curl_multi_assign, 
+GO(curl_multi_assign, uFpip)
 GO(curl_multi_cleanup, uFp)
 GO(curl_multi_fdset, uFppppp)
 GO(curl_multi_info_read, pFpp)
 GO(curl_multi_init, pFv)
 GO(curl_multi_perform, uFpp)
 GO(curl_multi_remove_handle, uFpp)
-//GO(curl_multi_setopt, 
+GOM(curl_multi_setopt, iFEpup)
 //GO(curl_multi_socket, 
-//GO(curl_multi_socket_action, 
+GO(curl_multi_socket_action, uFpiip)
 //GO(curl_multi_socket_all, 
 GO(curl_multi_strerror, pFi)
 GO(curl_multi_timeout, iFpp)
diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c
index 3ef151f5..6c407414 100755
--- a/src/wrapped/wrappedlibc.c
+++ b/src/wrapped/wrappedlibc.c
@@ -2149,7 +2149,10 @@ EXPORT int32_t my___sigsetjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/vo
         ((__jmp_buf_tag_t*)p)->__mask_was_saved = 0;
     return 0;
 }
-
+EXPORT int32_t my_sigsetjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p, int savesigs)
+{
+    return my___sigsetjmp(emu, p, savesigs);
+}
 EXPORT int32_t my__setjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p)
 {
     return  my___sigsetjmp(emu, p, 0);
@@ -2730,6 +2733,23 @@ EXPORT void my___cxa_pure_virtual(x64emu_t* emu)
     abort();
 }
 
+EXPORT size_t my_strlcpy(x64emu_t* emu, void* dst, void* src, size_t l)
+{
+    strncpy(dst, src, l-1);
+    ((char*)dst)[l-1] = '\0';
+    return strlen(src);
+}
+EXPORT size_t my_strlcat(x64emu_t* emu, void* dst, void* src, size_t l)
+{
+    size_t s = strlen(dst);
+    if(s>=l)
+        return l;
+    strncat(dst, src, l-1);
+    ((char*)dst)[l-1] = '\0';
+    return s+strlen(src);
+}
+
+
 EXPORT char** my_environ = NULL;
 EXPORT char** my__environ = NULL;
 EXPORT char** my___environ = NULL;  // all aliases
diff --git a/src/wrapped/wrappedlibc_private.h b/src/wrapped/wrappedlibc_private.h
index 9811861c..492bd512 100755
--- a/src/wrapped/wrappedlibc_private.h
+++ b/src/wrapped/wrappedlibc_private.h
@@ -62,6 +62,7 @@ GOM(__asprintf_chk, iFEpipV)
 GO(__assert, vFppi)
 GO(__assert_fail, vFppup)
 GO(__assert_perror_fail, vFipup)
+GOM(atexit, iFEp)
 GO(atof, dFp)
 GO(atoi, iFp)
 GO(atol, lFp)
@@ -1703,6 +1704,7 @@ GO(sigrelse, iFi)
 //GOW(sigreturn, iF!)
 GOM(sigset, pFEip)
 GOM(__sigsetjmp, iFEpi)
+GOM(sigsetjmp, iFEpi)
 GOW(sigsetmask, iFi)
 //GO(sigstack, iF!!)
 GO(__sigsuspend, iFp)
@@ -2303,6 +2305,9 @@ GOM(_ITM_deregisterTMCloneTable, vFEp)
 GOM(__register_frame_info, vFpp)    // faked function
 GOM(__deregister_frame_info, pFp)
 
+GOM(strlcpy, LFEppL)
+GOM(strlcat, LFEppL)
+
 GOWM(__cxa_pure_virtual, vFEv)     // create a function to trap pure virtual call
 
 DATAM(program_invocation_name, sizeof(void*))
diff --git a/src/wrapped/wrappedlibdl.c b/src/wrapped/wrappedlibdl.c
index d8582536..903c2b9e 100755
--- a/src/wrapped/wrappedlibdl.c
+++ b/src/wrapped/wrappedlibdl.c
@@ -62,7 +62,7 @@ void* my_dlopen(x64emu_t* emu, void *filename, int flag)
     library_t *lib = NULL;
     dlprivate_t *dl = my_context->dlprivate;
     size_t dlopened = 0;
-    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
+    int is_local = (flag&0x100)?0:1;  // if not global, then local, and that means symbols are not put in the global "pot" for other libs
     CLEARERR
     if(filename) {
         char* rfilename = (char*)alloca(MAX_PATH);
@@ -138,7 +138,7 @@ void* my_dlopen(x64emu_t* emu, void *filename, int flag)
         // Then open the lib
         const char* libs[] = {rfilename};
         my_context->deferedInit = 1;
-        int bindnow = (flag&0x2)?1:0;
+        int bindnow = (!box64_musl && (flag&0x2))?1:0;
         if(AddNeededLib(NULL, NULL, NULL, is_local, bindnow, libs, 1, emu->context, emu)) {
             printf_log(LOG_INFO, "Warning: Cannot dlopen(\"%s\"/%p, %X)\n", rfilename, filename, flag);
             if(!dl->last_error)
@@ -553,5 +553,9 @@ int my_dlinfo(x64emu_t* emu, void* handle, int request, void* info)
     return -1;
 }
 
+#define CUSTOM_INIT\
+    setNeededLibs(lib, 1, "libc.so.6");
+
+
 // define all standard library functions
 #include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibm_private.h b/src/wrapped/wrappedlibm_private.h
index b8245298..482c36b2 100755
--- a/src/wrapped/wrappedlibm_private.h
+++ b/src/wrapped/wrappedlibm_private.h
@@ -92,7 +92,11 @@ GO2(cbrtl, KFK, cbrt)
 // ccosl    // Weak
 GOW(ceil, dFd)
 GOW(ceilf, fFf)
-// ceill    // Weak
+#ifdef HAVE_LD80BITS
+GOW(ceill, DFD)    // Weak
+#else
+GO2(ceill, KFK, ceil)
+#endif
 //GOS(cexp, pFpV)     // Weak, return complex
 //GOM(cexpf, UFV)     // Weak, return complex
 // cexpl    // Weak
@@ -185,8 +189,8 @@ GOW(expm1f, fFf)
 GOW(fabs, dFd)
 GOW(fabsf, fFf)
 // fabsl    // Weak
-// fdim // Weak
-// fdimf    // Weak
+GOW(fdim, dFdd)
+GOW(fdimf, fFff)
 // fdiml    // Weak
 GO(feclearexcept, iFi)
 GO(fedisableexcept, iFi)
diff --git a/src/wrapped/wrappedlibpthread_private.h b/src/wrapped/wrappedlibpthread_private.h
index d2291657..bf92d775 100755
--- a/src/wrapped/wrappedlibpthread_private.h
+++ b/src/wrapped/wrappedlibpthread_private.h
@@ -119,8 +119,12 @@ GO(pthread_exit, vFp)
 GOM(pthread_getaffinity_np, iFEpLp)
 #ifdef NOALIGN
 GO(pthread_getattr_np, iFLp)
+GO(pthread_getattr_default_np, iFp)
+GO(pthread_setattr_default_np, iFp)
 #else
 GOM(pthread_getattr_np, iFELp)
+GOM(pthread_getattr_default_np, iFEp)
+GOM(pthread_setattr_default_np, iFEp)
 #endif
 //GO(pthread_getconcurrency, iFv)
 //GO(pthread_getcpuclockid, iFup)