diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2025-04-09 01:12:55 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-04-08 19:12:55 +0200 |
| commit | d592c1996d74e9e6e728026486cdab6a75f43aaa (patch) | |
| tree | 935f142dff05d4640f2cd5865f8d63f8c3ca8cf9 /src | |
| parent | 8b3d4404d77bcc806631e17038f046d409cb6b69 (diff) | |
| download | box64-d592c1996d74e9e6e728026486cdab6a75f43aaa.tar.gz box64-d592c1996d74e9e6e728026486cdab6a75f43aaa.zip | |
[WOW64] Add wow64 PE build scaffolding (#2513)
Diffstat (limited to 'src')
| -rw-r--r-- | src/custommem.c | 99 | ||||
| -rw-r--r-- | src/custommmap.c | 8 | ||||
| -rw-r--r-- | src/dynarec/dynablock.c | 2 | ||||
| -rw-r--r-- | src/include/custommem.h | 8 | ||||
| -rw-r--r-- | src/include/debug.h | 20 | ||||
| -rw-r--r-- | src/include/os.h | 33 | ||||
| -rw-r--r-- | src/libtools/threads.c | 12 | ||||
| -rw-r--r-- | src/os/os_linux.c | 38 | ||||
| -rw-r--r-- | src/os/os_wine.c | 90 |
9 files changed, 227 insertions, 83 deletions
diff --git a/src/custommem.c b/src/custommem.c index a35aab57..f74666e7 100644 --- a/src/custommem.c +++ b/src/custommem.c @@ -2,16 +2,11 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <dlfcn.h> -#include <signal.h> #include <pthread.h> #include <errno.h> -#include <syscall.h> -#include <sys/personality.h> #include "os.h" #include "box64context.h" -#include "elfloader.h" #include "debug.h" #include "x64trace.h" #include "x64emu.h" @@ -19,7 +14,6 @@ #include "bridge.h" #include "library.h" #include "callback.h" -#include "wrapper.h" #include "threads.h" #include "x64trace.h" #include "signals.h" @@ -538,8 +532,8 @@ void* map128_customMalloc(size_t size, int is32bits) if(is32bits) // unlocking, because mmap might use it mutex_unlock(&mutex_blocks); void* p = is32bits - ?box_mmap(NULL, allocsize, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE|MAP_32BIT, -1, 0) - :(box64_is32bits?box32_dynarec_mmap(allocsize):internal_mmap(NULL, allocsize, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0)); + ? box_mmap(NULL, allocsize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_32BIT, -1, 0) + : (box64_is32bits ? box32_dynarec_mmap(allocsize) : InternalMmap(NULL, allocsize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)); if(is32bits) mutex_lock(&mutex_blocks); #ifdef TRACE_MEMSTAT @@ -644,8 +638,8 @@ void* internal_customMalloc(size_t size, int is32bits) if(is32bits) // unlocking, because mmap might use it mutex_unlock(&mutex_blocks); void* p = is32bits - ?box_mmap(NULL, allocsize, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE|MAP_32BIT, -1, 0) - :(box64_is32bits?box32_dynarec_mmap(allocsize):internal_mmap(NULL, allocsize, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0)); + ? box_mmap(NULL, allocsize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_32BIT, -1, 0) + : (box64_is32bits ? box32_dynarec_mmap(allocsize) : InternalMmap(NULL, allocsize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)); if(is32bits) mutex_lock(&mutex_blocks); #ifdef TRACE_MEMSTAT @@ -902,8 +896,8 @@ void* internal_customMemAligned(size_t align, size_t size, int is32bits) if(is32bits) mutex_unlock(&mutex_blocks); void* p = is32bits - ?mmap(NULL, allocsize, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE|MAP_32BIT, -1, 0) - :internal_mmap(NULL, allocsize, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); + ? mmap(NULL, allocsize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_32BIT, -1, 0) + : InternalMmap(NULL, allocsize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); if(is32bits) mutex_lock(&mutex_blocks); #ifdef TRACE_MEMSTAT @@ -988,7 +982,7 @@ void* box32_dynarec_mmap(size_t size) while(bend<0x800000000000LL) { if(rb_get_end(mapallmem, cur, &flag, &bend)) { if(flag==2 && bend-cur>=size) { - void* ret = internal_mmap((void*)cur, size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); + void* ret = InternalMmap((void*)cur, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); if(ret!=MAP_FAILED) rb_set(mapallmem, cur, cur+size, 1); // mark as allocated else @@ -1001,7 +995,8 @@ void* box32_dynarec_mmap(size_t size) } #endif //printf_log(LOG_INFO, "BOX32: Error allocating Dynarec memory: %s\n", "fallback to internal mmap"); - return internal_mmap((void*)0x100000000LL, size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);; + return InternalMmap((void*)0x100000000LL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + ; } #ifdef DYNAREC @@ -1075,13 +1070,13 @@ uintptr_t AllocDynarecMap(size_t size) // At least with a 2M allocation, transparent huge page should kick-in #if 0//def MAP_HUGETLB if(p==MAP_FAILED && allocsize==DYNMMAPSZ) { - p = internal_mmap(NULL, allocsize, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB, -1, 0); + p = InternalMmap(NULL, allocsize, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB, -1, 0); if(p!=MAP_FAILED) printf_log(LOG_INFO, "Allocated a dynarec memory block with HugeTLB\n"); else printf_log(LOG_INFO, "Failled to allocated a dynarec memory block with HugeTLB (%s)\n", strerror(errno)); } #endif if(p==MAP_FAILED) - p = internal_mmap(NULL, allocsize, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); + p = InternalMmap(NULL, allocsize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); if(p==MAP_FAILED) { dynarec_log(LOG_INFO, "Cannot create dynamic map of %zu bytes (%s)\n", allocsize, strerror(errno)); return 0; @@ -2085,10 +2080,10 @@ void relockCustommemMutex(int locks) static void init_mutexes(void) { - #ifdef USE_CUSTOM_MUTEX +#ifdef USE_CUSTOM_MUTEX native_lock_store(&mutex_blocks, 0); native_lock_store(&mutex_prot, 0); - #else +#else pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); @@ -2096,7 +2091,7 @@ static void init_mutexes(void) pthread_mutex_init(&mutex_prot, &attr); pthread_mutexattr_destroy(&attr); - #endif +#endif } static void atfork_child_custommem(void) @@ -2111,11 +2106,11 @@ void reverveHigMem32(void) uintptr_t cur_size = 1024LL*1024*1024*1024; // start with 1TB check void* cur; while(cur_size>=65536) { - cur = internal_mmap(NULL, cur_size, 0, MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0); + cur = InternalMmap(NULL, cur_size, 0, MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE, -1, 0); if((cur==MAP_FAILED) || (cur<(void*)0x100000000LL)) { if(cur!=MAP_FAILED) { //printf_log(LOG_INFO, " Failed to reserve high %p (%zx)\n", cur, cur_size); - internal_munmap(cur, cur_size); + InternalMunmap(cur, cur_size); } //else //printf_log(LOG_INFO, " Failed to reserve %zx sized block\n", cur_size); cur_size>>=1; @@ -2136,7 +2131,7 @@ void reverveHigMem32(void) start = bend; } } - personality(ADDR_LIMIT_32BIT); + PersonalityAddrLimit32Bit(); } #endif void my_reserveHighMem() @@ -2165,7 +2160,7 @@ void my_reserveHighMem() // create a border at 48bits if(cur<(1ULL<<48) && bend>(1ULL<<48)) bend = 1ULL<<48; - void* ret = internal_mmap((void*)cur, bend-cur, 0, MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0); + void* ret = InternalMmap((void*)cur, bend - cur, 0, MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE, -1, 0); printf_log(LOG_DEBUG, "Reserve %p-%p => %p (%s)\n", (void*)cur, bend, ret, (ret==MAP_FAILED)?strerror(errno):"ok"); if(ret!=(void*)-1) { rb_set(mapallmem, cur, bend, 1); @@ -2189,7 +2184,10 @@ void init_custommem_helper(box64context_t* ctx) if(inited) // already initialized return; inited = 1; + +#ifndef _WIN32 // TODO: better wow64 support? cur_brk = dlsym(RTLD_NEXT, "__curbrk"); +#endif blockstree = rbtree_init("blockstree"); // if there is some blocks already if(n_blocks) @@ -2219,7 +2217,9 @@ void init_custommem_helper(box64context_t* ctx) lockaddress = kh_init(lockaddress); rbt_dynmem = rbtree_init("rbt_dynmem"); #endif +#ifndef _WIN32 // TODO: better wow64 support? pthread_atfork(NULL, NULL, atfork_child_custommem); +#endif // init mapallmem list mapallmem = rbtree_init("mapallmem"); // init mmapmem list @@ -2275,7 +2275,7 @@ void fini_custommem_helper(box64context_t *ctx) while(head) { for (int i=0; i<NCHUNK; ++i) { if(head->chunks[i].chunk.block) - internal_munmap(head->chunks[i].chunk.block, head->chunks[i].chunk.size); + InternalMunmap(head->chunks[i].chunk.block, head->chunks[i].chunk.size); if(head->chunks[i].tree) rbtree_delete(head->chunks[i].tree); } @@ -2323,12 +2323,12 @@ void fini_custommem_helper(box64context_t *ctx) blockstree = NULL; for(int i=0; i<n_blocks; ++i) - internal_munmap(p_blocks[i].block, p_blocks[i].size); + InternalMunmap(p_blocks[i].block, p_blocks[i].size); box_free(p_blocks); - #ifndef USE_CUSTOM_MUTEX +#if !defined(USE_CUSTOM_MUTEX) && !defined(_WIN32) // TODO: better wow64 support? pthread_mutex_destroy(&mutex_prot); pthread_mutex_destroy(&mutex_blocks); - #endif +#endif } #ifdef DYNAREC @@ -2348,37 +2348,6 @@ int isLockAddress(uintptr_t addr) #endif -void* internal_mmap(void *addr, unsigned long length, int prot, int flags, int fd, ssize_t offset) -{ - #if 1//def STATICBUILD - void* ret = (void*)syscall(__NR_mmap, addr, length, prot, flags, fd, offset); - #else - static int grab = 1; - typedef void*(*pFpLiiiL_t)(void*, unsigned long, int, int, int, size_t); - static pFpLiiiL_t libc_mmap64 = NULL; - if(grab) { - libc_mmap64 = dlsym(RTLD_NEXT, "mmap64"); - } - void* ret = libc_mmap64(addr, length, prot, flags, fd, offset); - #endif - return ret; -} -int internal_munmap(void* addr, unsigned long length) -{ - #if 1//def STATICBUILD - int ret = syscall(__NR_munmap, addr, length); - #else - static int grab = 1; - typedef int(*iFpL_t)(void*, unsigned long); - static iFpL_t libc_munmap = NULL; - if(grab) { - libc_munmap = dlsym(RTLD_NEXT, "munmap"); - } - int ret = libc_munmap(addr, length); - #endif - return ret; -} - #ifndef MAP_FIXED_NOREPLACE #define MAP_FIXED_NOREPLACE 0x200000 #endif @@ -2401,28 +2370,28 @@ EXPORT void* box_mmap(void *addr, size_t length, int prot, int flags, int fd, ss addr = find47bitBlock(length); } #endif - void* ret = internal_mmap(addr, length, prot, new_flags, fd, offset); - #if !defined(NOALIGN) + void* ret = InternalMmap(addr, length, prot, new_flags, fd, offset); +#if !defined(NOALIGN) if((ret!=MAP_FAILED) && (flags&MAP_32BIT) && (((uintptr_t)ret>0xffffffffLL) || ((box64_wine) && ((uintptr_t)ret&0xffff) && (ret!=addr)))) { int olderr = errno; - internal_munmap(ret, length); + InternalMunmap(ret, length); loadProtectionFromMap(); // reload map, because something went wrong previously addr = find31bitBlockNearHint(old_addr, length, 0); // is this the best way? new_flags = (addr && isBlockFree(addr, length) )? (new_flags|MAP_FIXED) : new_flags; if((new_flags&(MAP_FIXED|MAP_FIXED_NOREPLACE))==(MAP_FIXED|MAP_FIXED_NOREPLACE)) new_flags&=~MAP_FIXED_NOREPLACE; - ret = internal_mmap(addr, length, prot, new_flags, fd, offset); + ret = InternalMmap(addr, length, prot, new_flags, fd, offset); if(old_addr && ret!=old_addr && ret!=MAP_FAILED) errno = olderr; } else if((ret!=MAP_FAILED) && !(flags&MAP_FIXED) && ((box64_wine)) && (addr && (addr!=ret)) && (((uintptr_t)ret>0x7fffffffffffLL) || ((uintptr_t)ret&~0xffff))) { int olderr = errno; - internal_munmap(ret, length); + InternalMunmap(ret, length); loadProtectionFromMap(); // reload map, because something went wrong previously addr = find47bitBlockNearHint(old_addr, length, 0); // is this the best way? new_flags = (addr && isBlockFree(addr, length)) ? (new_flags|MAP_FIXED) : new_flags; if((new_flags&(MAP_FIXED|MAP_FIXED_NOREPLACE))==(MAP_FIXED|MAP_FIXED_NOREPLACE)) new_flags&=~MAP_FIXED_NOREPLACE; - ret = internal_mmap(addr, length, prot, new_flags, fd, offset); + ret = InternalMmap(addr, length, prot, new_flags, fd, offset); if(old_addr && ret!=old_addr && ret!=MAP_FAILED) { errno = olderr; if(old_addr>(void*)0x7fffffffff && !have48bits) @@ -2435,6 +2404,6 @@ EXPORT void* box_mmap(void *addr, size_t length, int prot, int flags, int fd, ss EXPORT int box_munmap(void* addr, size_t length) { - int ret = internal_munmap(addr, length); + int ret = InternalMunmap(addr, length); return ret; } diff --git a/src/custommmap.c b/src/custommmap.c index 4f506f32..45e88fb5 100644 --- a/src/custommmap.c +++ b/src/custommmap.c @@ -24,8 +24,8 @@ extern void* mapallmem; extern int box64_is32bits; void setProtection(uintptr_t addr, size_t size, uint32_t prot); void freeProtection(uintptr_t addr, size_t size); -void* internal_mmap(void *addr, unsigned long length, int prot, int flags, int fd, ssize_t offset); -int internal_munmap(void* addr, unsigned long length); +void* InternalMmap(void* addr, unsigned long length, int prot, int flags, int fd, ssize_t offset); +int InternalMunmap(void* addr, unsigned long length); void* box_mmap(void *addr, unsigned long length, int prot, int flags, int fd, ssize_t offset); void* my_mmap64(x64emu_t* emu, void *addr, unsigned long length, int prot, int flags, int fd, ssize_t offset); @@ -39,7 +39,7 @@ EXPORT void* mmap64(void *addr, unsigned long length, int prot, int flags, int f if(!addr && ((running32bits && BOX64ENV(mmap32)) || (flags&MAP_32BIT) || box64_is32bits)) ret = box_mmap(addr, length, prot, flags | MAP_32BIT, fd, offset); else - ret = internal_mmap(addr, length, prot, flags, fd, offset); + ret = InternalMmap(addr, length, prot, flags, fd, offset); if(ret!=MAP_FAILED && mapallmem) setProtection((uintptr_t)ret, length, prot); return ret; @@ -48,7 +48,7 @@ EXPORT void* mmap(void *addr, unsigned long length, int prot, int flags, int fd, EXPORT int munmap(void* addr, unsigned long length) { - int ret = internal_munmap(addr, length); + int ret = InternalMunmap(addr, length); if(!ret && mapallmem) { freeProtection((uintptr_t)addr, length); } diff --git a/src/dynarec/dynablock.c b/src/dynarec/dynablock.c index 28f726f1..c12210b5 100644 --- a/src/dynarec/dynablock.c +++ b/src/dynarec/dynablock.c @@ -15,8 +15,6 @@ #include "dynablock.h" #include "dynablock_private.h" #include "dynarec_private.h" -#include "elfloader.h" -#include "signals.h" #include "alternate.h" #include "dynarec_native.h" diff --git a/src/include/custommem.h b/src/include/custommem.h index b17eff99..5e883570 100644 --- a/src/include/custommem.h +++ b/src/include/custommem.h @@ -138,13 +138,9 @@ int checkInHotPage(uintptr_t addr); #endif // this will simulate an x86_64 version of the function (no tracking will done, but tracking will be used) -void* box_mmap(void *addr, unsigned long length, int prot, int flags, int fd, ssize_t offset); +void* box_mmap(void* addr, size_t length, int prot, int flags, int fd, ssize_t offset); // this will simulate an x86_64 version of the function (no tracking will done) -int box_munmap(void* addr, unsigned long length); -// this will call the syscall directly -void* internal_mmap(void *addr, unsigned long length, int prot, int flags, int fd, ssize_t offset); -// this will call the syscall directly -int internal_munmap(void* addr, unsigned long length); +int box_munmap(void* addr, size_t length); void reserveHighMem(); diff --git a/src/include/debug.h b/src/include/debug.h index 631e35d7..93268420 100644 --- a/src/include/debug.h +++ b/src/include/debug.h @@ -68,6 +68,7 @@ extern int box64_tcmalloc_minimal; // when using tcmalloc_minimal #define LOG_NEVER 3 #define LOG_VERBOSE 3 +#ifndef _WIN32 // TODO: better wow64 support? void printf_ftrace(int prefix, const char* fmt, ...); #define printf_log_prefix(prefix, L, ...) \ @@ -98,6 +99,18 @@ void printf_ftrace(int prefix, const char* fmt, ...); #define dynarec_log(L, ...) dynarec_log_prefix(1, L, __VA_ARGS__) +#else +#define printf_log_prefix(prefix, L, ...) +#define printf_log(L, ...) +#define printf_dump_prefix(prefix, L, ...) +#define printf_dump(L, ...) +#define printf_dlsym_prefix(prefix, L, ...) +#define printf_dlsym(L, ...) +#define dynarec_log_prefix(prefix, L, ...) +#define dynarec_log(L, ...) +#endif + + #define EXPORT __attribute__((visibility("default"))) #ifdef BUILD_DYNAMIC #define EXPORTDYN __attribute__((visibility("default"))) @@ -105,6 +118,7 @@ void printf_ftrace(int prefix, const char* fmt, ...); #define EXPORTDYN #endif +#ifndef _WIN32 // TODO: better wow64 support? #ifndef STATICBUILD void init_malloc_hook(void); #endif @@ -131,6 +145,12 @@ extern void* __libc_memalign(size_t, size_t); extern char* box_strdup(const char* s); extern char* box_realpath(const char* path, char* ret); #endif +#else +#define box_malloc WinMalloc +#define box_realloc WinRealloc +#define box_calloc WinCalloc +#define box_free WinFree +#endif //use actual_XXXX for internal memory that should be in 32bits space when box32 is active //use box_XXX for internal memory that doesn't need anything special diff --git a/src/include/os.h b/src/include/os.h index 6968df19..2ab70722 100644 --- a/src/include/os.h +++ b/src/include/os.h @@ -2,6 +2,37 @@ #define __OS_H_ #include <stdint.h> +#include <sys/types.h> + +#ifndef _WIN32 +#include <dlfcn.h> +#include <sys/mman.h> +#else +typedef __int64 ssize_t; + +#define PROT_READ 0x1 +#define PROT_WRITE 0x2 +#define PROT_EXEC 0x4 + +#define MAP_FAILED ((void*)-1) +#define MAP_PRIVATE 0x02 +#define MAP_FIXED 0x10 +#define MAP_ANONYMOUS 0x20 +#define MAP_32BIT 0x40 +#define MAP_NORESERVE 0 + +void* mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset); +int munmap(void* addr, size_t length); +int mprotect(void* addr, size_t len, int prot); + +void* WinMalloc(size_t size); +void* WinRealloc(void* ptr, size_t size); +void* WinCalloc(size_t nmemb, size_t size); +void WinFree(void* ptr); +#endif + +void* InternalMmap(void* addr, unsigned long length, int prot, int flags, int fd, ssize_t offset); +int InternalMunmap(void* addr, unsigned long length); int GetTID(void); int SchedYield(void); @@ -17,6 +48,8 @@ int IsBridgeSignature(char s, char c); int IsNativeCall(uintptr_t addr, int is32bits, uintptr_t* calladdress, uint16_t* retn); void EmuInt3(void* emu, void* addr); void* EmuFork(void* emu, int forktype); + +void PersonalityAddrLimit32Bit(void); // ---------------------------------------------------------------- #ifndef _WIN32 diff --git a/src/libtools/threads.c b/src/libtools/threads.c index 2454f929..02ada9ca 100644 --- a/src/libtools/threads.c +++ b/src/libtools/threads.c @@ -206,8 +206,8 @@ x64emu_t* thread_get_emu() if(box64_is32bits) stack = mmap64(NULL, stacksize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_32BIT, -1, 0); else - stack = internal_mmap(NULL, stacksize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_GROWSDOWN, -1, 0); - if(stack!=MAP_FAILED) + stack = InternalMmap(NULL, stacksize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_GROWSDOWN, -1, 0); + if(stack!=MAP_FAILED) setProtection((uintptr_t)stack, stacksize, PROT_READ|PROT_WRITE); x64emu_t *emu = NewX64Emu(my_context, 0, (uintptr_t)stack, stacksize, 1); SetupX64Emu(emu, NULL); @@ -523,8 +523,8 @@ EXPORT int my_pthread_create(x64emu_t *emu, void* t, void* attr, void* start_rou stacksize = attr_stacksize; own = 0; } else { - stack = internal_mmap(NULL, stacksize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_GROWSDOWN, -1, 0); - if(stack!=MAP_FAILED) + stack = InternalMmap(NULL, stacksize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_GROWSDOWN, -1, 0); + if(stack!=MAP_FAILED) setProtection((uintptr_t)stack, stacksize, PROT_READ|PROT_WRITE); own = 1; } @@ -552,8 +552,8 @@ EXPORT int my_pthread_create(x64emu_t *emu, void* t, void* attr, void* start_rou void* my_prepare_thread(x64emu_t *emu, void* f, void* arg, int ssize, void** pet) { int stacksize = (ssize)?ssize:(2*1024*1024); //default stack size is 2Mo - void* stack = internal_mmap(NULL, stacksize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_GROWSDOWN, -1, 0); - if(stack!=MAP_FAILED) + void* stack = InternalMmap(NULL, stacksize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_GROWSDOWN, -1, 0); + if(stack!=MAP_FAILED) setProtection((uintptr_t)stack, stacksize, PROT_READ|PROT_WRITE); emuthread_t *et = (emuthread_t*)box_calloc(1, sizeof(emuthread_t)); x64emu_t *emuthread = NewX64Emu(emu->context, (uintptr_t)f, (uintptr_t)stack, stacksize, 1); diff --git a/src/os/os_linux.c b/src/os/os_linux.c index 46a0434b..e11a41a2 100644 --- a/src/os/os_linux.c +++ b/src/os/os_linux.c @@ -2,6 +2,7 @@ #include <sched.h> #include <unistd.h> #include <stdint.h> +#include <sys/personality.h> #include "os.h" #include "signals.h" @@ -62,3 +63,40 @@ void EmuX86Syscall(void* emu) { x86Syscall((x64emu_t*)emu); } + +void PersonalityAddrLimit32Bit(void) +{ + personality(ADDR_LIMIT_32BIT); +} + +void* InternalMmap(void* addr, unsigned long length, int prot, int flags, int fd, ssize_t offset) +{ +#if 1 // def STATICBUILD + void* ret = (void*)syscall(__NR_mmap, addr, length, prot, flags, fd, offset); +#else + static int grab = 1; + typedef void* (*pFpLiiiL_t)(void*, unsigned long, int, int, int, size_t); + static pFpLiiiL_t libc_mmap64 = NULL; + if (grab) { + libc_mmap64 = dlsym(RTLD_NEXT, "mmap64"); + } + void* ret = libc_mmap64(addr, length, prot, flags, fd, offset); +#endif + return ret; +} + +int InternalMunmap(void* addr, unsigned long length) +{ +#if 1 // def STATICBUILD + int ret = syscall(__NR_munmap, addr, length); +#else + static int grab = 1; + typedef int (*iFpL_t)(void*, unsigned long); + static iFpL_t libc_munmap = NULL; + if (grab) { + libc_munmap = dlsym(RTLD_NEXT, "munmap"); + } + int ret = libc_munmap(addr, length); +#endif + return ret; +} \ No newline at end of file diff --git a/src/os/os_wine.c b/src/os/os_wine.c new file mode 100644 index 00000000..e5bc47b5 --- /dev/null +++ b/src/os/os_wine.c @@ -0,0 +1,90 @@ +#include <windows.h> + +#include "os.h" + +int GetTID(void) +{ + return GetCurrentThreadId(); +} + +void PersonalityAddrLimit32Bit(void) { } + +ULONG_PTR default_zero_bits32 = 0x7fffffff; + +static uint32_t prot_unix_to_win32(uint32_t unx) +{ + if ((unx & (PROT_READ | PROT_WRITE | PROT_EXEC)) == (PROT_READ | PROT_WRITE | PROT_EXEC)) + return PAGE_EXECUTE_READWRITE; + if ((unx & (PROT_READ | PROT_EXEC)) == (PROT_READ | PROT_EXEC)) + return PAGE_EXECUTE_READ; + if ((unx & PROT_EXEC) == PROT_EXEC) + return PAGE_EXECUTE_READ; + if ((unx & (PROT_READ | PROT_WRITE)) == (PROT_READ | PROT_WRITE)) + return PAGE_READWRITE; + if ((unx & PROT_READ) == PROT_READ) + return PAGE_READONLY; + return 0; +} + +int mprotect(void* addr, size_t len, int prot) +{ + ULONG old_prot; + if (VirtualProtect(&addr, len, prot_unix_to_win32(prot), &old_prot)) + return 0; + return -1; +} + +void* mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset) +{ + if (fd && fd != -1) { + return MAP_FAILED; + } + if (offset) { + return MAP_FAILED; + } + return VirtualAlloc(addr, length, MEM_COMMIT | MEM_RESERVE, prot_unix_to_win32(prot)); +} + +int munmap(void* addr, size_t length) +{ + if (VirtualFree(addr, length, MEM_RELEASE)) + return 0; + return -1; +} + +void* InternalMmap(void* addr, unsigned long length, int prot, int flags, int fd, ssize_t offset) +{ + return mmap(addr, length, prot, flags, fd, offset); +} + +int InternalMunmap(void* addr, unsigned long length) +{ + return munmap(addr, length); +} + +void* WinMalloc(size_t size) +{ + void* ret; + ret = HeapAlloc(GetProcessHeap(), 0, size); + return ret; +} + +void* WinRealloc(void* ptr, size_t size) +{ + void* ret; + if (!ptr) return WinMalloc(size); + ret = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ptr, size); + return ret; +} + +void* WinCalloc(size_t nmemb, size_t size) +{ + void* ret; + ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nmemb * size); + return ret; +} + +void WinFree(void* ptr) +{ + HeapFree(GetProcessHeap(), 0, ptr); +} \ No newline at end of file |