about summary refs log tree commit diff stats
path: root/src/box32.c
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/box32.c
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/box32.c')
-rw-r--r--src/box32.c283
1 files changed, 283 insertions, 0 deletions
diff --git a/src/box32.c b/src/box32.c
new file mode 100644
index 00000000..85a647a6
--- /dev/null
+++ b/src/box32.c
@@ -0,0 +1,283 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+#include "debug.h"
+#include "box32.h"
+#include "custommem.h"
+#include "converter32.h"
+
+#include "khash.h"
+
+KHASH_MAP_INIT_INT64(to, ulong_t);
+KHASH_MAP_INIT_INT(from, uintptr_t);
+
+static kh_from_t*   hash_from;
+static kh_to_t*     hash_to;
+#define CNT_INIT 0x80000001
+#define HASH_MASK 0x7fffffff
+static uint32_t     hash_cnt = CNT_INIT;
+static pthread_rwlock_t hash_lock = {0};
+static int          hash_running = 0;
+// locale
+static kh_from_t*   locale_from;
+static kh_to_t*     locale_to;
+
+
+void init_hash_helper() {
+    hash_from = kh_init(from);
+    hash_to = kh_init(to);
+    locale_from = kh_init(from);
+    locale_to = kh_init(to);
+    pthread_rwlock_init(&hash_lock, NULL);
+    hash_running = 1;
+}
+void fini_hash_helper() {
+    hash_running = 0;
+    kh_destroy(from, hash_from);
+    hash_from = NULL;
+    kh_destroy(to, hash_to);
+    hash_to = NULL;
+    hash_cnt = CNT_INIT;
+    kh_destroy(from, locale_from);
+    locale_from = NULL;
+    kh_destroy(to, locale_to);
+    locale_to = NULL;
+    pthread_rwlock_destroy(&hash_lock);
+}
+
+// Convert from hash key to original 64bits value
+uintptr_t from_hash(ulong_t l) {
+    // easy case first
+    if((l&HASH_MASK)==l) {
+        return (uintptr_t)l;
+    }
+    if(l==0xffffffff) {
+        return 0xffffffffffffffffll;
+    }
+    // get value from hash table second
+    uintptr_t ret = 0;
+    if(!hash_running) {
+        //printf_log(LOG_INFO, "Warning, from_hash used but hash not running\n");
+        return ret;
+    }
+    pthread_rwlock_rdlock(&hash_lock);
+    khint_t k = kh_get(from, hash_from, l);
+    if (k==kh_end(hash_from)) {
+        ret = (uintptr_t)l;
+    } else {
+        ret = kh_value(hash_from, k);
+    }
+    pthread_rwlock_unlock(&hash_lock);
+    return ret;
+}
+// same as from_hash
+uintptr_t from_hash_d(ulong_t l) {
+    return from_hash(l);
+}
+
+// Convert from 64bits to hash key, creating it if needed
+ulong_t to_hash(uintptr_t p) {
+    if((p&(uintptr_t)HASH_MASK)==p) {
+        return (ulong_t)p;
+    }
+    if(p==0xffffffffffffffffll) {
+        return 0xffffffff;
+    }
+    ulong_t ret = 0;
+    if(!hash_running) {
+        //printf_log(LOG_INFO, "Warning, to_hash used but hash not running\n");
+        return ret;
+    }
+    khint_t k;
+    pthread_rwlock_rdlock(&hash_lock);
+    k = kh_get(to, hash_to, p);
+    if(k==kh_end(hash_to)) {
+        // create a new key, but need write lock!
+        pthread_rwlock_unlock(&hash_lock);
+        pthread_rwlock_wrlock(&hash_lock);
+        ret = hash_cnt++;
+        if(hash_cnt==0xffffffff)
+            hash_cnt = CNT_INIT;
+        int r;
+        k = kh_put(to, hash_to, p, &r);
+        kh_value(hash_to, k) = ret;
+        k = kh_put(from, hash_from, ret, &r);
+        kh_value(hash_from, k) = p;
+    } else {
+        ret = kh_value(hash_to, k);
+    }
+    pthread_rwlock_unlock(&hash_lock);
+    return ret;
+}
+
+// Convert from 64bits to hash key and delete the entry from both hash table
+ulong_t to_hash_d(uintptr_t p) {
+    if((p&(uintptr_t)HASH_MASK)==p)
+        return (ulong_t)p;
+    if(p==0xffffffffffffffffll)
+        return 0xffffffff;
+    ulong_t ret = 0;
+    if(!hash_running) {
+        //printf_log(LOG_INFO, "Warning, to_hash_d used but hash not running\n");
+        return ret;
+    }
+    khint_t k;
+    pthread_rwlock_wrlock(&hash_lock);
+    k = kh_get(to, hash_to, p);
+    if(k==kh_end(hash_to)) {
+        /// should this be an assert?
+    } else {
+        ret = kh_value(hash_to, k);
+        // delete both entries
+        k = kh_get(to, hash_to, p);
+        kh_del(to, hash_to, k);
+        k = kh_get(from, hash_from, ret);
+        kh_del(from, hash_from, k);
+    }
+    pthread_rwlock_unlock(&hash_lock);
+    return ret;
+}
+
+typedef struct struct_locale_s {
+	void* p0[13];
+	void* p1;
+	void* p2;
+	void* p3;
+	void* p4[13];
+} struct_locale_t;
+void from_struct_locale(struct_locale_t *dest, ptr_t s) {
+	uint8_t* src = (uint8_t*)from_ptrv(s);
+    for(int i=0; i<13; ++i) {
+	    dest->p0[i] = (void*)from_hash(*(ptr_t*)src); src += 4;
+    }
+	dest->p1 = from_ptrv(*(ptr_t*)src); src += 4;
+	dest->p2 = from_ptrv(*(ptr_t*)src); src += 4;
+	dest->p3 = from_ptrv(*(ptr_t*)src); src += 4;
+    for(int i=0; i<13; ++i) {
+	    dest->p4[i] = (void*)from_hash(*(ptr_t*)src); src += 4;
+    }
+}
+void to_struct_locale(ptr_t d, const struct_locale_t *src) {
+	if (!src) return;
+	uint8_t* dest = (uint8_t*)from_ptrv(d);
+    for(int i=0; i<13; ++i) {
+	    *(ptr_t*)dest = to_hashv(src->p0[i]); dest += 4;
+    }
+    // copy the 3 ctype int (1st is short int, but int will do)
+    *(unsigned short int*)(d+(13+3+13)*sizeof(ptr_t)) = *(unsigned short int*)src->p1;
+	*(ptr_t*)dest = d+(13+3+13)*sizeof(ptr_t); dest += 4;
+    *(int*)(d+(13+3+13+1)*sizeof(ptr_t)) = *(int*)src->p2;
+	*(ptr_t*)dest = d+(13+3+13+1)*sizeof(ptr_t); dest += 4;
+    *(int*)(d+(13+3+13+3)*sizeof(ptr_t)) = *(int*)src->p3;
+	*(ptr_t*)dest = d+(13+3+13+2)*sizeof(ptr_t); dest += 4;
+    for(int i=0; i<13; ++i) {
+	    *(ptr_t*)dest = to_hashv(src->p4[i]); dest += 4;
+    }
+}
+void free_struct_locale(const struct_locale_t *src) {
+    for(int i=0; i<13; ++i) {
+	    to_hash_d((uintptr_t)src->p0[i]);
+    }
+    for(int i=0; i<13; ++i) {
+	    to_hash_d((uintptr_t)src->p4[i]);
+    }
+}
+
+// Convert from locale key to original 64bits value
+void* from_locale(ptr_t l) {
+    // easy case first
+    if(l < 0x100) {
+        return from_ptrv(l);
+    }
+    if(l == 0xffffffff) {
+        return (void*)-1;
+    }
+    // get value from hash table second
+    void* ret = 0;
+    if(!hash_running) {
+        //printf_log(LOG_INFO, "Warning, from_locale used but hash not running\n");
+        return ret;
+    }
+    pthread_rwlock_rdlock(&hash_lock);
+    khint_t k = kh_get(from, locale_from, l);
+    if (k==kh_end(locale_from)) {
+        ret = from_ptrv(l);
+    } else {
+        ret = (void*)kh_value(locale_from, k);
+    }
+    pthread_rwlock_unlock(&hash_lock);
+    //from_struct_locale((struct_locale_t*)ret, l);
+    return ret;
+}
+// same as from_locale
+void* from_locale_d(ptr_t l) {
+    return from_locale(l);
+}
+
+// Convert from 64bits to locale key, creating it if needed
+ptr_t to_locale(void* p) {
+    if((uintptr_t)p < 0x100) {
+        return to_ptrv(p);
+    }
+    if(p == (void*)-1) {
+        return 0xffffffff;
+    }
+    ptr_t ret = 0;
+    if(!hash_running) {
+        //printf_log(LOG_INFO, "Warning, to_locale used but hash not running\n");
+        return ret;
+    }
+    khint_t k;
+    pthread_rwlock_rdlock(&hash_lock);
+    k = kh_get(to, locale_to, (uintptr_t)p);
+    int conv = 0;
+    if(k==kh_end(locale_to)) {
+        // create a new key, but need write lock!
+        pthread_rwlock_unlock(&hash_lock);
+        pthread_rwlock_wrlock(&hash_lock);
+        // a locale_t is 5 pointer!
+        void* m = calloc(13+3+13+3, sizeof(ptr_t)); // the 3 ctype value are also inside the locale struct
+        ret = to_ptrv(m);
+        // add to hash maps
+        int r;
+        k = kh_put(to, locale_to, (uintptr_t)p, &r);
+        kh_value(locale_to, k) = ret;
+        k = kh_put(from, locale_from, ret, &r);
+        kh_value(locale_from, k) = (uintptr_t)p;
+        conv = 1;
+    } else {
+        ret = kh_value(locale_to, k);
+    }
+    pthread_rwlock_unlock(&hash_lock);
+    if(conv)
+        to_struct_locale(ret, (struct_locale_t*)p);
+    return ret;
+}
+
+// Convert from 64bits to hash key and delete the entry from both hash table
+ptr_t to_locale_d(void* p) {
+    if((uintptr_t)p < 0x100)
+        return to_ptrv(p);
+    ptr_t ret = 0;
+    if(!hash_running)
+        return ret;
+    khint_t k;
+    pthread_rwlock_wrlock(&hash_lock);
+    k = kh_get(to, locale_to, (uintptr_t)p);
+    if(k==kh_end(locale_to)) {
+        /// should this be an assert?
+    } else {
+        ret = kh_value(locale_to, k);
+        // free the memory
+        free_struct_locale(p);
+        free(from_ptrv(ret));
+        // delete both entries
+        k = kh_get(to, locale_to, (uintptr_t)p);
+        kh_del(to, locale_to, k);
+        k = kh_get(from, locale_from, ret);
+        kh_del(from, locale_from, k);
+    }
+    pthread_rwlock_unlock(&hash_lock);
+    return ret;
+}
\ No newline at end of file