about summary refs log tree commit diff stats
path: root/src/tools
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-06-23 14:52:28 +0200
committerptitSeb <sebastien.chev@gmail.com>2025-06-23 14:52:28 +0200
commit0d02532dab06c20a5ea4bed90c2a7f9fbb7eb96d (patch)
treea6ed742a77379545a6054f803b9c222beb163280 /src/tools
parent8ae0b6e1813caae72c66cf70150ce6a55a8a10d4 (diff)
downloadbox64-0d02532dab06c20a5ea4bed90c2a7f9fbb7eb96d.tar.gz
box64-0d02532dab06c20a5ea4bed90c2a7f9fbb7eb96d.zip
[DYNACACHE] Added support for unaligned addresses
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/env.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/src/tools/env.c b/src/tools/env.c
index bb89cc49..9c9ad41b 100644
--- a/src/tools/env.c
+++ b/src/tools/env.c
@@ -39,6 +39,9 @@ int MmaplistAddBlock(mmaplist_t* list, int fd, off_t offset, void* orig, size_t
 int nLockAddressRange(uintptr_t start, size_t size);
 void getLockAddressRange(uintptr_t start, size_t size, uintptr_t addrs[]);
 void addLockAddress(uintptr_t addr);
+int nUnalignedRange(uintptr_t start, size_t size);
+void getUnalignedRange(uintptr_t start, size_t size, uintptr_t addrs[]);
+void add_unaligned_address(uintptr_t addr);
 #endif
 
 static rbtree_t* envmap = NULL;
@@ -800,7 +803,7 @@ done:
     `box64 --dynacache-clean` can be used from command line to purge obsolete DyaCache files
 */
 
-#define FILE_VERSION               1
+#define FILE_VERSION               2
 #define HEADER_SIGN "DynaCache"
 #define SET_VERSION(MAJ, MIN, REV) (((MAJ)<<24)|((MIN)<<16)|(REV))
 #ifdef ARM64
@@ -829,6 +832,7 @@ typedef struct DynaCacheHeader_s {
     uint32_t    filename_length;
     uint32_t    nblocks;
     uint32_t    nLockAddresses;
+    uint32_t    nUnalignedAddresses;
     char        filename[];
 } DynaCacheHeader_t;
 
@@ -944,7 +948,8 @@ void SerializeMmaplist(mapping_t* mapping)
     }
     size_t map_len = SizeFileMapped(mapping->start);
     size_t nLockAddresses = nLockAddressRange(mapping->start, map_len);
-    size_t total = sizeof(DynaCacheHeader_t) + strlen(mapping->fullname) + 1 + nblocks*sizeof(DynaCacheBlock_t) + nLockAddresses*sizeof(uintptr_t);
+    size_t nUnaligned = nUnalignedRange(mapping->start, map_len);
+    size_t total = sizeof(DynaCacheHeader_t) + strlen(mapping->fullname) + 1 + nblocks*sizeof(DynaCacheBlock_t) + nLockAddresses*sizeof(uintptr_t) + nUnaligned*sizeof(uintptr_t);;
     total = (total + box64_pagesize-1)&~(box64_pagesize-1); // align on pagesize
     uint8_t all_header[total];
     memset(all_header, 0, total);
@@ -964,6 +969,7 @@ void SerializeMmaplist(mapping_t* mapping)
     header->nblocks = MmaplistNBlocks(mapping->mmaplist);
     header->map_len = map_len;
     header->nLockAddresses = nLockAddresses;
+    header->nUnalignedAddresses = nUnaligned;
     size_t dynacache_min = box64env.dynacache_min;
     if(mapping->env && mapping->env->is_dynacache_min_overridden)
         dynacache_min = mapping->env->dynacache_min;
@@ -978,7 +984,12 @@ void SerializeMmaplist(mapping_t* mapping)
     MmaplistFillBlocks(mapping->mmaplist, blocks);
     p += nblocks*sizeof(DynaCacheBlock_t);
     uintptr_t* lockAddresses = p;
-    getLockAddressRange(mapping->start, map_len, lockAddresses);
+    p += nLockAddresses*sizeof(uintptr_t);
+    uintptr_t* unalignedAddresses = p;
+    if(nLockAddresses)
+        getLockAddressRange(mapping->start, map_len, lockAddresses);
+    if(nUnaligned)
+        getUnalignedRange(mapping->start, map_len, unalignedAddresses);
     // all done, now just create the file and write all this down...
     #ifndef WIN32
     unlink(mapname);
@@ -1102,6 +1113,12 @@ int ReadDynaCache(const char* folder, const char* name, mapping_t* mapping, int
         fclose(f);
         return DCERR_FERROR;
     }
+    uintptr_t unalignedAddresses[header.nUnalignedAddresses];
+    if(fread(unalignedAddresses, sizeof(uintptr_t), header.nUnalignedAddresses, f)!=header.nUnalignedAddresses) {
+        if(verbose) printf_log_prefix(0, LOG_NONE, "Cannot read unalignedAddresses\n");
+        fclose(f);
+        return DCERR_FERROR;
+    }
     off_t p = ftell(f);
     p = (p+box64_pagesize-1)&~(box64_pagesize-1);
     if(fseek(f, p, SEEK_SET)<0) {
@@ -1145,7 +1162,7 @@ int ReadDynaCache(const char* folder, const char* name, mapping_t* mapping, int
             }
             printf_log_prefix(0, LOG_NONE, "\tHas %d blocks for a total of %s", header.nblocks, NicePrintSize(total_blocks));
             printf_log_prefix(0, LOG_NONE, " with %s still free", NicePrintSize(total_free));
-            printf_log_prefix(0, LOG_NONE, " and %s non-canceled blocks (mapped at %p-%p, with %zu lock addresses)\n", NicePrintSize(total_code), (void*)header.map_addr, (void*)header.map_addr+header.map_len, header.nLockAddresses);
+            printf_log_prefix(0, LOG_NONE, " and %s non-canceled blocks (mapped at %p-%p, with %zu lock and %zu unaligned addresses)\n", NicePrintSize(total_code), (void*)header.map_addr, (void*)header.map_addr+header.map_len, header.nLockAddresses, header.nUnalignedAddresses);
         }
     } else {
         // actually reading!
@@ -1165,6 +1182,8 @@ int ReadDynaCache(const char* folder, const char* name, mapping_t* mapping, int
         }
         for(size_t i=0; i<header.nLockAddresses; ++i)
             addLockAddress(lockAddresses[i]+delta_map);
+        for(size_t i=0; i<header.nUnalignedAddresses; ++i)
+            add_unaligned_address(lockAddresses[i]+delta_map);
         dynarec_log(LOG_INFO, "Loaded DynaCache for %s, with %d blocks\n", mapping->fullname, header.nblocks);
     }
     fclose(f);