mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 19:00:17 +02:00
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.
73 lines
2.3 KiB
C++
73 lines
2.3 KiB
C++
#include "Tests/LinuxSyscalls/Syscalls.h"
|
|
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
|
|
|
|
#include <sys/resource.h>
|
|
#include <sys/utsname.h>
|
|
#include <sys/sysinfo.h>
|
|
|
|
namespace FEX::HLE::x32 {
|
|
struct rlimit32 {
|
|
uint32_t rlim_cur;
|
|
uint32_t rlim_max;
|
|
};
|
|
|
|
struct sysinfo32 {
|
|
int32_t uptime;
|
|
uint32_t loads[3];
|
|
uint32_t totalram;
|
|
uint32_t freeram;
|
|
uint32_t sharedram;
|
|
uint32_t bufferram;
|
|
uint32_t totalswap;
|
|
uint32_t freeswap;
|
|
uint16_t procs;
|
|
uint32_t totalhigh;
|
|
uint32_t mem_unit;
|
|
char _pad[12];
|
|
};
|
|
|
|
static_assert(sizeof(sysinfo32) == 64, "Needs to be 64bytes");
|
|
|
|
void RegisterInfo() {
|
|
REGISTER_SYSCALL_IMPL_X32(uname, [](FEXCore::Core::InternalThreadState *Thread, struct utsname *buf) -> uint64_t {
|
|
strcpy(buf->sysname, "Linux");
|
|
strcpy(buf->nodename, "FEXCore");
|
|
strcpy(buf->release, "5.0.0");
|
|
strcpy(buf->version, "#" FEXCORE_VERSION);
|
|
// Tell the guest that we are a 64bit kernel
|
|
strcpy(buf->machine, "x86_64");
|
|
return 0;
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL_X32(ugetrlimit, [](FEXCore::Core::InternalThreadState *Thread, int resource, rlimit32 *rlim) -> uint64_t {
|
|
struct rlimit rlim64{};
|
|
uint64_t Result = ::getrlimit(resource, &rlim64);
|
|
rlim->rlim_cur = rlim64.rlim_cur;
|
|
rlim->rlim_max = rlim64.rlim_max;
|
|
SYSCALL_ERRNO();
|
|
});
|
|
|
|
REGISTER_SYSCALL_IMPL_X32(sysinfo, [](FEXCore::Core::InternalThreadState *Thread, struct sysinfo32 *info) -> uint64_t {
|
|
struct sysinfo Host{};
|
|
uint64_t Result = ::sysinfo(&Host);
|
|
if (Result != -1) {
|
|
#define Copy(x) info->x = static_cast<decltype(info->x)>(std::min(Host.x, static_cast<decltype(Host.x)>(std::numeric_limits<decltype(info->x)>::max())));
|
|
Copy(uptime);
|
|
info->loads[0] = std::min(Host.loads[0], static_cast<unsigned long>(std::numeric_limits<uint32_t>::max()));
|
|
info->loads[1] = std::min(Host.loads[1], static_cast<unsigned long>(std::numeric_limits<uint32_t>::max()));
|
|
info->loads[2] = std::min(Host.loads[2], static_cast<unsigned long>(std::numeric_limits<uint32_t>::max()));
|
|
Copy(totalram);
|
|
Copy(sharedram);
|
|
Copy(bufferram);
|
|
Copy(totalswap);
|
|
Copy(freeswap);
|
|
Copy(procs);
|
|
Copy(totalhigh);
|
|
Copy(mem_unit);
|
|
}
|
|
SYSCALL_ERRNO();
|
|
});
|
|
|
|
}
|
|
}
|