about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-01-27 16:35:50 +0100
committerptitSeb <sebastien.chev@gmail.com>2025-01-27 16:35:50 +0100
commit3ab56994daab4d193e3f7bdc70c514a0c876f07b (patch)
treeba254a924a0f1080fc38430ff5eaca4dc5452d52 /src
parenta54afc8e0476c774ee0c1e3c35a1636e025c2d50 (diff)
downloadbox64-3ab56994daab4d193e3f7bdc70c514a0c876f07b.tar.gz
box64-3ab56994daab4d193e3f7bdc70c514a0c876f07b.zip
Improved file map tracking, and use file map info in dynarec for bigblock setting
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/dynarec_native_pass.c2
-rw-r--r--src/include/env.h1
-rw-r--r--src/include/rbtree.h10
-rw-r--r--src/tools/env.c33
-rw-r--r--src/tools/rbtree.c14
5 files changed, 58 insertions, 2 deletions
diff --git a/src/dynarec/dynarec_native_pass.c b/src/dynarec/dynarec_native_pass.c
index 99401201..f767942c 100644
--- a/src/dynarec/dynarec_native_pass.c
+++ b/src/dynarec/dynarec_native_pass.c
@@ -57,7 +57,7 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
     ARCH_INIT();
     int reset_n = -1; // -1 no reset; -2 reset to 0; else reset to the state of reset_n
     dyn->last_ip = (alternate || (dyn->insts && dyn->insts[0].pred_sz))?0:ip;  // RIP is always set at start of block unless there is a predecessor!
-    int stopblock = 2 + (FindElfAddress(my_context, addr) ? 0 : 1);            // if block is in elf_memory, it can be extended with BOX64DRENV(dynarec_bigblock)==2, else it needs 3
+    int stopblock = 2 + ((FindElfAddress(my_context, addr) || IsAddrFileMapped(addr)) ? 0 : 1);            // if block is in elf memory or file mapped memory, it can be extended with BOX64DRENV(dynarec_bigblock)==2, else it needs 3
     // ok, go now
     INIT;
     #if STEP == 0
diff --git a/src/include/env.h b/src/include/env.h
index 0503b413..1b7f2130 100644
--- a/src/include/env.h
+++ b/src/include/env.h
@@ -205,5 +205,6 @@ void PrintEnvVariables(box64env_t* env, int level);
 void RecordEnvMappings(uintptr_t addr, size_t length, int fd);
 void RemoveMapping(uintptr_t addr, size_t length);
 box64env_t* GetCurEnvByAddr(uintptr_t addr);
+int IsAddrFileMapped(uintptr_t addr);
 
 #endif // __ENV_H
diff --git a/src/include/rbtree.h b/src/include/rbtree.h
index 83eddb78..0d267fde 100644
--- a/src/include/rbtree.h
+++ b/src/include/rbtree.h
@@ -250,4 +250,14 @@ int rb_unset(rbtree_t* tree, uintptr_t start, uintptr_t end);
  */
 uintptr_t rb_get_righter(rbtree_t* tree);
 
+/**
+ * rb_get_lefter() - Retrieves the start value of the left-most node in a red-black tree.
+ * @tree: Pointer to the red-black tree whose left-most node's start value is to be retrieved.
+ *
+ * This function traverses the red-black tree from the root to the left-most node, which is the node
+ * with the lowest key value in the tree. 
+ * Return: The start value of the left-most node if the tree is not empty; otherwise, 0.
+ */
+uintptr_t rb_get_lefter(rbtree_t* tree);
+
 #endif // RBTREE_H
diff --git a/src/tools/env.c b/src/tools/env.c
index 9383c7d7..b22da4b3 100644
--- a/src/tools/env.c
+++ b/src/tools/env.c
@@ -591,8 +591,30 @@ void RecordEnvMappings(uintptr_t addr, size_t length, int fd)
 void RemoveMapping(uintptr_t addr, size_t length)
 {
     if(!envmap) return;
-    // TODO: handling memory to free mapping_entries entry when needed
+    mapping_t* mapping = (mapping_t*)rb_get_64(envmap, addr);
     rb_unset(envmap, addr, addr+length);
+    // quick check at next address
+    if(mapping) {
+        if(mapping == (mapping_t*)rb_get_64(envmap, addr+length))
+            return; // still present, don't purge mapping
+        // Will traverse the tree to find any left over
+        uintptr_t start = rb_get_lefter(envmap);
+        uintptr_t end;
+        uint64_t val;
+        do {
+            rb_get_end_64(envmap, start, &val, &end);
+            if((mapping_t*)val==mapping)
+                return; // found more occurance, exiting
+            start = end;
+        } while(end!=UINTPTR_MAX);
+        // no occurence found, delete mapping
+        khint_t k = kh_get(mapping_entry, mapping_entries, mapping->filename);
+        if(k!=kh_end(mapping_entries))
+            kh_del(mapping_entry, mapping_entries, k);
+        box_free(mapping->filename);
+        box_free(mapping->fullname);
+        box_free(mapping);
+    }
 }
 
 box64env_t* GetCurEnvByAddr(uintptr_t addr)
@@ -604,3 +626,12 @@ box64env_t* GetCurEnvByAddr(uintptr_t addr)
     if(!env) return &box64env;
     return env;
 }
+
+int IsAddrFileMapped(uintptr_t addr)
+{
+    if(!envmap) return 0;
+    mapping_t* mapping = ((mapping_t*)rb_get_64(envmap, addr));
+    if(!mapping) return 0;
+    if(mapping->fullname) return 1;
+    return 0;
+}
diff --git a/src/tools/rbtree.c b/src/tools/rbtree.c
index daa01f35..cc19c4e5 100644
--- a/src/tools/rbtree.c
+++ b/src/tools/rbtree.c
@@ -830,6 +830,20 @@ dynarec_log(LOG_DEBUG, "rb_get_righter(%s);\n", tree->name);
     return 0;
 }
 
+uintptr_t rb_get_lefter(rbtree_t* tree)
+{
+dynarec_log(LOG_DEBUG, "rb_get_lefter(%s);\n", tree->name);
+    if (!tree->root) return 0;
+
+    rbnode *node = tree->root;
+    while (node) {
+        if(!node->left)
+            return node->start;
+        node = node->left;
+    }
+    return 0;
+}
+
 #include <stdio.h>
 static void print_rbnode(const rbnode *node, unsigned depth, uintptr_t minstart, uintptr_t maxend, unsigned *bdepth) {
     if (!node) {