[orbis-kernel] implement sys_wait4 and sys_kill

This commit is contained in:
DH 2023-12-31 18:58:02 +03:00
parent f5c8fce5aa
commit ebe051f6fb
8 changed files with 100 additions and 13 deletions

View file

@ -54,6 +54,7 @@ public:
Process *createProcess(pid_t pid);
void deleteProcess(Process *proc);
Process *findProcessById(pid_t pid) const;
Process *findProcessByHostId(std::uint64_t pid) const;
utils::LinkedNode<Process> *getProcessList() { return m_processes; }

View file

@ -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;

View file

@ -2,8 +2,10 @@
#include "orbis/thread/Process.hpp"
#include "orbis/thread/ProcessOps.hpp"
#include "orbis/utils/Logs.hpp"
#include <chrono>
#include <sys/mman.h>
#include <sys/unistd.h>
#include <thread>
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;

View file

@ -1,7 +1,11 @@
#include "KernelContext.hpp"
#include "sys/sysproto.hpp"
#include "utils/Logs.hpp"
#include <chrono>
#include <sys/wait.h>
#include <thread>
#include <unistd.h>
#include <sys/resource.h>
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<sint> status,
sint options, ptr<struct rusage> 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<ErrorCode>(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 {};
}

View file

@ -29,6 +29,10 @@ orbis::SysResult orbis::sys_read(Thread *thread, sint fd, ptr<void> 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);
}

View file

@ -1,5 +1,7 @@
#include "KernelContext.hpp"
#include "sys/sysproto.hpp"
#include "utils/Logs.hpp"
#include <csignal>
orbis::SysResult orbis::sys_sigaction(Thread *thread, sint sig,
ptr<struct sigaction> act,
@ -67,8 +69,26 @@ orbis::SysResult orbis::sys_sigaltstack(Thread *thread, ptr<struct stack_t> 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<ErrorCode>(errno);
}
return {};
}
orbis::SysResult orbis::sys_pdkill(Thread *thread, sint fd, sint signum) {
return ErrorCode::NOSYS;
}

View file

@ -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;

View file

@ -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;