diff options
| -rw-r--r-- | src/custommem.c | 36 | ||||
| -rw-r--r-- | src/dynarec/dynarec_native.c | 4 | ||||
| -rw-r--r-- | src/include/custommem.h | 5 | ||||
| -rw-r--r-- | src/include/env.h | 3 | ||||
| -rw-r--r-- | src/tools/env.c | 18 |
5 files changed, 60 insertions, 6 deletions
diff --git a/src/custommem.c b/src/custommem.c index 84cf8cc1..a1722dd8 100644 --- a/src/custommem.c +++ b/src/custommem.c @@ -1069,6 +1069,34 @@ typedef struct mmaplist_s { mmaplist_t* next; } mmaplist_t; +mmaplist_t* NewMmaplist() +{ + return (mmaplist_t*)box_calloc(1, sizeof(mmaplist_t)); +} + +void DelMmaplist(mmaplist_t* list) +{ + if(!list) return; + while(list) { + for(int i=0; i<NCHUNK; ++i) + if(list->chunks[i].chunk.size) { + cleanDBFromAddressRange((uintptr_t)list->chunks[i].chunk.block, list->chunks[i].chunk.size, 1); + rb_unset(rbt_dynmem, (uintptr_t)list->chunks[i].chunk.block, (uintptr_t)list->chunks[i].chunk.block+list->chunks[i].chunk.size); + InternalMunmap(list->chunks[i].chunk.block, list->chunks[i].chunk.size); + // check if memory should be protected and alloced for box32 + if(box64_is32bits && (uintptr_t)list->chunks[i].chunk.block>0xffffffffLL) { + //rereserve and mark as reserved + if(InternalMmap(list->chunks[i].chunk.block, list->chunks[i].chunk.size, 0, MAP_NORESERVE|MAP_ANON|MAP_FIXED, -1, 0)!=MAP_FAILED) + rb_set(mapallmem, (uintptr_t)list->chunks[i].chunk.block, (uintptr_t)list->chunks[i].chunk.block+list->chunks[i].chunk.size, MEM_RESERVED); + } else + rb_unset(mapallmem, (uintptr_t)list->chunks[i].chunk.block, (uintptr_t)list->chunks[i].chunk.block+list->chunks[i].chunk.size); + } + mmaplist_t* next = list->next; + box_free(list); + list = next; + } +} + dynablock_t* FindDynablockFromNativeAddress(void* p) { if(!p) @@ -1098,16 +1126,18 @@ dynablock_t* FindDynablockFromNativeAddress(void* p) #ifdef TRACE_MEMSTAT static uint64_t dynarec_allocated = 0; #endif -uintptr_t AllocDynarecMap(size_t size) +uintptr_t AllocDynarecMap(uintptr_t x64_addr, size_t size) { if(!size) return 0; size = roundSize(size); - mmaplist_t* list = mmaplist; + mmaplist_t* list = GetMmaplistByAddr(x64_addr); + if(!list) + list = mmaplist; if(!list) - list = mmaplist = (mmaplist_t*)box_calloc(1, sizeof(mmaplist_t)); + list = mmaplist = NewMmaplist(); // check if there is space in current open ones int idx = 0; uintptr_t sz = size + 2*sizeof(blockmark_t); diff --git a/src/dynarec/dynarec_native.c b/src/dynarec/dynarec_native.c index d47ab2fb..0a57db95 100644 --- a/src/dynarec/dynarec_native.c +++ b/src/dynarec/dynarec_native.c @@ -562,7 +562,7 @@ void* CreateEmptyBlock(dynablock_t* block, uintptr_t addr, int is32bits) { block->isize = 0; block->done = 0; size_t sz = 4*sizeof(void*); - void* actual_p = (void*)AllocDynarecMap(sz); + void* actual_p = (void*)AllocDynarecMap(addr, sz); void* p = actual_p + sizeof(void*); if(actual_p==NULL) { dynarec_log(LOG_INFO, "AllocDynarecMap(%p, %zu) failed, canceling block\n", block, sz); @@ -808,7 +808,7 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bit // ok, now allocate mapped memory, with executable flag on size_t sz = sizeof(void*) + native_size + helper.table64size*sizeof(uint64_t) + 4*sizeof(void*) + insts_rsize + arch_size + callret_size; // dynablock_t* block (arm insts) table64 jmpnext code instsize arch callrets - void* actual_p = (void*)AllocDynarecMap(sz); + void* actual_p = (void*)AllocDynarecMap(addr, sz); void* p = (void*)(((uintptr_t)actual_p) + sizeof(void*)); void* tablestart = p + native_size; void* next = tablestart + helper.table64size*sizeof(uint64_t); diff --git a/src/include/custommem.h b/src/include/custommem.h index d7b79296..1ff4bdcc 100644 --- a/src/include/custommem.h +++ b/src/include/custommem.h @@ -31,9 +31,12 @@ size_t customGetUsableSize(void* p); #ifdef DYNAREC typedef struct dynablock_s dynablock_t; +typedef struct mmaplist_s mmaplist_t; // custom protection flag to mark Page that are Write protected for Dynarec purpose -uintptr_t AllocDynarecMap(size_t size); +uintptr_t AllocDynarecMap(uintptr_t x64_addr, size_t size); void FreeDynarecMap(uintptr_t addr); +mmaplist_t* NewMmaplist(); +void DelMmaplist(mmaplist_t* list); void addDBFromAddressRange(uintptr_t addr, size_t size); // Will return 1 if at least 1 db in the address range diff --git a/src/include/env.h b/src/include/env.h index ff8961c6..75eb0982 100644 --- a/src/include/env.h +++ b/src/include/env.h @@ -193,6 +193,8 @@ typedef struct box64env_s { uint64_t is_dynarec_perf_map_fd_overridden : 1; } box64env_t; +typedef struct mmaplist_s mmaplist_t; + void InitializeEnvFiles(); void ApplyEnvFileEntry(const char* name); const char* GetLastApplyEntryName(); @@ -204,5 +206,6 @@ void RemoveMapping(uintptr_t addr, size_t length); box64env_t* GetCurEnvByAddr(uintptr_t addr); int IsAddrFileMapped(uintptr_t addr, const char** filename, uintptr_t* start); size_t SizeFileMapped(uintptr_t addr); +mmaplist_t* GetMmaplistByAddr(uintptr_t addr); #endif // __ENV_H diff --git a/src/tools/env.c b/src/tools/env.c index 9d84fd5c..016d4025 100644 --- a/src/tools/env.c +++ b/src/tools/env.c @@ -22,6 +22,9 @@ KHASH_MAP_INIT_STR(box64env_entry, box64env_t) static kh_box64env_entry_t* box64env_entries = NULL; static kh_box64env_entry_t* box64env_entries_gen = NULL; +mmaplist_t* NewMmaplist(); +void DelMmaplist(mmaplist_t* list); + static rbtree_t* envmap = NULL; static const char default_rcfile[] = @@ -649,6 +652,7 @@ typedef struct mapping_s { char* fullname; box64env_t* env; uintptr_t start; //lower address of the map for this file + mmaplist_t* mmaplist; } mapping_t; KHASH_MAP_INIT_STR(mapping_entry, mapping_t*); @@ -742,6 +746,8 @@ void RemoveMapping(uintptr_t addr, size_t length) khint_t k = kh_get(mapping_entry, mapping_entries, mapping->fullname); if(k!=kh_end(mapping_entries)) kh_del(mapping_entry, mapping_entries, k); + if(mapping->mmaplist) + DelMmaplist(mapping->mmaplist); box_free(mapping->filename); box_free(mapping->fullname); box_free(mapping); @@ -758,6 +764,18 @@ box64env_t* GetCurEnvByAddr(uintptr_t addr) return env; } +mmaplist_t* GetMmaplistByAddr(uintptr_t addr) +{ + if (!envmap) return NULL; + mapping_t* mapping = ((mapping_t*)rb_get_64(envmap, addr)); + if(!mapping) return NULL; + mmaplist_t* list = mapping->mmaplist; + if(!list) + list = mapping->mmaplist = NewMmaplist(); + return list; +} + + int IsAddrFileMapped(uintptr_t addr, const char** filename, uintptr_t* start) { if(!envmap) return 0; |