[kernel] Implement code address offset for Skyline compatibility (#2858)

- Add debug logging for 32-bit syscall argument tracking.

- Add CodeStartOffset constant (0x500000) applied to only 32-bit code address space
  types in KProcess::LoadFromMetadata.

- Replace CheckMemoryStateContiguous with two-stage CheckMemoryState
  in KPageTableBase::UnmapCodeMemory to discover and verify memory
  state more accurately.

Based on similar fixes in Ryujinx (commit 5e9678c8fe)
Fixes compatibility with:
- Skyline 32-bit modding framework
- CTGP-DX (Mario Kart 8 Deluxe mod)
- Other homebrew using 32bit Skyline

Co-authored-by: JPikachu <jpikachu.eden@gmail.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2858
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Co-authored-by: JPikachu <jpikachu@eden-emu.dev>
Co-committed-by: JPikachu <jpikachu@eden-emu.dev>
This commit is contained in:
JPikachu
2025-10-31 19:49:37 +01:00
committed by crueter
parent bfb112dad1
commit ead5978b34
2 changed files with 20 additions and 2 deletions

View File

@@ -28,6 +28,9 @@ namespace Kernel {
namespace {
// TODO: Remove this workaround when proper ASLR is implemented for all address spaces.
constexpr u64 CodeStartOffset = 0x500000UL;
Result TerminateChildren(KernelCore& kernel, KProcess* process,
const KThread* thread_to_not_terminate) {
// Request that all children threads terminate.
@@ -1198,11 +1201,11 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
break;
case FileSys::ProgramAddressSpaceType::Is32Bit:
flag |= Svc::CreateProcessFlag::AddressSpace32Bit;
code_address = 0x20'0000;
code_address = 0x20'0000 + CodeStartOffset;
break;
case FileSys::ProgramAddressSpaceType::Is32BitNoMap:
flag |= Svc::CreateProcessFlag::AddressSpace32BitWithoutAlias;
code_address = 0x20'0000;
code_address = 0x20'0000 + CodeStartOffset;
break;
}

View File

@@ -1828,6 +1828,10 @@ static void SvcWrap_SetProcessMemoryPermission64From32(Core::System& system, std
uint64_t size{};
MemoryPermission perm{};
LOG_DEBUG(Kernel_SVC, "Raw args, [0]={:#x} [1]={:#x} [2]={:#x} [3]={:#x} [4]={:#x} [5]={:#x}",
GetArg32(args, 0), GetArg32(args, 1), GetArg32(args, 2),
GetArg32(args, 3), GetArg32(args, 4), GetArg32(args, 5));
process_handle = Convert<Handle>(GetArg32(args, 0));
std::array<uint32_t, 2> address_gather{};
address_gather[0] = GetArg32(args, 2);
@@ -1915,6 +1919,10 @@ static void SvcWrap_MapProcessCodeMemory64From32(Core::System& system, std::span
uint64_t src_address{};
uint64_t size{};
LOG_DEBUG(Kernel_SVC, "Raw args, [0]={:#x} [1]={:#x} [2]={:#x} [3]={:#x} [4]={:#x} [5]={:#x} [6]={:#x}",
GetArg32(args, 0), GetArg32(args, 1), GetArg32(args, 2),
GetArg32(args, 3), GetArg32(args, 4), GetArg32(args, 5), GetArg32(args, 6));
process_handle = Convert<Handle>(GetArg32(args, 0));
std::array<uint32_t, 2> dst_address_gather{};
dst_address_gather[0] = GetArg32(args, 2);
@@ -1942,6 +1950,10 @@ static void SvcWrap_UnmapProcessCodeMemory64From32(Core::System& system, std::sp
uint64_t src_address{};
uint64_t size{};
LOG_DEBUG(Kernel_SVC, "Raw args, [0]={:#x} [1]={:#x} [2]={:#x} [3]={:#x} [4]={:#x} [5]={:#x} [6]={:#x}",
GetArg32(args, 0), GetArg32(args, 1), GetArg32(args, 2),
GetArg32(args, 3), GetArg32(args, 4), GetArg32(args, 5), GetArg32(args, 6));
process_handle = Convert<Handle>(GetArg32(args, 0));
std::array<uint32_t, 2> dst_address_gather{};
dst_address_gather[0] = GetArg32(args, 2);
@@ -1956,6 +1968,9 @@ static void SvcWrap_UnmapProcessCodeMemory64From32(Core::System& system, std::sp
size_gather[1] = GetArg32(args, 6);
size = Convert<uint64_t>(size_gather);
LOG_DEBUG(Kernel_SVC, "Reconstructed, handle={:#x} dst={:#x} src={:#x} size={:#x}",
process_handle, dst_address, src_address, size);
ret = UnmapProcessCodeMemory64From32(system, process_handle, dst_address, src_address, size);
SetArg32(args, 0, Convert<uint32_t>(ret));