mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-14 07:00:43 +02:00
LinuxSyscalls: Unify shmat implementations
This commit is contained in:
1 parent
365ed2cd70
commit
ca12dc9213
5 files changed
+41
-80
No files matched your search
@@ -248,6 +248,7 @@ public:
|
||||
uint64_t GuestMunmap(bool Is64Bit, FEXCore::Core::InternalThreadState* Thread, void* addr, uint64_t length);
|
||||
|
||||
uint64_t GuestMprotect(FEXCore::Core::InternalThreadState*, void* addr, size_t len, int prot);
|
||||
uint64_t GuestShmat(bool Is64Bit, FEXCore::Core::InternalThreadState*, int shmid, const void* shmaddr, int shmflg);
|
||||
|
||||
///// Memory Manager tracking /////
|
||||
void TrackMmap(FEXCore::Core::InternalThreadState* Thread, uint64_t addr, size_t length, int prot, int flags, int fd, off_t offset);
|
||||
|
||||
@@ -239,6 +239,41 @@ uint64_t SyscallHandler::GuestMprotect(FEXCore::Core::InternalThreadState* Threa
|
||||
return Result;
|
||||
}
|
||||
|
||||
uint64_t SyscallHandler::GuestShmat(bool Is64Bit, FEXCore::Core::InternalThreadState* Thread, int shmid, const void* shmaddr, int shmflg) {
|
||||
auto CTX = Thread->CTX;
|
||||
uint64_t Result {};
|
||||
uint64_t Length {};
|
||||
CTX->MarkMemoryShared(Thread);
|
||||
|
||||
{
|
||||
auto lk = FEXCore::GuardSignalDeferringSection(FEX::HLE::_SyscallHandler->VMATracking.Mutex, Thread);
|
||||
if (Is64Bit) {
|
||||
Result = reinterpret_cast<uint64_t>(::shmat(shmid, shmaddr, shmflg));
|
||||
if (Result == -1) {
|
||||
return Result;
|
||||
}
|
||||
} else {
|
||||
uint32_t Addr;
|
||||
Result = FEX::HLE::_SyscallHandler->Get32BitAllocator()->Shmat(shmid, shmaddr, shmflg, &Addr);
|
||||
if (FEX::HLE::HasSyscallError(Result)) {
|
||||
return Result;
|
||||
}
|
||||
Result = Addr;
|
||||
}
|
||||
|
||||
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);
|
||||
return Result;
|
||||
}
|
||||
|
||||
// MMan Tracking
|
||||
void SyscallHandler::TrackMmap(FEXCore::Core::InternalThreadState* Thread, uint64_t addr, size_t length, int prot, int flags, int fd, off_t offset) {
|
||||
size_t Size = FEXCore::AlignUp(length, FEXCore::Utils::FEX_PAGE_SIZE);
|
||||
|
||||
@@ -82,34 +82,7 @@ void RegisterMemory(FEX::HLE::SyscallHandler* Handler) {
|
||||
});
|
||||
|
||||
REGISTER_SYSCALL_IMPL_X32(shmat, [](FEXCore::Core::CpuStateFrame* Frame, int shmid, const void* shmaddr, int shmflg) -> uint64_t {
|
||||
// also implemented in ipc:OP_SHMAT
|
||||
auto Thread = Frame->Thread;
|
||||
auto CTX = Thread->CTX;
|
||||
uint64_t Result {};
|
||||
uint32_t ResultAddr {};
|
||||
uint64_t Length {};
|
||||
CTX->MarkMemoryShared(Thread);
|
||||
|
||||
{
|
||||
auto lk = FEXCore::GuardSignalDeferringSection(FEX::HLE::_SyscallHandler->VMATracking.Mutex, Thread);
|
||||
|
||||
Result = FEX::HLE::_SyscallHandler->Get32BitAllocator()->Shmat(shmid, reinterpret_cast<const void*>(shmaddr), shmflg, &ResultAddr);
|
||||
|
||||
if (FEX::HLE::HasSyscallError(Result)) {
|
||||
return Result;
|
||||
}
|
||||
|
||||
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, ResultAddr, shmflg, Length);
|
||||
}
|
||||
|
||||
FEX::HLE::_SyscallHandler->InvalidateCodeRangeIfNecessary(Thread, ResultAddr, Length);
|
||||
return ResultAddr;
|
||||
return FEX::HLE::_SyscallHandler->GuestShmat(false, Frame->Thread, shmid, shmaddr, shmflg);
|
||||
});
|
||||
|
||||
REGISTER_SYSCALL_IMPL_X32(shmdt, [](FEXCore::Core::CpuStateFrame* Frame, const void* shmaddr) -> uint64_t {
|
||||
|
||||
@@ -293,35 +293,10 @@ uint64_t _ipc(FEXCore::Core::CpuStateFrame* Frame, uint32_t call, uint32_t first
|
||||
// shmat explicitly doesn't support version 1.
|
||||
return -EINVAL;
|
||||
}
|
||||
// also implemented in memory:shmat
|
||||
auto Thread = Frame->Thread;
|
||||
auto CTX = Thread->CTX;
|
||||
uint64_t Result {};
|
||||
uint32_t ResultAddr {};
|
||||
uint64_t Length {};
|
||||
CTX->MarkMemoryShared(Thread);
|
||||
|
||||
{
|
||||
auto lk = FEXCore::GuardSignalDeferringSection(FEX::HLE::_SyscallHandler->VMATracking.Mutex, Thread);
|
||||
|
||||
Result = FEX::HLE::_SyscallHandler->Get32BitAllocator()->Shmat(first, reinterpret_cast<const void*>(ptr), second, &ResultAddr);
|
||||
|
||||
if (FEX::HLE::HasSyscallError(Result)) {
|
||||
return Result;
|
||||
}
|
||||
|
||||
shmid_ds stat;
|
||||
|
||||
[[maybe_unused]] auto res = shmctl(first, IPC_STAT, &stat);
|
||||
LOGMAN_THROW_A_FMT(res != -1, "shmctl IPC_STAT failed");
|
||||
|
||||
Length = stat.shm_segsz;
|
||||
FEX::HLE::_SyscallHandler->TrackShmat(Thread, first, ResultAddr, second, Length);
|
||||
auto Result = FEX::HLE::_SyscallHandler->GuestShmat(false, Frame->Thread, first, reinterpret_cast<const void*>(ptr), second);
|
||||
if (!FEX::HLE::HasSyscallError(Result)) {
|
||||
*reinterpret_cast<uint32_t*>(third) = Result;
|
||||
}
|
||||
|
||||
FEX::HLE::_SyscallHandler->InvalidateCodeRangeIfNecessary(Thread, ResultAddr, Length);
|
||||
|
||||
*reinterpret_cast<uint32_t*>(third) = ResultAddr;
|
||||
return Result;
|
||||
}
|
||||
case OP_SHMDT: {
|
||||
|
||||
@@ -67,30 +67,7 @@ void RegisterMemory(FEX::HLE::SyscallHandler* Handler) {
|
||||
|
||||
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);
|
||||
auto Result = FEX::HLE::_SyscallHandler->GuestShmat(true, Frame->Thread, shmid, shmaddr, shmflg);
|
||||
SYSCALL_ERRNO();
|
||||
}));
|
||||
|
||||
|
||||
Reference in new issue
Block a user