mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-08 00:00:16 +02:00
134 lines
5.8 KiB
C++
134 lines
5.8 KiB
C++
// SPDX-License-Identifier: MIT
|
|
/*
|
|
$info$
|
|
tags: LinuxSyscalls|syscalls-x86-64
|
|
$end_info$
|
|
*/
|
|
|
|
#include "LinuxSyscalls/LinuxAllocator.h"
|
|
#include "LinuxSyscalls/Syscalls.h"
|
|
#include "LinuxSyscalls/x64/Syscalls.h"
|
|
#include <FEXCore/Core/Context.h>
|
|
#include <FEXCore/Debug/InternalThreadState.h>
|
|
|
|
#include <FEXCore/IR/IR.h>
|
|
|
|
#include <sys/mman.h>
|
|
#include <sys/shm.h>
|
|
#include <unistd.h>
|
|
|
|
#include <FEXCore/Core/Context.h>
|
|
#include <FEXCore/Config/Config.h>
|
|
#include <FEXCore/Utils/Allocator.h>
|
|
#include <FEXCore/Utils/MathUtils.h>
|
|
|
|
namespace FEX::HLE::x64 {
|
|
|
|
void RegisterMemory(FEX::HLE::SyscallHandler* Handler) {
|
|
using namespace FEXCore::IR;
|
|
|
|
REGISTER_SYSCALL_IMPL_X64_FLAGS(
|
|
mmap, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
|
|
[](FEXCore::Core::CpuStateFrame* Frame, void* addr, size_t length, int prot, int flags, int fd, off_t offset) -> uint64_t {
|
|
return (uint64_t)FEX::HLE::_SyscallHandler->GuestMmap(Frame->Thread, addr, length, prot, flags, fd, offset);
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL_X64_FLAGS(munmap, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
|
|
[](FEXCore::Core::CpuStateFrame* Frame, void* addr, size_t length) -> uint64_t {
|
|
return FEX::HLE::_SyscallHandler->GuestMunmap(Frame->Thread, addr, length);
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL_X64_FLAGS(
|
|
mremap, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
|
|
[](FEXCore::Core::CpuStateFrame* Frame, void* old_address, size_t old_size, size_t new_size, int flags, void* new_address) -> uint64_t {
|
|
auto Thread = Frame->Thread;
|
|
uint64_t Result {};
|
|
|
|
{
|
|
auto lk = FEXCore::GuardSignalDeferringSection(FEX::HLE::_SyscallHandler->VMATracking.Mutex, Thread);
|
|
Result = reinterpret_cast<uint64_t>(::mremap(old_address, old_size, new_size, flags, new_address));
|
|
|
|
if (Result == -1) {
|
|
SYSCALL_ERRNO();
|
|
}
|
|
FEX::HLE::_SyscallHandler->TrackMremap(Thread, reinterpret_cast<uint64_t>(old_address), old_size, new_size, flags, Result);
|
|
}
|
|
|
|
FEX::HLE::_SyscallHandler->InvalidateCodeRangeIfNecessaryOnRemap(Thread, reinterpret_cast<uint64_t>(old_address), Result, old_size, new_size);
|
|
|
|
return Result;
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL_X64_FLAGS(mprotect, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
|
|
[](FEXCore::Core::CpuStateFrame* Frame, void* addr, size_t len, int prot) -> uint64_t {
|
|
auto Thread = Frame->Thread;
|
|
uint64_t Result {};
|
|
|
|
{
|
|
auto lk = FEXCore::GuardSignalDeferringSection(FEX::HLE::_SyscallHandler->VMATracking.Mutex, Thread);
|
|
Result = ::mprotect(addr, len, prot);
|
|
if (Result == -1) {
|
|
SYSCALL_ERRNO();
|
|
}
|
|
|
|
FEX::HLE::_SyscallHandler->TrackMprotect(Thread, addr, len, prot);
|
|
}
|
|
|
|
|
|
FEX::HLE::_SyscallHandler->InvalidateCodeRangeIfNecessary(Thread, reinterpret_cast<uint64_t>(addr), len);
|
|
|
|
SYSCALL_ERRNO();
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL_X64_FLAGS(shmat, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
|
|
([](FEXCore::Core::CpuStateFrame* Frame, int shmid, const void* shmaddr, int shmflg) -> uint64_t {
|
|
auto Thread = Frame->Thread;
|
|
auto CTX = Thread->CTX;
|
|
uint64_t Result {};
|
|
uint64_t Length {};
|
|
CTX->MarkMemoryShared(Thread);
|
|
|
|
{
|
|
auto lk = FEXCore::GuardSignalDeferringSection(FEX::HLE::_SyscallHandler->VMATracking.Mutex, Thread);
|
|
Result = reinterpret_cast<uint64_t>(::shmat(shmid, shmaddr, shmflg));
|
|
|
|
if (Result == -1) {
|
|
SYSCALL_ERRNO();
|
|
}
|
|
|
|
shmid_ds stat;
|
|
|
|
[[maybe_unused]] auto res = shmctl(shmid, IPC_STAT, &stat);
|
|
LOGMAN_THROW_A_FMT(res != -1, "shmctl IPC_STAT failed");
|
|
|
|
Length = stat.shm_segsz;
|
|
FEX::HLE::_SyscallHandler->TrackShmat(Thread, shmid, Result, shmflg, Length);
|
|
}
|
|
|
|
FEX::HLE::_SyscallHandler->InvalidateCodeRangeIfNecessary(Thread, Result, Length);
|
|
SYSCALL_ERRNO();
|
|
}));
|
|
|
|
REGISTER_SYSCALL_IMPL_X64_FLAGS(
|
|
shmdt, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, [](FEXCore::Core::CpuStateFrame* Frame, const void* shmaddr) -> uint64_t {
|
|
auto Thread = Frame->Thread;
|
|
uint64_t Result {};
|
|
uint64_t Length {};
|
|
{
|
|
auto lk = FEXCore::GuardSignalDeferringSection(FEX::HLE::_SyscallHandler->VMATracking.Mutex, Thread);
|
|
Result = ::shmdt(shmaddr);
|
|
|
|
if (Result == -1) {
|
|
SYSCALL_ERRNO();
|
|
return Result;
|
|
}
|
|
|
|
Length = FEX::HLE::_SyscallHandler->TrackShmdt(Thread, reinterpret_cast<uintptr_t>(shmaddr));
|
|
}
|
|
|
|
FEX::HLE::_SyscallHandler->InvalidateCodeRangeIfNecessary(Thread, reinterpret_cast<uintptr_t>(shmaddr), Length);
|
|
SYSCALL_ERRNO();
|
|
});
|
|
}
|
|
} // namespace FEX::HLE::x64
|