From ebe051f6fb9c4583f24ef926b102f275293cc491 Mon Sep 17 00:00:00 2001 From: DH Date: Sun, 31 Dec 2023 18:58:02 +0300 Subject: [PATCH] [orbis-kernel] implement sys_wait4 and sys_kill --- orbis-kernel/include/orbis/KernelContext.hpp | 1 + orbis-kernel/include/orbis/thread/Process.hpp | 1 + orbis-kernel/src/KernelContext.cpp | 31 ++++++++++++++--- orbis-kernel/src/sys/sys_exit.cpp | 33 ++++++++++++++++++- orbis-kernel/src/sys/sys_generic.cpp | 5 +++ orbis-kernel/src/sys/sys_sig.cpp | 22 ++++++++++++- rpcsx-os/main.cpp | 19 +++++++---- rpcsx-os/ops.cpp | 1 + 8 files changed, 100 insertions(+), 13 deletions(-) diff --git a/orbis-kernel/include/orbis/KernelContext.hpp b/orbis-kernel/include/orbis/KernelContext.hpp index 40c39e63..4ce58527 100644 --- a/orbis-kernel/include/orbis/KernelContext.hpp +++ b/orbis-kernel/include/orbis/KernelContext.hpp @@ -54,6 +54,7 @@ class alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__) KernelContext final { Process *createProcess(pid_t pid); void deleteProcess(Process *proc); Process *findProcessById(pid_t pid) const; + Process *findProcessByHostId(std::uint64_t pid) const; utils::LinkedNode *getProcessList() { return m_processes; } diff --git a/orbis-kernel/include/orbis/thread/Process.hpp b/orbis-kernel/include/orbis/thread/Process.hpp index 55412d2e..302b04b8 100644 --- a/orbis-kernel/include/orbis/thread/Process.hpp +++ b/orbis-kernel/include/orbis/thread/Process.hpp @@ -45,6 +45,7 @@ struct NamedMemoryRange { struct Process final { KernelContext *context = nullptr; pid_t pid = -1; + std::uint64_t hostPid = -1; sysentvec *sysent = nullptr; ProcessState state = ProcessState::NEW; Process *parentProcess = nullptr; diff --git a/orbis-kernel/src/KernelContext.cpp b/orbis-kernel/src/KernelContext.cpp index dfe54691..f6c8ec47 100644 --- a/orbis-kernel/src/KernelContext.cpp +++ b/orbis-kernel/src/KernelContext.cpp @@ -2,8 +2,10 @@ #include "orbis/thread/Process.hpp" #include "orbis/thread/ProcessOps.hpp" #include "orbis/utils/Logs.hpp" +#include #include #include +#include namespace orbis { thread_local Thread *g_currentThread; @@ -69,11 +71,32 @@ void KernelContext::deleteProcess(Process *proc) { } Process *KernelContext::findProcessById(pid_t pid) const { - std::lock_guard lock(m_proc_mtx); - for (auto proc = m_processes; proc != nullptr; proc = proc->next) { - if (proc->object.pid == pid) { - return &proc->object; + for (std::size_t i = 0; i < 5; ++i) { + { + std::lock_guard lock(m_proc_mtx); + for (auto proc = m_processes; proc != nullptr; proc = proc->next) { + if (proc->object.pid == pid) { + return &proc->object; + } + } + } + std::this_thread::sleep_for(std::chrono::microseconds(50)); + } + + return nullptr; +} + +Process *KernelContext::findProcessByHostId(std::uint64_t pid) const { + for (std::size_t i = 0; i < 5; ++i) { + { + std::lock_guard lock(m_proc_mtx); + for (auto proc = m_processes; proc != nullptr; proc = proc->next) { + if (proc->object.hostPid == pid) { + return &proc->object; + } + } } + std::this_thread::sleep_for(std::chrono::microseconds(50)); } return nullptr; diff --git a/orbis-kernel/src/sys/sys_exit.cpp b/orbis-kernel/src/sys/sys_exit.cpp index 1fc9b864..7ee4fc06 100644 --- a/orbis-kernel/src/sys/sys_exit.cpp +++ b/orbis-kernel/src/sys/sys_exit.cpp @@ -1,7 +1,11 @@ +#include "KernelContext.hpp" #include "sys/sysproto.hpp" #include "utils/Logs.hpp" #include +#include #include +#include +#include orbis::SysResult orbis::sys_exit(Thread *thread, sint status) { if (auto exit = thread->tproc->ops->exit) { @@ -18,6 +22,33 @@ orbis::SysResult orbis::sys_wait4(Thread *thread, sint pid, ptr status, sint options, ptr rusage) { // TODO ORBIS_LOG_ERROR(__FUNCTION__, pid, status, options, rusage); - std::this_thread::sleep_for(std::chrono::days(1)); + + int hostPid = pid; + if (pid > 0) { + auto process = g_context.findProcessById(pid); + if (process == nullptr) { + return ErrorCode::SRCH; + } + hostPid = process->hostPid; + } + + ::rusage hostUsage; + int stat; + int result = ::wait4(hostPid, &stat, options, &hostUsage); + if (result < 0) { + return static_cast(errno); + } + + ORBIS_LOG_ERROR(__FUNCTION__, pid, status, options, rusage, result, stat); + + auto process = g_context.findProcessByHostId(result); + if (process == nullptr) { + std::abort(); + } + + if (status != nullptr) { + ORBIS_RET_ON_ERROR(uwrite(status, stat)); + } + thread->retval[0] = process->pid; return {}; } diff --git a/orbis-kernel/src/sys/sys_generic.cpp b/orbis-kernel/src/sys/sys_generic.cpp index b678540a..fdcc40f3 100644 --- a/orbis-kernel/src/sys/sys_generic.cpp +++ b/orbis-kernel/src/sys/sys_generic.cpp @@ -29,6 +29,10 @@ orbis::SysResult orbis::sys_read(Thread *thread, sint fd, ptr buf, auto error = read(file.get(), &io, thread); if (error != ErrorCode{} && error != ErrorCode::AGAIN) { + if (error == ErrorCode::BUSY) { + return SysResult::notAnError(error); + } + return error; } @@ -286,6 +290,7 @@ orbis::SysResult orbis::sys_ftruncate(Thread *thread, sint fd, off_t length) { return ErrorCode::NOTSUP; } + ORBIS_LOG_WARNING(__FUNCTION__, fd, length); std::lock_guard lock(file->mtx); return truncate(file.get(), length, thread); } diff --git a/orbis-kernel/src/sys/sys_sig.cpp b/orbis-kernel/src/sys/sys_sig.cpp index cabea89d..1207a48b 100644 --- a/orbis-kernel/src/sys/sys_sig.cpp +++ b/orbis-kernel/src/sys/sys_sig.cpp @@ -1,5 +1,7 @@ +#include "KernelContext.hpp" #include "sys/sysproto.hpp" #include "utils/Logs.hpp" +#include orbis::SysResult orbis::sys_sigaction(Thread *thread, sint sig, ptr act, @@ -67,8 +69,26 @@ orbis::SysResult orbis::sys_sigaltstack(Thread *thread, ptr ss, return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_kill(Thread *thread, sint pid, sint signum) { - return ErrorCode::NOSYS; + ORBIS_LOG_ERROR(__FUNCTION__, pid, signum); + + int hostPid = pid; + if (pid > 0) { + auto process = g_context.findProcessById(pid); + if (process == nullptr) { + return ErrorCode::SRCH; + } + hostPid = process->hostPid; + } + + // TODO: wrap signal + int result = ::kill(hostPid, signum); + if (result < 0) { + return static_cast(errno); + } + + return {}; } + orbis::SysResult orbis::sys_pdkill(Thread *thread, sint fd, sint signum) { return ErrorCode::NOSYS; } diff --git a/rpcsx-os/main.cpp b/rpcsx-os/main.cpp index 8c1133a4..da88a12f 100644 --- a/rpcsx-os/main.cpp +++ b/rpcsx-os/main.cpp @@ -405,9 +405,9 @@ static void ps4InitDev() { orbis::g_context.blockpoolDevice = createBlockPoolDevice(); mbusAv->emitEvent({ - .unk0 = 9, - .unk1 = 1, - .unk2 = 1, + .unk0 = 9, + .unk1 = 1, + .unk2 = 1, }); } @@ -548,16 +548,20 @@ ExecEnv ps4CreateExecEnv(orbis::Thread *mainThread, for (auto sym : libkernel->symbols) { if (sym.id == 0xd2f4e7e480cc53d0) { auto address = (uint64_t)libkernel->base + sym.address; - ::mprotect((void *)utils::alignDown(address, 0x1000), utils::alignUp(sym.size + sym.address, 0x1000), PROT_WRITE); + ::mprotect((void *)utils::alignDown(address, 0x1000), + utils::alignUp(sym.size + sym.address, 0x1000), PROT_WRITE); std::printf("patching sceKernelGetMainSocId\n"); struct GetMainSocId : Xbyak::CodeGenerator { - GetMainSocId(std::uint64_t address, std::uint64_t size) : Xbyak::CodeGenerator(size, (void *)address) { + GetMainSocId(std::uint64_t address, std::uint64_t size) + : Xbyak::CodeGenerator(size, (void *)address) { mov(eax, 0x710f00); ret(); } - } gen{ address, sym.size }; + } gen{address, sym.size}; - ::mprotect((void *)utils::alignDown(address, 0x1000), utils::alignUp(sym.size + sym.address, 0x1000), PROT_READ | PROT_EXEC); + ::mprotect((void *)utils::alignDown(address, 0x1000), + utils::alignUp(sym.size + sym.address, 0x1000), + PROT_READ | PROT_EXEC); break; } } @@ -1297,6 +1301,7 @@ static orbis::SysResult launchDaemon(orbis::Thread *thread, std::string path, dup2(logFd, 1); dup2(logFd, 2); + process->hostPid = ::getpid(); process->sysent = thread->tproc->sysent; process->onSysEnter = thread->tproc->onSysEnter; process->onSysExit = thread->tproc->onSysExit; diff --git a/rpcsx-os/ops.cpp b/rpcsx-os/ops.cpp index 41889464..4762b7fc 100644 --- a/rpcsx-os/ops.cpp +++ b/rpcsx-os/ops.cpp @@ -734,6 +734,7 @@ SysResult fork(Thread *thread, slong flags) { } auto process = g_context.createProcess(childPid); + process->hostPid = ::getpid(); process->sysent = thread->tproc->sysent; process->onSysEnter = thread->tproc->onSysEnter; process->onSysExit = thread->tproc->onSysExit;