diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-02-28 14:19:04 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-02-28 14:19:04 +0100 |
| commit | e753c19da1b621b1e667de85ce5ef60d186f0684 (patch) | |
| tree | 9bc80378efbe42ec72678230de2905ab121a4d8f /src/tools/wine_tools.c | |
| parent | 7b50468b61b7bdd9a15753c0a28711c1654a8c12 (diff) | |
| download | box64-e753c19da1b621b1e667de85ce5ef60d186f0684.tar.gz box64-e753c19da1b621b1e667de85ce5ef60d186f0684.zip | |
Added some minimal set of source (now box64 compile and say hello at least)
Diffstat (limited to 'src/tools/wine_tools.c')
| -rwxr-xr-x | src/tools/wine_tools.c | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/src/tools/wine_tools.c b/src/tools/wine_tools.c new file mode 100755 index 00000000..6fa7a47d --- /dev/null +++ b/src/tools/wine_tools.c @@ -0,0 +1,107 @@ +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <sys/mman.h> +#include <errno.h> + +#include "wine_tools.h" +#include "debug.h" +#include "box64context.h" + +typedef struct wine_prereserve_s +{ + void* addr; + size_t size; +} wine_prereserve_t; + +// only the prereseve argument is reserved, not the other zone that wine-preloader reserve +static wine_prereserve_t my_wine_reserve[] = {{(void*)0x00010000, 0x00008000}, {(void*)0x00110000, 0x30000000}, {(void*)0x7f000000, 0x03000000}, {0, 0}, {0, 0}}; + +int wine_preloaded = 0; + +static int get_prereserve(const char* reserve, void** addr, size_t* size) +{ + if(!reserve) + return 0; + uintptr_t r = 0; + int first = 1; + while(*reserve) { + // numbers reading + if(*reserve>='0' && *reserve<='9') r=r*16+(*reserve)-'0'; + else if(*reserve>='A' && *reserve<='F') r=r*16+(*reserve)-'A'+10; + else if(*reserve>='a' && *reserve<='f') r=r*16+(*reserve)-'a'+10; + else if(*reserve=='-') {if(first) {*addr=(void*)(r&~(box64_pagesize-1)); r=0; first=0;} else {printf_log(LOG_NONE, "Warning, Wine prereserve badly formated\n"); return 0;}} + else {printf_log(LOG_NONE, "Warning, Wine prereserve badly formated\n"); return 0;} + ++reserve; + } + *size = r; + return 1; +} + +static void add_no_overlap(void* addr, size_t size) +{ + int idx = 0; + while(my_wine_reserve[idx].addr && my_wine_reserve[idx].size) { + if(addr>=my_wine_reserve[idx].addr && addr<my_wine_reserve[idx].addr+my_wine_reserve[idx].size) { + // overlap + if (addr+size > my_wine_reserve[idx].addr+my_wine_reserve[idx].size) + // need adjust size + my_wine_reserve[idx].size = (intptr_t)addr-(intptr_t)my_wine_reserve[idx].addr+size; + return; + } + ++idx; + } + my_wine_reserve[idx].addr = addr; + my_wine_reserve[idx].size = size; +} + +void wine_prereserve(const char* reserve) +{ + void* addr = NULL; + size_t size = 0; + + if(get_prereserve(reserve, &addr, &size)) { + add_no_overlap(addr, size); + } + + int idx = 0; + while(my_wine_reserve[idx].addr && my_wine_reserve[idx].size) { + void* p = mmap(my_wine_reserve[idx].addr, my_wine_reserve[idx].size, + PROT_NONE, /*MAP_FIXED |*/ MAP_PRIVATE | MAP_ANON | MAP_NORESERVE, -1, 0); + if(p==(void*)-1 || p!=my_wine_reserve[idx].addr) { + printf_log(LOG_NONE, "Warning, prereserve of %p:0x%x failed (%s)\n", my_wine_reserve[idx].addr, my_wine_reserve[idx].size, strerror(errno)); + if(p!=(void*)-1) + munmap(p, my_wine_reserve[idx].size); + my_wine_reserve[idx].addr = NULL; + my_wine_reserve[idx].size = 0; + } else { + printf_log(LOG_DEBUG, "WINE prereserve of %p:0x%x done\n", my_wine_reserve[idx].addr, my_wine_reserve[idx].size); + ++idx; + } + } + + wine_preloaded = 1; +} + +void* get_wine_prereserve() +{ + if(!wine_preloaded) + wine_prereserve(NULL); + return (void*)my_wine_reserve; +} + +#ifdef DYNAREC +void dynarec_wine_prereserve() +{ + #if 0 + // disable for now, as it break some installer + if(!wine_preloaded) + wine_prereserve(NULL); + // don't reserve the initial arbritrary block as "with linker", it's not true + for(int i=1; i<sizeof(my_wine_reserve)/sizeof(my_wine_reserve[0]); ++i) + if(my_wine_reserve[i].addr && my_wine_reserve[i].size) + addDBFromAddressRange(my_context, (uintptr_t)my_wine_reserve[i].addr, my_wine_reserve[i].size, 0); // prepare the prereserved area for exec, with linker + #endif +} +#endif |