From 0c27b82ff3b8a1da27d7ed32e89c90518f9c2c0c Mon Sep 17 00:00:00 2001 From: mogery Date: Tue, 12 Oct 2021 19:47:31 +0200 Subject: [PATCH 1/3] Map bricks below first 2GB of address space This fixes an issue with mono where JIT compiled code would near-call wrapped libraries, but fail because the difference between PC and the call address did not fit into an imm32. This was fixed by replacing posix_memalign with my_mmap and providing the MAP_32BIT flag. Fixes #131 --- src/tools/bridge.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tools/bridge.c b/src/tools/bridge.c index 5f6bb5af8..c800b8c55 100755 --- a/src/tools/bridge.c +++ b/src/tools/bridge.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "custommem.h" #include "bridge.h" @@ -36,9 +37,11 @@ typedef struct bridge_s { brick_t* NewBrick() { brick_t* ret = (brick_t*)calloc(1, sizeof(brick_t)); - if(posix_memalign((void**)&ret->b, box64_pagesize, NBRICK*sizeof(onebridge_t))) { + void* ptr = my_mmap(thread_get_emu(), NULL, NBRICK * sizeof(onebridge_t), PROT_READ | PROT_WRITE, MAP_PRIVATE | 0x40 | MAP_ANONYMOUS, -1, 0); // 0x40 is MAP_32BIT + if(ptr == MAP_FAILED) { printf_log(LOG_NONE, "Warning, cannot allocate 0x%lx aligned bytes for bridge, will probably crash later\n", NBRICK*sizeof(onebridge_t)); } + ret->b = ptr; return ret; } From 4ca58d1f994900d2025258cadf19dd633c8a7c09 Mon Sep 17 00:00:00 2001 From: mogery Date: Tue, 12 Oct 2021 20:05:22 +0200 Subject: [PATCH 2/3] Fix incorrect brick cleanup FreeBridge used free to clean up the pointer allocated by my_mmap, which is incorrect and lead to a crash upon code that exited gracefully. The free was replaced with my_munmap. --- src/tools/bridge.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/bridge.c b/src/tools/bridge.c index c800b8c55..4ee34824c 100755 --- a/src/tools/bridge.c +++ b/src/tools/bridge.c @@ -6,6 +6,7 @@ #include #include +#include #include "custommem.h" #include "bridge.h" #include "bridge_private.h" @@ -59,13 +60,14 @@ void FreeBridge(bridge_t** bridge) if(!bridge || !*bridge) return; brick_t *b = (*bridge)->head; + x64emu_t* emu = thread_get_emu(); while(b) { brick_t *n = b->next; #ifdef DYNAREC if(getProtection((uintptr_t)b->b)&PROT_DYNAREC) unprotectDB((uintptr_t)b->b, NBRICK*sizeof(onebridge_t)); #endif - free(b->b); + my_munmap(emu, b->b, NBRICK*sizeof(onebridge_t)); free(b); b = n; } From bcb0bdea77207f30a988d9f0c3ec5841844efe55 Mon Sep 17 00:00:00 2001 From: mogery Date: Wed, 13 Oct 2021 15:09:48 +0200 Subject: [PATCH 3/3] Declare my_mmap and my_munmap to avoid warning This adds a declaration of my_mmap and my_munmap to src/tools/bridge.c in order to avoid a -Wimplicit-function-declaration warning when compiling. This should probably be moved to a header file in the future. --- src/tools/bridge.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tools/bridge.c b/src/tools/bridge.c index 4ee34824c..2574ddbdc 100755 --- a/src/tools/bridge.c +++ b/src/tools/bridge.c @@ -35,6 +35,10 @@ typedef struct bridge_s { kh_bridgemap_t *bridgemap; } bridge_t; +// 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); +int my_munmap(x64emu_t* emu, void* addr, unsigned long length); + brick_t* NewBrick() { brick_t* ret = (brick_t*)calloc(1, sizeof(brick_t));