mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-15 02:00:41 +02:00
ARM64EC: Use ImageTracker for volatile metadata handling
This commit is contained in:
1 parent
64ad853a5c
commit
47a8fc4b49
1 file changed
+15
-75
@@ -31,6 +31,7 @@ $end_info$
|
||||
#include "Common/JITGuardPage.h"
|
||||
#include "Common/Config.h"
|
||||
#include "Common/Exception.h"
|
||||
#include "Common/ImageTracker.h"
|
||||
#include "Common/InvalidationTracker.h"
|
||||
#include "Common/OvercommitTracker.h"
|
||||
#include "Common/TSOHandlerConfig.h"
|
||||
@@ -40,7 +41,6 @@ $end_info$
|
||||
#include "Common/CRT/CRT.h"
|
||||
#include "Common/PortabilityInfo.h"
|
||||
#include "Common/Handle.h"
|
||||
#include "Common/VolatileMetadata.h"
|
||||
#include "DummyHandlers.h"
|
||||
#include "BTInterface.h"
|
||||
#include "Windows/Common/SHMStats.h"
|
||||
@@ -81,7 +81,6 @@ void* WineSyscallDispatcher;
|
||||
uint64_t WineNtContinueSyscallId;
|
||||
uint64_t WineNtAllocateVirtualMemorySyscallId;
|
||||
uint64_t WineNtProtectVirtualMemorySyscallId;
|
||||
static fextl::unordered_map<fextl::string, FEX::VolatileMetadata::ExtendedVolatileMetadata> ExtendedMetaData {};
|
||||
|
||||
NTSTATUS NtContinueNative(ARM64_NT_CONTEXT* NativeContext, BOOLEAN Alert);
|
||||
NTSTATUS NtAllocateVirtualMemoryNative(HANDLE, PVOID*, ULONG_PTR, SIZE_T*, ULONG, ULONG);
|
||||
@@ -135,6 +134,7 @@ fextl::unique_ptr<FEX::Windows::StatAlloc> StatAllocHandler;
|
||||
std::optional<FEX::Windows::InvalidationTracker> InvalidationTracker;
|
||||
std::optional<FEX::Windows::CPUFeatures> CPUFeatures;
|
||||
std::optional<FEX::Windows::OvercommitTracker> OvercommitTracker;
|
||||
std::optional<FEX::Windows::ImageTracker> ImageTracker;
|
||||
|
||||
std::recursive_mutex ThreadCreationMutex;
|
||||
// Map of TIDs to their FEX thread state, `ThreadCreationMutex` must be locked when accessing
|
||||
@@ -269,72 +269,15 @@ void InitSyscalls() {
|
||||
PatchCallChecker();
|
||||
}
|
||||
|
||||
void LoadImageVolatileMetadata(fextl::set<uint64_t>& VolatileInstructions, FEXCore::IntervalList<uint64_t>& VolatileValidRanges,
|
||||
HMODULE Module, IMAGE_NT_HEADERS* Nt, uint64_t Address, uint64_t EndAddress) {
|
||||
ULONG Size;
|
||||
|
||||
const auto* LoadConfig =
|
||||
reinterpret_cast<_IMAGE_LOAD_CONFIG_DIRECTORY64*>(RtlImageDirectoryEntryToData(Module, true, IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG, &Size));
|
||||
if (!LoadConfig || LoadConfig->Size <= offsetof(_IMAGE_LOAD_CONFIG_DIRECTORY64, VolatileMetadataPointer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (LoadConfig->VolatileMetadataPointer < Address || LoadConfig->VolatileMetadataPointer + sizeof(IMAGE_VOLATILE_METADATA) >= EndAddress) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto* VolatileMetadata = reinterpret_cast<IMAGE_VOLATILE_METADATA*>(LoadConfig->VolatileMetadataPointer);
|
||||
if (!VolatileMetadata || Address + VolatileMetadata->VolatileAccessTable + VolatileMetadata->VolatileAccessTableSize >= EndAddress ||
|
||||
Address + VolatileMetadata->VolatileInfoRangeTable + VolatileMetadata->VolatileInfoRangeTableSize >= EndAddress) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto* VolatileAccessTableBegin = reinterpret_cast<IMAGE_VOLATILE_RVA_METADATA*>(Address + VolatileMetadata->VolatileAccessTable);
|
||||
const auto* VolatileAccessTableEnd =
|
||||
VolatileAccessTableBegin + (VolatileMetadata->VolatileAccessTableSize / sizeof(IMAGE_VOLATILE_RVA_METADATA));
|
||||
for (auto It = VolatileAccessTableBegin; It != VolatileAccessTableEnd; It++) {
|
||||
VolatileInstructions.emplace(Address + It->Rva);
|
||||
}
|
||||
|
||||
const auto* VolatileInfoRangeTableBegin = reinterpret_cast<IMAGE_VOLATILE_RANGE_METADATA*>(Address + VolatileMetadata->VolatileInfoRangeTable);
|
||||
const auto* VolatileInfoRangeTableEnd =
|
||||
VolatileInfoRangeTableBegin + (VolatileMetadata->VolatileInfoRangeTableSize / sizeof(IMAGE_VOLATILE_RANGE_METADATA));
|
||||
for (auto It = VolatileInfoRangeTableBegin; It != VolatileInfoRangeTableEnd; It++) {
|
||||
VolatileValidRanges.Insert({Address + It->Rva, Address + It->Rva + It->Size});
|
||||
}
|
||||
}
|
||||
|
||||
void LoadImageVolatileMetadata(const fextl::string& ModuleName, uint64_t Address) {
|
||||
const auto Module = reinterpret_cast<HMODULE>(Address);
|
||||
IMAGE_NT_HEADERS* Nt = RtlImageNtHeader(Module);
|
||||
uint64_t EndAddress = Address + Nt->OptionalHeader.SizeOfImage;
|
||||
|
||||
fextl::set<uint64_t> VolatileInstructions {};
|
||||
FEXCore::IntervalList<uint64_t> VolatileValidRanges {};
|
||||
LoadImageVolatileMetadata(VolatileInstructions, VolatileValidRanges, Module, Nt, Address, EndAddress);
|
||||
|
||||
auto it = ExtendedMetaData.find(ModuleName);
|
||||
if (it != ExtendedMetaData.end()) {
|
||||
FEX::VolatileMetadata::ApplyFEXExtendedVolatileMetadata(it->second, VolatileInstructions, VolatileValidRanges, Address, EndAddress);
|
||||
}
|
||||
|
||||
if (VolatileInstructions.empty() && VolatileValidRanges.Empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LogMan::Msg::DFmt("Loaded volatile metadata for {:X}: {} entries", Address, VolatileInstructions.size());
|
||||
std::scoped_lock Lock(CTX->GetCodeInvalidationMutex());
|
||||
CTX->AddForceTSOInformation(VolatileValidRanges, std::move(VolatileInstructions));
|
||||
}
|
||||
|
||||
void HandleImageMap(uint64_t Address) {
|
||||
fextl::string ModuleName = fextl::string {FEX::Windows::BaseName(FEX::Windows::GetSectionFilePath(Address))};
|
||||
LogMan::Msg::DFmt("Load module {}: {:X}", ModuleName, Address);
|
||||
FEX_CONFIG_OPT(VolatileMetadata, VOLATILEMETADATA);
|
||||
if (VolatileMetadata) {
|
||||
LoadImageVolatileMetadata(ModuleName, Address);
|
||||
}
|
||||
void HandleImageMap(uint64_t Address, bool MainImage = false) {
|
||||
fextl::string ModulePath = FEX::Windows::GetSectionFilePath(Address);
|
||||
fextl::string ModuleName = fextl::string {FEX::Windows::BaseName(ModulePath)};
|
||||
InvalidationTracker->HandleImageMap(ModuleName, Address);
|
||||
ImageTracker->HandleImageMap(ModulePath, Address, MainImage);
|
||||
}
|
||||
|
||||
void HandleImageUnmap(uint64_t Address, uint64_t Size) {
|
||||
ImageTracker->HandleImageUnmap(Address, Size);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
@@ -635,9 +578,6 @@ NTSTATUS ProcessInit() {
|
||||
|
||||
FEXCore::Profiler::Init("", "");
|
||||
|
||||
FEX_CONFIG_OPT(ExtendedVolatileMetadataConfig, EXTENDEDVOLATILEMETADATA);
|
||||
ExtendedMetaData = FEX::VolatileMetadata::ParseExtendedVolatileMetadata(ExtendedVolatileMetadataConfig());
|
||||
|
||||
SignalDelegator = fextl::make_unique<FEX::DummyHandlers::DummySignalDelegator>();
|
||||
SyscallHandler = fextl::make_unique<Exception::ECSyscallHandler>();
|
||||
|
||||
@@ -655,11 +595,12 @@ NTSTATUS ProcessInit() {
|
||||
CTX->InitCore();
|
||||
Exception::HandlerConfig.emplace(*CTX);
|
||||
InvalidationTracker.emplace(*CTX, Threads);
|
||||
|
||||
HandleImageMap(NtDllBase);
|
||||
ImageTracker.emplace(*CTX);
|
||||
|
||||
auto MainModule = reinterpret_cast<__TEB*>(NtCurrentTeb())->Peb->ImageBaseAddress;
|
||||
HandleImageMap(reinterpret_cast<uint64_t>(MainModule));
|
||||
HandleImageMap(reinterpret_cast<uint64_t>(MainModule), true);
|
||||
|
||||
HandleImageMap(NtDllBase);
|
||||
|
||||
CPUFeatures.emplace(*CTX);
|
||||
|
||||
@@ -900,8 +841,7 @@ void NotifyUnmapViewOfSection(void* Address, BOOL After, NTSTATUS Status) {
|
||||
ThreadCreationMutex.lock();
|
||||
auto [Start, Size] = InvalidationTracker->InvalidateContainingSection(reinterpret_cast<uint64_t>(Address), true);
|
||||
if (Size) {
|
||||
std::scoped_lock Lock(CTX->GetCodeInvalidationMutex());
|
||||
CTX->RemoveForceTSOInformation(Start, Size);
|
||||
HandleImageUnmap(Start, Size);
|
||||
}
|
||||
} else {
|
||||
ThreadCreationMutex.unlock();
|
||||
|
||||
Reference in new issue
Block a user