diff --git a/Source/Tools/FEXInterpreter/ELFCodeLoader.h b/Source/Tools/FEXInterpreter/ELFCodeLoader.h index dab09f85a..93df310e4 100644 --- a/Source/Tools/FEXInterpreter/ELFCodeLoader.h +++ b/Source/Tools/FEXInterpreter/ELFCodeLoader.h @@ -645,6 +645,11 @@ public: if (Is64BitMode()) { AuxVariables.emplace_back(auxv_t {4, 0x38}); // AT_PHENT + + // 64-bit vsyscall entry points are hardcoded to a single page at 0xffffffffff600000. + // FEX can't actually map anything there so it is a hardcoded quirk, similar to how the kernel traps these executions. + // Just track it as a mapped anonymous executable page. + Handler->AddVirtualPage(Thread, 0xFFFFFFFFFF600000ULL, FEXCore::Utils::FEX_PAGE_SIZE, PROT_READ | PROT_EXEC); } else { AuxVariables.emplace_back(auxv_t {4, 0x20}); // AT_PHENT diff --git a/Source/Tools/FEXOfflineCompiler/Main.cpp b/Source/Tools/FEXOfflineCompiler/Main.cpp index 80688afb8..3181c6bc1 100644 --- a/Source/Tools/FEXOfflineCompiler/Main.cpp +++ b/Source/Tools/FEXOfflineCompiler/Main.cpp @@ -64,6 +64,11 @@ public: uint64_t GuestMunmap(FEXCore::Core::InternalThreadState*, void* addr, uint64_t length) override { return munmap(addr, length); } + + void AddVirtualPage(FEXCore::Core::InternalThreadState* Thread, uint64_t addr, size_t length, int prot) override { + LogMan::Msg::AFmt("Can't Track mmap through here"); + FEX_UNREACHABLE; + } }; static void MsgHandler(LogMan::DebugLevels Level, const char* Message) { diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.h b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.h index 6b7a30602..a3189a6e0 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.h +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.h @@ -108,6 +108,8 @@ public: // does a guest munmap as if done via a guest syscall virtual uint64_t GuestMunmap(FEXCore::Core::InternalThreadState* Thread, void* addr, uint64_t length) = 0; + + virtual void AddVirtualPage(FEXCore::Core::InternalThreadState* Thread, uint64_t addr, size_t length, int prot) = 0; }; class SyscallHandler : public FEXCore::HLE::SyscallHandler, @@ -254,6 +256,10 @@ public: std::optional TrackMmap(FEXCore::Core::InternalThreadState* Thread, uint64_t addr, size_t length, int prot, int flags, int fd, off_t offset, std::optional& CachedSection); + + void AddVirtualPage(FEXCore::Core::InternalThreadState* Thread, uint64_t addr, size_t length, int prot) override; + using SyscallMmapInterface::AddVirtualPage; + void TrackMunmap(FEXCore::Core::InternalThreadState* Thread, void* addr, size_t length); void TrackMremap(FEXCore::Core::InternalThreadState* Thread, uint64_t OldAddress, size_t OldSize, size_t NewSize, int flags, uint64_t NewAddress); void TrackShmat(FEXCore::Core::InternalThreadState* Thread, int shmid, uint64_t shmaddr, int shmflg, uint64_t Length); diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/SyscallsSMCTracking.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/SyscallsSMCTracking.cpp index 12ad90772..cdad4b217 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/SyscallsSMCTracking.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/SyscallsSMCTracking.cpp @@ -721,6 +721,12 @@ SyscallHandler::TrackMmap(FEXCore::Core::InternalThreadState* Thread, uint64_t a return VolatileMetadata; } +void SyscallHandler::AddVirtualPage(FEXCore::Core::InternalThreadState* Thread, uint64_t addr, size_t length, int prot) { + auto lk = FEXCore::GuardSignalDeferringSectionWithFallback(VMATracking.Mutex, Thread); + VMATracking.TrackVMARange(CTX, nullptr, addr, 0, length, VMATracking::VMAFlags::fromFlags(MAP_ANONYMOUS | MAP_PRIVATE), + VMATracking::VMAProt::fromProt(prot)); +} + void SyscallHandler::TrackMunmap(FEXCore::Core::InternalThreadState* Thread, void* addr, size_t length) { uint64_t Size = FEXCore::AlignUp(length, FEXCore::Utils::FEX_PAGE_SIZE); VMATracking.DeleteVMARange(CTX, reinterpret_cast(addr), Size);