mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-07 01:00:17 +02:00
The JIT was doing a bunch of additional work where it was saving and restoring registers and then juggling the arguments back in to a stack frame. All of this is nonsensical without the optimization where we could call syscalls inline without a stack frame. Instead remove this optimization entirely and behave like a "generic" syscall path always. The Linux syscall handler now pulls the arguments out of the CPU context directly and stores the result back in to RAX directly as well. This has knock-on effects where technically syscalls are going to be slightly faster because no stack frame setup for the arguments, but additionally we are going to be able to have syscalls be proper serialization points where we can interrupt the syscall and long-jump out without problems. Bumps the DiskCache version again because it causes codegen to change.
82 lines
2.6 KiB
C++
82 lines
2.6 KiB
C++
// SPDX-License-Identifier: MIT
|
|
/*
|
|
$info$
|
|
tags: LinuxSyscalls|syscalls-x86-32
|
|
$end_info$
|
|
*/
|
|
|
|
#include "LinuxSyscalls/Syscalls.h"
|
|
#include "LinuxSyscalls/x32/IoctlEmulation.h"
|
|
#include "LinuxSyscalls/x32/Syscalls.h"
|
|
#include "LinuxSyscalls/x32/SyscallsEnum.h"
|
|
|
|
#include <FEXCore/HLE/SyscallHandler.h>
|
|
#include <FEXCore/Utils/LogManager.h>
|
|
#include <FEXCore/fextl/memory.h>
|
|
|
|
#include <bitset>
|
|
#include <cerrno>
|
|
#include <cstdint>
|
|
#include <limits>
|
|
#include <mutex>
|
|
#include <sys/mman.h>
|
|
#include <sys/shm.h>
|
|
#include <utility>
|
|
|
|
namespace FEX::HLE::x32 {
|
|
|
|
x32SyscallHandler::x32SyscallHandler(FEXCore::Context::Context* ctx, FEX::HLE::SignalDelegator* _SignalDelegation,
|
|
FEX::HLE::ThunkHandler* ThunkHandler, fextl::unique_ptr<MemAllocator> Allocator)
|
|
: SyscallHandler {ctx, _SignalDelegation, ThunkHandler}
|
|
, AllocHandler {std::move(Allocator)} {
|
|
RegisterSyscallHandlers();
|
|
}
|
|
|
|
void x32SyscallHandler::RegisterSyscallHandlers() {
|
|
FEX::HLE::RegisterEpoll(this);
|
|
FEX::HLE::RegisterFD(this);
|
|
FEX::HLE::RegisterFS(this);
|
|
FEX::HLE::RegisterInfo(this);
|
|
FEX::HLE::RegisterIO(this);
|
|
FEX::HLE::RegisterMemory(this);
|
|
FEX::HLE::RegisterSignals(this);
|
|
FEX::HLE::RegisterThread(this);
|
|
FEX::HLE::RegisterTimer(this);
|
|
FEX::HLE::RegisterNotImplemented(this);
|
|
FEX::HLE::RegisterStubs(this);
|
|
|
|
// 32bit specific
|
|
FEX::HLE::x32::RegisterEpoll(this);
|
|
FEX::HLE::x32::RegisterFD(this);
|
|
FEX::HLE::x32::RegisterFS(this);
|
|
FEX::HLE::x32::RegisterInfo(this);
|
|
FEX::HLE::x32::RegisterIO(this);
|
|
FEX::HLE::x32::RegisterMemory(this);
|
|
FEX::HLE::x32::RegisterMsg(this);
|
|
FEX::HLE::x32::RegisterNotImplemented(this);
|
|
FEX::HLE::x32::RegisterSched(this);
|
|
FEX::HLE::x32::RegisterSemaphore(this);
|
|
FEX::HLE::x32::RegisterSignals(this);
|
|
FEX::HLE::x32::RegisterSocket(this);
|
|
FEX::HLE::x32::RegisterStubs(this);
|
|
FEX::HLE::x32::RegisterThread(this);
|
|
FEX::HLE::x32::RegisterTime(this);
|
|
FEX::HLE::x32::RegisterTimer(this);
|
|
FEX::HLE::x32::RegisterPassthrough(this);
|
|
|
|
#if PRINT_MISSING_SYSCALLS
|
|
for (auto& Syscall : SyscallNames) {
|
|
if (Definitions[Syscall.first].Ptr == reinterpret_cast<void*>(&UnimplementedSyscall)) {
|
|
LogMan::Msg::DFmt("Unimplemented syscall: {}: {}", Syscall.first, Syscall.second);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
fextl::unique_ptr<FEX::HLE::SyscallHandler> CreateHandler(FEXCore::Context::Context* ctx, FEX::HLE::SignalDelegator* _SignalDelegation,
|
|
FEX::HLE::ThunkHandler* ThunkHandler, fextl::unique_ptr<MemAllocator> Allocator) {
|
|
return fextl::make_unique<x32SyscallHandler>(ctx, _SignalDelegation, ThunkHandler, std::move(Allocator));
|
|
}
|
|
|
|
} // namespace FEX::HLE::x32
|