mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-01-10 18:50:03 +01:00
[orbis-kernel] Initial rfork implementation
This commit is contained in:
parent
058c746ac1
commit
e9897441fe
|
|
@ -659,7 +659,7 @@ SysResult sys_opmc_get_ctr(Thread *thread /* TODO */);
|
|||
SysResult sys_budget_create(Thread *thread /* TODO */);
|
||||
SysResult sys_budget_delete(Thread *thread /* TODO */);
|
||||
SysResult sys_budget_get(Thread *thread /* TODO */);
|
||||
SysResult sys_budget_set(Thread *thread /* TODO */);
|
||||
SysResult sys_budget_set(Thread *thread, slong budget);
|
||||
SysResult sys_virtual_query(Thread *thread, ptr<void> addr, uint64_t unk,
|
||||
ptr<void> info, size_t infosz);
|
||||
SysResult sys_mdbg_call(Thread *thread /* TODO */);
|
||||
|
|
|
|||
|
|
@ -39,4 +39,6 @@ struct Thread {
|
|||
void incRef() {}
|
||||
void decRef() {}
|
||||
};
|
||||
|
||||
extern thread_local Thread *g_currentThread;
|
||||
} // namespace orbis
|
||||
|
|
|
|||
|
|
@ -33,6 +33,16 @@ class RcIdMap {
|
|||
}
|
||||
}
|
||||
|
||||
bool insert(std::size_t index, T *object) {
|
||||
if (mask.test(index)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mask.set(index);
|
||||
objects[index] = object;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::size_t insert(T *object) {
|
||||
std::size_t index = mask.countr_one();
|
||||
mask.set(index);
|
||||
|
|
@ -117,6 +127,28 @@ public:
|
|||
end_iterator end() const { return {}; }
|
||||
|
||||
private:
|
||||
bool insert_impl(IdT id, T *object) {
|
||||
std::lock_guard lock(mutex);
|
||||
|
||||
auto raw = static_cast<std::size_t>(id);
|
||||
auto page = (raw - MinId) / ChunkSize;
|
||||
auto index = (raw - MinId) % ChunkSize;
|
||||
|
||||
if (page >= ChunkCount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_chunks[page].insert(index, object)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_chunks[page].mask.full()) {
|
||||
m_fullChunks.set(page);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
IdT insert_impl(T *object) {
|
||||
std::lock_guard lock(mutex);
|
||||
|
||||
|
|
@ -159,7 +191,29 @@ public:
|
|||
return result;
|
||||
}
|
||||
|
||||
T *get(IdT id) {
|
||||
bool insert(IdT id, T *object) {
|
||||
if (insert_impl(id, object)) {
|
||||
object->incRef();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool insert(IdT id, const Ref<T> &ref) { return insert(id, ref.get()); }
|
||||
|
||||
bool insert(IdT id, Ref<T> &&ref) {
|
||||
auto object = ref.release();
|
||||
|
||||
if (!insert_impl(id, object)) {
|
||||
object->decRef();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Ref<T> get(IdT id) {
|
||||
const auto rawId = static_cast<std::size_t>(id) - MinId;
|
||||
|
||||
if (rawId >= MaxId - MinId) {
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@
|
|||
#include <sys/unistd.h>
|
||||
|
||||
namespace orbis {
|
||||
thread_local Thread *g_currentThread;
|
||||
|
||||
KernelContext &g_context = *[]() -> KernelContext * {
|
||||
// Allocate global shared kernel memory
|
||||
// TODO: randomize for hardening and reduce size
|
||||
auto ptr = mmap(reinterpret_cast<void *>(0x200'0000'0000), 0x1'0000'0000,
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
|
||||
if (!ptr)
|
||||
std::abort();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,52 @@
|
|||
#include "KernelContext.hpp"
|
||||
#include "sys/sysproto.hpp"
|
||||
#include "utils/Logs.hpp"
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
|
||||
orbis::SysResult orbis::sys_fork(Thread *thread) { return ErrorCode::NOSYS; }
|
||||
orbis::SysResult orbis::sys_pdfork(Thread *thread, ptr<sint> fdp, sint flags) {
|
||||
return ErrorCode::NOSYS;
|
||||
}
|
||||
|
||||
orbis::SysResult orbis::sys_vfork(Thread *thread) { return ErrorCode::NOSYS; }
|
||||
orbis::SysResult orbis::sys_rfork(Thread *thread, sint flags) {
|
||||
return ErrorCode::NOSYS;
|
||||
ORBIS_LOG_TODO(__FUNCTION__, flags);
|
||||
|
||||
int hostPid = ::fork();
|
||||
if (hostPid) {
|
||||
thread->retval[0] = 10001;
|
||||
thread->retval[1] = 0;
|
||||
} else {
|
||||
auto process = g_context.createProcess(10001);
|
||||
std::lock_guard lock(thread->tproc->fileDescriptors.mutex);
|
||||
process->sysent = thread->tproc->sysent;
|
||||
process->onSysEnter = thread->tproc->onSysEnter;
|
||||
process->onSysExit = thread->tproc->onSysExit;
|
||||
process->ops = thread->tproc->ops;
|
||||
process->isSystem = thread->tproc->isSystem;
|
||||
for (auto [id, mod] : thread->tproc->modulesMap) {
|
||||
if (!process->modulesMap.insert(id, mod)) {
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
|
||||
for (auto [id, mod] : thread->tproc->fileDescriptors) {
|
||||
if (!process->fileDescriptors.insert(id, mod)) {
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
|
||||
auto [baseId, newThread] = process->threadsMap.emplace();
|
||||
newThread->tproc = process;
|
||||
newThread->tid = process->pid + baseId;
|
||||
newThread->state = orbis::ThreadState::RUNNING;
|
||||
newThread->context = thread->context;
|
||||
newThread->fsBase = thread->fsBase;
|
||||
|
||||
orbis::g_currentThread = newThread;
|
||||
newThread->retval[0] = 0;
|
||||
newThread->retval[1] = 1;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ orbis::SysResult orbis::sys_socketclose(Thread *thread, sint fd) {
|
|||
return ErrorCode::BADF;
|
||||
}
|
||||
orbis::SysResult orbis::sys_netgetiflist(Thread *thread /* TODO */) {
|
||||
return ErrorCode::NOSYS;
|
||||
return {};
|
||||
}
|
||||
|
||||
orbis::SysResult orbis::sys_mtypeprotect(Thread *thread /* TODO */) {
|
||||
|
|
@ -215,8 +215,9 @@ orbis::SysResult orbis::sys_evf_open(Thread *thread, ptr<const char[32]> name) {
|
|||
return sys_evf_create(thread, name, kEvfAttrShared, 0x400000);
|
||||
}
|
||||
|
||||
if (std::string_view("SceShellCoreUtilAppFocus") == _name) {
|
||||
return sys_evf_create(thread, name, kEvfAttrShared, 1);
|
||||
if (std::string_view("SceShellCoreUtilAppFocus") == _name ||
|
||||
std::string_view("SceBootStatusFlags") == _name) {
|
||||
return sys_evf_create(thread, name, kEvfAttrShared, 0x2408);
|
||||
}
|
||||
return sys_evf_create(thread, name, kEvfAttrShared, 0);
|
||||
return ErrorCode::SRCH;
|
||||
|
|
@ -290,7 +291,7 @@ orbis::SysResult orbis::sys_evf_trywait(Thread *thread, sint id,
|
|||
|
||||
auto result = evf->tryWait(thread, mode, patternSet);
|
||||
ORBIS_LOG_TRACE(__FUNCTION__, evf->name, thread->tid, id, patternSet, mode,
|
||||
pPatternSet, result);
|
||||
pPatternSet, result);
|
||||
|
||||
if (pPatternSet != nullptr) {
|
||||
uwrite(pPatternSet, thread->evfResultPattern);
|
||||
|
|
@ -332,7 +333,7 @@ orbis::SysResult orbis::sys_evf_cancel(Thread *thread, sint id, uint64_t value,
|
|||
}
|
||||
|
||||
ORBIS_LOG_TRACE(__FUNCTION__, evf->name, thread->tid, id, value,
|
||||
pNumWaitThreads);
|
||||
pNumWaitThreads);
|
||||
|
||||
auto numWaitThreads = evf->cancel(value);
|
||||
if (pNumWaitThreads != 0) {
|
||||
|
|
@ -403,7 +404,7 @@ orbis::SysResult orbis::sys_osem_create(Thread *thread,
|
|||
return {};
|
||||
}
|
||||
orbis::SysResult orbis::sys_osem_delete(Thread *thread, sint id) {
|
||||
ORBIS_LOG_WARNING(__FUNCTION__, id);
|
||||
ORBIS_LOG_TRACE(__FUNCTION__, id);
|
||||
Ref<Semaphore> sem = thread->tproc->semMap.get(id);
|
||||
if (sem == nullptr) {
|
||||
return ErrorCode::SRCH;
|
||||
|
|
@ -444,7 +445,7 @@ orbis::SysResult orbis::sys_osem_open(Thread *thread,
|
|||
return {};
|
||||
}
|
||||
orbis::SysResult orbis::sys_osem_close(Thread *thread, sint id) {
|
||||
ORBIS_LOG_WARNING(__FUNCTION__, id);
|
||||
ORBIS_LOG_TRACE(__FUNCTION__, id);
|
||||
if (!thread->tproc->semMap.close(id)) {
|
||||
return ErrorCode::SRCH;
|
||||
}
|
||||
|
|
@ -473,7 +474,7 @@ orbis::SysResult orbis::sys_osem_wait(Thread *thread, sint id, sint need,
|
|||
return {};
|
||||
}
|
||||
orbis::SysResult orbis::sys_osem_trywait(Thread *thread, sint id, sint need) {
|
||||
ORBIS_LOG_NOTICE(__FUNCTION__, thread, id, need);
|
||||
ORBIS_LOG_TRACE(__FUNCTION__, thread, id, need);
|
||||
Ref<Semaphore> sem = thread->tproc->semMap.get(id);
|
||||
if (need < 1 || need > sem->maxValue)
|
||||
return ErrorCode::INVAL;
|
||||
|
|
@ -485,7 +486,7 @@ orbis::SysResult orbis::sys_osem_trywait(Thread *thread, sint id, sint need) {
|
|||
return {};
|
||||
}
|
||||
orbis::SysResult orbis::sys_osem_post(Thread *thread, sint id, sint count) {
|
||||
ORBIS_LOG_NOTICE(__FUNCTION__, thread, id, count);
|
||||
ORBIS_LOG_WARNING(__FUNCTION__, thread, id, count);
|
||||
Ref<Semaphore> sem = thread->tproc->semMap.get(id);
|
||||
if (count < 1 || count > sem->maxValue - sem->value)
|
||||
return ErrorCode::INVAL;
|
||||
|
|
@ -500,6 +501,7 @@ orbis::SysResult orbis::sys_osem_post(Thread *thread, sint id, sint count) {
|
|||
orbis::SysResult orbis::sys_osem_cancel(Thread *thread, sint id, sint set,
|
||||
ptr<uint> pNumWaitThreads) {
|
||||
ORBIS_LOG_TODO(__FUNCTION__, thread, id, set, pNumWaitThreads);
|
||||
std::abort();
|
||||
return ErrorCode::NOSYS;
|
||||
}
|
||||
orbis::SysResult orbis::sys_namedobj_create(Thread *thread,
|
||||
|
|
@ -589,8 +591,9 @@ orbis::SysResult orbis::sys_budget_delete(Thread *thread /* TODO */) {
|
|||
orbis::SysResult orbis::sys_budget_get(Thread *thread /* TODO */) {
|
||||
return ErrorCode::NOSYS;
|
||||
}
|
||||
orbis::SysResult orbis::sys_budget_set(Thread *thread /* TODO */) {
|
||||
return ErrorCode::NOSYS;
|
||||
orbis::SysResult orbis::sys_budget_set(Thread *thread, slong budget) {
|
||||
ORBIS_LOG_TODO(__FUNCTION__, budget);
|
||||
return {};
|
||||
}
|
||||
orbis::SysResult orbis::sys_virtual_query(Thread *thread, ptr<void> addr,
|
||||
uint64_t unk, ptr<void> info,
|
||||
|
|
@ -601,9 +604,7 @@ orbis::SysResult orbis::sys_virtual_query(Thread *thread, ptr<void> addr,
|
|||
|
||||
return ErrorCode::NOSYS;
|
||||
}
|
||||
orbis::SysResult orbis::sys_mdbg_call(Thread *thread /* TODO */) {
|
||||
return ErrorCode::NOSYS;
|
||||
}
|
||||
orbis::SysResult orbis::sys_mdbg_call(Thread *thread /* TODO */) { return {}; }
|
||||
orbis::SysResult orbis::sys_obs_sblock_create(Thread *thread /* TODO */) {
|
||||
return ErrorCode::NOSYS;
|
||||
}
|
||||
|
|
@ -942,7 +943,8 @@ orbis::sys_dynlib_get_info_ex(Thread *thread, SceKernelModule handle,
|
|||
return uwrite(destModuleInfoEx, result);
|
||||
}
|
||||
orbis::SysResult orbis::sys_budget_getid(Thread *thread) {
|
||||
return ErrorCode::NOSYS;
|
||||
thread->retval[0] = 1;
|
||||
return {};
|
||||
}
|
||||
orbis::SysResult orbis::sys_budget_get_ptype(Thread *thread, sint budgetId) {
|
||||
thread->retval[0] = 1;
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ void orbis::syscall_entry(Thread *thread) {
|
|||
|
||||
auto result = sysent.call(thread, args);
|
||||
|
||||
thread = orbis::g_currentThread;
|
||||
|
||||
if (thread->tproc->onSysExit != nullptr) {
|
||||
thread->tproc->onSysExit(thread, syscall_num, args, sysent.narg,
|
||||
result);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@ add_library(orbis::kernel::config ALIAS standalone-config)
|
|||
add_executable(rpcsx-os
|
||||
iodev/ajm.cpp
|
||||
iodev/blockpool.cpp
|
||||
iodev/bt.cpp
|
||||
iodev/camera.cpp
|
||||
iodev/cd.cpp
|
||||
iodev/console.cpp
|
||||
iodev/dce.cpp
|
||||
iodev/dipsw.cpp
|
||||
|
|
@ -25,6 +27,7 @@ add_executable(rpcsx-os
|
|||
iodev/sbl_srv.cpp
|
||||
iodev/shm.cpp
|
||||
iodev/urandom.cpp
|
||||
iodev/xpt.cpp
|
||||
iodev/zero.cpp
|
||||
|
||||
main.cpp
|
||||
|
|
|
|||
|
|
@ -25,3 +25,6 @@ IoDevice *createUrandomCharacterDevice();
|
|||
IoDevice *createCameraCharacterDevice();
|
||||
IoDevice *createNotificationCharacterDevice(int index);
|
||||
IoDevice *createMBusCharacterDevice();
|
||||
IoDevice *createBtCharacterDevice();
|
||||
IoDevice *createXptCharacterDevice();
|
||||
IoDevice *createCdCharacterDevice();
|
||||
|
|
|
|||
32
rpcsx-os/iodev/bt.cpp
Normal file
32
rpcsx-os/iodev/bt.cpp
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#include "io-device.hpp"
|
||||
#include "orbis/KernelAllocator.hpp"
|
||||
#include "orbis/file.hpp"
|
||||
#include "orbis/utils/Logs.hpp"
|
||||
|
||||
struct BtFile : orbis::File {};
|
||||
|
||||
static orbis::ErrorCode bt_ioctl(orbis::File *file, std::uint64_t request,
|
||||
void *argp, orbis::Thread *thread) {
|
||||
|
||||
ORBIS_LOG_FATAL("Unhandled bt ioctl", request);
|
||||
return {};
|
||||
}
|
||||
|
||||
static const orbis::FileOps fileOps = {
|
||||
.ioctl = bt_ioctl,
|
||||
};
|
||||
|
||||
struct BtDevice : 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<BtFile>();
|
||||
newFile->ops = &fileOps;
|
||||
newFile->device = this;
|
||||
|
||||
*file = newFile;
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
IoDevice *createBtCharacterDevice() { return orbis::knew<BtDevice>(); }
|
||||
32
rpcsx-os/iodev/cd.cpp
Normal file
32
rpcsx-os/iodev/cd.cpp
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#include "io-device.hpp"
|
||||
#include "orbis/KernelAllocator.hpp"
|
||||
#include "orbis/file.hpp"
|
||||
#include "orbis/utils/Logs.hpp"
|
||||
|
||||
struct CdFile : orbis::File {};
|
||||
|
||||
static orbis::ErrorCode cd_ioctl(orbis::File *file, std::uint64_t request,
|
||||
void *argp, orbis::Thread *thread) {
|
||||
|
||||
ORBIS_LOG_FATAL("Unhandled cd ioctl", request);
|
||||
return {};
|
||||
}
|
||||
|
||||
static const orbis::FileOps fileOps = {
|
||||
.ioctl = cd_ioctl,
|
||||
};
|
||||
|
||||
struct CdDevice : 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<CdFile>();
|
||||
newFile->ops = &fileOps;
|
||||
newFile->device = this;
|
||||
|
||||
*file = newFile;
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
IoDevice *createCdCharacterDevice() { return orbis::knew<CdDevice>(); }
|
||||
|
|
@ -2,6 +2,8 @@
|
|||
#include "orbis/KernelAllocator.hpp"
|
||||
#include "orbis/file.hpp"
|
||||
#include "orbis/utils/Logs.hpp"
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
struct NotificationFile : orbis::File {};
|
||||
struct NotificationDevice : IoDevice {
|
||||
|
|
@ -20,8 +22,15 @@ static orbis::ErrorCode notification_ioctl(orbis::File *file, std::uint64_t requ
|
|||
return {};
|
||||
}
|
||||
|
||||
static orbis::ErrorCode notification_read(orbis::File *file, orbis::Uio *uio, orbis::Thread *thread) {
|
||||
ORBIS_LOG_FATAL("Unhandled notification_read");
|
||||
std::this_thread::sleep_for(std::chrono::hours(120));
|
||||
return {};
|
||||
}
|
||||
|
||||
static const orbis::FileOps fileOps = {
|
||||
.ioctl = notification_ioctl,
|
||||
.read = notification_read,
|
||||
};
|
||||
|
||||
orbis::ErrorCode NotificationDevice::open(orbis::Ref<orbis::File> *file, const char *path,
|
||||
|
|
|
|||
38
rpcsx-os/iodev/xpt.cpp
Normal file
38
rpcsx-os/iodev/xpt.cpp
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#include "io-device.hpp"
|
||||
#include "orbis/KernelAllocator.hpp"
|
||||
#include "orbis/file.hpp"
|
||||
#include "orbis/utils/Logs.hpp"
|
||||
#include "orbis/thread/Thread.hpp"
|
||||
#include <thread>
|
||||
|
||||
struct XptFile : orbis::File {};
|
||||
|
||||
static orbis::ErrorCode xpt_ioctl(orbis::File *file, std::uint64_t request,
|
||||
void *argp, orbis::Thread *thread) {
|
||||
|
||||
ORBIS_LOG_FATAL("Unhandled xpt ioctl", request);
|
||||
if (request == 0xc4a81602) {
|
||||
thread->where();
|
||||
std::this_thread::sleep_for(std::chrono::hours(120));
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
static const orbis::FileOps fileOps = {
|
||||
.ioctl = xpt_ioctl,
|
||||
};
|
||||
|
||||
struct XptDevice : 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<XptFile>();
|
||||
newFile->ops = &fileOps;
|
||||
newFile->device = this;
|
||||
|
||||
*file = newFile;
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
IoDevice *createXptCharacterDevice() { return orbis::knew<XptDevice>(); }
|
||||
|
|
@ -41,7 +41,7 @@ handle_signal(int sig, siginfo_t *info, void *ucontext) {
|
|||
|
||||
auto signalAddress = reinterpret_cast<std::uintptr_t>(info->si_addr);
|
||||
|
||||
if (rx::thread::g_current != nullptr && sig == SIGSEGV &&
|
||||
if (orbis::g_currentThread != nullptr && sig == SIGSEGV &&
|
||||
signalAddress >= 0x40000 && signalAddress < 0x100'0000'0000) {
|
||||
auto ctx = reinterpret_cast<ucontext_t *>(ucontext);
|
||||
bool isWrite = (ctx->uc_mcontext.gregs[REG_ERR] & 0x2) != 0;
|
||||
|
|
@ -103,7 +103,7 @@ handle_signal(int sig, siginfo_t *info, void *ucontext) {
|
|||
std::abort();
|
||||
}
|
||||
|
||||
_writefsbase_u64(rx::thread::g_current->fsBase);
|
||||
_writefsbase_u64(orbis::g_currentThread->fsBase);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -120,22 +120,22 @@ handle_signal(int sig, siginfo_t *info, void *ucontext) {
|
|||
if (sig != SIGINT) {
|
||||
char buf[128] = "";
|
||||
int len = snprintf(buf, sizeof(buf), " [%s] %u: Signal address=%p\n",
|
||||
rx::thread::g_current ? "guest" : "host",
|
||||
rx::thread::g_current ? rx::thread::g_current->tid
|
||||
: ::gettid(),
|
||||
orbis::g_currentThread ? "guest" : "host",
|
||||
orbis::g_currentThread ? orbis::g_currentThread->tid
|
||||
: ::gettid(),
|
||||
info->si_addr);
|
||||
write(2, buf, len);
|
||||
|
||||
if (std::size_t printed =
|
||||
rx::printAddressLocation(buf, sizeof(buf), rx::thread::g_current,
|
||||
rx::printAddressLocation(buf, sizeof(buf), orbis::g_currentThread,
|
||||
(std::uint64_t)info->si_addr)) {
|
||||
printed += std::snprintf(buf + printed, sizeof(buf) - printed, "\n");
|
||||
write(2, buf, printed);
|
||||
}
|
||||
|
||||
if (rx::thread::g_current) {
|
||||
if (orbis::g_currentThread) {
|
||||
rx::printStackTrace(reinterpret_cast<ucontext_t *>(ucontext),
|
||||
rx::thread::g_current, 2);
|
||||
orbis::g_currentThread, 2);
|
||||
} else {
|
||||
rx::printStackTrace(reinterpret_cast<ucontext_t *>(ucontext), 2);
|
||||
}
|
||||
|
|
@ -159,10 +159,11 @@ handle_signal(int sig, siginfo_t *info, void *ucontext) {
|
|||
}
|
||||
}
|
||||
|
||||
static void setupSigHandlers() {
|
||||
stack_t ss;
|
||||
void setupSigHandlers() {
|
||||
auto sigStackSize = std::max<std::size_t>(
|
||||
SIGSTKSZ, utils::alignUp(8 * 1024 * 1024, sysconf(_SC_PAGE_SIZE)));
|
||||
|
||||
stack_t ss{};
|
||||
ss.ss_sp = malloc(sigStackSize);
|
||||
if (ss.ss_sp == NULL) {
|
||||
perror("malloc");
|
||||
|
|
@ -170,7 +171,7 @@ static void setupSigHandlers() {
|
|||
}
|
||||
|
||||
ss.ss_size = sigStackSize;
|
||||
ss.ss_flags = 0;
|
||||
ss.ss_flags = 1 << 31;
|
||||
|
||||
if (sigaltstack(&ss, NULL) == -1) {
|
||||
perror("sigaltstack");
|
||||
|
|
@ -250,7 +251,7 @@ static const char *getSyscallName(orbis::Thread *thread, int sysno) {
|
|||
}
|
||||
static void onSysEnter(orbis::Thread *thread, int id, uint64_t *args,
|
||||
int argsCount) {
|
||||
if (!g_traceSyscalls) {
|
||||
if (!g_traceSyscalls && thread->tid < 10000) {
|
||||
return;
|
||||
}
|
||||
flockfile(stderr);
|
||||
|
|
@ -276,7 +277,7 @@ static void onSysEnter(orbis::Thread *thread, int id, uint64_t *args,
|
|||
|
||||
static void onSysExit(orbis::Thread *thread, int id, uint64_t *args,
|
||||
int argsCount, orbis::SysResult result) {
|
||||
if (!result.isError() && !g_traceSyscalls) {
|
||||
if (!result.isError() && !g_traceSyscalls && thread->tid < 10000) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -327,7 +328,8 @@ static int ps4Exec(orbis::Thread *mainThread,
|
|||
|
||||
rx::vfs::addDevice("dmem0", createDmemCharacterDevice(0));
|
||||
rx::vfs::addDevice("npdrm", createNpdrmCharacterDevice());
|
||||
rx::vfs::addDevice("icc_configuration", createIccConfigurationCharacterDevice());
|
||||
rx::vfs::addDevice("icc_configuration",
|
||||
createIccConfigurationCharacterDevice());
|
||||
rx::vfs::addDevice("console", createConsoleCharacterDevice());
|
||||
rx::vfs::addDevice("camera", createCameraCharacterDevice());
|
||||
rx::vfs::addDevice("dmem1", dmem1);
|
||||
|
|
@ -353,6 +355,9 @@ static int ps4Exec(orbis::Thread *mainThread,
|
|||
rx::vfs::addDevice("ajm", createAjmCharacterDevice());
|
||||
rx::vfs::addDevice("urandom", createUrandomCharacterDevice());
|
||||
rx::vfs::addDevice("mbus", createMBusCharacterDevice());
|
||||
rx::vfs::addDevice("bt", createBtCharacterDevice());
|
||||
rx::vfs::addDevice("xpt0", createXptCharacterDevice());
|
||||
rx::vfs::addDevice("cd0", createXptCharacterDevice());
|
||||
rx::vfs::addDevice("notification0", createNotificationCharacterDevice(0));
|
||||
rx::vfs::addDevice("notification1", createNotificationCharacterDevice(1));
|
||||
rx::vfs::addDevice("notification2", createNotificationCharacterDevice(2));
|
||||
|
|
@ -385,7 +390,8 @@ static int ps4Exec(orbis::Thread *mainThread,
|
|||
return 1;
|
||||
}
|
||||
|
||||
libSceLibcInternal->id = mainThread->tproc->modulesMap.insert(libSceLibcInternal);
|
||||
libSceLibcInternal->id =
|
||||
mainThread->tproc->modulesMap.insert(libSceLibcInternal);
|
||||
|
||||
auto libkernel = rx::linker::loadModuleFile(
|
||||
"/system/common/lib/libkernel_sys.sprx", mainThread);
|
||||
|
|
@ -403,7 +409,6 @@ static int ps4Exec(orbis::Thread *mainThread,
|
|||
// *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) {
|
||||
|
|
|
|||
|
|
@ -167,7 +167,8 @@ orbis::SysResult mmap(orbis::Thread *thread, orbis::caddr_t addr,
|
|||
}
|
||||
|
||||
void *maddr = addr;
|
||||
auto result = file->ops->mmap(file, &maddr, len, prot, flags, pos, thread);
|
||||
auto result =
|
||||
file->ops->mmap(file.get(), &maddr, len, prot, flags, pos, thread);
|
||||
|
||||
if (result != ErrorCode{}) {
|
||||
return result;
|
||||
|
|
@ -282,7 +283,8 @@ orbis::SysResult rmdir(Thread *thread, ptr<const char> path) {
|
|||
ORBIS_LOG_TODO(__FUNCTION__, path);
|
||||
return rx::vfs::rmdir(path, thread);
|
||||
}
|
||||
orbis::SysResult rename(Thread *thread, ptr<const char> from, ptr<const char> to) {
|
||||
orbis::SysResult rename(Thread *thread, ptr<const char> from,
|
||||
ptr<const char> to) {
|
||||
ORBIS_LOG_TODO(__FUNCTION__, from, to);
|
||||
return rx::vfs::rename(from, to, thread);
|
||||
}
|
||||
|
|
@ -317,7 +319,7 @@ orbis::SysResult blockpool_unmap(orbis::Thread *thread, orbis::caddr_t addr,
|
|||
orbis::SysResult socket(orbis::Thread *thread, orbis::ptr<const char> name,
|
||||
orbis::sint domain, orbis::sint type,
|
||||
orbis::sint protocol, Ref<File> *file) {
|
||||
return createSocket(file, name, domain, type, protocol);
|
||||
return createSocket(file, name ? name : "", domain, type, protocol);
|
||||
}
|
||||
|
||||
orbis::SysResult shm_unlink(orbis::Thread *thread, const char *path) {
|
||||
|
|
@ -376,7 +378,7 @@ orbis::SysResult dynlib_dlsym(orbis::Thread *thread, orbis::ModuleHandle handle,
|
|||
std::string_view symView(symbol);
|
||||
|
||||
if (auto nid = rx::linker::decodeNid(symView)) {
|
||||
if (auto addr = findSymbolById(module, *nid)) {
|
||||
if (auto addr = findSymbolById(module.get(), *nid)) {
|
||||
*addrp = addr;
|
||||
return {};
|
||||
}
|
||||
|
|
@ -386,7 +388,8 @@ orbis::SysResult dynlib_dlsym(orbis::Thread *thread, orbis::ModuleHandle handle,
|
|||
module->moduleName,
|
||||
rx::linker::encodeNid(rx::linker::encodeFid(symView)).string);
|
||||
|
||||
if (auto addr = findSymbolById(module, rx::linker::encodeFid(symView))) {
|
||||
if (auto addr =
|
||||
findSymbolById(module.get(), rx::linker::encodeFid(symView))) {
|
||||
*addrp = addr;
|
||||
return {};
|
||||
}
|
||||
|
|
@ -486,7 +489,7 @@ SysResult thr_new(orbis::Thread *thread, orbis::ptr<thr_param> param,
|
|||
childThread->stackStart);
|
||||
|
||||
auto stdthr = std::thread{[=, childThread = Ref<Thread>(childThread)] {
|
||||
stack_t ss;
|
||||
stack_t ss{};
|
||||
|
||||
auto sigStackSize = std::max<std::size_t>(
|
||||
SIGSTKSZ, ::utils::alignUp(8 * 1024 * 1024, sysconf(_SC_PAGE_SIZE)));
|
||||
|
|
@ -498,7 +501,7 @@ SysResult thr_new(orbis::Thread *thread, orbis::ptr<thr_param> param,
|
|||
}
|
||||
|
||||
ss.ss_size = sigStackSize;
|
||||
ss.ss_flags = 0;
|
||||
ss.ss_flags = 1 << 31;
|
||||
|
||||
if (sigaltstack(&ss, NULL) == -1) {
|
||||
perror("sigaltstack");
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "thread.hpp"
|
||||
#include "backtrace.hpp"
|
||||
#include "orbis/sys/sysentry.hpp"
|
||||
#include "orbis/thread/Thread.hpp"
|
||||
#include <asm/prctl.h>
|
||||
#include <csignal>
|
||||
#include <immintrin.h>
|
||||
|
|
@ -12,8 +13,6 @@
|
|||
#include <unistd.h>
|
||||
#include <xbyak/xbyak.h>
|
||||
|
||||
thread_local orbis::Thread *rx::thread::g_current = nullptr;
|
||||
|
||||
static auto setContext = [] {
|
||||
struct SetContext : Xbyak::CodeGenerator {
|
||||
SetContext() {
|
||||
|
|
@ -34,6 +33,8 @@ static auto setContext = [] {
|
|||
return setContextStorage.getCode<void (*)(const mcontext_t &)>();
|
||||
}();
|
||||
|
||||
void setupSigHandlers();
|
||||
|
||||
static __attribute__((no_stack_protector)) void
|
||||
handleSigSys(int sig, siginfo_t *info, void *ucontext) {
|
||||
if (auto hostFs = _readgsbase_u64()) {
|
||||
|
|
@ -42,10 +43,24 @@ handleSigSys(int sig, siginfo_t *info, void *ucontext) {
|
|||
|
||||
// rx::printStackTrace(reinterpret_cast<ucontext_t *>(ucontext),
|
||||
// rx::thread::g_current, 1);
|
||||
auto prevContext = std::exchange(rx::thread::g_current->context, ucontext);
|
||||
orbis::syscall_entry(rx::thread::g_current);
|
||||
rx::thread::g_current->context = prevContext;
|
||||
_writefsbase_u64(rx::thread::g_current->fsBase);
|
||||
auto thread = orbis::g_currentThread;
|
||||
auto prevContext = std::exchange(thread->context, ucontext);
|
||||
orbis::syscall_entry(thread);
|
||||
if (thread != orbis::g_currentThread) {
|
||||
thread = orbis::g_currentThread;
|
||||
|
||||
setupSigHandlers();
|
||||
rx::thread::initialize();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
thread->context = prevContext;
|
||||
_writefsbase_u64(thread->fsBase);
|
||||
}
|
||||
|
||||
void rx::thread::initialize() {
|
||||
|
|
@ -62,7 +77,7 @@ void rx::thread::initialize() {
|
|||
void rx::thread::deinitialize() {}
|
||||
|
||||
void rx::thread::invoke(orbis::Thread *thread) {
|
||||
g_current = thread;
|
||||
orbis::g_currentThread = thread;
|
||||
|
||||
sigset_t unblockSigs{};
|
||||
sigset_t oldSigmask{};
|
||||
|
|
|
|||
|
|
@ -6,6 +6,5 @@ namespace rx::thread {
|
|||
void initialize();
|
||||
void deinitialize();
|
||||
|
||||
extern thread_local orbis::Thread *g_current;
|
||||
void invoke(orbis::Thread *thread);
|
||||
} // namespace rx::thread
|
||||
|
|
|
|||
Loading…
Reference in a new issue