diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-10-07 09:25:04 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-10-07 09:25:04 +0200 |
| commit | f81677278f6bbe387e20f7b9f642f8dcbef12387 (patch) | |
| tree | 36b13e609477329ba3736f27931c408eb1f0f486 /src | |
| parent | 2ef6011c7aebe44870795e1faaae9dde462cb7af (diff) | |
| download | box64-f81677278f6bbe387e20f7b9f642f8dcbef12387.tar.gz box64-f81677278f6bbe387e20f7b9f642f8dcbef12387.zip | |
Reworked mmap allocator and wine prereserve handling ([BOX32] fix handling of wine prereserve)
Diffstat (limited to 'src')
| -rw-r--r-- | src/core.c | 33 | ||||
| -rw-r--r-- | src/custommem.c | 4 | ||||
| -rw-r--r-- | src/tools/wine_tools.c | 40 | ||||
| -rw-r--r-- | src/wrapped/wrappedlibc.c | 8 |
4 files changed, 59 insertions, 26 deletions
diff --git a/src/core.c b/src/core.c index 58acfd30..a07b1aff 100644 --- a/src/core.c +++ b/src/core.c @@ -2388,22 +2388,6 @@ int initialize(int argc, const char **argv, char** env, x64emu_t** emulator, elf // export symbols AddSymbols(my_context->maplib, elf_header); - if(wine_preloaded) { - uintptr_t wineinfo = 0; - int ver = -1, veropt = 0; - const char* vername = NULL; - if(!ElfGetGlobalSymbolStartEnd(elf_header, &wineinfo, NULL, "wine_main_preload_info", &ver, &vername, 1, &veropt)) - if(!ElfGetWeakSymbolStartEnd(elf_header, &wineinfo, NULL, "wine_main_preload_info", &ver, &vername, 1, &veropt)) - ElfGetLocalSymbolStartEnd(elf_header, &wineinfo, NULL, "wine_main_preload_info", &ver, &vername, 1, &veropt); - if(!wineinfo) {printf_log(LOG_NONE, "Warning, Symbol wine_main_preload_info not found\n");} - else { - *(void**)wineinfo = get_wine_prereserve(); - printf_log(LOG_DEBUG, "WINE wine_main_preload_info found and updated %p -> %p\n", get_wine_prereserve(), *(void**)wineinfo); - } - #ifdef DYNAREC - dynarec_wine_prereserve(); - #endif - } AddMainElfToLinkmap(elf_header); // pre-load lib if needed if(ld_preload.size) { @@ -2437,6 +2421,23 @@ int initialize(int argc, const char **argv, char** env, x64emu_t** emulator, elf } // and handle PLT RelocateElfPlt(my_context->maplib, NULL, 0, 0, elf_header); + // wine preload special case + if(wine_preloaded) { + uintptr_t wineinfo = 0; + int ver = -1, veropt = 0; + const char* vername = NULL; + if(!ElfGetGlobalSymbolStartEnd(elf_header, &wineinfo, NULL, "wine_main_preload_info", &ver, &vername, 1, &veropt)) + if(!ElfGetWeakSymbolStartEnd(elf_header, &wineinfo, NULL, "wine_main_preload_info", &ver, &vername, 1, &veropt)) + ElfGetLocalSymbolStartEnd(elf_header, &wineinfo, NULL, "wine_main_preload_info", &ver, &vername, 1, &veropt); + if(!wineinfo) {printf_log(LOG_NONE, "Warning, Symbol wine_main_preload_info not found\n");} + else { + printf_log(LOG_INFO, "WINE wine_main_preload_info found and updated %p -> %p\n", (void**)wineinfo, get_wine_prereserve()); + *(void**)wineinfo = get_wine_prereserve(); + } + #ifdef DYNAREC + dynarec_wine_prereserve(); + #endif + } // deferred init setupTraceInit(); RunDeferredElfInit(emu); diff --git a/src/custommem.c b/src/custommem.c index 5e3de17a..4243b2f2 100644 --- a/src/custommem.c +++ b/src/custommem.c @@ -1656,7 +1656,9 @@ void* find47bitBlock(size_t size) { void* ret = find47bitBlockNearHint(HIGH, size, 0); if(!ret) - ret = find32bitBlock(size); + ret = find31bitBlockNearHint(MEDIUM, size, 0); + if(!ret) + ret = find31bitBlockNearHint(LOWEST, size, 0); return ret; } void* find47bitBlockNearHint(void* hint, size_t size, uintptr_t mask) diff --git a/src/tools/wine_tools.c b/src/tools/wine_tools.c index 17f5bc8d..32106154 100644 --- a/src/tools/wine_tools.c +++ b/src/tools/wine_tools.c @@ -15,7 +15,14 @@ typedef struct wine_prereserve_s void* addr; size_t size; } wine_prereserve_t; - +#ifdef BOX32 +typedef struct wine_prereserve_32_s +{ + ptr_t addr; + ulong_t size; +} wine_prereserve_32_t; +#include "box32.h" +#endif // 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}}; @@ -57,6 +64,15 @@ static void add_no_overlap(void* addr, size_t size) my_wine_reserve[idx].size = size; } +static void remove_prereserve(int idx) +{ + while(my_wine_reserve[idx].size) { + my_wine_reserve[idx].addr = my_wine_reserve[idx+1].addr; + my_wine_reserve[idx].size = my_wine_reserve[idx+1].size; + ++idx; + } +} + void wine_prereserve(const char* reserve) { init_custommem_helper(my_context); @@ -70,12 +86,14 @@ void wine_prereserve(const char* reserve) int idx = 0; while(my_wine_reserve[idx].addr && my_wine_reserve[idx].size) { void* ret = NULL; - if(!isBlockFree(my_wine_reserve[idx].addr, my_wine_reserve[idx].size) && ((ret=mmap(my_wine_reserve[idx].addr, my_wine_reserve[idx].size, 0, MAP_ANONYMOUS|MAP_NORESERVE, -1, 0))==my_wine_reserve[idx].addr)) { - printf_log(LOG_NONE, "Warning, prereserve of %p:0x%lx is not free\n", my_wine_reserve[idx].addr, my_wine_reserve[idx].size); + int isfree = isBlockFree(my_wine_reserve[idx].addr, my_wine_reserve[idx].size); + if(isfree) ret=mmap(my_wine_reserve[idx].addr, my_wine_reserve[idx].size, 0, MAP_FIXED|MAP_PRIVATE|MAP_ANON|MAP_NORESERVE, -1, 0); else ret = NULL; + if(!isfree || (ret!=my_wine_reserve[idx].addr)) { + if(addr>=(void*)0x10000LL) + printf_log(LOG_NONE, "Warning, prereserve of %p:0x%lx is not free\n", my_wine_reserve[idx].addr, my_wine_reserve[idx].size); if(ret) munmap(ret, my_wine_reserve[idx].size); - my_wine_reserve[idx].addr = NULL; - my_wine_reserve[idx].size = 0; + remove_prereserve(idx); } else { setProtection_mmap((uintptr_t)my_wine_reserve[idx].addr, my_wine_reserve[idx].size, 0); printf_log(/*LOG_DEBUG*/LOG_INFO, "WINE prereserve of %p:0x%lx done\n", my_wine_reserve[idx].addr, my_wine_reserve[idx].size); @@ -90,7 +108,17 @@ void* get_wine_prereserve() { if(!wine_preloaded) wine_prereserve(NULL); - return (void*)my_wine_reserve; + #ifdef BOX32 + if(box64_is32bits) { + static wine_prereserve_32_t my_wine_reserve_32[5]; + for(int i=0; i<5; ++i) { + my_wine_reserve_32[i].addr = to_ptrv(my_wine_reserve[i].addr); + my_wine_reserve_32[i].size = to_ulong(my_wine_reserve[i].size); + } + return &my_wine_reserve_32; + } else + #endif + return &my_wine_reserve; } extern int box64_quit; diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c index 1482d9d9..db57e446 100644 --- a/src/wrapped/wrappedlibc.c +++ b/src/wrapped/wrappedlibc.c @@ -2928,9 +2928,10 @@ EXPORT void* my_mmap64(x64emu_t* emu, void *addr, size_t length, int prot, int f new_flags&=~MAP_32BIT; // remove MAP_32BIT if((flags&MAP_32BIT) && !(flags&MAP_FIXED)) { // MAP_32BIT only exist on x86_64! - addr = find31bitBlockNearHint(old_addr, length, 0); + if(!(flags&MAP_FIXED) && (!old_addr || !isBlockFree(old_addr, length))) + addr = find31bitBlockNearHint(old_addr, length, 0); } else if (box64_wine || 1) { // other mmap should be restricted to 47bits - if(!addr) + if(!(flags&MAP_FIXED) && (!addr || !isBlockFree(addr, length))) addr = find47bitBlock(length); } #endif @@ -2972,7 +2973,8 @@ EXPORT void* my_mmap64(x64emu_t* emu, void *addr, size_t length, int prot, int f errno = EEXIST; return MAP_FAILED; } - if((emu || box64_is32bits) && (box64_log>=LOG_DEBUG || box64_dynarec_log>=LOG_DEBUG)) {printf_log(LOG_NONE, "%p\n", ret);} + if((ret==MAP_FAILED && (emu || box64_is32bits)) && (box64_log>=LOG_DEBUG || box64_dynarec_log>=LOG_DEBUG)) {printf_log(LOG_NONE, "%s (%d)\n", strerror(errno), errno);} + if(((ret!=MAP_FAILED) && (emu || box64_is32bits)) && (box64_log>=LOG_DEBUG || box64_dynarec_log>=LOG_DEBUG)) {printf_log(LOG_NONE, "%p\n", ret);} #ifdef DYNAREC if(box64_dynarec && ret!=MAP_FAILED) { /*if(flags&0x100000 && addr!=ret) |