Merge pull request #1255 from Sonicadvance1/syscall_fixes

Syscall fixes
This commit is contained in:
Ryan Houdek authored and GitHub committed 2021-09-04 18:39:33 -07:00
commit befd0aa9cf
21 files changed
+455 -131

No files matched your search

+4
View File
@@ -651,6 +651,7 @@ def main():
"-I/usr/x86_64-linux-gnu/include/",
"-O2",
"--target=x86_64-linux-unknown",
"-D_M_X86_64",
]
args_aarch64 = [
@@ -658,6 +659,7 @@ def main():
"-I/usr/aarch64-linux-gnu/include/",
"-O2",
"--target=aarch64-linux-unknown",
"-D_M_ARM_64",
]
args_x86_win32 = [
@@ -686,11 +688,13 @@ def main():
args_x86_32 = FindClangArguments(args_x86_32)
args_x86_64 = FindClangArguments(args_x86_64)
args_aarch64 = FindClangArguments(args_aarch64)
args_x86_win32 = FindClangArguments(args_x86_win32)
args_x86_win64 = FindClangArguments(args_x86_win64)
Arch_x86_32 = ArchDB("x86_32")
Arch_x86_64 = ArchDB("x86_64")
Arch_aarch64 = ArchDB("aarch64")
Arch_x86_win32 = ArchDB("win32")
Arch_x86_win64 = ArchDB("win64")
@@ -45,6 +45,7 @@ add_library(LinuxEmulation STATIC
Syscalls/Key.cpp
Syscalls/Memory.cpp
Syscalls/Msg.cpp
Syscalls/Namespace.cpp
Syscalls/Sched.cpp
Syscalls/Semaphore.cpp
Syscalls/SHM.cpp
@@ -70,6 +71,7 @@ set(HEADERS_TO_VERIFY
x32/Ioctl/input.h x86_32 # This needs to match structs to 32bit structs
x32/Ioctl/sockios.h x86_32 # This needs to match structs to 32bit structs
x32/Ioctl/joystick.h x86_32 # This needs to match structs to 32bit structs
x64/Types.h x86_64 # This needs to match structs to 64bit structs
)
list(LENGTH HEADERS_TO_VERIFY ARG_COUNT)
+1 -22
View File
@@ -17,7 +17,6 @@ $end_info$
#include <errno.h>
#include <stdint.h>
#include <sys/epoll.h>
#include <type_traits>
#include <vector>
@@ -45,6 +44,7 @@ class SignalDelegator;
void RegisterKey();
void RegisterMemory();
void RegisterMsg();
void RegisterNamespace(FEX::HLE::SyscallHandler *const Handler);
void RegisterNuma();
void RegisterSched();
void RegisterSemaphore();
@@ -250,27 +250,6 @@ struct FunctionToLambda<R(*)(Args...) noexcept> {
}
};
struct FEX_PACKED epoll_event_x86 {
uint32_t events;
epoll_data_t data;
epoll_event_x86() = delete;
operator struct epoll_event() const {
epoll_event event{};
event.events = events;
event.data = data;
return event;
}
epoll_event_x86(struct epoll_event event) {
events = event.events;
data = event.data;
}
};
static_assert(std::is_trivial<epoll_event_x86>::value, "Needs to be trivial");
static_assert(sizeof(epoll_event_x86) == 12, "Incorrect size");
struct open_how {
uint64_t flags;
uint64_t mode;
@@ -235,17 +235,6 @@ namespace FEX::HLE {
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(timerfd_settime, [](FEXCore::Core::CpuStateFrame *Frame, int fd, int flags, const struct itimerspec *new_value, struct itimerspec *old_value) -> uint64_t {
// Flags don't need remapped
uint64_t Result = ::timerfd_settime(fd, flags, new_value, old_value);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(timerfd_gettime, [](FEXCore::Core::CpuStateFrame *Frame, int fd, struct itimerspec *curr_value) -> uint64_t {
uint64_t Result = ::timerfd_gettime(fd, curr_value);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(eventfd, [](FEXCore::Core::CpuStateFrame *Frame, uint32_t count) -> uint64_t {
uint64_t Result = ::syscall(SYS_eventfd2, count, 0);
SYSCALL_ERRNO();
+3 -2
View File
@@ -5,6 +5,7 @@ $end_info$
*/
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/Types.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
@@ -14,12 +15,12 @@ $end_info$
namespace FEX::HLE {
void RegisterKey() {
REGISTER_SYSCALL_IMPL(add_key, [](FEXCore::Core::CpuStateFrame *Frame, const char *type, const char *description, const void *payload, size_t plen, int32_t /*key_serial_t*/ keyring) -> uint64_t {
REGISTER_SYSCALL_IMPL(add_key, [](FEXCore::Core::CpuStateFrame *Frame, const char *type, const char *description, const void *payload, size_t plen, key_serial_t keyring) -> uint64_t {
uint64_t Result = syscall(SYS_add_key, type, description, payload, plen, keyring);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(request_key, [](FEXCore::Core::CpuStateFrame *Frame, const char *type, const char *description, const char *callout_info, int32_t /*key_serial_t*/ dest_keyring) -> uint64_t {
REGISTER_SYSCALL_IMPL(request_key, [](FEXCore::Core::CpuStateFrame *Frame, const char *type, const char *description, const char *callout_info, key_serial_t dest_keyring) -> uint64_t {
uint64_t Result = syscall(SYS_request_key, type, description, callout_info, dest_keyring);
SYSCALL_ERRNO();
});
@@ -0,0 +1,71 @@
/*
$info$
tags: LinuxSyscalls|syscalls-shared
$end_info$
*/
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls/Thread.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <signal.h>
#include <sys/syscall.h>
#include <unistd.h>
namespace SignalDelegator {
struct GuestSigAction;
}
namespace FEX::HLE {
void RegisterNamespace(FEX::HLE::SyscallHandler *const Handler) {
if (Handler->GetHostKernelVersion() >= FEX::HLE::SyscallHandler::KernelVersion(5, 1, 0)) {
REGISTER_SYSCALL_IMPL(open_tree, [](FEXCore::Core::CpuStateFrame *Frame, int dfd, const char *filename, unsigned int flags) -> uint64_t {
uint64_t Result = ::syscall(SYS_open_tree, dfd, filename, flags);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(move_mount, [](FEXCore::Core::CpuStateFrame *Frame, int from_dfd, const char *from_pathname, int to_dfd, const char *to_pathname, unsigned int flags) -> uint64_t {
uint64_t Result = ::syscall(SYS_move_mount, from_dfd, from_pathname, to_dfd, to_pathname, flags);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(fsopen, [](FEXCore::Core::CpuStateFrame *Frame, int dfd, const char *path, unsigned int flags) -> uint64_t {
uint64_t Result = ::syscall(SYS_fsopen, dfd, path, flags);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(fsconfig, [](FEXCore::Core::CpuStateFrame *Frame, int fd, unsigned int cmd, const char *key, const void *value, int aux) -> uint64_t {
uint64_t Result = ::syscall(SYS_fsconfig, fd, cmd, key, value, aux);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(fspick, [](FEXCore::Core::CpuStateFrame *Frame, int dfd, const char *path, unsigned int flags) -> uint64_t {
uint64_t Result = ::syscall(SYS_fspick, dfd, path, flags);
SYSCALL_ERRNO();
});
}
else {
REGISTER_SYSCALL_IMPL(open_tree, UnimplementedSyscallSafe);
REGISTER_SYSCALL_IMPL(move_mount, UnimplementedSyscallSafe);
REGISTER_SYSCALL_IMPL(fsopen, UnimplementedSyscallSafe);
REGISTER_SYSCALL_IMPL(fsconfig, UnimplementedSyscallSafe);
REGISTER_SYSCALL_IMPL(fsmount, UnimplementedSyscallSafe);
REGISTER_SYSCALL_IMPL(fspick, UnimplementedSyscallSafe);
}
#ifndef SYS_mount_setattr
#define SYS_mount_setattr 442
#endif
if (Handler->GetHostKernelVersion() >= FEX::HLE::SyscallHandler::KernelVersion(5, 12, 0)) {
REGISTER_SYSCALL_IMPL(mount_setattr, [](FEXCore::Core::CpuStateFrame *Frame, int dfd, const char *path, unsigned int flags, void *uattr, size_t usize) -> uint64_t {
uint64_t Result = ::syscall(SYS_mount_setattr, dfd, path, flags, uattr, usize);
SYSCALL_ERRNO();
});
}
else {
REGISTER_SYSCALL_IMPL(mount_setattr, UnimplementedSyscallSafe);
}
}
}
@@ -56,12 +56,14 @@ namespace FEX::HLE {
SYSCALL_ERRNO();
});
// XXX: siginfo_t definitely isn't correct for 32-bit
REGISTER_SYSCALL_IMPL(rt_tgsigqueueinfo, [](FEXCore::Core::CpuStateFrame *Frame, pid_t tgid, pid_t tid, int sig, siginfo_t *info) -> uint64_t {
uint64_t Result = ::syscall(SYS_rt_tgsigqueueinfo, tgid, tid, sig, info);
SYSCALL_ERRNO();
});
if (Handler->IsHostKernelVersionAtLeast(5, 1, 0)) {
// XXX: siginfo_t definitely isn't correct for 32-bit
REGISTER_SYSCALL_IMPL(pidfd_send_signal, [](FEXCore::Core::CpuStateFrame *Frame, int pidfd, int sig, siginfo_t *info, unsigned int flags) -> uint64_t {
uint64_t Result = ::syscall(SYS_pidfd_send_signal, pidfd, sig, info, flags);
SYSCALL_ERRNO();
@@ -24,21 +24,6 @@ namespace FEX::HLE {
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(time, [](FEXCore::Core::CpuStateFrame *Frame, time_t *tloc) -> uint64_t {
uint64_t Result = ::time(tloc);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(times, [](FEXCore::Core::CpuStateFrame *Frame, struct tms *buf) -> uint64_t {
uint64_t Result = ::times(buf);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(utime, [](FEXCore::Core::CpuStateFrame *Frame, char* filename, const struct utimbuf* times) -> uint64_t {
uint64_t Result = ::utime(filename, times);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(adjtimex, [](FEXCore::Core::CpuStateFrame *Frame, struct timex *buf) -> uint64_t {
uint64_t Result = ::adjtimex(buf);
SYSCALL_ERRNO();
+4 -13
View File
@@ -5,6 +5,7 @@ $end_info$
*/
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/Types.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
@@ -24,27 +25,17 @@ namespace FEX::HLE {
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(timer_create, [](FEXCore::Core::CpuStateFrame *Frame, clockid_t clockid, struct sigevent *sevp, timer_t *timerid) -> uint64_t {
REGISTER_SYSCALL_IMPL(timer_create, [](FEXCore::Core::CpuStateFrame *Frame, clockid_t clockid, struct sigevent *sevp, kernel_timer_t *timerid) -> uint64_t {
uint64_t Result = ::syscall(SYS_timer_create, clockid, sevp, timerid);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(timer_settime, [](FEXCore::Core::CpuStateFrame *Frame, timer_t timerid, int flags, const struct itimerspec *new_value, struct itimerspec *old_value) -> uint64_t {
uint64_t Result = ::syscall(SYS_timer_settime, timerid, flags, new_value, old_value);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(timer_gettime, [](FEXCore::Core::CpuStateFrame *Frame, timer_t timerid, struct itimerspec *curr_value) -> uint64_t {
uint64_t Result = ::syscall(SYS_timer_gettime, timerid, curr_value);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(timer_getoverrun, [](FEXCore::Core::CpuStateFrame *Frame, timer_t timerid) -> uint64_t {
REGISTER_SYSCALL_IMPL(timer_getoverrun, [](FEXCore::Core::CpuStateFrame *Frame, kernel_timer_t timerid) -> uint64_t {
uint64_t Result = ::syscall(SYS_timer_getoverrun, timerid);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(timer_delete, [](FEXCore::Core::CpuStateFrame *Frame, timer_t timerid) -> uint64_t {
REGISTER_SYSCALL_IMPL(timer_delete, [](FEXCore::Core::CpuStateFrame *Frame, kernel_timer_t timerid) -> uint64_t {
uint64_t Result = ::syscall(SYS_timer_delete, timerid);
SYSCALL_ERRNO();
});
+34
View File
@@ -0,0 +1,34 @@
#pragma once
#include <FEXCore/Utils/CompilerDefs.h>
#include <sys/epoll.h>
#include <type_traits>
namespace FEX::HLE {
using key_serial_t = int32_t;
using kernel_timer_t = int32_t;
struct FEX_PACKED epoll_event_x86 {
uint32_t events;
epoll_data_t data;
epoll_event_x86() = delete;
operator struct epoll_event() const {
epoll_event event{};
event.events = events;
event.data = data;
return event;
}
epoll_event_x86(struct epoll_event event) {
events = event.events;
data = event.data;
}
};
static_assert(std::is_trivial<epoll_event_x86>::value, "Needs to be trivial");
static_assert(sizeof(epoll_event_x86) == 12, "Incorrect size");
}
+5 -4
View File
@@ -6,6 +6,7 @@ $end_info$
*/
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/Types.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Types.h"
@@ -26,7 +27,7 @@ namespace FEXCore::Core {
namespace FEX::HLE::x32 {
void RegisterEpoll(FEX::HLE::SyscallHandler *const Handler) {
REGISTER_SYSCALL_IMPL_X32(epoll_wait, [](FEXCore::Core::CpuStateFrame *Frame, int epfd, compat_ptr<epoll_event_x86> events, int maxevents, int timeout) -> uint64_t {
REGISTER_SYSCALL_IMPL_X32(epoll_wait, [](FEXCore::Core::CpuStateFrame *Frame, int epfd, compat_ptr<FEX::HLE::epoll_event_x86> events, int maxevents, int timeout) -> uint64_t {
std::vector<struct epoll_event> Events(std::max(0, maxevents));
uint64_t Result = ::syscall(SYS_epoll_pwait, epfd, Events.data(), maxevents, timeout, nullptr);
@@ -38,7 +39,7 @@ namespace FEX::HLE::x32 {
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X32(epoll_ctl, [](FEXCore::Core::CpuStateFrame *Frame, int epfd, int op, int fd, compat_ptr<epoll_event_x86> event) -> uint64_t {
REGISTER_SYSCALL_IMPL_X32(epoll_ctl, [](FEXCore::Core::CpuStateFrame *Frame, int epfd, int op, int fd, compat_ptr<FEX::HLE::epoll_event_x86> event) -> uint64_t {
struct epoll_event Event = *event;
uint64_t Result = ::syscall(SYS_epoll_ctl, epfd, op, fd, &Event);
if (Result != -1) {
@@ -47,7 +48,7 @@ namespace FEX::HLE::x32 {
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X32(epoll_pwait, [](FEXCore::Core::CpuStateFrame *Frame, int epfd, compat_ptr<epoll_event_x86> events, int maxevent, int timeout, const uint64_t* sigmask, size_t sigsetsize) -> uint64_t {
REGISTER_SYSCALL_IMPL_X32(epoll_pwait, [](FEXCore::Core::CpuStateFrame *Frame, int epfd, compat_ptr<FEX::HLE::epoll_event_x86> events, int maxevent, int timeout, const uint64_t* sigmask, size_t sigsetsize) -> uint64_t {
std::vector<struct epoll_event> Events(std::max(0, maxevent));
uint64_t Result = ::syscall(SYS_epoll_pwait,
@@ -71,7 +72,7 @@ namespace FEX::HLE::x32 {
#ifndef SYS_epoll_pwait2
#define SYS_epoll_pwait2 354
#endif
REGISTER_SYSCALL_IMPL_X32(epoll_pwait2, [](FEXCore::Core::CpuStateFrame *Frame, int epfd, compat_ptr<epoll_event_x86> events, int maxevent, compat_ptr<timespec32> timeout, const uint64_t* sigmask, size_t sigsetsize) -> uint64_t {
REGISTER_SYSCALL_IMPL_X32(epoll_pwait2, [](FEXCore::Core::CpuStateFrame *Frame, int epfd, compat_ptr<FEX::HLE::epoll_event_x86> events, int maxevent, compat_ptr<timespec32> timeout, const uint64_t* sigmask, size_t sigsetsize) -> uint64_t {
std::vector<struct epoll_event> Events(std::max(0, maxevent));
struct timespec tp64{};
+35
View File
@@ -736,6 +736,41 @@ namespace FEX::HLE::x32 {
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X32(timerfd_settime, [](FEXCore::Core::CpuStateFrame *Frame,
int fd,
int flags,
const FEX::HLE::x32::old_itimerspec32 *new_value,
FEX::HLE::x32::old_itimerspec32 *old_value) -> uint64_t {
struct itimerspec new_value_host{};
struct itimerspec old_value_host{};
struct itimerspec *old_value_host_p{};
new_value_host = *new_value;
if (old_value) {
old_value_host_p = &old_value_host;
}
// Flags don't need remapped
uint64_t Result = ::timerfd_settime(fd, flags, &new_value_host, old_value_host_p);
if (Result != -1 && old_value) {
*old_value = old_value_host;
}
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X32(timerfd_gettime, [](FEXCore::Core::CpuStateFrame *Frame, int fd, FEX::HLE::x32::old_itimerspec32 *curr_value) -> uint64_t {
struct itimerspec Host{};
uint64_t Result = ::timerfd_gettime(fd, &Host);
if (Result != -1) {
*curr_value = Host;
}
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X32(pselect6_time64, [](FEXCore::Core::CpuStateFrame *Frame, int nfds, fd_set32 *readfds, fd_set32 *writefds, fd_set32 *exceptfds, struct timespec *timeout, compat_ptr<sigset_argpack32> sigmaskpack) -> uint64_t {
fd_set Host_readfds;
fd_set Host_writefds;
@@ -684,6 +684,7 @@ public:
FEX::HLE::RegisterKey();
FEX::HLE::RegisterMemory();
FEX::HLE::RegisterMsg();
FEX::HLE::RegisterNamespace(this);
FEX::HLE::RegisterSched();
FEX::HLE::RegisterSemaphore();
FEX::HLE::RegisterSHM();
+34
View File
@@ -15,6 +15,7 @@ $end_info$
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <utime.h>
ARG_TO_STR(FEX::HLE::x32::compat_ptr<FEX::HLE::x32::timespec32>, "%lx")
@@ -25,6 +26,39 @@ namespace FEXCore::Core {
namespace FEX::HLE::x32 {
void RegisterTime() {
REGISTER_SYSCALL_IMPL_X32(time, [](FEXCore::Core::CpuStateFrame *Frame, FEX::HLE::x32::old_time32_t *tloc) -> uint64_t {
time_t Host{};
uint64_t Result = ::time(&Host);
if (tloc) {
// On 32-bit this truncates
*tloc = (FEX::HLE::x32::old_time32_t)Host;
}
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X32(times, [](FEXCore::Core::CpuStateFrame *Frame, struct FEX::HLE::x32::compat_tms *buf) -> uint64_t {
struct tms Host{};
uint64_t Result = ::times(&Host);
if (buf) {
*buf = Host;
}
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X32(utime, [](FEXCore::Core::CpuStateFrame *Frame, char* filename, const FEX::HLE::x32::old_utimbuf32* times) -> uint64_t {
struct utimbuf Host{};
struct utimbuf *Host_p{};
if (times) {
Host = *times;
Host_p = &Host;
}
uint64_t Result = ::utime(filename, Host_p);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X32(gettimeofday, [](FEXCore::Core::CpuStateFrame *Frame, timeval32 *tv, struct timezone *tz) -> uint64_t {
struct timeval tv64{};
struct timeval *tv_ptr{};
+33 -2
View File
@@ -5,6 +5,7 @@ $end_info$
*/
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/Types.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Types.h"
@@ -20,12 +21,42 @@ namespace FEXCore::Core {
namespace FEX::HLE::x32 {
void RegisterTimer() {
REGISTER_SYSCALL_IMPL_X32(timer_settime64, [](FEXCore::Core::CpuStateFrame *Frame, timer_t timerid, int flags, const struct itimerspec *new_value, struct itimerspec *old_value) -> uint64_t {
REGISTER_SYSCALL_IMPL_X32(timer_settime, [](FEXCore::Core::CpuStateFrame *Frame,
kernel_timer_t timerid,
int flags,
const FEX::HLE::x32::old_itimerspec32 *new_value,
FEX::HLE::x32::old_itimerspec32 *old_value) -> uint64_t {
itimerspec new_value_host{};
itimerspec old_value_host{};
itimerspec *old_value_host_p{};
new_value_host = *new_value;
if (old_value) {
old_value_host_p = &old_value_host;
}
uint64_t Result = ::syscall(SYS_timer_settime, timerid, flags, &new_value_host, old_value_host_p);
if (Result != -1 && old_value) {
*old_value = old_value_host;
}
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X32(timer_gettime, [](FEXCore::Core::CpuStateFrame *Frame,
kernel_timer_t timerid,
FEX::HLE::x32::old_itimerspec32 *curr_value) -> uint64_t {
itimerspec curr_value_host{};
uint64_t Result = ::syscall(SYS_timer_gettime, timerid, curr_value_host);
*curr_value = curr_value_host;
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X32(timer_settime64, [](FEXCore::Core::CpuStateFrame *Frame, kernel_timer_t timerid, int flags, const struct itimerspec *new_value, struct itimerspec *old_value) -> uint64_t {
uint64_t Result = ::syscall(SYS_timer_settime, timerid, flags, new_value, old_value);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X32(timer_gettime64, [](FEXCore::Core::CpuStateFrame *Frame, timer_t timerid, struct itimerspec *curr_value) -> uint64_t {
REGISTER_SYSCALL_IMPL_X32(timer_gettime64, [](FEXCore::Core::CpuStateFrame *Frame, kernel_timer_t timerid, struct itimerspec *curr_value) -> uint64_t {
uint64_t Result = ::syscall(SYS_timer_gettime, timerid, curr_value);
SYSCALL_ERRNO();
});
+83
View File
@@ -18,9 +18,13 @@ $end_info$
#include <sys/stat.h>
#include <sys/statfs.h>
#include <sys/time.h>
#include <sys/times.h>
#include <sys/uio.h>
#include <time.h>
#include <type_traits>
#include <utime.h>
#include "Tests/LinuxSyscalls/Types.h"
namespace FEX::HLE::x32 {
@@ -39,6 +43,8 @@ using compat_nlink_t = uint16_t;
using compat_uid_t = uint16_t;
using compat_gid_t = uint16_t;
using compat_old_sigset_t = uint32_t;
using old_time32_t = int32_t;
using compat_clock_t = int32_t;
// Can't use using with aligned attributes, clang doesn't honour it
typedef FEX_ALIGNED(4) uint64_t compat_uint64_t;
@@ -832,4 +838,81 @@ GuestSigAction_32 {
static_assert(std::is_trivial<GuestSigAction_32>::value, "Needs to be trivial");
static_assert(sizeof(GuestSigAction_32) == 20, "Incorrect size");
struct
FEX_ANNOTATE("alias-x86_32-tms")
FEX_ANNOTATE("fex-match")
compat_tms {
compat_clock_t tms_utime;
compat_clock_t tms_stime;
compat_clock_t tms_cutime;
compat_clock_t tms_cstime;
compat_tms() = delete;
operator tms() const {
tms val{};
val.tms_utime = tms_utime;
val.tms_stime = tms_stime;
val.tms_cutime = tms_cutime;
val.tms_cstime = tms_cstime;
return val;
}
compat_tms(struct tms val) {
tms_utime = val.tms_utime;
tms_stime = val.tms_stime;
tms_cutime = val.tms_cutime;
tms_cstime = val.tms_cstime;
}
};
static_assert(std::is_trivial<compat_tms>::value, "Needs to be trivial");
static_assert(sizeof(compat_tms) == 16, "Incorrect size");
struct
FEX_ANNOTATE("alias-x86_32-utimbuf")
FEX_ANNOTATE("fex-match")
old_utimbuf32 {
old_time32_t actime;
old_time32_t modtime;
old_utimbuf32() = delete;
operator utimbuf() const {
utimbuf val{};
val.actime = actime;
val.modtime = modtime;
return val;
}
old_utimbuf32(struct utimbuf val) {
actime = val.actime;
modtime = val.modtime;
}
};
static_assert(std::is_trivial<old_utimbuf32>::value, "Needs to be trivial");
static_assert(sizeof(old_utimbuf32) == 8, "Incorrect size");
struct
FEX_ANNOTATE("alias-x86_32-itimerspec")
FEX_ANNOTATE("fex-match")
old_itimerspec32 {
timespec32 it_interval;
timespec32 it_value;
old_itimerspec32() = delete;
operator itimerspec() const {
itimerspec val{};
val.it_interval = it_interval;
val.it_value = it_value;
return val;
}
old_itimerspec32(struct itimerspec val)
: it_interval { val.it_interval }
, it_value { val.it_value } {
}
};
static_assert(std::is_trivial<old_itimerspec32>::value, "Needs to be trivial");
static_assert(sizeof(old_itimerspec32) == 16, "Incorrect size");
}
+6 -4
View File
@@ -6,7 +6,9 @@ $end_info$
*/
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/Types.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Types.h"
#include <algorithm>
#include <cstdint>
@@ -23,7 +25,7 @@ namespace FEXCore::Core {
namespace FEX::HLE::x64 {
void RegisterEpoll(FEX::HLE::SyscallHandler *const Handler) {
REGISTER_SYSCALL_IMPL_X64(epoll_wait, [](FEXCore::Core::CpuStateFrame *Frame, int epfd, epoll_event_x86 *events, int maxevents, int timeout) -> uint64_t {
REGISTER_SYSCALL_IMPL_X64(epoll_wait, [](FEXCore::Core::CpuStateFrame *Frame, int epfd, FEX::HLE::epoll_event_x86 *events, int maxevents, int timeout) -> uint64_t {
std::vector<struct epoll_event> Events(std::max(0, maxevents));
uint64_t Result = ::syscall(SYS_epoll_pwait, epfd, Events.data(), maxevents, timeout, nullptr, 8);
@@ -35,7 +37,7 @@ namespace FEX::HLE::x64 {
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X64(epoll_ctl, [](FEXCore::Core::CpuStateFrame *Frame, int epfd, int op, int fd, epoll_event_x86 *event) -> uint64_t {
REGISTER_SYSCALL_IMPL_X64(epoll_ctl, [](FEXCore::Core::CpuStateFrame *Frame, int epfd, int op, int fd, FEX::HLE::epoll_event_x86 *event) -> uint64_t {
struct epoll_event Event;
struct epoll_event *EventPtr{};
if (event) {
@@ -49,7 +51,7 @@ namespace FEX::HLE::x64 {
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X64(epoll_pwait, [](FEXCore::Core::CpuStateFrame *Frame, int epfd, epoll_event_x86 *events, int maxevent, int timeout, const uint64_t* sigmask, size_t sigsetsize) -> uint64_t {
REGISTER_SYSCALL_IMPL_X64(epoll_pwait, [](FEXCore::Core::CpuStateFrame *Frame, int epfd, FEX::HLE::epoll_event_x86 *events, int maxevent, int timeout, const uint64_t* sigmask, size_t sigsetsize) -> uint64_t {
std::vector<struct epoll_event> Events(std::max(0, maxevent));
uint64_t Result = ::syscall(SYS_epoll_pwait,
@@ -73,7 +75,7 @@ namespace FEX::HLE::x64 {
#ifndef SYS_epoll_pwait2
#define SYS_epoll_pwait2 354
#endif
REGISTER_SYSCALL_IMPL_X64(epoll_pwait2, [](FEXCore::Core::CpuStateFrame *Frame, int epfd, epoll_event_x86 *events, int maxevent, timespec *timeout, const uint64_t* sigmask, size_t sigsetsize) -> uint64_t {
REGISTER_SYSCALL_IMPL_X64(epoll_pwait2, [](FEXCore::Core::CpuStateFrame *Frame, int epfd, FEX::HLE::epoll_event_x86 *events, int maxevent, timespec *timeout, const uint64_t* sigmask, size_t sigsetsize) -> uint64_t {
std::vector<struct epoll_event> Events(std::max(0, maxevent));
uint64_t Result = ::syscall(SYS_epoll_pwait2,
+21 -58
View File
@@ -7,10 +7,10 @@ $end_info$
#include "Tests/LinuxSyscalls/FileManagement.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Types.h"
#include <FEXCore/Utils/CompilerDefs.h>
#include <asm/posix_types.h>
#include <fcntl.h>
#include <poll.h>
#include <stdint.h>
@@ -20,60 +20,12 @@ $end_info$
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/sendfile.h>
#include <sys/timerfd.h>
#include <syscall.h>
#include <time.h>
#include <unistd.h>
namespace FEX::HLE::x64 {
struct FEX_PACKED guest_stat {
__kernel_ulong_t st_dev;
__kernel_ulong_t st_ino;
__kernel_ulong_t st_nlink;
unsigned int st_mode;
unsigned int st_uid;
unsigned int st_gid;
unsigned int __pad0;
__kernel_ulong_t st_rdev;
__kernel_long_t st_size;
__kernel_long_t st_blksize;
__kernel_long_t st_blocks; /* Number 512-byte blocks allocated. */
__kernel_ulong_t st_atime_;
__kernel_ulong_t st_atime_nsec;
__kernel_ulong_t st_mtime_;
__kernel_ulong_t st_mtime_nsec;
__kernel_ulong_t st_ctime_;
__kernel_ulong_t st_ctime_nsec;
__kernel_long_t __unused[3];
};
static void CopyStat(guest_stat *guest, struct stat *host) {
#define COPY(x) guest->x = host->x
COPY(st_dev);
COPY(st_ino);
COPY(st_nlink);
COPY(st_mode);
COPY(st_uid);
COPY(st_gid);
COPY(st_rdev);
COPY(st_size);
COPY(st_blksize);
COPY(st_blocks);
guest->st_atime_ = host->st_atim.tv_sec;
guest->st_atime_nsec = host->st_atim.tv_nsec;
guest->st_mtime_ = host->st_mtime;
guest->st_mtime_nsec = host->st_mtim.tv_nsec;
guest->st_ctime_ = host->st_ctime;
guest->st_ctime_nsec = host->st_ctim.tv_nsec;
#undef COPY
}
void RegisterFD() {
REGISTER_SYSCALL_IMPL_X64(poll, [](FEXCore::Core::CpuStateFrame *Frame, struct pollfd *fds, nfds_t nfds, int timeout) -> uint64_t {
uint64_t Result = ::poll(fds, nfds, timeout);
@@ -119,29 +71,29 @@ namespace FEX::HLE::x64 {
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X64(stat, [](FEXCore::Core::CpuStateFrame *Frame, const char *pathname, guest_stat *buf) -> uint64_t {
REGISTER_SYSCALL_IMPL_X64(stat, [](FEXCore::Core::CpuStateFrame *Frame, const char *pathname, FEX::HLE::x64::guest_stat *buf) -> uint64_t {
struct stat host_stat;
uint64_t Result = FEX::HLE::_SyscallHandler->FM.Stat(pathname, &host_stat);
if (Result != -1) {
CopyStat(buf, &host_stat);
*buf = host_stat;
}
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X64(fstat, [](FEXCore::Core::CpuStateFrame *Frame, int fd, guest_stat *buf) -> uint64_t {
REGISTER_SYSCALL_IMPL_X64(fstat, [](FEXCore::Core::CpuStateFrame *Frame, int fd, FEX::HLE::x64::guest_stat *buf) -> uint64_t {
struct stat host_stat;
uint64_t Result = ::fstat(fd, &host_stat);
if (Result != -1) {
CopyStat(buf, &host_stat);
*buf = host_stat;
}
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X64(lstat, [](FEXCore::Core::CpuStateFrame *Frame, const char *path, guest_stat *buf) -> uint64_t {
REGISTER_SYSCALL_IMPL_X64(lstat, [](FEXCore::Core::CpuStateFrame *Frame, const char *path, FEX::HLE::x64::guest_stat *buf) -> uint64_t {
struct stat host_stat;
uint64_t Result = FEX::HLE::_SyscallHandler->FM.Lstat(path, &host_stat);
if (Result != -1) {
CopyStat(buf, &host_stat);
*buf = host_stat;
}
SYSCALL_ERRNO();
});
@@ -161,11 +113,11 @@ namespace FEX::HLE::x64 {
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X64(newfstatat, [](FEXCore::Core::CpuStateFrame *Frame, int dirfd, const char *pathname, guest_stat *buf, int flag) -> uint64_t {
REGISTER_SYSCALL_IMPL_X64(newfstatat, [](FEXCore::Core::CpuStateFrame *Frame, int dirfd, const char *pathname, FEX::HLE::x64::guest_stat *buf, int flag) -> uint64_t {
struct stat host_stat;
uint64_t Result = FEX::HLE::_SyscallHandler->FM.NewFSStatAt(dirfd, pathname, &host_stat, flag);
if (Result != -1) {
CopyStat(buf, &host_stat);
*buf = host_stat;
}
SYSCALL_ERRNO();
});
@@ -299,5 +251,16 @@ namespace FEX::HLE::x64 {
uint64_t Result = ::fallocate(fd, mode, offset, len);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X64(timerfd_settime, [](FEXCore::Core::CpuStateFrame *Frame, int fd, int flags, const struct itimerspec *new_value, struct itimerspec *old_value) -> uint64_t {
// Flags don't need remapped
uint64_t Result = ::timerfd_settime(fd, flags, new_value, old_value);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X64(timerfd_gettime, [](FEXCore::Core::CpuStateFrame *Frame, int fd, struct itimerspec *curr_value) -> uint64_t {
uint64_t Result = ::timerfd_gettime(fd, curr_value);
SYSCALL_ERRNO();
});
}
}
@@ -107,6 +107,7 @@ namespace FEX::HLE::x64 {
FEX::HLE::RegisterKey();
FEX::HLE::RegisterMemory();
FEX::HLE::RegisterMsg();
FEX::HLE::RegisterNamespace(this);
FEX::HLE::RegisterSched();
FEX::HLE::RegisterSemaphore();
FEX::HLE::RegisterSHM();
+26
View File
@@ -5,6 +5,7 @@ $end_info$
*/
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/Types.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include <stddef.h>
@@ -19,6 +20,21 @@ $end_info$
namespace FEX::HLE::x64 {
void RegisterTime() {
REGISTER_SYSCALL_IMPL_X64(time, [](FEXCore::Core::CpuStateFrame *Frame, time_t *tloc) -> uint64_t {
uint64_t Result = ::time(tloc);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X64(times, [](FEXCore::Core::CpuStateFrame *Frame, struct tms *buf) -> uint64_t {
uint64_t Result = ::times(buf);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X64(utime, [](FEXCore::Core::CpuStateFrame *Frame, char* filename, const struct utimbuf* times) -> uint64_t {
uint64_t Result = ::utime(filename, times);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X64(gettimeofday, [](FEXCore::Core::CpuStateFrame *Frame, struct timeval *tv, struct timezone *tz) -> uint64_t {
uint64_t Result = ::gettimeofday(tv, tz);
SYSCALL_ERRNO();
@@ -68,6 +84,16 @@ namespace FEX::HLE::x64 {
uint64_t Result = ::setitimer(which, new_value, old_value);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X64(timer_settime, [](FEXCore::Core::CpuStateFrame *Frame, kernel_timer_t timerid, int flags, const struct itimerspec *new_value, struct itimerspec *old_value) -> uint64_t {
uint64_t Result = ::syscall(SYS_timer_settime, timerid, flags, new_value, old_value);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL_X64(timer_gettime, [](FEXCore::Core::CpuStateFrame *Frame, kernel_timer_t timerid, struct itimerspec *curr_value) -> uint64_t {
uint64_t Result = ::syscall(SYS_timer_gettime, timerid, curr_value);
SYSCALL_ERRNO();
});
}
}
+89
View File
@@ -6,8 +6,12 @@ $end_info$
#pragma once
#include <FEXCore/Utils/CompilerDefs.h>
#include <asm/posix_types.h>
#include <cstdint>
#include <sys/sem.h>
#include <sys/stat.h>
#include <type_traits>
namespace FEX::HLE::x64 {
@@ -112,4 +116,89 @@ using __time_t = time_t;
static_assert(std::is_trivial<FEX::HLE::x64::semun>::value, "Needs to be trivial");
static_assert(sizeof(FEX::HLE::x64::semun) == 8, "Incorrect size");
struct
FEX_ANNOTATE("fex-match")
FEX_PACKED
guest_stat {
__kernel_ulong_t st_dev;
__kernel_ulong_t st_ino;
__kernel_ulong_t st_nlink;
unsigned int st_mode;
unsigned int st_uid;
unsigned int st_gid;
unsigned int __pad0;
__kernel_ulong_t st_rdev;
__kernel_long_t st_size;
__kernel_long_t st_blksize;
__kernel_long_t st_blocks; /* Number 512-byte blocks allocated. */
__kernel_ulong_t st_atime_;
__kernel_ulong_t st_atime_nsec;
__kernel_ulong_t st_mtime_;
__kernel_ulong_t st_mtime_nsec;
__kernel_ulong_t st_ctime_;
__kernel_ulong_t st_ctime_nsec;
__kernel_long_t __unused[3];
guest_stat() = delete;
operator struct stat() const {
struct stat val{};
#define COPY(x) val.x = x
COPY(st_dev);
COPY(st_ino);
COPY(st_nlink);
COPY(st_mode);
COPY(st_uid);
COPY(st_gid);
COPY(st_rdev);
COPY(st_size);
COPY(st_blksize);
COPY(st_blocks);
val.st_atim.tv_sec = st_atime_;
val.st_atim.tv_nsec = st_atime_nsec;
val.st_mtim.tv_sec = st_mtime_;
val.st_mtim.tv_nsec = st_mtime_nsec;
val.st_ctim.tv_sec = st_ctime_;
val.st_ctim.tv_nsec= st_ctime_nsec;
#undef COPY
return val;
}
guest_stat(struct stat val) {
#define COPY(x) x = val.x
COPY(st_dev);
COPY(st_ino);
COPY(st_nlink);
COPY(st_mode);
COPY(st_uid);
COPY(st_gid);
COPY(st_rdev);
COPY(st_size);
COPY(st_blksize);
COPY(st_blocks);
st_atime_ = val.st_atim.tv_sec;
st_atime_nsec = val.st_atim.tv_nsec;
st_mtime_ = val.st_mtime;
st_mtime_nsec = val.st_mtim.tv_nsec;
st_ctime_ = val.st_ctime;
st_ctime_nsec = val.st_ctim.tv_nsec;
#undef COPY
}
};
// Original definition in `arch/x86/include/uapi/asm/stat.h` for future excavation
static_assert(std::is_trivial<FEX::HLE::x64::guest_stat>::value, "Needs to be trivial");
static_assert(sizeof(FEX::HLE::x64::guest_stat) == 144, "Incorrect size");
}