diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2025-06-23 14:52:28 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2025-06-23 14:52:28 +0200 |
| commit | 0d02532dab06c20a5ea4bed90c2a7f9fbb7eb96d (patch) | |
| tree | a6ed742a77379545a6054f803b9c222beb163280 | |
| parent | 8ae0b6e1813caae72c66cf70150ce6a55a8a10d4 (diff) | |
| download | box64-0d02532dab06c20a5ea4bed90c2a7f9fbb7eb96d.tar.gz box64-0d02532dab06c20a5ea4bed90c2a7f9fbb7eb96d.zip | |
[DYNACACHE] Added support for unaligned addresses
| -rw-r--r-- | src/libtools/signals.c | 26 | ||||
| -rw-r--r-- | src/tools/env.c | 27 |
2 files changed, 49 insertions, 4 deletions
diff --git a/src/libtools/signals.c b/src/libtools/signals.c index 1c8247ec..5d932349 100644 --- a/src/libtools/signals.c +++ b/src/libtools/signals.c @@ -426,6 +426,32 @@ int is_addr_unaligned(uintptr_t addr) } #ifdef DYNAREC +int nUnalignedRange(uintptr_t start, size_t size) +{ + if(!unaligned) + return 0; + int n = 0; + uintptr_t end = start + size -1; + uintptr_t addr; + kh_foreach_key(unaligned, addr, + if(addr>=start && addr<=end) + ++n; + ); + return n; +} +void getUnalignedRange(uintptr_t start, size_t size, uintptr_t addrs[]) +{ + if(!unaligned) + return; + int n = 0; + uintptr_t end = start + size -1; + uintptr_t addr; + kh_foreach_key(unaligned, addr, + if(addr>=start && addr<=end) + addrs[n++] = addr; + ); +} + int mark_db_unaligned(dynablock_t* db, uintptr_t x64pc) { add_unaligned_address(x64pc); 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); |