diff options
| author | Maufeat <sahyno1996@gmail.com> | 2026-02-07 22:59:38 +0100 |
|---|---|---|
| committer | crueter <crueter@eden-emu.dev> | 2026-02-07 22:59:38 +0100 |
| commit | e544cb3cf6702fdec9ce2edc9f601a9e37d91153 (patch) | |
| tree | 191b12e960651ee6de6d389cb922a30607fe2963 /src/core/loader/nso.cpp | |
| parent | ca9f2d43beeb03ca2127a21ef34ead9f497bcb03 (diff) | |
[nce] add split patch mode to support modules bigger than 128MB (#3489)
nce patcher was extended to support modules larger than 128MB due to ARM64 branch limit. now added a pre-patch and (existing) post-patch module code. Allowwing MRS/MSR/SVC handler to remain within branch branch range
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3489
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: Maufeat <sahyno1996@gmail.com>
Co-committed-by: Maufeat <sahyno1996@gmail.com>
Diffstat (limited to 'src/core/loader/nso.cpp')
| -rw-r--r-- | src/core/loader/nso.cpp | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index e3e3f83ca2..458df110b6 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project @@ -102,6 +102,8 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core:: auto* patch = &patches->operator[](patch_index); if (patch->GetPatchMode() == Core::NCE::PatchMode::PreText) { return patch->GetSectionSize(); + } else if (patch->GetPatchMode() == Core::NCE::PatchMode::Split) { + return patch->GetPreSectionSize(); } } #endif @@ -178,12 +180,26 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core:: } } else if (patch) { // Relocate code patch and copy to the program_image. + // Save size before RelocateAndCopy (which may resize) + const size_t size_before_relocate = program_image.size(); if (patch->RelocateAndCopy(load_base, code, program_image, &process.GetPostHandlers())) { // Update patch section. auto& patch_segment = codeset.PatchSegment(); - patch_segment.addr = - patch->GetPatchMode() == Core::NCE::PatchMode::PreText ? 0 : image_size; - patch_segment.size = static_cast<u32>(patch->GetSectionSize()); + auto& post_patch_segment = codeset.PostPatchSegment(); + const auto patch_mode = patch->GetPatchMode(); + if (patch_mode == Core::NCE::PatchMode::PreText) { + patch_segment.addr = 0; + patch_segment.size = static_cast<u32>(patch->GetSectionSize()); + } else if (patch_mode == Core::NCE::PatchMode::Split) { + // For Split-mode, we are using pre-patch buffer at start, post-patch buffer at end + patch_segment.addr = 0; + patch_segment.size = static_cast<u32>(patch->GetPreSectionSize()); + post_patch_segment.addr = size_before_relocate; + post_patch_segment.size = static_cast<u32>(patch->GetSectionSize()); + } else { + patch_segment.addr = image_size; + patch_segment.size = static_cast<u32>(patch->GetSectionSize()); + } } // Refresh image_size to take account the patch section if it was added by RelocateAndCopy @@ -193,6 +209,18 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core:: // If we aren't actually loading (i.e. just computing the process code layout), we are done if (!load_into_process) { +#ifdef HAS_NCE + // Ok, so for Split mode, we need to account for pre-patch and post-patch space + // which will be added during RelocateAndCopy in the second pass. Where it crashed + // in Android Studio at PreText. May be a better way. Works for now. + if (patch && patch->GetPatchMode() == Core::NCE::PatchMode::Split) { + return load_base + patch->GetPreSectionSize() + image_size + patch->GetSectionSize(); + } else if (patch && patch->GetPatchMode() == Core::NCE::PatchMode::PreText) { + return load_base + patch->GetSectionSize() + image_size; + } else if (patch && patch->GetPatchMode() == Core::NCE::PatchMode::PostData) { + return load_base + image_size + patch->GetSectionSize(); + } +#endif return load_base + image_size; } |
