From 299df773cee3031726b7d595f040ba84637ace11 Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Mon, 22 Dec 2025 15:24:01 +0000 Subject: [PATCH 1/2] ImageTracker: Support codemap file generation --- Source/Windows/Common/ImageTracker.cpp | 26 ++++++++++++++++++++++++++ Source/Windows/Common/ImageTracker.h | 6 +++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/Source/Windows/Common/ImageTracker.cpp b/Source/Windows/Common/ImageTracker.cpp index 35f9eaaf8..676d3e4fb 100644 --- a/Source/Windows/Common/ImageTracker.cpp +++ b/Source/Windows/Common/ImageTracker.cpp @@ -108,6 +108,25 @@ FEXCore::ExecutableFileSectionInfo ImageTracker::HandleImageMap(std::string_view auto ID = FEXCore::CodeMap::GetBaseFilename(ImageInfo->Info, false); LogMan::Msg::DFmt("Load module {} ({}): {:X}", ModuleName, ID, Address); + if (FEXCore::Config::Get_ENABLECODECACHINGWIP()) { + if (MainImage) { + LARGE_INTEGER Time; + NtQuerySystemTime(&Time); + const auto CodeMapDir = fmt::format("{}codemap\\new\\", FEX::Config::GetCacheDirectory()); + std::error_code ec; + if (!std::filesystem::exists(CodeMapDir, ec)) { + std::filesystem::create_directories(CodeMapDir, ec); + } + if (!ec) { + ActiveCodeMapPath = fmt::format("{}{}.{}.bin", CodeMapDir, ID, Time.QuadPart); + + auto Writer = fextl::make_unique(*this, false); + Writer->AppendSetMainExecutable(ImageInfo->Info); + CTX.SetCodeMapWriter(std::move(Writer)); + } + } + } + uint64_t EndAddress = Address + Nt->OptionalHeader.SizeOfImage; fextl::set VolatileInstructions {}; FEXCore::IntervalList VolatileValidRanges {}; @@ -140,4 +159,11 @@ std::optional ImageTracker::LookupExecutable } return std::prev(It)->second.SectionInfo; } + +int ImageTracker::OpenCodeMapFile() { + if (ActiveCodeMapPath.empty()) { + return -1; + } + return _sopen(ActiveCodeMapPath.c_str(), O_CREAT | O_TRUNC | O_WRONLY | O_APPEND, _SH_DENYRW, 0644); +} } // namespace FEX::Windows diff --git a/Source/Windows/Common/ImageTracker.h b/Source/Windows/Common/ImageTracker.h index f54efbe1a..75ae663d7 100644 --- a/Source/Windows/Common/ImageTracker.h +++ b/Source/Windows/Common/ImageTracker.h @@ -36,7 +36,7 @@ FEXCore::CodeMapFileId ComputeCodeMapId(std::string_view FileName, uint32_t Time /** * @brief Tracks mapped PE code images and handles their volatile metadata */ -class ImageTracker { +class ImageTracker : public FEXCore::CodeMapOpener { public: ImageTracker(FEXCore::Context::Context& CTX); FEXCore::ExecutableFileSectionInfo HandleImageMap(std::string_view Path, uint64_t Address, bool MainImage); @@ -44,6 +44,8 @@ public: std::optional LookupExecutableFileSection(uint64_t Address); + int OpenCodeMapFile() override; + private: struct MappedImageInfo { FEXCore::ExecutableFileInfo Info; @@ -60,6 +62,8 @@ private: std::shared_mutex ImagesLock; std::map MappedImages; + + std::string ActiveCodeMapPath; }; } // namespace FEX::Windows From 085cf027dc64f4b9e56a3a4f875c06ab0f48298b Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Mon, 22 Dec 2025 15:26:52 +0000 Subject: [PATCH 2/2] ImageTracker: Do not generate codemaps when generating code caches --- Source/Windows/ARM64EC/Module.cpp | 2 +- Source/Windows/Common/ImageTracker.cpp | 7 ++++--- Source/Windows/Common/ImageTracker.h | 3 ++- Source/Windows/WOW64/Module.cpp | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Source/Windows/ARM64EC/Module.cpp b/Source/Windows/ARM64EC/Module.cpp index c26a5d116..19ac4f33d 100644 --- a/Source/Windows/ARM64EC/Module.cpp +++ b/Source/Windows/ARM64EC/Module.cpp @@ -595,7 +595,7 @@ NTSTATUS ProcessInit() { CTX->InitCore(); Exception::HandlerConfig.emplace(*CTX); InvalidationTracker.emplace(*CTX, Threads); - ImageTracker.emplace(*CTX); + ImageTracker.emplace(*CTX, false); auto MainModule = reinterpret_cast<__TEB*>(NtCurrentTeb())->Peb->ImageBaseAddress; HandleImageMap(reinterpret_cast(MainModule), true); diff --git a/Source/Windows/Common/ImageTracker.cpp b/Source/Windows/Common/ImageTracker.cpp index 676d3e4fb..8131ccbb8 100644 --- a/Source/Windows/Common/ImageTracker.cpp +++ b/Source/Windows/Common/ImageTracker.cpp @@ -75,9 +75,10 @@ static void LoadImageVolatileMetadata(fextl::set& VolatileInstructions } } -ImageTracker::ImageTracker(FEXCore::Context::Context& CTX) +ImageTracker::ImageTracker(FEXCore::Context::Context& CTX, bool IsGeneratingCache) : CTX {CTX} - , ExtendedMetaData {FEX::VolatileMetadata::ParseExtendedVolatileMetadata(ExtendedVolatileMetadataConfig())} {} + , ExtendedMetaData {FEX::VolatileMetadata::ParseExtendedVolatileMetadata(ExtendedVolatileMetadataConfig())} + , IsGeneratingCache {IsGeneratingCache} {} ImageTracker::MappedImageInfo::MappedImageInfo(std::string_view Path, uint64_t Address, ArchImageNtHeaders* Nt, fextl::unordered_map Relocations) @@ -108,7 +109,7 @@ FEXCore::ExecutableFileSectionInfo ImageTracker::HandleImageMap(std::string_view auto ID = FEXCore::CodeMap::GetBaseFilename(ImageInfo->Info, false); LogMan::Msg::DFmt("Load module {} ({}): {:X}", ModuleName, ID, Address); - if (FEXCore::Config::Get_ENABLECODECACHINGWIP()) { + if (FEXCore::Config::Get_ENABLECODECACHINGWIP() && !IsGeneratingCache) { if (MainImage) { LARGE_INTEGER Time; NtQuerySystemTime(&Time); diff --git a/Source/Windows/Common/ImageTracker.h b/Source/Windows/Common/ImageTracker.h index 75ae663d7..e377f055a 100644 --- a/Source/Windows/Common/ImageTracker.h +++ b/Source/Windows/Common/ImageTracker.h @@ -38,7 +38,7 @@ FEXCore::CodeMapFileId ComputeCodeMapId(std::string_view FileName, uint32_t Time */ class ImageTracker : public FEXCore::CodeMapOpener { public: - ImageTracker(FEXCore::Context::Context& CTX); + ImageTracker(FEXCore::Context::Context& CTX, bool IsGeneratingCache); FEXCore::ExecutableFileSectionInfo HandleImageMap(std::string_view Path, uint64_t Address, bool MainImage); void HandleImageUnmap(uint64_t Address, uint64_t Size); @@ -64,6 +64,7 @@ private: std::map MappedImages; std::string ActiveCodeMapPath; + bool IsGeneratingCache; }; } // namespace FEX::Windows diff --git a/Source/Windows/WOW64/Module.cpp b/Source/Windows/WOW64/Module.cpp index 5be957143..dfd015582 100644 --- a/Source/Windows/WOW64/Module.cpp +++ b/Source/Windows/WOW64/Module.cpp @@ -513,7 +513,7 @@ void BTCpuProcessInit() { CTX->InitCore(); Context::HandlerConfig.emplace(*CTX); InvalidationTracker.emplace(*CTX, Threads); - ImageTracker.emplace(*CTX); + ImageTracker.emplace(*CTX, false); auto MainModule = reinterpret_cast<__TEB*>(NtCurrentTeb())->Peb->ImageBaseAddress; HandleImageMap(reinterpret_cast(MainModule), true);