about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/custommem.c36
-rw-r--r--src/dynarec/dynarec_native.c4
-rw-r--r--src/include/custommem.h5
-rw-r--r--src/include/env.h3
-rw-r--r--src/tools/env.c18
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;