about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2025-05-08 22:49:48 +0800
committerGitHub <noreply@github.com>2025-05-08 16:49:48 +0200
commit78193c5f1acb4fd0311bbf96ed0f692016d6e350 (patch)
tree974f5798255854d960be1f89209fe12ef93fb31c /src
parent51d2b73cd73cb362255820fe86503d90cdd3dcd0 (diff)
downloadbox64-78193c5f1acb4fd0311bbf96ed0f692016d6e350.tar.gz
box64-78193c5f1acb4fd0311bbf96ed0f692016d6e350.zip
[ENV] Refactored file-mapping handling (#2612)
* [ENV] Refactored file-mapping handling

* fix
Diffstat (limited to 'src')
-rw-r--r--src/tools/env.c6
-rw-r--r--src/tools/pe_tools.c75
-rw-r--r--src/tools/wine_tools.c16
-rw-r--r--src/wrapped/wrappedlibc.c12
4 files changed, 38 insertions, 71 deletions
diff --git a/src/tools/env.c b/src/tools/env.c
index c21a3687..16c4b194 100644
--- a/src/tools/env.c
+++ b/src/tools/env.c
@@ -13,6 +13,8 @@
 #include "fileutils.h"
 #include "box64context.h"
 #include "rbtree.h"
+#include "wine_tools.h"
+#include "pe_tools.h"
 
 box64env_t box64env = { 0 };
 
@@ -614,6 +616,10 @@ void RecordEnvMappings(uintptr_t addr, size_t length, int fd)
     mapping_t* mapping = NULL;
     khint_t k = kh_get(mapping_entry, mapping_entries, lowercase_filename);
     if(k == kh_end(mapping_entries)) {
+        // First time we see this file
+        if (box64_wine && BOX64ENV(unityplayer)) DetectUnityPlayer(lowercase_filename+1);
+        if (box64_wine && BOX64ENV(dynarec_volatile_metadata)) ParseVolatileMetadata(fullname, (void*)addr);
+
         mapping = box_calloc(1, sizeof(mapping_t));
         mapping->filename = box_strdup(lowercase_filename);
         mapping->fullname = box_strdup(fullname);
diff --git a/src/tools/pe_tools.c b/src/tools/pe_tools.c
index 5d8bc2b4..6afee6c6 100644
--- a/src/tools/pe_tools.c
+++ b/src/tools/pe_tools.c
@@ -187,19 +187,9 @@ typedef struct _IMAGE_VOLATILE_RANGE_METADATA {
 KHASH_SET_INIT_STR(string);
 KHASH_SET_INIT_INT64(volatileopcode);
 
-static kh_string_t* dllNames = NULL;                // never freed
 static kh_volatileopcode_t* volatileOpcodes = NULL; // never freed
-
 static rbtree_t* volatileRanges = NULL; // never freed
 
-static int HasSuffix(const char* str, const char* suffix)
-{
-    size_t lenstr = strlen(str);
-    size_t lensuffix = strlen(suffix);
-    if (lensuffix > lenstr) return 0;
-    return strcmp(str + lenstr - lensuffix, suffix) == 0;
-}
-
 DWORD RVAToFileOffset(PIMAGE_SECTION_HEADER sections, DWORD numberOfSections, DWORD rva, BYTE* fileBuffer, size_t fileSize)
 {
     for (DWORD i = 0; i < numberOfSections; i++) {
@@ -216,12 +206,6 @@ DWORD RVAToFileOffset(PIMAGE_SECTION_HEADER sections, DWORD numberOfSections, DW
 
 void ParseVolatileMetadata(char* filename, void* addr)
 {
-    if (!filename) return;
-    if (!HasSuffix(filename, ".dll")) {
-        return;
-    }
-
-    if (!dllNames) dllNames = kh_init(string);
     if (!volatileOpcodes) volatileOpcodes = kh_init(volatileopcode);
     if (!volatileRanges) volatileRanges = rbtree_init("volatileRanges");
 
@@ -231,14 +215,31 @@ void ParseVolatileMetadata(char* filename, void* addr)
     else
         baseName++;
 
-    khint_t k = kh_get(string, dllNames, baseName);
-    if (k != kh_end(dllNames)) return;
+    IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*)addr;
+    if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) return;
+
+    PIMAGE_NT_HEADERS64 ntHeaders64 = (PIMAGE_NT_HEADERS64)(addr + dosHeader->e_lfanew);
+    if (ntHeaders64->Signature != IMAGE_NT_SIGNATURE || ntHeaders64->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) return;
+
+    int numberOfSections = ntHeaders64->FileHeader.NumberOfSections;
+    if (numberOfSections <= 0) {
+        return;
+    }
+    IMAGE_DATA_DIRECTORY loadConfigDir = ntHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG];
+    if (loadConfigDir.VirtualAddress == 0 || loadConfigDir.Size == 0) {
+        return;
+    }
 
-    int ret;
-    k = kh_put(string, dllNames, strdup(baseName), &ret);
+    PIMAGE_SECTION_HEADER sectionHeaders = (PIMAGE_SECTION_HEADER)((void*)ntHeaders64 + sizeof(IMAGE_NT_HEADERS64)); // immediately follows the optional header, if any.
+    DWORD loadConfigOffset = RVAToFileOffset(sectionHeaders, numberOfSections, loadConfigDir.VirtualAddress, (BYTE*)addr, ntHeaders64->OptionalHeader.SizeOfImage);
+    if (loadConfigOffset == 0) {
+        return;
+    }
 
     FILE* file = fopen(filename, "rb");
-    if (!file) return;
+    if (!file) {
+        return;
+    }
 
     fseek(file, 0, SEEK_END);
     long size = ftell(file);
@@ -257,36 +258,6 @@ void ParseVolatileMetadata(char* filename, void* addr)
     }
     fclose(file);
 
-    IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*)buffer;
-    if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
-        free(buffer);
-        return;
-    }
-
-    PIMAGE_NT_HEADERS64 ntHeaders64 = (PIMAGE_NT_HEADERS64)(buffer + dosHeader->e_lfanew);
-    if (ntHeaders64->Signature != IMAGE_NT_SIGNATURE || ntHeaders64->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
-        free(buffer);
-        return;
-    }
-
-    int numberOfSections = ntHeaders64->FileHeader.NumberOfSections;
-    if (numberOfSections <= 0) {
-        free(buffer);
-        return;
-    }
-    IMAGE_DATA_DIRECTORY loadConfigDir = ntHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG];
-    if (loadConfigDir.VirtualAddress == 0 || loadConfigDir.Size == 0) {
-        free(buffer);
-        return;
-    }
-
-    PIMAGE_SECTION_HEADER sectionHeaders = (PIMAGE_SECTION_HEADER)((void*)ntHeaders64 + sizeof(IMAGE_NT_HEADERS64)); // immediately follows the optional header, if any.
-    DWORD loadConfigOffset = RVAToFileOffset(sectionHeaders, numberOfSections, loadConfigDir.VirtualAddress, (BYTE*)buffer, ntHeaders64->OptionalHeader.SizeOfImage);
-    if (loadConfigOffset == 0) {
-        free(buffer);
-        return;
-    }
-
     PIMAGE_LOAD_CONFIG_DIRECTORY64 loadConfig = (PIMAGE_LOAD_CONFIG_DIRECTORY64)(buffer + loadConfigOffset);
     if (loadConfig->Size < offsetof(IMAGE_LOAD_CONFIG_DIRECTORY64, VolatileMetadataPointer) + sizeof(ULONGLONG)) {
         free(buffer);
@@ -342,6 +313,8 @@ void ParseVolatileMetadata(char* filename, void* addr)
             printf_log(LOG_DEBUG, "Volatile range metadata [%d]: %08lX-%08lX\n", i, rva, rva + size);
         }
     }
+    free(buffer);
+    return;
 }
 
 int VolatileRangesContains(uintptr_t addr)
diff --git a/src/tools/wine_tools.c b/src/tools/wine_tools.c
index 86a91598..e1fb72af 100644
--- a/src/tools/wine_tools.c
+++ b/src/tools/wine_tools.c
@@ -139,16 +139,14 @@ void dynarec_wine_prereserve()
 void DetectUnityPlayer(char* filename)
 {
     static int unityplayer_detected = 0;
-    if (!filename && BOX64ENV(unityplayer) && !unityplayer_detected) {
-        if (strlen(filename) > strlen("UnityPlayer.dll") && !strcasecmp(filename + strlen(filename) - strlen("UnityPlayer.dll"), "UnityPlayer.dll")) {
-            printf_log(LOG_NONE, "Detected UnityPlayer.dll\n");
+    if (filename && BOX64ENV(unityplayer) && !unityplayer_detected && !strcmp(filename, "unityplayer.dll")) {
+        printf_log(LOG_INFO, "Detected UnityPlayer.dll\n");
 #ifdef DYNAREC
-            if (!BOX64ENV(dynarec_strongmem)) {
-                SET_BOX64ENV(dynarec_strongmem, 1);
-                PrintEnvVariables(&box64env, LOG_INFO);
-            }
-#endif
-            unityplayer_detected = 1;
+        if (!BOX64ENV(dynarec_strongmem)) {
+            SET_BOX64ENV(dynarec_strongmem, 1);
+            PrintEnvVariables(&box64env, LOG_INFO);
         }
+#endif
+        unityplayer_detected = 1;
     }
 }
diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c
index fbfc9b21..631b270c 100644
--- a/src/wrapped/wrappedlibc.c
+++ b/src/wrapped/wrappedlibc.c
@@ -3032,17 +3032,7 @@ EXPORT void* my_mmap64(x64emu_t* emu, void *addr, size_t length, int prot, int f
     }
     #endif
     if(ret!=MAP_FAILED) {
-        if(emu && !(flags&MAP_ANONYMOUS) && (fd>0)) {
-            if ((box64_wine && BOX64ENV(dynarec_volatile_metadata)) || BOX64ENV(unityplayer)) {
-                char filename[4096];
-                char buf[128];
-                sprintf(buf, "/proc/self/fd/%d", fd);
-                ssize_t r = readlink(buf, filename, sizeof(filename) - 1);
-                if (r != -1) filename[r] = 0;
-
-                if (BOX64ENV(unityplayer)) DetectUnityPlayer(filename);
-                if (box64_wine && BOX64ENV(dynarec_volatile_metadata)) ParseVolatileMetadata(filename, addr);
-            }
+        if (emu && !(flags & MAP_ANONYMOUS) && (fd > 0)) {
             // 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[0]) && ret+length<(last_mmap_addr[0]+last_mmap_len[0]))
                 RecordEnvMappings((uintptr_t)last_mmap_addr[0], last_mmap_len[0], fd);