diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-08-26 17:45:13 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-08-26 17:45:13 +0200 |
| commit | b5105a1e57bba3305d5dce93ab4d2f7faab6b34a (patch) | |
| tree | ab26b700d3c48f2c8e32a1084ae7c2e7a8448b06 /src/box32.c | |
| parent | 9beb745765e9c99bad6410094a97bf0bf9ebc1eb (diff) | |
| download | box64-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.c | 283 |
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 |