diff --git a/Source/Windows/Common/ImageTracker.cpp b/Source/Windows/Common/ImageTracker.cpp index 02c777416..0738630e7 100644 --- a/Source/Windows/Common/ImageTracker.cpp +++ b/Source/Windows/Common/ImageTracker.cpp @@ -167,6 +167,8 @@ FEXCore::ExecutableFileSectionInfo ImageTracker::HandleImageMap(std::string_view Writer->AppendSetMainExecutable(ImageInfo->Info); CTX.SetCodeMapWriter(std::move(Writer)); } + } + if (!ActiveCodeMapPath.empty()) { LoadAOTImages(*ImageInfo); } @@ -220,84 +222,43 @@ int ImageTracker::OpenCodeMapFile() { } void ImageTracker::LoadAOTImages(MappedImageInfo& ImageInfo) { - const auto AnsiPath = - fmt::format("\\??\\{}cache\\{}", FEX::Config::GetCacheDirectory(), FEXCore::CodeMap::GetBaseFilename(ImageInfo.Info, false)); - - // Iterate over all files in the given executable's cache directory, mapping them into memory for future use. - // Each cache file name matches the unique ID (as returned by FEXCore::CodeMap::GetBaseFilename) of the image it corresponds to. - ScopedUnicodeString NtPath(AnsiPath.c_str()); - - OBJECT_ATTRIBUTES DirAttr; - InitializeObjectAttributes(&DirAttr, &*NtPath, OBJ_CASE_INSENSITIVE, NULL, NULL); - - ScopedHandle DirHandle; - IO_STATUS_BLOCK IOSB; - if (!NT_SUCCESS(NtOpenFile(&*DirHandle, FILE_LIST_DIRECTORY | SYNCHRONIZE, &DirAttr, &IOSB, FILE_SHARE_READ | FILE_SHARE_WRITE, - FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT))) { + // Don't attempt cache loading for FEXOfflineCompiler itself + static bool IsFOC = ImageInfo.Info.Filename.ends_with("fexofflinecompiler.exe"); + if (IsFOC) { return; } - std::array DirBuffer; - bool FirstScan = true; - auto QueryDir = [&]() { - NTSTATUS Status = NtQueryDirectoryFile(*DirHandle, nullptr, nullptr, nullptr, &IOSB, DirBuffer.data(), DirBuffer.size(), - FileBothDirectoryInformation, FALSE, nullptr, FirstScan); - if (FirstScan) { - FirstScan = false; - } - return NT_SUCCESS(Status); - }; + auto ID = FEXCore::CodeMap::GetBaseFilename(ImageInfo.Info, false); + const uint64_t CodeCacheConfigId = 0; // TODO + const auto AnsiPath = fmt::format("\\??\\{}cache\\{}-{:016x}", FEX::Config::GetCacheDirectory(), ID, CodeCacheConfigId); - while (QueryDir()) { - auto* Info = reinterpret_cast(DirBuffer.data()); + IO_STATUS_BLOCK IOSB; + ScopedUnicodeString CurrentFileName(AnsiPath.c_str()); - while (true) { - UNICODE_STRING CurrentFileName; - CurrentFileName.Buffer = Info->FileName; - CurrentFileName.Length = static_cast(Info->FileNameLength); - CurrentFileName.MaximumLength = CurrentFileName.Length; + OBJECT_ATTRIBUTES FileAttr; + InitializeObjectAttributes(&FileAttr, &*CurrentFileName, OBJ_CASE_INSENSITIVE, nullptr, nullptr); - bool Skip = (Info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) || (Info->FileNameLength == 2 && Info->FileName[0] == '.') || - (Info->FileNameLength == 4 && Info->FileName[0] == '.' && Info->FileName[1] == '.'); + ScopedHandle FileHandle; + if (NT_SUCCESS(NtOpenFile(&*FileHandle, GENERIC_READ | SYNCHRONIZE, &FileAttr, &IOSB, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT))) { + ScopedHandle SectionHandle; + if (NT_SUCCESS(NtCreateSection(&*SectionHandle, SECTION_MAP_EXECUTE | SECTION_MAP_READ, nullptr, nullptr, PAGE_EXECUTE_READ, SEC_COMMIT, + *FileHandle))) { + void* LoadAddress = nullptr; + SIZE_T MappedSize = 0; + if (NT_SUCCESS(NtMapViewOfSection(*SectionHandle, NtCurrentProcess(), &LoadAddress, 0, 0, nullptr, &MappedSize, ViewUnmap, + MEM_RESERVE | MEM_TOP_DOWN, PAGE_EXECUTE_READ))) { - if (!Skip) { - OBJECT_ATTRIBUTES FileAttr; - InitializeObjectAttributes(&FileAttr, &CurrentFileName, OBJ_CASE_INSENSITIVE, *DirHandle, nullptr); - - ScopedHandle FileHandle; - if (NT_SUCCESS(NtOpenFile(&*FileHandle, GENERIC_READ | SYNCHRONIZE, &FileAttr, &IOSB, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT))) { - ScopedHandle SectionHandle; - if (NT_SUCCESS(NtCreateSection(&*SectionHandle, SECTION_MAP_EXECUTE | SECTION_MAP_READ, nullptr, nullptr, PAGE_EXECUTE_READ, - SEC_COMMIT, *FileHandle))) { - void* LoadAddress = nullptr; - SIZE_T MappedSize = 0; - if (NT_SUCCESS(NtMapViewOfSection(*SectionHandle, NtCurrentProcess(), &LoadAddress, 0, 0, nullptr, &MappedSize, ViewUnmap, - MEM_RESERVE | MEM_TOP_DOWN, PAGE_EXECUTE_READ))) { - fextl::string UniqueId; - ULONG AnsiLength = 0; - RtlUnicodeToMultiByteSize(&AnsiLength, Info->FileName, Info->FileNameLength); - UniqueId.resize(AnsiLength); - RtlUnicodeToMultiByteN(UniqueId.data(), AnsiLength, NULL, Info->FileName, Info->FileNameLength); - - auto CacheSpan = std::span {static_cast(LoadAddress), MappedSize}; - auto MappedCache = CTX.GetCodeCache().LoadCache(CacheSpan, ImageInfo.Info, ImageInfo.SectionInfo.FileStartVA); - if (MappedCache) { - CTX.GetCodeCache().RegisterMappedCodeBuffer(*MappedCache); - AOTImages[UniqueId] = {.CacheFile = std::move(MappedCache)}; - LogMan::Msg::IFmt("Loaded cache: {}", UniqueId); - } else { - NtUnmapViewOfSection(NtCurrentProcess(), LoadAddress); - LogMan::Msg::EFmt("Failed to load cache: {}", UniqueId); - } - } - } + auto CacheSpan = std::span {static_cast(LoadAddress), MappedSize}; + auto MappedCache = CTX.GetCodeCache().LoadCache(CacheSpan, ImageInfo.Info, ImageInfo.SectionInfo.FileStartVA); + if (MappedCache) { + CTX.GetCodeCache().RegisterMappedCodeBuffer(*MappedCache); + AOTImages[ID] = {.CacheFile = std::move(MappedCache)}; + LogMan::Msg::IFmt("Loaded cache: {}", ID); + } else { + NtUnmapViewOfSection(NtCurrentProcess(), LoadAddress); + LogMan::Msg::EFmt("Failed to load cache: {}", ID); } } - - if (Info->NextEntryOffset == 0) { - break; - } - Info = reinterpret_cast(reinterpret_cast(Info) + Info->NextEntryOffset); } } }