These 32bit syscalls use a compat statfs which is only 64bytes in size.
This was overwriting data on the guest stack and causing crashes.
Describe a 32-bit statfs struct and ensure with struct verifier that it matches.
Fixes a crash in KOTOR2 that would happen just before the main menu.
The syscall is defined as taking in an array, so we can construct the
std::vector in place and surround it.
This also fixes an edge case where an out of bounds access on the
Host_iovec vectors could occur if these syscalls were called with an
iovcnt of zero (.at would cause an exception to be thrown).
Looking into the syscalls for readv and writev, these just return early
if a size of zero is passed in.
FD flag remapping was broken. It would remap one flag on to another and then the next check would remap it back.
Instead keep a mask of the flags to be remapped then remap them all at the end.
Also goes through the ops and fixes a few cases where it was remapping wrong flags.
For DRM applications have a three FD deep MRU cached for faster lookups of FD to DRM handlers.
In a completely DRM ioctl bound situation like es2gears or GL application without threaded context
Then this puts us /nearly/ at the performance of calling the ioctl32 handler directly.
Sadly there is overhead that can't be overcome so this is the best that can be done from userland
C++ no-op functions can't optimize out the predicate arguments in all cases.
This was causing a problem where zero cost assertions weren't actually zero cost.
The only way to resolve this is to actually use macros sadly enough.
This will give a fairly hefty performance uplift with anything operating on IR.
The vast majoirty of syscalls don't need anything in thread or frame.
So lets save an indirection for all those syscalls.
Most of the syscalls which do need Thread (or CTX via
Thread are in Thread.cpp or Memory.cpp
These have all been modifiy to fetch Thread from Frame
Sadly these things can't be split without breaking functionality so it
turns in to a bit of a mess.
SyscallHandler is very much something that is a Linux only construct and
shouldn't be in FEXCore itself. Lets the frontend register a
Syscallhandler with FEXCore. FEXCore itself is then aware of the current
syscall ABI and handles the ABI in an optimal fashion.
So it is not a 100% clean break otherwise we would lose performance.
The SignalDelegator then needs to move to the frontend since the
SyscallHandler requires it for signal based syscalls.
The CPU backend signal handling still needs to happen in FEXCore because
it is a very tight coupling with the CPU backend.
Once we need to support more Signal handling we can give the backends
cleaner support to select which specific OS handler to handle.