about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-01-29 20:37:08 +0100
committerptitSeb <sebastien.chev@gmail.com>2025-01-29 20:37:08 +0100
commit1db09fe897b79b6cdbb7fb9af7a9570c949d0d79 (patch)
tree93e62a610a39b0e7d70118c7b2a0d6bf74c713d8 /src
parent22a5b573d5cff6ff0c7d1f4ec7646136c4de8445 (diff)
downloadbox64-1db09fe897b79b6cdbb7fb9af7a9570c949d0d79.tar.gz
box64-1db09fe897b79b6cdbb7fb9af7a9570c949d0d79.zip
More improvmnet to map with fd tracking
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/dynarec_native_pass.c2
-rw-r--r--src/elfs/elfloader.c9
-rw-r--r--src/include/env.h3
-rw-r--r--src/tools/env.c24
-rw-r--r--src/wrapped/wrappedlibc.c16
5 files changed, 42 insertions, 12 deletions
diff --git a/src/dynarec/dynarec_native_pass.c b/src/dynarec/dynarec_native_pass.c
index f767942c..1e013eb6 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) || 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
+    int stopblock = 2 + ((FindElfAddress(my_context, addr) || IsAddrFileMapped(addr, NULL, NULL)) ? 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/elfs/elfloader.c b/src/elfs/elfloader.c
index 6924044d..b9d1b297 100644
--- a/src/elfs/elfloader.c
+++ b/src/elfs/elfloader.c
@@ -1341,6 +1341,15 @@ const char* FindNearestSymbolName(elfheader_t* h, void* p, uintptr_t* start, uin
                 }
             }
         }
+        if(!ret) {
+            const char* filename = NULL;
+            uintptr_t start_map = 0;
+            if(IsAddrFileMapped(addr, &filename, &start_map)) {
+                if(start) *start = start_map;
+                if(sz) *sz = SizeFileMapped(addr);
+                ret = filename;
+            }
+        }
         return ret;
     }
     if(!h || h->fini_done)
diff --git a/src/include/env.h b/src/include/env.h
index 9c2af8f8..a60ca9a7 100644
--- a/src/include/env.h
+++ b/src/include/env.h
@@ -205,6 +205,7 @@ 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);
+int IsAddrFileMapped(uintptr_t addr, const char** filename, uintptr_t* start);
+size_t SizeFileMapped(uintptr_t addr);
 
 #endif // __ENV_H
diff --git a/src/tools/env.c b/src/tools/env.c
index b22da4b3..3e6c168e 100644
--- a/src/tools/env.c
+++ b/src/tools/env.c
@@ -540,6 +540,7 @@ typedef struct mapping_s {
     char*       filename;
     char*       fullname;
     box64env_t* env;
+    uintptr_t   start;  //lower address of the map for this file
 } mapping_t;
 
 KHASH_MAP_INIT_STR(mapping_entry, mapping_t*);
@@ -572,6 +573,7 @@ void RecordEnvMappings(uintptr_t addr, size_t length, int fd)
         mapping = box_calloc(1, sizeof(mapping_t));
         mapping->filename = box_strdup(lowercase_filename);
         mapping->fullname = box_strdup(fullname);
+        mapping->start = addr;
         k = kh_put(mapping_entry, mapping_entries, mapping->filename, &ret);
         kh_value(mapping_entries, k) = mapping;
         khint_t k = kh_get(box64env_entry, box64env_entries, mapping->filename);
@@ -580,6 +582,7 @@ void RecordEnvMappings(uintptr_t addr, size_t length, int fd)
     } else
         mapping = kh_value(mapping_entries, k);
 
+    if(mapping && mapping->start>addr) mapping->start = addr;
     rb_set_64(envmap, addr, addr + length, (uint64_t)mapping);
     if(mapping->env) {
         printf_log(LOG_DEBUG, "Applied [%s] of range %p:%p\n", filename, addr, addr + length);
@@ -627,11 +630,28 @@ box64env_t* GetCurEnvByAddr(uintptr_t addr)
     return env;
 }
 
-int IsAddrFileMapped(uintptr_t addr)
+int IsAddrFileMapped(uintptr_t addr, const char** filename, uintptr_t* start)
 {
     if(!envmap) return 0;
     mapping_t* mapping = ((mapping_t*)rb_get_64(envmap, addr));
     if(!mapping) return 0;
-    if(mapping->fullname) return 1;
+    if(mapping->fullname) {
+        if(filename) *filename = mapping->fullname;
+        if(start) *start = mapping->start;
+        return 1;
+    }
     return 0;
 }
+
+size_t SizeFileMapped(uintptr_t addr)
+{
+    if(!envmap) return 0;
+    uint64_t val = 0;
+    uintptr_t end = 0;
+    if(rb_get_end_64(envmap, addr, &val, &end)) {
+        mapping_t* mapping = (mapping_t*)val;
+        if(mapping && (mapping->start<end))
+            return end - mapping->start;
+    }
+    return 0;
+}
\ No newline at end of file
diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c
index 71d811f2..181a8c8b 100644
--- a/src/wrapped/wrappedlibc.c
+++ b/src/wrapped/wrappedlibc.c
@@ -3006,14 +3006,14 @@ EXPORT void* my_mmap64(x64emu_t* emu, void *addr, size_t length, int prot, int f
                 if((BOX64ENV(log)>=LOG_DEBUG || BOX64ENV(dynarec_log)>=LOG_DEBUG)) {printf_log(LOG_NONE, "Note: Marking the region (%p-%p prot=%x) as NEVERCLEAN because fd have O_RDWR attribute\n", ret, ret+length, prot);}
                 prot |= PROT_NEVERCLEAN;
             }
-            if(emu) {
-                DetectUnityPlayer(fd);
-                // the last_mmap will allow mmap created by wine, even those that have hole, to be fully tracked as one single mmap
-                if((ret>=last_mmap_addr) && ret+length<(last_mmap_addr+last_mmap_len))
-                    RecordEnvMappings((uintptr_t)last_mmap_addr, last_mmap_len, fd);
-                else
-                    RecordEnvMappings((uintptr_t)ret, length, fd);
-            }
+        }
+        if(emu && !(flags&MAP_ANONYMOUS) && (fd>0)) {
+            DetectUnityPlayer(fd);
+            // the last_mmap will allow mmap created by wine, even those that have hole, to be fully tracked as one single mmap
+            if((ret>=last_mmap_addr) && ret+length<(last_mmap_addr+last_mmap_len))
+                RecordEnvMappings((uintptr_t)last_mmap_addr, last_mmap_len, fd);
+            else
+                RecordEnvMappings((uintptr_t)ret, length, fd);
         }
         // hack to capture full size of the mmap done by wine
         if(emu && (fd==-1) && (flags==(MAP_PRIVATE|MAP_ANON))) {