diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/custommem.c | 47 | ||||
| -rw-r--r-- | src/dynarec/dynarec.c | 3 | ||||
| -rw-r--r-- | src/emu/x64emu.c | 9 | ||||
| -rw-r--r-- | src/emu/x64run.c | 17 | ||||
| -rw-r--r-- | src/include/custommem.h | 3 | ||||
| -rw-r--r-- | src/include/debug.h | 1 | ||||
| -rw-r--r-- | src/libtools/threads.c | 15 | ||||
| -rw-r--r-- | src/main.c | 16 | ||||
| -rw-r--r-- | src/tools/box64stack.c | 9 | ||||
| -rw-r--r-- | src/tools/rcfile.c | 1 | ||||
| -rw-r--r-- | src/wrapped/wrappedlibc.c | 6 |
11 files changed, 103 insertions, 24 deletions
diff --git a/src/custommem.c b/src/custommem.c index c1eca7e0..b039c291 100644 --- a/src/custommem.c +++ b/src/custommem.c @@ -6,6 +6,7 @@ #include <signal.h> #include <pthread.h> #include <errno.h> +#include <syscall.h> #include "box64context.h" #include "elfloader.h" @@ -374,7 +375,7 @@ void* customMalloc(size_t size) } size_t allocsize = (fullsize>MMAPSIZE)?fullsize:MMAPSIZE; #ifdef USE_MMAP - void* p = mmap(NULL, allocsize, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); + void* p = internal_mmap(NULL, allocsize, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); memset(p, 0, allocsize); #else void* p = box_calloc(1, allocsize); @@ -571,7 +572,7 @@ uintptr_t AllocDynarecMap(size_t size) } mprotect(p, allocsize, PROT_READ | PROT_WRITE | PROT_EXEC); #else - void* p = mmap(NULL, allocsize, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); + void* p = internal_mmap(NULL, allocsize, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); if(p==(void*)-1) { dynarec_log(LOG_INFO, "Cannot create dynamic map of %zu bytes\n", allocsize); return 0; @@ -1390,7 +1391,7 @@ void reserveHighMem() int prot; while (bend!=0xffffffffffffffffLL) { if(!rb_get_end(mapallmem, cur, &prot, &bend)) { - void* ret = mmap64((void*)cur, bend-cur, 0, MAP_ANONYMOUS|MAP_FIXED|MAP_PRIVATE|MAP_NORESERVE, -1, 0); + void* ret = internal_mmap((void*)cur, bend-cur, 0, MAP_ANONYMOUS|MAP_FIXED|MAP_PRIVATE|MAP_NORESERVE, -1, 0); printf_log(LOG_DEBUG, "Reserve %p-%p => %p (%s)\n", (void*)cur, bend, ret, strerror(errno)); printf_log(LOG_DEBUG, "mmap %p-%p\n", cur, bend); if(ret!=(void*)-1) { @@ -1485,7 +1486,7 @@ void fini_custommem_helper(box64context_t *ctx) for (int i=0; i<NCHUNK; ++i) { if(head->chunks[i].block) #ifdef USE_MMAP - munmap(head->chunks[i].block, head->chunks[i].size); + internal_munmap(head->chunks[i].block, head->chunks[i].size); #else box_free(head->chunks[i].block); #endif @@ -1531,7 +1532,7 @@ void fini_custommem_helper(box64context_t *ctx) for(int i=0; i<n_blocks; ++i) #ifdef USE_MMAP - munmap(p_blocks[i].block, p_blocks[i].size); + internal_munmap(p_blocks[i].block, p_blocks[i].size); #else box_free(p_blocks[i].block); #endif @@ -1558,3 +1559,39 @@ int isLockAddress(uintptr_t addr) } #endif + +void* internal_mmap(void *addr, unsigned long length, int prot, int flags, int fd, ssize_t offset) +{ + void* ret = (void*)syscall(__NR_mmap, addr, length, prot, flags, fd, offset); + return ret; +} +int internal_munmap(void* addr, unsigned long length) +{ + int ret = syscall(__NR_munmap, addr, length); + return ret; +} + +void* my_mmap64(x64emu_t* emu, void *addr, unsigned long length, int prot, int flags, int fd, ssize_t offset); + +extern int running32bits; +EXPORT void* mmap64(void *addr, unsigned long length, int prot, int flags, int fd, ssize_t offset) +{ + void* ret; + if(running32bits && box64_mmap32 && !addr) + ret = my_mmap64(NULL, addr, length, prot, flags | 0x40, fd, offset); + else + ret = internal_mmap(addr, length, prot, flags, fd, offset); + if(ret!=MAP_FAILED && mapallmem) + setProtection((uintptr_t)ret, length, prot); + return ret; +} +EXPORT void* mmap(void *addr, unsigned long length, int prot, int flags, int fd, ssize_t offset) __attribute__((alias("mmap64"))); + +EXPORT int munmap(void* addr, unsigned long length) +{ + int ret = internal_munmap(addr, length); + if(!ret && mapallmem) { + freeProtection((uintptr_t)addr, length); + } + return ret; +} diff --git a/src/dynarec/dynarec.c b/src/dynarec/dynarec.c index 6fef6935..032e34b7 100644 --- a/src/dynarec/dynarec.c +++ b/src/dynarec/dynarec.c @@ -180,6 +180,9 @@ void DynaRun(x64emu_t* emu) dynarec_log(LOG_DEBUG, "%04d|Running DynaRec Block @%p (%p) of %d x64 insts (hash=0x%x) emu=%p\n", GetTID(), (void*)R_RIP, block->block, block->isize, block->hash, emu); // block is here, let's run it! native_prolog(emu, block->block); + extern int running32bits; + if(emu->segs[_CS]==0x23) + running32bits = 1; } if(emu->fork) { int forktype = emu->fork; diff --git a/src/emu/x64emu.c b/src/emu/x64emu.c index 0173ea22..d1ae11c8 100644 --- a/src/emu/x64emu.c +++ b/src/emu/x64emu.c @@ -31,9 +31,6 @@ #warning Architecture cannot follow SSE Flush to 0 flag #endif -// from src/wrapped/wrappedlibc.c -int my_munmap(x64emu_t* emu, void* addr, unsigned long length); - typedef struct cleanup_s { void* f; int arg; @@ -194,8 +191,10 @@ void CallAllCleanup(x64emu_t *emu) static void internalFreeX64(x64emu_t* emu) { - if(emu && emu->stack2free) - my_munmap(NULL, emu->stack2free, emu->size_stack); + if(emu && emu->stack2free) { + if(!internal_munmap(emu->stack2free, emu->size_stack)) + freeProtection((uintptr_t)emu->stack2free, emu->size_stack); + } } EXPORTDYN diff --git a/src/emu/x64run.c b/src/emu/x64run.c index 7bec6b91..986c371a 100644 --- a/src/emu/x64run.c +++ b/src/emu/x64run.c @@ -31,6 +31,7 @@ int my_setcontext(x64emu_t* emu, void* ucp); #ifdef TEST_INTERPRETER int RunTest(x64test_t *test) #else +int running32bits = 0; int Run(x64emu_t *emu, int step) #endif { @@ -440,6 +441,8 @@ x64emurun: goto fini; } is32bits = (emu->segs[_CS]==0x23); + if(is32bits) + running32bits = 1; #endif break; case 0x65: /* GS: prefix */ @@ -456,6 +459,8 @@ x64emurun: goto fini; } is32bits = (emu->segs[_CS]==0x23); + if(is32bits) + running32bits = 1; #endif break; case 0x66: /* 16bits prefix */ @@ -1426,6 +1431,10 @@ x64emurun: R_RIP = addr; STEP; is32bits = (emu->segs[_CS]==0x23); + #ifndef TEST_INTERPRETER + if(is32bits) + running32bits = 1; + #endif break; case 0xD0: /* GRP2 Eb,1 */ case 0xD2: /* GRP2 Eb,CL */ @@ -1941,6 +1950,10 @@ x64emurun: } STEP2; is32bits = (emu->segs[_CS]==0x23); + #ifndef TEST_INTERPRETER + if(is32bits) + running32bits = 1; + #endif } break; case 4: /* JMP NEAR Ed */ @@ -1967,6 +1980,10 @@ x64emurun: } STEP2; is32bits = (emu->segs[_CS]==0x23); + #ifndef TEST_INTERPRETER + if(is32bits) + running32bits = 1; + #endif } break; case 6: /* Push Ed */ diff --git a/src/include/custommem.h b/src/include/custommem.h index df1d652a..d6867a4f 100644 --- a/src/include/custommem.h +++ b/src/include/custommem.h @@ -112,4 +112,7 @@ void addLockAddress(uintptr_t addr); // add an address to the list of "LOCK"a int isLockAddress(uintptr_t addr); // return 1 is the address is used as a LOCK, 0 else #endif +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); + #endif //__CUSTOM_MEM__H_ diff --git a/src/include/debug.h b/src/include/debug.h index 4ab2e80a..177404da 100644 --- a/src/include/debug.h +++ b/src/include/debug.h @@ -11,6 +11,7 @@ extern uintptr_t box64_pagesize; extern uintptr_t box64_load_addr; extern int box64_dynarec_test; extern int box64_maxcpu; +extern int box64_mmap32; #ifdef DYNAREC extern int box64_dynarec_dump; extern int box64_dynarec_trace; diff --git a/src/libtools/threads.c b/src/libtools/threads.c index d6a49a8a..14fbcd77 100644 --- a/src/libtools/threads.c +++ b/src/libtools/threads.c @@ -46,9 +46,6 @@ void _pthread_cleanup_pop(void* buffer, int exec); // it will be pthread_kill@GLIBC_2.17 on aarch64, but it's GLIBC_2.2.5 on x86_64 static iFli_t real_phtread_kill_old = NULL; -// from src/wrapped/wrappedlibc.c -void* my_mmap(x64emu_t* emu, void* addr, unsigned long length, int prot, int flags, int fd, int64_t offset); - typedef struct threadstack_s { void* stack; size_t stacksize; @@ -203,7 +200,9 @@ x64emu_t* thread_get_emu() stacksize = stack_size; pthread_attr_destroy(&attr); } - void* stack = my_mmap(NULL, NULL, stacksize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_GROWSDOWN, -1, 0); + void* stack = internal_mmap(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); thread_set_emu(emu); @@ -484,7 +483,9 @@ EXPORT int my_pthread_create(x64emu_t *emu, void* t, void* attr, void* start_rou stacksize = attr_stacksize; own = 0; } else { - stack = my_mmap(NULL, NULL, stacksize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_GROWSDOWN, -1, 0); + stack = internal_mmap(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; } @@ -509,7 +510,9 @@ 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 = my_mmap(NULL, NULL, stacksize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_GROWSDOWN, -1, 0); + void* stack = internal_mmap(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); SetupX64Emu(emuthread, emu ); diff --git a/src/main.c b/src/main.c index a17e3eb8..7be65580 100644 --- a/src/main.c +++ b/src/main.c @@ -51,6 +51,11 @@ int box64_inprocessgpu = 0; int box64_malloc_hack = 0; int box64_dynarec_test = 0; int box64_maxcpu = 0; +#if defined(SD845) || defined(SD888) || defined(SD8G2) +int box64_mmap32 = 1; +#else +int box64_mmap32 = 0; +#endif #ifdef DYNAREC int box64_dynarec = 1; int box64_dynarec_dump = 0; @@ -964,6 +969,17 @@ void LoadLogEnv() printf_log(LOG_NONE, "Will not limit the number of cpu cores exposed\n"); } } + p = getenv("BOX64_MMAP32"); + if(p) { + if(strlen(p)==1) { + if(p[0]>='0' && p[0]<='0'+1) + box64_mmap32 = p[0]-'0'; + } + if(box64_mmap32) + printf_log(LOG_INFO, "Will use 32bits address in priority for external MMAP (when 32bits process are detected)\n"); + else + printf_log(LOG_INFO, "Will not use 32bits address in priority for external MMAP (when 32bits process are detected)\n"); + } box64_pagesize = sysconf(_SC_PAGESIZE); if(!box64_pagesize) box64_pagesize = 4096; diff --git a/src/tools/box64stack.c b/src/tools/box64stack.c index d1c55d07..7be31b4d 100644 --- a/src/tools/box64stack.c +++ b/src/tools/box64stack.c @@ -11,9 +11,7 @@ #include "emu/x64emu_private.h" #include "emu/x64run_private.h" #include "auxval.h" - -// from src/wrapped/wrappedlibc.c -void* my_mmap(x64emu_t* emu, void* addr, unsigned long length, int prot, int flags, int fd, int64_t offset); +#include "custommem.h" EXPORTDYN int CalcStackSize(box64context_t *context) @@ -24,11 +22,12 @@ int CalcStackSize(box64context_t *context) CalcStack(context->elfs[i], &context->stacksz, &context->stackalign); //if (posix_memalign((void**)&context->stack, context->stackalign, context->stacksz)) { - context->stack = my_mmap(NULL, NULL, context->stacksz, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_GROWSDOWN, -1, 0); + context->stack = internal_mmap(NULL, context->stacksz, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_GROWSDOWN, -1, 0); if (context->stack==(void*)-1) { printf_log(LOG_NONE, "Cannot allocate aligned memory (0x%lx/0x%zx) for stack\n", context->stacksz, context->stackalign); return 1; - } + } else + setProtection((uintptr_t)context->stack, context->stacksz, PROT_READ|PROT_WRITE); //memset(context->stack, 0, context->stacksz); printf_log(LOG_DEBUG, "Stack is @%p size=0x%lx align=0x%zx\n", context->stack, context->stacksz, context->stackalign); diff --git a/src/tools/rcfile.c b/src/tools/rcfile.c index cea7d5cf..15cb6955 100644 --- a/src/tools/rcfile.c +++ b/src/tools/rcfile.c @@ -86,6 +86,7 @@ CENTRYBOOL(BOX64_NOSIGSEGV, no_sigsegv) \ CENTRYBOOL(BOX64_NOSIGILL, no_sigill) \ ENTRYBOOL(BOX64_SHOWSEGV, box64_showsegv) \ ENTRYBOOL(BOX64_SHOWBT, box64_showbt) \ +ENTRYBOOL(BOX64_MMAP32, box64_mmap32) \ ENTRYBOOL(BOX64_X11THREADS, box64_x11threads) \ ENTRYBOOL(BOX64_X11GLX, box64_x11glx) \ ENTRYDSTRING(BOX64_LIBGL, box64_libGL) \ diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c index 2d444495..74e958b8 100644 --- a/src/wrapped/wrappedlibc.c +++ b/src/wrapped/wrappedlibc.c @@ -2621,7 +2621,7 @@ EXPORT void* my_mmap64(x64emu_t* emu, void *addr, unsigned long length, int prot addr = find47bitBlock(length); } #endif - void* ret = mmap64(addr, length, prot, new_flags, fd, offset); + void* ret = internal_mmap(addr, length, prot, new_flags, fd, offset); #ifndef NOALIGN if((ret!=MAP_FAILED) && (flags&MAP_32BIT) && (((uintptr_t)ret>0xffffffffLL) || (box64_wine && ((uintptr_t)ret&0xffff) && (ret!=addr)))) { @@ -2655,7 +2655,7 @@ EXPORT void* my_mmap64(x64emu_t* emu, void *addr, unsigned long length, int prot } #endif if((ret!=MAP_FAILED) && (flags&MAP_FIXED_NOREPLACE) && (ret!=addr)) { - munmap(ret, length); + internal_munmap(ret, length); errno = EEXIST; return MAP_FAILED; } @@ -2738,7 +2738,7 @@ EXPORT int my_munmap(x64emu_t* emu, void* addr, unsigned long length) { (void)emu; if(emu && (box64_log>=LOG_DEBUG || box64_dynarec_log>=LOG_DEBUG)) {printf_log(LOG_NONE, "munmap(%p, %lu)\n", addr, length);} - int ret = munmap(addr, length); + int ret = internal_munmap(addr, length); #ifdef DYNAREC if(!ret && box64_dynarec && length) { cleanDBFromAddressRange((uintptr_t)addr, length, 1); |