mirror of
https://github.com/RPCSX/rpcsx.git
synced 2025-12-06 07:12:14 +01:00
[rpcsx-os] Use xbyak to set context
This commit is contained in:
parent
0d86217715
commit
adacb8daa6
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "3rdparty/xbyak"]
|
||||||
|
path = 3rdparty/xbyak
|
||||||
|
url = git@github.com:herumi/xbyak.git
|
||||||
1
3rdparty/xbyak
vendored
Submodule
1
3rdparty/xbyak
vendored
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit ce083a0dcc306c1717685a81f577a4e050193919
|
||||||
|
|
@ -10,9 +10,30 @@
|
||||||
#include <sys/prctl.h>
|
#include <sys/prctl.h>
|
||||||
#include <ucontext.h>
|
#include <ucontext.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <xbyak/xbyak.h>
|
||||||
|
|
||||||
thread_local orbis::Thread *rx::thread::g_current = nullptr;
|
thread_local orbis::Thread *rx::thread::g_current = nullptr;
|
||||||
|
|
||||||
|
static auto setContext = [] {
|
||||||
|
struct SetContext : Xbyak::CodeGenerator {
|
||||||
|
SetContext() {
|
||||||
|
mov(rbp, rdi);
|
||||||
|
mov(rax, qword[rbp + REG_RAX * sizeof(unsigned long long)]);
|
||||||
|
mov(rdi, qword[rbp + REG_RDI * sizeof(unsigned long long)]);
|
||||||
|
mov(rdx, qword[rbp + REG_RDX * sizeof(unsigned long long)]);
|
||||||
|
mov(rcx, qword[rbp + REG_RCX * sizeof(unsigned long long)]);
|
||||||
|
mov(rbx, qword[rbp + REG_RBX * sizeof(unsigned long long)]);
|
||||||
|
mov(rsi, qword[rbp + REG_RSI * sizeof(unsigned long long)]);
|
||||||
|
mov(rsp, qword[rbp + REG_RSP * sizeof(unsigned long long)]);
|
||||||
|
|
||||||
|
mov(rbp, qword[rbp + REG_RIP * sizeof(unsigned long long)]);
|
||||||
|
call(rbp);
|
||||||
|
}
|
||||||
|
} static setContextStorage;
|
||||||
|
|
||||||
|
return setContextStorage.getCode<void (*)(const mcontext_t &)>();
|
||||||
|
}();
|
||||||
|
|
||||||
static __attribute__((no_stack_protector)) void
|
static __attribute__((no_stack_protector)) void
|
||||||
handleSigSys(int sig, siginfo_t *info, void *ucontext) {
|
handleSigSys(int sig, siginfo_t *info, void *ucontext) {
|
||||||
if (auto hostFs = _readgsbase_u64()) {
|
if (auto hostFs = _readgsbase_u64()) {
|
||||||
|
|
@ -63,16 +84,6 @@ void rx::thread::invoke(orbis::Thread *thread) {
|
||||||
_writefsbase_u64(thread->fsBase);
|
_writefsbase_u64(thread->fsBase);
|
||||||
auto context = reinterpret_cast<ucontext_t *>(thread->context);
|
auto context = reinterpret_cast<ucontext_t *>(thread->context);
|
||||||
|
|
||||||
asm volatile("movq %1, %%rsp\n"
|
setContext(context->uc_mcontext);
|
||||||
"callq *%0\n"
|
|
||||||
:
|
|
||||||
: "rm"(context->uc_mcontext.gregs[REG_RIP]),
|
|
||||||
"rm"(context->uc_mcontext.gregs[REG_RSP]),
|
|
||||||
"D"(context->uc_mcontext.gregs[REG_RDI]),
|
|
||||||
"S"(context->uc_mcontext.gregs[REG_RSI]),
|
|
||||||
"d"(context->uc_mcontext.gregs[REG_RDX]),
|
|
||||||
"c"(context->uc_mcontext.gregs[REG_RCX]),
|
|
||||||
"b"(context->uc_mcontext.gregs[REG_RBX])
|
|
||||||
: "memory");
|
|
||||||
_writefsbase_u64(hostFs);
|
_writefsbase_u64(hostFs);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue