mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-08-03 11:23:49 +00:00
loader: preserve guest root stack frame
Build and Release KytyPS5 / Build KytyPS5 (Windows) (push) Waiting to run
Build and Release KytyPS5 / Build KytyPS5 (macOS) (push) Waiting to run
Build and Release KytyPS5 / Build KytyPS5 (Linux) (push) Waiting to run
Build and Release KytyPS5 / Release KytyPS5 (push) Blocked by required conditions
Build and Release KytyPS5 / Build KytyPS5 (Windows) (push) Waiting to run
Build and Release KytyPS5 / Build KytyPS5 (macOS) (push) Waiting to run
Build and Release KytyPS5 / Build KytyPS5 (Linux) (push) Waiting to run
Build and Release KytyPS5 / Release KytyPS5 (push) Blocked by required conditions
This commit is contained in:
@@ -876,9 +876,11 @@ bool TestGuestStackOwnerLifecycle(uint64_t* first_address, uint64_t* second_addr
|
|||||||
|
|
||||||
static KYTY_SYSV_ABI void* RunOnGuestStack(void* arg, pthread_entry_func_t func, void* stack_top) {
|
static KYTY_SYSV_ABI void* RunOnGuestStack(void* arg, pthread_entry_func_t func, void* stack_top) {
|
||||||
#if defined(__x86_64__) || defined(_M_X64)
|
#if defined(__x86_64__) || defined(_M_X64)
|
||||||
void* ret = nullptr;
|
void* ret = nullptr;
|
||||||
const auto guest_rsp = reinterpret_cast<uintptr_t>(stack_top) & ~static_cast<uintptr_t>(0x0f);
|
const auto aligned_stack_top =
|
||||||
const auto guest_rbp = guest_rsp - 4u * sizeof(uint64_t);
|
reinterpret_cast<uintptr_t>(stack_top) & ~static_cast<uintptr_t>(0x0f);
|
||||||
|
const auto guest_rsp = aligned_stack_top - 2u * sizeof(uintptr_t);
|
||||||
|
const auto guest_rbp = guest_rsp;
|
||||||
|
|
||||||
auto* guest_root_frame = reinterpret_cast<uintptr_t*>(guest_rbp);
|
auto* guest_root_frame = reinterpret_cast<uintptr_t*>(guest_rbp);
|
||||||
guest_root_frame[0] = 0;
|
guest_root_frame[0] = 0;
|
||||||
|
|||||||
@@ -360,9 +360,10 @@ static KYTY_SYSV_ABI void RunEntry(uint64_t addr, EntryParams* params, atexit_fu
|
|||||||
auto* func = reinterpret_cast<entry_func_t>(addr);
|
auto* func = reinterpret_cast<entry_func_t>(addr);
|
||||||
|
|
||||||
if (stack_top != nullptr) {
|
if (stack_top != nullptr) {
|
||||||
const auto guest_rsp =
|
const auto aligned_stack_top =
|
||||||
reinterpret_cast<uintptr_t>(stack_top) & ~static_cast<uintptr_t>(0x0f);
|
reinterpret_cast<uintptr_t>(stack_top) & ~static_cast<uintptr_t>(0x0f);
|
||||||
const auto guest_rbp = guest_rsp - 4u * sizeof(uint64_t);
|
const auto guest_rsp = aligned_stack_top - 2u * sizeof(uintptr_t);
|
||||||
|
const auto guest_rbp = guest_rsp;
|
||||||
|
|
||||||
auto* guest_root_frame = reinterpret_cast<uintptr_t*>(guest_rbp);
|
auto* guest_root_frame = reinterpret_cast<uintptr_t*>(guest_rbp);
|
||||||
guest_root_frame[0] = 0;
|
guest_root_frame[0] = 0;
|
||||||
@@ -507,6 +508,13 @@ struct MainEntryStackTestState {
|
|||||||
static KYTY_SYSV_ABI void TestMainEntryStackCallback(EntryParams* params,
|
static KYTY_SYSV_ABI void TestMainEntryStackCallback(EntryParams* params,
|
||||||
atexit_func_t /*atexit_func*/) {
|
atexit_func_t /*atexit_func*/) {
|
||||||
auto* state = reinterpret_cast<MainEntryStackTestState*>(const_cast<char*>(params->argv[0]));
|
auto* state = reinterpret_cast<MainEntryStackTestState*>(const_cast<char*>(params->argv[0]));
|
||||||
|
asm volatile("pushq %%r15\n\t"
|
||||||
|
"pushq %%r14\n\t"
|
||||||
|
"popq %%r14\n\t"
|
||||||
|
"popq %%r15\n\t"
|
||||||
|
:
|
||||||
|
:
|
||||||
|
: "memory");
|
||||||
asm volatile("movq %%rsp, %0" : "=r"(state->rsp) : : "memory");
|
asm volatile("movq %%rsp, %0" : "=r"(state->rsp) : : "memory");
|
||||||
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS
|
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS
|
||||||
asm volatile("movq %%gs:0x08, %0\n\t"
|
asm volatile("movq %%gs:0x08, %0\n\t"
|
||||||
@@ -529,6 +537,8 @@ bool TestMainEntryUsesGuestStack() {
|
|||||||
MainEntryStackTestState state {};
|
MainEntryStackTestState state {};
|
||||||
EntryParams params {};
|
EntryParams params {};
|
||||||
params.argv[0] = reinterpret_cast<const char*>(&state);
|
params.argv[0] = reinterpret_cast<const char*>(&state);
|
||||||
|
std::memset(reinterpret_cast<void*>(stack_base), 0xcd, stack_size);
|
||||||
|
auto* root_frame = reinterpret_cast<const uintptr_t*>(stack_base + stack_size) - 2;
|
||||||
|
|
||||||
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS
|
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS
|
||||||
uintptr_t original_teb_stack_base = 0;
|
uintptr_t original_teb_stack_base = 0;
|
||||||
@@ -558,9 +568,10 @@ bool TestMainEntryUsesGuestStack() {
|
|||||||
constexpr bool teb_ok = true;
|
constexpr bool teb_ok = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const bool rsp_ok = state.rsp >= stack_base && state.rsp < stack_base + stack_size;
|
const bool rsp_ok = state.rsp >= stack_base && state.rsp < stack_base + stack_size;
|
||||||
const bool freed = Libs::LibKernel::Memory::FreeGuestMemory(stack_base, stack_size);
|
const bool root_ok = root_frame[0] == 0 && root_frame[1] == 0;
|
||||||
return state.called && rsp_ok && teb_ok && freed;
|
const bool freed = Libs::LibKernel::Memory::FreeGuestMemory(stack_base, stack_size);
|
||||||
|
return state.called && rsp_ok && root_ok && teb_ok && freed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TestModuleRelocationUsesWritableHostMapping() {
|
bool TestModuleRelocationUsesWritableHostMapping() {
|
||||||
|
|||||||
Reference in New Issue
Block a user