From 2cfba8c6d02a4b30912cee7a3e0946656be2e389 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Wed, 15 Oct 2025 22:34:52 +0200 Subject: [PATCH] LinuxSyscalls: Fix LookupExecutableFileSection implementation The file offset of a file mapping doesn't necessarily match its address offset in virtual memory from the base file mapping. Indeed, most libraries violate this assumption. Now that the MappedResource::FirstVMA reliably identifies the base memory mapping for a given library (even when that library is mapped multiple times), this can easily be fixed. --- .../LinuxSyscalls/SyscallsSMCTracking.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/SyscallsSMCTracking.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/SyscallsSMCTracking.cpp index 3cfb9f0ac..43da1c512 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/SyscallsSMCTracking.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/SyscallsSMCTracking.cpp @@ -174,15 +174,13 @@ std::optional SyscallHandler::LookupExecutableFileSection(FEXCore::Core::InternalThreadState& Thread, uint64_t GuestAddr) { auto lk = FEXCore::GuardSignalDeferringSection(VMATracking.Mutex, &Thread); - // Get the first mapping after GuestAddr, or end - // GuestAddr is inclusive - // If the write spans two pages, they will be flushed one at a time (generating two faults) - auto Entry = VMATracking.FindVMAEntry(GuestAddr); - if (Entry == VMATracking.VMAs.end() || !Entry->second.Resource) { + auto EntryIt = VMATracking.FindVMAEntry(GuestAddr); + if (EntryIt == VMATracking.VMAs.end() || !EntryIt->second.Resource) { return std::nullopt; } - return FEXCore::ExecutableFileSectionInfo {*Entry->second.Resource->MappedFile, Entry->second.Base - Entry->second.Offset}; + auto& [MappingBaseAddr, Entry] = *EntryIt; + return FEXCore::ExecutableFileSectionInfo {*Entry.Resource->MappedFile, Entry.Resource->FirstVMA->Base}; } FEXCore::HLE::ExecutableRangeInfo SyscallHandler::QueryGuestExecutableRange(FEXCore::Core::InternalThreadState* Thread, uint64_t Address) {