mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 14:00:16 +02:00
Linux: Fixes some 32-bit syscalls
This commit is contained in:
1 parent
d8350353d6
commit
fd3a88389b
13 files changed
+331
-101
No files matched your search
@@ -70,6 +70,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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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{};
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
|
||||
@@ -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");
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
Reference in new issue
Block a user