diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-11-05 13:17:50 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-11-05 13:17:50 +0100 |
| commit | 9c120168593c9565780c365aef0f511f3e692d61 (patch) | |
| tree | 9c9a94ca40d11fdeb32d574b26ac51264bcfd8db /src | |
| parent | e6943c8a9dad781aa5e1caf7c0cd59041e3c29f8 (diff) | |
| download | box64-9c120168593c9565780c365aef0f511f3e692d61.tar.gz box64-9c120168593c9565780c365aef0f511f3e692d61.zip | |
Better way to track mapped memory
Diffstat (limited to 'src')
| -rw-r--r-- | src/custommem.c | 94 | ||||
| -rw-r--r-- | src/elfs/elfloader.c | 6 | ||||
| -rw-r--r-- | src/include/custommem.h | 3 | ||||
| -rw-r--r-- | src/tools/bridge.c | 2 |
4 files changed, 62 insertions, 43 deletions
diff --git a/src/custommem.c b/src/custommem.c index dbbd223c..b4bdde6c 100644 --- a/src/custommem.c +++ b/src/custommem.c @@ -93,7 +93,8 @@ typedef struct mapmem_s { struct mapmem_s *next; } mapmem_t; -static mapmem_t *mapmem = NULL; +static mapmem_t *mapallmem = NULL; +static mapmem_t *mmapmem = NULL; typedef struct blocklist_s { void* block; @@ -1069,7 +1070,6 @@ void protectDB(uintptr_t addr, uintptr_t size) prot = native_lock_xchg_b(&block[i&0xffff], PROT_WAIT); } while(prot==PROT_WAIT); uint32_t dyn = prot&PROT_DYN; - uint32_t mapped = prot&PROT_MMAP; if(!prot) prot = PROT_READ | PROT_WRITE | PROT_EXEC; // comes from malloc & co, so should not be able to execute prot&=~PROT_CUSTOM; @@ -1077,9 +1077,9 @@ void protectDB(uintptr_t addr, uintptr_t size) if(prot&PROT_WRITE) { if(!dyn) mprotect((void*)(i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, prot&~PROT_WRITE); - prot |= mapped|PROT_DYNAREC; + prot |= PROT_DYNAREC; } else - prot |= mapped|PROT_DYNAREC_R; + prot |= PROT_DYNAREC_R; } native_lock_storeb(&block[i&0xffff], prot); } @@ -1110,7 +1110,7 @@ void unprotectDB(uintptr_t addr, size_t size, int mark) prot&=~PROT_DYN; if(mark) cleanDBFromAddressRange((i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, 0); - mprotect((void*)(i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, prot&~PROT_MMAP); + mprotect((void*)(i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, prot); } else if(prot&PROT_DYNAREC_R) prot &= ~PROT_CUSTOM; } @@ -1147,7 +1147,7 @@ int isprotectedDB(uintptr_t addr, size_t size) #endif -void printMapMem() +void printMapMem(mapmem_t* mapmem) { mapmem_t* m = mapmem; while(m) { @@ -1156,10 +1156,12 @@ void printMapMem() } } -void addMapMem(uintptr_t begin, uintptr_t end) +void addMapMem(mapmem_t* mapmem, uintptr_t begin, uintptr_t end) { if(!mapmem) return; + if(begin<box64_pagesize) + begin = box64_pagesize; begin &=~(box64_pagesize-1); end = (end&~(box64_pagesize-1))+(box64_pagesize-1); // full page // sanitize values @@ -1195,10 +1197,12 @@ void addMapMem(uintptr_t begin, uintptr_t end) } // all done! } -void removeMapMem(uintptr_t begin, uintptr_t end) +void removeMapMem(mapmem_t* mapmem, uintptr_t begin, uintptr_t end) { if(!mapmem) return; + if(begin<box64_pagesize) + begin = box64_pagesize; begin &=~(box64_pagesize-1); end = (end&~(box64_pagesize-1))+(box64_pagesize-1); // full page // sanitize values @@ -1249,7 +1253,7 @@ void updateProtection(uintptr_t addr, size_t size, uint32_t prot) if(end>=(1LL<<(48-MEMPROT_SHIFT))) end = (1LL<<(48-MEMPROT_SHIFT))-1; mutex_lock(&mutex_prot); - addMapMem(addr, addr+size-1); + addMapMem(mapallmem, addr, addr+size-1); UNLOCK_DYNAREC(); uintptr_t bidx = ~1LL; uint8_t *block = NULL; @@ -1260,7 +1264,6 @@ void updateProtection(uintptr_t addr, size_t size, uint32_t prot) } GET_PROT_WAIT(old_prot, i&0xffff); uint32_t dyn=(old_prot&PROT_DYN); - uint32_t mapped=(old_prot&PROT_MMAP); if(!(dyn&PROT_NOPROT)) { if(dyn && (prot&PROT_WRITE)) { // need to remove the write protection from this block dyn = PROT_DYNAREC; @@ -1269,7 +1272,7 @@ void updateProtection(uintptr_t addr, size_t size, uint32_t prot) dyn = PROT_DYNAREC_R; } } - SET_PROT(i&0xffff, prot|dyn|mapped); + SET_PROT(i&0xffff, prot|dyn); } UNLOCK_NODYNAREC(); } @@ -1281,7 +1284,7 @@ void setProtection(uintptr_t addr, size_t size, uint32_t prot) if(end>=(1LL<<(48-MEMPROT_SHIFT))) end = (1LL<<(48-MEMPROT_SHIFT))-1; mutex_lock(&mutex_prot); - addMapMem(addr, addr+size-1); + addMapMem(mapallmem, addr, addr+size-1); UNLOCK_DYNAREC(); for (uintptr_t i=(idx>>16); i<=(end>>16); ++i) { uint8_t* block = getProtBlock(i, prot?1:0); @@ -1297,11 +1300,14 @@ void setProtection(uintptr_t addr, size_t size, uint32_t prot) void setProtection_mmap(uintptr_t addr, size_t size, uint32_t prot) { + mutex_lock(&mutex_prot); + addMapMem(mmapmem, addr, addr+size-1); + mutex_unlock(&mutex_prot); if(prot) - setProtection(addr, size, prot|PROT_MMAP); + setProtection(addr, size, prot); else { mutex_lock(&mutex_prot); - addMapMem(addr, addr+size-1); + addMapMem(mapallmem, addr, addr+size-1); mutex_unlock(&mutex_prot); } } @@ -1327,7 +1333,7 @@ void allocProtection(uintptr_t addr, size_t size, uint32_t prot) if(end>=(1LL<<(48-MEMPROT_SHIFT))) end = (1LL<<(48-MEMPROT_SHIFT))-1; mutex_lock(&mutex_prot); - addMapMem(addr, addr+size-1); + addMapMem(mapallmem, addr, addr+size-1); mutex_unlock(&mutex_prot); // don't need to add precise tracking probably } @@ -1436,7 +1442,8 @@ void freeProtection(uintptr_t addr, size_t size) if(end>=(1LL<<(48-MEMPROT_SHIFT))) end = (1LL<<(48-MEMPROT_SHIFT))-1; mutex_lock(&mutex_prot); - removeMapMem(addr, addr+size-1); + removeMapMem(mapallmem, addr, addr+size-1); + removeMapMem(mmapmem, addr, addr+size-1); UNLOCK_DYNAREC(); for (uintptr_t i=idx; i<=end; ++i) { const uint32_t key = (i>>16); @@ -1503,19 +1510,23 @@ uint32_t getProtection(uintptr_t addr) uint8_t *block = getProtBlock(idx>>16, 0); GET_PROT(ret, idx&0xffff); UNLOCK_NODYNAREC(); - return ret&~PROT_MMAP; + return ret; } int getMmapped(uintptr_t addr) { - if(addr>=(1LL<<48)) - return 0; - LOCK_NODYNAREC(); - const uintptr_t idx = (addr>>MEMPROT_SHIFT); - uint8_t *block = getProtBlock(idx>>16, 0); - GET_PROT(ret, idx&0xffff); - UNLOCK_NODYNAREC(); - return (ret&PROT_MMAP)?1:0; + mapmem_t* m = mmapmem; + if(addr<box64_pagesize) return 0; + while(m) { + uintptr_t begin = m->begin; + uintptr_t end = m->end; + if(addr>=begin && addr<=end) + return 1; + if(addr<begin) + return 0; + m = m->next; + } + return 0; } #define LOWEST (void*)0x10000 @@ -1523,7 +1534,7 @@ int getMmapped(uintptr_t addr) void* find31bitBlockNearHint(void* hint, size_t size, uintptr_t mask) { - mapmem_t* m = mapmem; + mapmem_t* m = mapallmem; uintptr_t h = (uintptr_t)hint; if(hint<LOWEST) hint = LOWEST; if(!mask) mask = 0xffff; @@ -1559,7 +1570,7 @@ void* find47bitBlock(size_t size) } void* find47bitBlockNearHint(void* hint, size_t size, uintptr_t mask) { - mapmem_t* m = mapmem; + mapmem_t* m = mapallmem; uintptr_t h = (uintptr_t)hint; if(hint<LOWEST) hint = LOWEST; if(!mask) mask = 0xffff; @@ -1596,7 +1607,7 @@ void* find47bitBlockElf(size_t size, int mainbin, uintptr_t mask) int isBlockFree(void* hint, size_t size) { - mapmem_t* m = mapmem; + mapmem_t* m = mapallmem; uintptr_t h = (uintptr_t)hint; if(h>0x800000000000LL) return 0; // no tracking there @@ -1679,7 +1690,7 @@ void reserveHighMem() #endif return; // don't reserve by default intptr_t cur = 1LL<<47; - mapmem_t* m = mapmem; + mapmem_t* m = mapallmem; while(m && (m->end<cur)) { m = m->next; } @@ -1697,7 +1708,7 @@ void reserveHighMem() cur = m->end + 1; m = m->next; if(addr) - addMapMem(addr, end); + addMapMem(mapallmem, addr, end); } } @@ -1732,12 +1743,16 @@ void init_custommem_helper(box64context_t* ctx) lockaddress = kh_init(lockaddress); #endif pthread_atfork(NULL, NULL, atfork_child_custommem); - // init mapmem list - mapmem = (mapmem_t*)box_calloc(1, sizeof(mapmem_t)); - mapmem->begin = 0x0; - mapmem->end = (uintptr_t)LOWEST - 1; + // init mapallmem list + mapallmem = (mapmem_t*)box_calloc(1, sizeof(mapmem_t)); + mapallmem->begin = 0x0; + mapallmem->end = (uintptr_t)LOWEST - 1; loadProtectionFromMap(); reserveHighMem(); + // init mmapmem list + mmapmem = (mapmem_t*)box_calloc(1, sizeof(mapmem_t)); + mmapmem->begin = 0x0; + mmapmem->end = (uintptr_t)box64_pagesize - 1; // check if PageSize is correctly defined if(box64_pagesize != (1<<MEMPROT_SHIFT)) { printf_log(LOG_NONE, "Error: PageSize configuration is wrong: configured with %d, but got %zd\n", 1<<MEMPROT_SHIFT, box64_pagesize); @@ -1849,9 +1864,14 @@ void fini_custommem_helper(box64context_t *ctx) pthread_mutex_destroy(&mutex_prot); pthread_mutex_destroy(&mutex_blocks); #endif - while(mapmem) { - mapmem_t *tmp = mapmem; - mapmem = mapmem->next; + while(mapallmem) { + mapmem_t *tmp = mapallmem; + mapallmem = mapallmem->next; + box_free(tmp); + } + while(mmapmem) { + mapmem_t *tmp = mmapmem; + mmapmem = mmapmem->next; box_free(tmp); } } diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c index 7cc4ec12..0e9feb75 100644 --- a/src/elfs/elfloader.c +++ b/src/elfs/elfloader.c @@ -216,7 +216,7 @@ int AllocLoadElfMemory(box64context_t* context, elfheader_t* head, int mainbin) printf_log(log_level, "Delta of %p (vaddr=%p) for Elf \"%s\"\n", (void*)offs, (void*)head->vaddr, head->name); head->image = image; - setProtection_mmap((uintptr_t)image, head->memsz, 0); + setProtection((uintptr_t)image, head->memsz, 0); head->multiblocks = (multiblock_t*)box_calloc(head->multiblock_n, sizeof(multiblock_t)); head->tlsbase = AddTLSPartition(context, head->tlssize); @@ -260,7 +260,7 @@ int AllocLoadElfMemory(box64context_t* context, elfheader_t* head, int mainbin) try_mmap = 0; printf_log(log_level, "Mapping failed, using regular mmap+read"); } else { - setProtection_mmap((uintptr_t)p, head->multiblocks[n].asize, prot); + setProtection((uintptr_t)p, head->multiblocks[n].asize, prot); head->multiblocks[n].p = p; } @@ -285,7 +285,7 @@ int AllocLoadElfMemory(box64context_t* context, elfheader_t* head, int mainbin) } return 1; } - setProtection_mmap((uintptr_t)p, head->multiblocks[n].asize, prot); + setProtection((uintptr_t)p, head->multiblocks[n].asize, prot); head->multiblocks[n].p = p; if(e->p_filesz) { fseeko64(head->file, head->multiblocks[n].offs, SEEK_SET); diff --git a/src/include/custommem.h b/src/include/custommem.h index 4fbdae6d..76157123 100644 --- a/src/include/custommem.h +++ b/src/include/custommem.h @@ -71,9 +71,8 @@ uintptr_t getJumpAddress64(uintptr_t addr); #define PROT_DYNAREC 0x80 #define PROT_DYNAREC_R 0x40 #define PROT_NOPROT 0x20 -#define PROT_MMAP 0x10 #define PROT_DYN (PROT_DYNAREC | PROT_DYNAREC_R | PROT_NOPROT) -#define PROT_CUSTOM (PROT_DYNAREC | PROT_DYNAREC_R | PROT_MMAP | PROT_NOPROT) +#define PROT_CUSTOM (PROT_DYNAREC | PROT_DYNAREC_R | PROT_NOPROT) #define PROT_WAIT 0xFF void updateProtection(uintptr_t addr, size_t size, uint32_t prot); diff --git a/src/tools/bridge.c b/src/tools/bridge.c index f86998a5..d009021d 100644 --- a/src/tools/bridge.c +++ b/src/tools/bridge.c @@ -60,7 +60,7 @@ brick_t* NewBrick(void* old) printf_log(LOG_NONE, "Warning, cannot allocate 0x%lx aligned bytes for bridge, will probably crash later\n", NBRICK*sizeof(onebridge_t)); } #ifdef DYNAREC - setProtection((uintptr_t)ptr, NBRICK * sizeof(onebridge_t), PROT_READ | PROT_WRITE | PROT_EXEC | PROT_NOPROT | PROT_MMAP); + setProtection((uintptr_t)ptr, NBRICK * sizeof(onebridge_t), PROT_READ | PROT_WRITE | PROT_EXEC | PROT_NOPROT); #endif dynarec_log(LOG_INFO, "New Bridge brick at %p (size 0x%zx)\n", ptr, NBRICK*sizeof(onebridge_t)); ret->b = ptr; |