about summary refs log tree commit diff stats
path: root/src/librarian
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-08-26 17:45:13 +0200
committerGitHub <noreply@github.com>2024-08-26 17:45:13 +0200
commitb5105a1e57bba3305d5dce93ab4d2f7faab6b34a (patch)
treeab26b700d3c48f2c8e32a1084ae7c2e7a8448b06 /src/librarian
parent9beb745765e9c99bad6410094a97bf0bf9ebc1eb (diff)
downloadbox64-b5105a1e57bba3305d5dce93ab4d2f7faab6b34a.tar.gz
box64-b5105a1e57bba3305d5dce93ab4d2f7faab6b34a.zip
Added preliminary Box32 support (#1760)
* Improve the ReserveHigMemory helper function

* [BOX32] Added some wrapping infrastructure

* [BOX32] More wrapped 32bits lib infrastructure

* [BOX32] Added callback and tls 32bits handling

* [BOX32] Added more 32bits, around wrappers and elfs

* [BOX32] Added the 32bits version of myalign

* [BOX32] More wrapped libs and 32bits fixes and imrpovments

* [BOX32] Added some 32bits tests

* [BOX32] Try to enable some Box32 build and test on the CI

* [BOX32] Disable Box32 testing on CI platform that use qemu

* [BOX32] Another attempt to disable Box32 testing on CI platform that use qemu

* [BOX32] Small fix for another attempt to disable Box32 testing on CI platform that use qemu

* [BOX32] Yet another fix for another attempt to disable Box32 testing on CI platform that use qemu

* [BOX32] Fixed a typo in CI script

* [BOX32] Better scratch alighnment and enabled more tests

* [BOX32] Added (partial) wrapped 32bits librt

* [BOX32] Added mention of Box32 in README

* [BOX32] Added phtread handling, and numerous fixes to 32bits handling. [ARM64_DYNAREC] Fixed access to segment with negative offset

* [BOX32] Added system libs and cpp testing, plus some more fixes

* [BOX32] Fix previous commit

* [BOX32] Better stack adjustment for 32bits processes

* [BOX32] Added getenv wrapped 32bits function and friends

* [BOX32] Don't look for box86 for a Box32 build

* [BOX32] Don't do 32bits cppThreads test for now on CI

* [BOX32] Enabled a few more 32bits tests

* [BOX32] For ld_lib_path for both CppThreads tests

* [BOX32] [ANDROID] Some Fixes for Android Build

* [BOX32] Still need to disable cppThread_32bits test on CI for some reason

* [BOX32] [ANDROID] Don't show PreInit Array Warning (#1751)

* [BOX32] [ANDROID] One More Fix for Android Build That I forgotten to … (#1752)

* [BOX32] [ANDROID] One More Fix for Android Build That I forgotten to push before

* [BOX32] [ANDROID] Try to Create __libc_init

* [BOX32] [ANDROID] Try to disable NEEDED_LIBS for now (libdl is not wrapped)

* [BOX32] Updated generated files

* [BOX32] Added 32bits context functions

* [BOX32] Added 32bits signal handling

* [BOX32] Added some missing 32bits elfloader functions

* [BOX32] Fix build on x86_64 machine

* [BOX32] Better fix for x86_64 build

* [BOX32] Actually added missing libs, and re-enabled cppThreads_32bits test

* [BOX32] Added wrapped 32bits libdl

* [BOX32] Try to re-enabled Box32 test on CI for ARM64 builds

* [BOX32] fine-tuning Box32 test on CI for ARM64 builds

* [BOX32] More fine-tuning to Box32 test on CI for ARM64 builds

* [BOX32] Enabled Box32 test on CI for LA64 and RV64 builds too

* [BOX32] re-Disabled Box32 test on CI for LA64 and RV64 builds, not working for now

* [BOX32] Temporarily disabled cppThreads_32bits test on CI

---------

Co-authored-by: KreitinnSoftware <pablopro5051@gmail.com>
Co-authored-by: KreitinnSoftware <80591934+KreitinnSoftware@users.noreply.github.com>
Diffstat (limited to 'src/librarian')
-rw-r--r--src/librarian/librarian.c35
-rw-r--r--src/librarian/library.c108
-rw-r--r--src/librarian/library_private.h18
3 files changed, 137 insertions, 24 deletions
diff --git a/src/librarian/librarian.c b/src/librarian/librarian.c
index b836e4ca..259f7e0c 100644
--- a/src/librarian/librarian.c
+++ b/src/librarian/librarian.c
@@ -12,6 +12,9 @@
 #include "x64emu.h"
 #include "box64context.h"
 #include "elfloader.h"
+#ifdef BOX32
+#include "box32.h"
+#endif
 
 #include "bridge.h"
 
@@ -254,15 +257,31 @@ static int AddNeededLib_add(lib_t** maplib, int local, needed_libs_t* needed, in
 
     if (lib->type == LIB_EMULATED) {
         // Need to add library to the linkmap (put here so the link is ordered)
-        linkmap_t *lm = addLinkMapLib(lib);
-        if(!lm) {
-            // Crashed already
-            printf_dump(LOG_DEBUG, "Failure to add lib linkmap\n");
-            return 1;
+        #ifdef BOX32
+        if(box64_is32bits) {
+            linkmap32_t *lm = addLinkMapLib32(lib);
+            if(!lm) {
+                // Crashed already
+                printf_dump(LOG_DEBUG, "Failure to add lib linkmap\n");
+                return 1;
+            }
+            lm->l_addr = (Elf32_Addr)to_ptrv(GetElfDelta(lib->e.elf));
+            lm->l_name = to_ptrv(lib->name);
+            lm->l_ld = to_ptrv(GetDynamicSection(lib->e.elf));
+        } else
+        #endif
+        {
+            linkmap_t *lm = addLinkMapLib(lib);
+            if(!lm) {
+                // Crashed already
+                printf_dump(LOG_DEBUG, "Failure to add lib linkmap\n");
+                return 1;
+            }
+            lm->l_addr = (Elf64_Addr)GetElfDelta(lib->e.elf);
+            lm->l_name = lib->name;
+            lm->l_ld = GetDynamicSection(lib->e.elf);
         }
-        lm->l_addr = (Elf64_Addr)GetElfDelta(lib->e.elf);
-        lm->l_name = lib->name;
-        lm->l_ld = GetDynamicSection(lib->e.elf);
+        //TODO: it seems to never be removed!
     }
     IncRefCount(lib, emu);
     return 0;
diff --git a/src/librarian/library.c b/src/librarian/library.c
index 69f27d5f..e4ab45e5 100644
--- a/src/librarian/library.c
+++ b/src/librarian/library.c
@@ -40,6 +40,16 @@
 #endif
 
 #undef GO
+#ifdef BOX32
+#define GO(P, N) int wrapped##N##_init32(library_t* lib, box64context_t *box64); \
+                 void wrapped##N##_fini32(library_t* lib);
+#ifdef STATICBUILD
+#include "library_list_static_32.h"
+#else
+#include "library_list_32.h"
+#endif
+#undef GO
+#endif
 
 #define GO(P, N) {P, wrapped##N##_init, wrapped##N##_fini},
 wrappedlib_t wrappedlibs[] = {
@@ -50,6 +60,17 @@ wrappedlib_t wrappedlibs[] = {
 #endif
 };
 #undef GO
+#define GO(P, N) {P, wrapped##N##_init32, wrapped##N##_fini32},
+wrappedlib_t wrappedlibs32[] = {
+#ifdef BOX32
+#ifdef STATICBUILD
+#include "library_list_static_32.h"
+#else
+#include "library_list_32.h"
+#endif
+#endif
+};
+#undef GO
 
 KHASH_MAP_IMPL_STR(symbolmap, symbol1_t)
 KHASH_MAP_IMPL_STR(symbol2map, symbol2_t)
@@ -232,14 +253,11 @@ int DummyLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr
 }
 
 static void initWrappedLib(library_t *lib, box64context_t* context) {
-    if(box64_is32bits) {
-        // TODO
-        return; // nothing wrapped yet
-    }
-    int nb = sizeof(wrappedlibs) / sizeof(wrappedlib_t);
+    int nb = (box64_is32bits?sizeof(wrappedlibs32):sizeof(wrappedlibs)) / sizeof(wrappedlib_t);
     for (int i=0; i<nb; ++i) {
-        if(strcmp(lib->name, wrappedlibs[i].name)==0) {
-            if(wrappedlibs[i].init(lib, context)) {
+        wrappedlib_t* w = box64_is32bits?(&wrappedlibs32[i]):(&wrappedlibs[i]);
+        if(strcmp(lib->name, w->name)==0) {
+            if(w->init(lib, context)) {
                 // error!
                 const char* error_str = dlerror();
                 if(error_str)   // don't print the message if there is no error string from last error
@@ -247,7 +265,7 @@ static void initWrappedLib(library_t *lib, box64context_t* context) {
                 return; // non blocker...
             }
             printf_dump(LOG_INFO, "Using native(wrapped) %s\n", lib->name);
-            lib->fini = wrappedlibs[i].fini;
+            lib->fini = w->fini;
             lib->getglobal = WrappedLib_GetGlobal;
             lib->getweak = WrappedLib_GetWeak;
             lib->getlocal = WrappedLib_GetLocal;
@@ -366,7 +384,7 @@ static void initEmulatedLib(const char* path, library_t *lib, box64context_t* co
 {
     char libname[MAX_PATH];
     strcpy(libname, path);
-    int found = FileIsX64ELF(libname);
+    int found = box64_is32bits?FileIsX86ELF(libname):FileIsX64ELF(libname);
     if(found)
         if(loadEmulatedLib(libname, lib, context, verneeded))
             return;
@@ -375,14 +393,14 @@ static void initEmulatedLib(const char* path, library_t *lib, box64context_t* co
         {
             strcpy(libname, context->box64_ld_lib.paths[i]);
             strcat(libname, path);
-            if(FileIsX64ELF(libname))
+            if(box64_is32bits?FileIsX86ELF(libname):FileIsX64ELF(libname))
                 if(loadEmulatedLib(libname, lib, context, verneeded))
                     return;
             // also try x86_64 variant
             strcpy(libname, context->box64_ld_lib.paths[i]);
-            strcat(libname, "x86_64/");
+            strcat(libname, box64_is32bits?"i386/":"x86_64/");
             strcat(libname, path);
-            if(FileIsX64ELF(libname))
+            if(box64_is32bits?FileIsX86ELF(libname):FileIsX64ELF(libname))
                 if(loadEmulatedLib(libname, lib, context, verneeded))
                     return;            
         }
@@ -793,7 +811,7 @@ static int getSymbolInDataMaps(library_t*lib, const char* name, int noweak, uint
         if(lib->w.altmy)
             strcpy(buff, lib->w.altmy);
         else
-            strcpy(buff, "my_");
+            strcpy(buff, box64_is32bits?"my32_":"my_");
         strcat(buff, name);
         #ifdef STATICBUILD
         symbol = (void*)kh_value(lib->w.mydatamap, k).addr;
@@ -828,7 +846,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui
             if(lib->w.altmy)
                 strcpy(buff, lib->w.altmy);
             else
-                strcpy(buff, "my_");
+                strcpy(buff, box64_is32bits?"my32_":"my_");
             strcat(buff, name);
             #ifdef STATICBUILD
             symbol = (void*)s->addr;
@@ -856,7 +874,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui
             if(lib->w.altmy)
                 strcpy(buff, lib->w.altmy);
             else
-                strcpy(buff, "my_");
+                strcpy(buff, box64_is32bits?"my32_":"my_");
             strcat(buff, name);
             #ifdef STATICBUILD
             symbol = (void*)s->addr;
@@ -921,7 +939,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui
                 if(lib->w.altmy)
                     strcpy(buff, lib->w.altmy);
                 else
-                    strcpy(buff, "my_");
+                    strcpy(buff, box64_is32bits?"my32_":"my_");
                 strcat(buff, name);
                 #ifdef STATICBUILD
                 symbol = (void*)s->addr;
@@ -1078,6 +1096,64 @@ int GetDeepBind(library_t* lib)
     return lib->deepbind;
 }
 
+#ifdef BOX32
+linkmap32_t* getLinkMapLib32(library_t* lib)
+{
+    linkmap32_t* lm = my_context->linkmap32;
+    while(lm) {
+        if(lm->l_lib == lib)
+            return lm;
+        lm = (linkmap32_t*)from_ptrv(lm->l_next);
+    }
+    return NULL;
+}
+linkmap32_t* getLinkMapElf32(elfheader_t* h)
+{
+    linkmap32_t* lm = my_context->linkmap32;
+    while(lm) {
+        if(lm->l_lib && lm->l_lib->type==LIB_EMULATED && lm->l_lib->e.elf == h)
+            return lm;
+        lm = (linkmap32_t*)from_ptrv(lm->l_next);
+    }
+    return NULL;
+}
+linkmap32_t* addLinkMapLib32(library_t* lib)
+{
+    if(!my_context->linkmap32) {
+        my_context->linkmap32 = (linkmap32_t*)box_calloc(1, sizeof(linkmap32_t));
+        my_context->linkmap32->l_lib = lib;
+        return my_context->linkmap32;
+    }
+    linkmap32_t* lm = my_context->linkmap32;
+    while(lm->l_next)
+        lm = (linkmap32_t*)from_ptrv(lm->l_next);
+    lm->l_next = to_ptrv(box_calloc(1, sizeof(linkmap32_t)));
+    linkmap32_t* l_next = (linkmap32_t*)from_ptrv(lm->l_next);
+    l_next->l_lib = lib;
+    l_next->l_prev = to_ptrv(lm);
+    return l_next;
+}
+void removeLinkMapLib32(library_t* lib)
+{
+    linkmap32_t* lm = getLinkMapLib32(lib);
+    if(!lm) return;
+    if(lm->l_next)
+        ((linkmap32_t*)from_ptrv(lm->l_next))->l_prev = lm->l_prev;
+    if(lm->l_prev)
+        ((linkmap32_t*)from_ptrv(lm->l_prev))->l_next = lm->l_next;
+    box_free(lm);
+}
+
+void AddMainElfToLinkmap32(elfheader_t* elf)
+{
+    linkmap32_t* lm = addLinkMapLib32(NULL);    // main elf will have a null lib link
+
+    lm->l_addr = (Elf32_Addr)to_ptrv(GetElfDelta(elf));
+    lm->l_name = to_ptrv(my_context->fullpath);
+    lm->l_ld = to_ptrv(GetDynamicSection(elf));
+}
+#endif
+
 linkmap_t* getLinkMapLib(library_t* lib)
 {
     linkmap_t* lm = my_context->linkmap;
diff --git a/src/librarian/library_private.h b/src/librarian/library_private.h
index a13df4a0..495ad000 100644
--- a/src/librarian/library_private.h
+++ b/src/librarian/library_private.h
@@ -133,11 +133,29 @@ typedef struct linkmap_s {
     library_t*  l_lib;
 
 } linkmap_t;
+#ifdef BOX32
+typedef struct linkmap32_s {
+    // actual struct link_map
+    Elf32_Addr  l_addr;
+    ptr_t       l_name; // char*
+    ptr_t       l_ld;   //Elf64_Dyn*
+    ptr_t l_next, l_prev;   // struct linkmap32_s *
+    // custom
+    library_t*  l_lib;
+
+} linkmap32_t;
+#endif
 
 linkmap_t* getLinkMapLib(library_t* lib);
 linkmap_t* getLinkMapElf(elfheader_t* h);
 linkmap_t* addLinkMapLib(library_t* lib);
 void removeLinkMapLib(library_t* lib);
+#ifdef BOX32
+linkmap32_t* getLinkMapLib32(library_t* lib);
+linkmap32_t* getLinkMapElf32(elfheader_t* h);
+linkmap32_t* addLinkMapLib32(library_t* lib);
+void removeLinkMapLib32(library_t* lib);
+#endif
 
 int FiniLibrary(library_t* lib, x64emu_t* emu);
 void Free1Library(library_t **lib, x64emu_t* emu);