Add linux_getrusage and linux_setitimer syscall implementation

This commit is contained in:
EnderIce2 2024-03-28 00:16:32 +02:00
parent eb3020bde7
commit 147027b613
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
2 changed files with 142 additions and 6 deletions

View File

@ -172,10 +172,21 @@
#define SA_IMMUTABLE 0x00800000 #define SA_IMMUTABLE 0x00800000
#define ITIMER_REAL 0
#define ITIMER_VIRTUAL 1
#define ITIMER_PROF 2
#define RUSAGE_SELF 0
#define RUSAGE_CHILDREN (-1)
#define RUSAGE_THREAD 1
typedef long __kernel_old_time_t; typedef long __kernel_old_time_t;
typedef long __kernel_suseconds_t; typedef long __kernel_suseconds_t;
typedef int clockid_t; typedef int clockid_t;
typedef long time64_t;
typedef unsigned long timeu64_t;
struct iovec struct iovec
{ {
void *iov_base; void *iov_base;
@ -188,6 +199,18 @@ struct timeval
__kernel_suseconds_t tv_usec; __kernel_suseconds_t tv_usec;
}; };
struct timespec64
{
time64_t tv_sec;
long tv_nsec;
};
struct itimerspec64
{
struct timespec64 it_interval;
struct timespec64 it_value;
};
struct rusage struct rusage
{ {
struct timeval ru_utime; struct timeval ru_utime;

View File

@ -991,6 +991,46 @@ static pid_t linux_getpid(SysFrm *)
return thisProcess->ID; return thisProcess->ID;
} }
/* https://man7.org/linux/man-pages/man2/setitimer.2.html */
static int linux_setitimer(SysFrm *, int which,
const struct itimerspec64 *new_value,
struct itimerspec64 *old_value)
{
PCB *pcb = thisProcess;
Memory::VirtualMemoryArea *vma = pcb->vma;
auto pNewValue = vma->UserCheckAndGetAddress(new_value);
auto pOldValue = vma->UserCheckAndGetAddress(old_value);
if (pNewValue == nullptr)
return -EFAULT;
if (pOldValue == nullptr && old_value)
return -EFAULT;
switch (which)
{
case ITIMER_REAL:
{
fixme("ITIMER_REAL not implemented");
return 0;
}
case ITIMER_VIRTUAL:
{
fixme("ITIMER_VIRTUAL not implemented");
return 0;
}
case ITIMER_PROF:
{
fixme("ITIMER_PROF not implemented");
return 0;
}
default:
return -EINVAL;
}
return 0;
}
/* https://man7.org/linux/man-pages/man2/shutdown.2.html */ /* https://man7.org/linux/man-pages/man2/shutdown.2.html */
static int linux_shutdown(SysFrm *, int sockfd, int how) static int linux_shutdown(SysFrm *, int sockfd, int how)
{ {
@ -1770,6 +1810,79 @@ static ssize_t linux_readlink(SysFrm *, const char *pathname,
return len; return len;
} }
/* https://man7.org/linux/man-pages/man2/getrusage.2.html */
static int linux_getrusage(SysFrm *, int who, struct rusage *usage)
{
PCB *pcb = thisProcess;
Memory::VirtualMemoryArea *vma = pcb->vma;
auto pUsage = vma->UserCheckAndGetAddress(usage);
if (pUsage == nullptr)
return -EFAULT;
switch (who)
{
case RUSAGE_SELF:
{
size_t kTime = pcb->Info.KernelTime;
size_t uTime = pcb->Info.UserTime;
size_t _maxrss = pcb->GetSize();
pUsage->ru_utime.tv_sec = uTime / 1000000000000000; /* Seconds */
pUsage->ru_utime.tv_usec = uTime / 1000000000; /* Microseconds */
pUsage->ru_stime.tv_sec = kTime / 1000000000000000; /* Seconds */
pUsage->ru_stime.tv_usec = kTime / 1000000000; /* Microseconds */
pUsage->ru_maxrss = _maxrss;
break;
}
case RUSAGE_CHILDREN:
{
size_t kTime = 0;
size_t uTime = 0;
size_t _maxrss = 0;
foreach (auto child in pcb->Children)
{
kTime += child->Info.KernelTime;
uTime += child->Info.UserTime;
_maxrss += child->GetSize();
}
pUsage->ru_utime.tv_sec = uTime / 1000000000000000; /* Seconds */
pUsage->ru_utime.tv_usec = uTime / 1000000000; /* Microseconds */
pUsage->ru_stime.tv_sec = kTime / 1000000000000000; /* Seconds */
pUsage->ru_stime.tv_usec = kTime / 1000000000; /* Microseconds */
pUsage->ru_maxrss = _maxrss;
break;
}
case RUSAGE_THREAD:
{
TCB *tcb = thisThread;
size_t kTime = tcb->Info.KernelTime;
size_t uTime = tcb->Info.UserTime;
size_t _maxrss = tcb->GetSize();
pUsage->ru_utime.tv_sec = uTime / 1000000000000000; /* Seconds */
pUsage->ru_utime.tv_usec = uTime / 1000000000; /* Microseconds */
pUsage->ru_stime.tv_sec = kTime / 1000000000000000; /* Seconds */
pUsage->ru_stime.tv_usec = kTime / 1000000000; /* Microseconds */
pUsage->ru_maxrss = _maxrss;
break;
}
default:
return -EINVAL;
}
return 0;
}
/* https://man7.org/linux/man-pages/man2/getuid.2.html */ /* https://man7.org/linux/man-pages/man2/getuid.2.html */
static uid_t linux_getuid(SysFrm *) static uid_t linux_getuid(SysFrm *)
{ {
@ -2562,7 +2675,7 @@ static SyscallData LinuxSyscallsTableAMD64[] = {
[__NR_amd64_nanosleep] = {"nanosleep", (void *)linux_nanosleep}, [__NR_amd64_nanosleep] = {"nanosleep", (void *)linux_nanosleep},
[__NR_amd64_getitimer] = {"getitimer", (void *)nullptr}, [__NR_amd64_getitimer] = {"getitimer", (void *)nullptr},
[__NR_amd64_alarm] = {"alarm", (void *)nullptr}, [__NR_amd64_alarm] = {"alarm", (void *)nullptr},
[__NR_amd64_setitimer] = {"setitimer", (void *)nullptr}, [__NR_amd64_setitimer] = {"setitimer", (void *)linux_setitimer},
[__NR_amd64_getpid] = {"getpid", (void *)linux_getpid}, [__NR_amd64_getpid] = {"getpid", (void *)linux_getpid},
[__NR_amd64_sendfile] = {"sendfile", (void *)nullptr}, [__NR_amd64_sendfile] = {"sendfile", (void *)nullptr},
[__NR_amd64_socket] = {"socket", (void *)nullptr}, [__NR_amd64_socket] = {"socket", (void *)nullptr},
@ -2622,7 +2735,7 @@ static SyscallData LinuxSyscallsTableAMD64[] = {
[__NR_amd64_umask] = {"umask", (void *)nullptr}, [__NR_amd64_umask] = {"umask", (void *)nullptr},
[__NR_amd64_gettimeofday] = {"gettimeofday", (void *)nullptr}, [__NR_amd64_gettimeofday] = {"gettimeofday", (void *)nullptr},
[__NR_amd64_getrlimit] = {"getrlimit", (void *)nullptr}, [__NR_amd64_getrlimit] = {"getrlimit", (void *)nullptr},
[__NR_amd64_getrusage] = {"getrusage", (void *)nullptr}, [__NR_amd64_getrusage] = {"getrusage", (void *)linux_getrusage},
[__NR_amd64_sysinfo] = {"sysinfo", (void *)nullptr}, [__NR_amd64_sysinfo] = {"sysinfo", (void *)nullptr},
[__NR_amd64_times] = {"times", (void *)nullptr}, [__NR_amd64_times] = {"times", (void *)nullptr},
[__NR_amd64_ptrace] = {"ptrace", (void *)nullptr}, [__NR_amd64_ptrace] = {"ptrace", (void *)nullptr},
@ -3051,7 +3164,7 @@ static SyscallData LinuxSyscallsTableI386[] = {
[__NR_i386_sethostname] = {"sethostname", (void *)nullptr}, [__NR_i386_sethostname] = {"sethostname", (void *)nullptr},
[__NR_i386_setrlimit] = {"setrlimit", (void *)nullptr}, [__NR_i386_setrlimit] = {"setrlimit", (void *)nullptr},
[__NR_i386_getrlimit] = {"getrlimit", (void *)nullptr}, [__NR_i386_getrlimit] = {"getrlimit", (void *)nullptr},
[__NR_i386_getrusage] = {"getrusage", (void *)nullptr}, [__NR_i386_getrusage] = {"getrusage", (void *)linux_getrusage},
[__NR_i386_gettimeofday_time32] = {"gettimeofday_time32", (void *)nullptr}, [__NR_i386_gettimeofday_time32] = {"gettimeofday_time32", (void *)nullptr},
[__NR_i386_settimeofday_time32] = {"settimeofday_time32", (void *)nullptr}, [__NR_i386_settimeofday_time32] = {"settimeofday_time32", (void *)nullptr},
[__NR_i386_getgroups] = {"getgroups", (void *)nullptr}, [__NR_i386_getgroups] = {"getgroups", (void *)nullptr},
@ -3078,7 +3191,7 @@ static SyscallData LinuxSyscallsTableI386[] = {
[__NR_i386_ioperm] = {"ioperm", (void *)nullptr}, [__NR_i386_ioperm] = {"ioperm", (void *)nullptr},
[__NR_i386_socketcall] = {"socketcall", (void *)nullptr}, [__NR_i386_socketcall] = {"socketcall", (void *)nullptr},
[__NR_i386_syslog] = {"syslog", (void *)nullptr}, [__NR_i386_syslog] = {"syslog", (void *)nullptr},
[__NR_i386_setitimer] = {"setitimer", (void *)nullptr}, [__NR_i386_setitimer] = {"setitimer", (void *)linux_setitimer},
[__NR_i386_getitimer] = {"getitimer", (void *)nullptr}, [__NR_i386_getitimer] = {"getitimer", (void *)nullptr},
[__NR_i386_stat] = {"stat", (void *)linux_stat}, [__NR_i386_stat] = {"stat", (void *)linux_stat},
[__NR_i386_lstat] = {"lstat", (void *)linux_lstat}, [__NR_i386_lstat] = {"lstat", (void *)linux_lstat},
@ -3440,7 +3553,7 @@ uintptr_t HandleLinuxSyscalls(SyscallsFrame *Frame)
if (unlikely(!call)) if (unlikely(!call))
{ {
fixme("Syscall %s(%d) not implemented.", fixme("Syscall %s(%d) not implemented",
Syscall.Name, Frame->rax); Syscall.Name, Frame->rax);
return -ENOSYS; return -ENOSYS;
} }
@ -3471,7 +3584,7 @@ uintptr_t HandleLinuxSyscalls(SyscallsFrame *Frame)
if (unlikely(!call)) if (unlikely(!call))
{ {
fixme("Syscall %s(%d) not implemented.", fixme("Syscall %s(%d) not implemented",
Syscall.Name, Frame->eax); Syscall.Name, Frame->eax);
return -ENOSYS; return -ENOSYS;
} }