[orbis-kernel] do not use linker for exec

implement hdd device stub
implement /dev/console rw
remove dup2 hack
fix altstack after execve
This commit is contained in:
DH 2023-11-02 16:26:58 +03:00
parent 3464f50eb9
commit 3cb4baed51
11 changed files with 289 additions and 130 deletions

View file

@ -6,16 +6,12 @@ orbis::SysResult orbis::sys_getdtablesize(Thread *thread) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_dup2(Thread *thread, uint from, uint to) {
if (to == 1 || to == 2) { // HACK: ignore setup /dev/console to stdout/stderr
return {};
}
std::lock_guard lock(thread->tproc->fileDescriptors.mutex);
auto file = thread->tproc->fileDescriptors.get(from);
if (file == nullptr) {
return ErrorCode::BADF;
}
thread->tproc->fileDescriptors.close(to);
thread->tproc->fileDescriptors.insert(to, file);
return {};

View file

@ -60,6 +60,14 @@ orbis::SysResult orbis::sys_mtypeprotect(Thread *thread /* TODO */) {
orbis::SysResult orbis::sys_regmgr_call(Thread *thread, uint32_t op,
uint32_t id, ptr<void> result,
ptr<void> value, uint64_t type) {
ORBIS_LOG_ERROR(__FUNCTION__, op, id, type);
thread->where();
if (op == 2) {
if (id == 0x2010000) {
return uwrite((ptr<uint>)value, 0u);
}
}
if (op == 25) {
struct nonsys_int {
union {

View file

@ -8,8 +8,6 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
size_t newlen) {
enum sysctl_ctl { unspec, kern, vm, vfs, net, debug, hw, machdep, user };
// machdep.tsc_freq
enum sysctl_kern {
usrstack = 33,
kern_14 = 14,
@ -154,11 +152,14 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
auto result = uread(thread->tproc->appInfo, (ptr<AppInfo>)new_);
if (result == ErrorCode{}) {
auto appInfo = thread->tproc->appInfo;
auto &appInfo = thread->tproc->appInfo;
ORBIS_LOG_ERROR("set AppInfo", appInfo.appId, appInfo.unk0,
appInfo.unk1, appInfo.appType, appInfo.titleId,
appInfo.unk2, appInfo.unk3, appInfo.unk5, appInfo.unk6,
appInfo.unk7, appInfo.unk8);
// HACK
appInfo.unk4 = orbis::slong(0x80000000'00000000);
}
return result;

View file

@ -9,6 +9,7 @@ add_executable(rpcsx-os
iodev/camera.cpp
iodev/cd.cpp
iodev/console.cpp
iodev/hdd.cpp
iodev/dce.cpp
iodev/dipsw.cpp
iodev/dmem.cpp

View file

@ -17,7 +17,7 @@ IoDevice *createRngCharacterDevice();
IoDevice *createAjmCharacterDevice();
IoDevice *createIccConfigurationCharacterDevice();
IoDevice *createNpdrmCharacterDevice();
IoDevice *createConsoleCharacterDevice();
IoDevice *createConsoleCharacterDevice(int inputFd, int outputFd);
IoDevice *createSblSrvCharacterDevice();
IoDevice *createShmDevice();
IoDevice *createBlockPoolDevice();
@ -29,3 +29,4 @@ IoDevice *createBtCharacterDevice();
IoDevice *createXptCharacterDevice();
IoDevice *createCdCharacterDevice();
IoDevice *createMetaDbgCharacterDevice();
IoDevice *createHddCharacterDevice();

View file

@ -1,32 +1,78 @@
#include "io-device.hpp"
#include "orbis/KernelAllocator.hpp"
#include "orbis/error/ErrorCode.hpp"
#include "orbis/file.hpp"
#include "orbis/uio.hpp"
#include "orbis/utils/Logs.hpp"
#include <span>
#include <unistd.h>
struct ConsoleFile : orbis::File {};
struct ConsoleDevice : IoDevice {
int inputFd;
int outputFd;
ConsoleDevice(int inputFd, int outputFd)
: inputFd(inputFd), outputFd(outputFd) {}
orbis::ErrorCode open(orbis::Ref<orbis::File> *file, const char *path,
std::uint32_t flags, std::uint32_t mode,
orbis::Thread *thread) override;
};
static orbis::ErrorCode console_ioctl(orbis::File *file, std::uint64_t request,
void *argp, orbis::Thread *thread) {
void *argp, orbis::Thread *thread) {
ORBIS_LOG_FATAL("Unhandled console ioctl", request);
return {};
}
static orbis::ErrorCode console_read(orbis::File *file, orbis::Uio *uio,
orbis::Thread *thread) {
auto dev = dynamic_cast<ConsoleDevice *>(file->device.get());
for (auto vec : std::span(uio->iov, uio->iovcnt)) {
auto result = ::read(dev->inputFd, vec.base, vec.len);
if (result < 0) {
return orbis::ErrorCode::IO;
}
uio->offset += result;
break;
}
return {};
}
static orbis::ErrorCode console_write(orbis::File *file, orbis::Uio *uio,
orbis::Thread *thread) {
auto dev = dynamic_cast<ConsoleDevice *>(file->device.get());
for (auto vec : std::span(uio->iov, uio->iovcnt)) {
::write(dev->outputFd, vec.base, vec.len);
}
uio->resid = 0;
return {};
}
static const orbis::FileOps fileOps = {
.ioctl = console_ioctl,
.read = console_read,
.write = console_write,
};
struct ConsoleDevice : IoDevice {
orbis::ErrorCode open(orbis::Ref<orbis::File> *file, const char *path,
std::uint32_t flags, std::uint32_t mode,
orbis::Thread *thread) override {
auto newFile = orbis::knew<ConsoleFile>();
newFile->ops = &fileOps;
newFile->device = this;
orbis::ErrorCode ConsoleDevice::open(orbis::Ref<orbis::File> *file,
const char *path, std::uint32_t flags,
std::uint32_t mode,
orbis::Thread *thread) {
auto newFile = orbis::knew<ConsoleFile>();
newFile->ops = &fileOps;
newFile->device = this;
*file = newFile;
return {};
}
};
*file = newFile;
return {};
}
IoDevice *createConsoleCharacterDevice() { return orbis::knew<ConsoleDevice>(); }
IoDevice *createConsoleCharacterDevice(int inputFd, int outputFd) {
return orbis::knew<ConsoleDevice>(inputFd, outputFd);
}

70
rpcsx-os/iodev/hdd.cpp Normal file
View file

@ -0,0 +1,70 @@
#include "io-device.hpp"
#include "orbis/KernelAllocator.hpp"
#include "orbis/error/ErrorCode.hpp"
#include "orbis/file.hpp"
#include "orbis/thread/Thread.hpp"
#include "orbis/uio.hpp"
#include "orbis/utils/Logs.hpp"
#include <span>
struct HddFile : orbis::File {};
static orbis::ErrorCode hdd_ioctl(orbis::File *fs, std::uint64_t request,
void *argp, orbis::Thread *thread) {
if (request == 0x40046480) { // DIOCGSECTORSIZE
return orbis::uwrite(orbis::ptr<orbis::uint>(argp), 0x1000u);
}
ORBIS_LOG_FATAL("Unhandled hdd ioctl", request);
thread->where();
return {};
}
static orbis::ErrorCode hdd_read(orbis::File *file, orbis::Uio *uio,
orbis::Thread *thread) {
auto dev = file->device.get();
ORBIS_LOG_ERROR(__FUNCTION__, uio->offset);
for (auto vec : std::span(uio->iov, uio->iovcnt)) {
std::memset(vec.base, 0, vec.len);
// HACK: dummy UFS header
if (uio->offset == 0x10000) {
*(uint32_t *)((char *)vec.base + 0x55c) = 0x19540119;
*(uint64_t *)((char *)vec.base + 0x3e8) = 0x1000;
*(uint8_t *)((char *)vec.base + 0xd3) = 1;
*(uint8_t *)((char *)vec.base + 0xd1) = 1;
}
uio->offset += vec.len;
}
return {};
}
static orbis::ErrorCode hdd_stat(orbis::File *fs, orbis::Stat *sb,
orbis::Thread *thread) {
// TODO
return {};
}
static const orbis::FileOps fsOps = {
.ioctl = hdd_ioctl,
.read = hdd_read,
.stat = hdd_stat,
};
struct HddDevice : IoDevice {
orbis::ErrorCode open(orbis::Ref<orbis::File> *fs, const char *path,
std::uint32_t flags, std::uint32_t mode,
orbis::Thread *thread) override {
auto newFile = orbis::knew<HddFile>();
newFile->ops = &fsOps;
newFile->device = this;
*fs = newFile;
return {};
}
};
IoDevice *createHddCharacterDevice() { return orbis::knew<HddDevice>(); }

View file

@ -13,6 +13,7 @@
#include <atomic>
#include <elf.h>
#include <filesystem>
#include <linux/prctl.h>
#include <orbis/KernelContext.hpp>
#include <orbis/module.hpp>
#include <orbis/module/Module.hpp>
@ -25,6 +26,7 @@
#include <fcntl.h>
#include <pthread.h>
#include <sys/mman.h>
#include <sys/prctl.h>
#include <ucontext.h>
#include <csignal>
@ -160,23 +162,29 @@ handle_signal(int sig, siginfo_t *info, void *ucontext) {
}
void setupSigHandlers() {
auto sigStackSize = std::max<std::size_t>(
SIGSTKSZ, utils::alignUp(8 * 1024 * 1024, sysconf(_SC_PAGE_SIZE)));
stack_t oss{};
stack_t ss{};
ss.ss_sp = malloc(sigStackSize);
if (ss.ss_sp == NULL) {
perror("malloc");
exit(EXIT_FAILURE);
}
// if (sigaltstack(nullptr, &oss) < 0 || oss.ss_size == 0) {
auto sigStackSize = std::max<std::size_t>(
SIGSTKSZ, utils::alignUp(64 * 1024 * 1024, sysconf(_SC_PAGE_SIZE)));
ss.ss_size = sigStackSize;
ss.ss_flags = 1 << 31;
stack_t ss{};
ss.ss_sp = malloc(sigStackSize);
if (ss.ss_sp == NULL) {
perror("malloc");
exit(EXIT_FAILURE);
}
if (sigaltstack(&ss, NULL) == -1) {
perror("sigaltstack");
exit(EXIT_FAILURE);
}
ss.ss_size = sigStackSize;
ss.ss_flags = 1 << 31;
std::fprintf(stderr, "installing sp [%p, %p]\n", ss.ss_sp, (char *)ss.ss_sp + ss.ss_size);
if (sigaltstack(&ss, NULL) == -1) {
perror("sigaltstack");
exit(EXIT_FAILURE);
}
// }
struct sigaction act {};
act.sa_sigaction = handle_signal;
@ -309,24 +317,23 @@ static void ps4InitDev() {
auto dmem1 = createDmemCharacterDevice(1);
orbis::g_context.dmemDevice = dmem1;
auto stdoutDev = createFdWrapDevice(::open("stdout.txt", O_CREAT | O_TRUNC | O_WRONLY, 0666));
auto stderrDev = createFdWrapDevice(::open("stderr.txt", O_CREAT | O_TRUNC | O_WRONLY, 0666));
auto stdinDev = createFdWrapDevice(STDIN_FILENO);
auto consoleDev = createConsoleCharacterDevice(
STDIN_FILENO, ::open("tty.txt", O_CREAT | O_TRUNC | O_WRONLY, 0666));
rx::vfs::addDevice("dmem0", createDmemCharacterDevice(0));
rx::vfs::addDevice("npdrm", createNpdrmCharacterDevice());
rx::vfs::addDevice("icc_configuration",
createIccConfigurationCharacterDevice());
rx::vfs::addDevice("console", createConsoleCharacterDevice());
rx::vfs::addDevice("console", consoleDev);
rx::vfs::addDevice("camera", createCameraCharacterDevice());
rx::vfs::addDevice("dmem1", dmem1);
rx::vfs::addDevice("dmem2", createDmemCharacterDevice(2));
rx::vfs::addDevice("stdout", stdoutDev);
rx::vfs::addDevice("stderr", stderrDev);
rx::vfs::addDevice("deci_stdin", stdinDev);
rx::vfs::addDevice("deci_stdout", stdoutDev);
rx::vfs::addDevice("deci_stderr", stderrDev);
rx::vfs::addDevice("stdin", stdinDev);
rx::vfs::addDevice("stdout", consoleDev);
rx::vfs::addDevice("stderr", consoleDev);
rx::vfs::addDevice("deci_stdin", consoleDev);
rx::vfs::addDevice("deci_stdout", consoleDev);
rx::vfs::addDevice("deci_stderr", consoleDev);
rx::vfs::addDevice("stdin", consoleDev);
rx::vfs::addDevice("zero", createZeroCharacterDevice());
rx::vfs::addDevice("null", createNullCharacterDevice());
rx::vfs::addDevice("dipsw", createDipswCharacterDevice());
@ -346,6 +353,20 @@ static void ps4InitDev() {
rx::vfs::addDevice("bt", createBtCharacterDevice());
rx::vfs::addDevice("xpt0", createXptCharacterDevice());
rx::vfs::addDevice("cd0", createXptCharacterDevice());
rx::vfs::addDevice("da0x0.crypt", createHddCharacterDevice());
rx::vfs::addDevice("da0x1.crypt", createHddCharacterDevice());
rx::vfs::addDevice("da0x2.crypt", createHddCharacterDevice());
rx::vfs::addDevice("da0x3.crypt", createHddCharacterDevice());
rx::vfs::addDevice("da0x4.crypt", createHddCharacterDevice());
rx::vfs::addDevice("da0x5.crypt", createHddCharacterDevice());
// rx::vfs::addDevice("da0x6x0", createHddCharacterDevice()); // boot log
rx::vfs::addDevice("da0x6x2.crypt", createHddCharacterDevice());
rx::vfs::addDevice("da0x8", createHddCharacterDevice());
rx::vfs::addDevice("da0x9.crypt", createHddCharacterDevice());
rx::vfs::addDevice("da0x12.crypt", createHddCharacterDevice());
rx::vfs::addDevice("da0x13.crypt", createHddCharacterDevice());
rx::vfs::addDevice("da0x14.crypt", createHddCharacterDevice());
rx::vfs::addDevice("da0x15", createHddCharacterDevice());
rx::vfs::addDevice("notification0", createNotificationCharacterDevice(0));
rx::vfs::addDevice("notification1", createNotificationCharacterDevice(1));
rx::vfs::addDevice("notification2", createNotificationCharacterDevice(2));
@ -374,7 +395,7 @@ int ps4Exec(orbis::Thread *mainThread,
orbis::utils::Ref<orbis::Module> executableModule,
std::span<std::string> argv, std::span<std::string> envp) {
const auto stackEndAddress = 0x7'ffff'c000ull;
const auto stackSize = 0x40000 * 16;
const auto stackSize = 0x40000 * 32;
auto stackStartAddress = stackEndAddress - stackSize;
mainThread->stackStart =
rx::vm::map(reinterpret_cast<void *>(stackStartAddress), stackSize,
@ -388,33 +409,40 @@ int ps4Exec(orbis::Thread *mainThread,
std::vector<std::uint64_t> argvOffsets;
std::vector<std::uint64_t> envpOffsets;
auto libSceLibcInternal = rx::linker::loadModuleFile(
"/system/common/lib/libSceLibcInternal.sprx", mainThread);
std::uint64_t interpBase = 0;
std::uint64_t entryPoint = executableModule->entryPoint;
if (libSceLibcInternal == nullptr) {
std::fprintf(stderr, "libSceLibcInternal not found\n");
return 1;
if (executableModule->type != rx::linker::kElfTypeExec) {
auto libSceLibcInternal = rx::linker::loadModuleFile(
"/system/common/lib/libSceLibcInternal.sprx", mainThread);
if (libSceLibcInternal == nullptr) {
std::fprintf(stderr, "libSceLibcInternal not found\n");
return 1;
}
libSceLibcInternal->id =
mainThread->tproc->modulesMap.insert(libSceLibcInternal);
auto libkernel = rx::linker::loadModuleFile(
"/system/common/lib/libkernel_sys.sprx", mainThread);
if (libkernel == nullptr) {
std::fprintf(stderr, "libkernel not found\n");
return 1;
}
libkernel->id = mainThread->tproc->modulesMap.insert(libkernel);
interpBase = reinterpret_cast<std::uint64_t>(libkernel->base);
entryPoint = libkernel->entryPoint;
// *reinterpret_cast<std::uint32_t *>(
// reinterpret_cast<std::byte *>(libkernel->base) + 0x6c2e4) = ~0;
// *reinterpret_cast<std::uint32_t *>(
// reinterpret_cast<std::byte *>(libkernel->base) + 0x71300) = ~0;
}
libSceLibcInternal->id =
mainThread->tproc->modulesMap.insert(libSceLibcInternal);
auto libkernel = rx::linker::loadModuleFile(
"/system/common/lib/libkernel_sys.sprx", mainThread);
if (libkernel == nullptr) {
std::fprintf(stderr, "libkernel not found\n");
return 1;
}
libkernel->id = mainThread->tproc->modulesMap.insert(libkernel);
// *reinterpret_cast<std::uint32_t *>(
// reinterpret_cast<std::byte *>(libkernel->base) + 0x6c2e4) = ~0;
// *reinterpret_cast<std::uint32_t *>(
// reinterpret_cast<std::byte *>(libkernel->base) + 0x71300) = ~0;
StackWriter stack{reinterpret_cast<std::uint64_t>(mainThread->stackEnd)};
for (auto &elem : argv) {
@ -432,7 +460,7 @@ int ps4Exec(orbis::Thread *mainThread,
// clang-format off
std::uint64_t auxv[] = {
AT_ENTRY, executableModule->entryPoint,
AT_BASE, reinterpret_cast<std::uint64_t>(libkernel->base),
AT_BASE, interpBase,
AT_NULL, 0
};
// clang-format on
@ -466,8 +494,7 @@ int ps4Exec(orbis::Thread *mainThread,
// FIXME: should be at guest user space
context->uc_mcontext.gregs[REG_RDX] =
reinterpret_cast<std::uint64_t>(+[] { std::printf("At exit\n"); });
;
context->uc_mcontext.gregs[REG_RIP] = libkernel->entryPoint;
context->uc_mcontext.gregs[REG_RIP] = entryPoint;
mainThread->context = context;
rx::thread::invoke(mainThread);
@ -744,6 +771,12 @@ int main(int argc, const char *argv[]) {
initProcess->processParam = executableModule->processParam;
initProcess->processParamSize = executableModule->processParamSize;
if (prctl(PR_SET_SYSCALL_USER_DISPATCH, PR_SYS_DISPATCH_ON,
(void *)0x100'0000'0000, ~0ull - 0x100'0000'0000, nullptr)) {
perror("prctl failed\n");
exit(-1);
}
if (executableModule->type == rx::linker::kElfTypeSceDynExec ||
executableModule->type == rx::linker::kElfTypeSceExec ||
executableModule->type == rx::linker::kElfTypeExec) {

View file

@ -2,6 +2,7 @@
#include "align.hpp"
#include "backtrace.hpp"
#include "io-device.hpp"
#include "io-devices.hpp"
#include "iodev/blockpool.hpp"
#include "iodev/dmem.hpp"
#include "linker.hpp"
@ -28,6 +29,7 @@
#include <map>
#include <optional>
#include <set>
#include <string>
#include <sys/prctl.h>
#include <thread>
#include <unistd.h>
@ -500,25 +502,6 @@ SysResult thr_new(orbis::Thread *thread, orbis::ptr<thr_param> param,
childThread->stackStart);
auto stdthr = std::thread{[=, childThread = Ref<Thread>(childThread)] {
stack_t ss{};
auto sigStackSize = std::max<std::size_t>(
SIGSTKSZ, ::utils::alignUp(8 * 1024 * 1024, sysconf(_SC_PAGE_SIZE)));
ss.ss_sp = malloc(sigStackSize);
if (ss.ss_sp == NULL) {
perror("malloc");
::exit(EXIT_FAILURE);
}
ss.ss_size = sigStackSize;
ss.ss_flags = 1 << 31;
if (sigaltstack(&ss, NULL) == -1) {
perror("sigaltstack");
::exit(EXIT_FAILURE);
}
static_cast<void>(
uwrite(_param.child_tid, slong(childThread->tid))); // TODO: verify
auto context = new ucontext_t{};
@ -534,6 +517,9 @@ SysResult thr_new(orbis::Thread *thread, orbis::ptr<thr_param> param,
childThread->context = context;
childThread->state = orbis::ThreadState::RUNNING;
rx::thread::setupSignalStack();
rx::thread::setupThisThread();
rx::thread::invoke(childThread.get());
}};
@ -632,18 +618,17 @@ SysResult fork(Thread *thread, slong flags) {
ORBIS_LOG_TODO(__FUNCTION__, flags);
auto childPid = g_context.allocatePid() * 10000 + 1;
auto mtx = knew<shared_mutex>();
auto cv = knew<shared_cv>();
mtx->lock();
auto flag = knew<std::atomic<bool>>();
*flag = false;
int hostPid = ::fork();
if (hostPid) {
cv->wait(*mtx);
mtx->unlock();
while (*flag == false) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
kdelete(cv);
kdelete(mtx);
kfree(flag, sizeof(*flag));
thread->retval[0] = childPid;
thread->retval[1] = 0;
@ -674,7 +659,7 @@ SysResult fork(Thread *thread, slong flags) {
rx::vm::fork(thread->tproc->pid);
rx::vfs::fork();
cv->notify_all(*mtx);
*flag = true;
auto [baseId, newThread] = process->threadsMap.emplace();
newThread->tproc = process;
@ -691,33 +676,14 @@ SysResult fork(Thread *thread, slong flags) {
setupSigHandlers();
rx::thread::initialize();
rx::thread::setupThisThread();
if (prctl(PR_SET_SYSCALL_USER_DISPATCH, PR_SYS_DISPATCH_ON,
(void *)0x100'0000'0000, ~0ull - 0x100'0000'0000, nullptr)) {
perror("prctl failed\n");
std::exit(-1);
}
auto stdoutFd =
::open(("stdout-" + std::to_string(thread->tproc->pid) + ".txt").c_str(),
O_CREAT | O_TRUNC | O_WRONLY, 0666);
auto stderrFd =
::open(("stderr-" + std::to_string(thread->tproc->pid) + ".txt").c_str(),
O_CREAT | O_TRUNC | O_WRONLY, 0666);
auto logFd =
::open(("log-" + std::to_string(thread->tproc->pid) + ".txt").c_str(),
O_CREAT | O_TRUNC | O_WRONLY, 0666);
dup2(logFd, 1);
dup2(logFd, 2);
auto stdoutDev = createFdWrapDevice(stdoutFd);
auto stderrDev = createFdWrapDevice(stderrFd);
rx::vfs::addDevice("stdout", stdoutDev);
rx::vfs::addDevice("stderr", stderrDev);
rx::vfs::addDevice("deci_stdout", stdoutDev);
rx::vfs::addDevice("deci_stderr", stderrDev);
return {};
}
@ -768,7 +734,18 @@ SysResult execve(Thread *thread, ptr<char> fname, ptr<ptr<char>> argv,
thread->tproc->processParam = executableModule->processParam;
thread->tproc->processParamSize = executableModule->processParamSize;
ps4Exec(thread, executableModule, _argv, _envv);
auto name = path;
if (auto slashP = name.rfind('/'); slashP != std::string::npos) {
name = name.substr(slashP + 1);
}
pthread_setname_np(pthread_self(), name.c_str());
std::thread([&] {
rx::thread::setupSignalStack();
rx::thread::setupThisThread();
ps4Exec(thread, executableModule, _argv, _envv);
}).join();
std::abort();
}

View file

@ -1,4 +1,5 @@
#include "thread.hpp"
#include "align.hpp"
#include "orbis/sys/sysentry.hpp"
#include "orbis/thread/Process.hpp"
#include "orbis/thread/Thread.hpp"
@ -61,25 +62,48 @@ void rx::thread::initialize() {
void rx::thread::deinitialize() {}
void rx::thread::invoke(orbis::Thread *thread) {
orbis::g_currentThread = thread;
void rx::thread::setupSignalStack() {
stack_t ss{};
auto sigStackSize = std::max<std::size_t>(
SIGSTKSZ, ::utils::alignUp(64 * 1024 * 1024, sysconf(_SC_PAGE_SIZE)));
ss.ss_sp = malloc(sigStackSize);
if (ss.ss_sp == NULL) {
perror("malloc");
std::exit(EXIT_FAILURE);
}
ss.ss_size = sigStackSize;
ss.ss_flags = 1 << 31;
if (sigaltstack(&ss, NULL) == -1) {
perror("sigaltstack");
std::exit(EXIT_FAILURE);
}
}
void rx::thread::setupThisThread() {
sigset_t unblockSigs{};
sigset_t oldSigmask{};
sigaddset(&unblockSigs, SIGSYS);
if (pthread_sigmask(SIG_UNBLOCK, &unblockSigs, &oldSigmask)) {
perror("pthread_sigmask failed\n");
exit(-1);
std::exit(-1);
}
std::uint64_t hostFs = _readfsbase_u64();
_writegsbase_u64(hostFs);
if (prctl(PR_SET_SYSCALL_USER_DISPATCH, PR_SYS_DISPATCH_ON,
(void *)0x100'0000'0000, ~0ull - 0x100'0000'0000, nullptr)) {
perror("prctl failed\n");
exit(-1);
std::exit(-1);
}
}
void rx::thread::invoke(orbis::Thread *thread) {
orbis::g_currentThread = thread;
std::uint64_t hostFs = _readfsbase_u64();
_writegsbase_u64(hostFs);
_writefsbase_u64(thread->fsBase);
auto context = reinterpret_cast<ucontext_t *>(thread->context);

View file

@ -5,6 +5,8 @@
namespace rx::thread {
void initialize();
void deinitialize();
void setupSignalStack();
void setupThisThread();
void invoke(orbis::Thread *thread);
} // namespace rx::thread