aboutsummaryrefslogtreecommitdiff
path: root/src/core/loader
diff options
context:
space:
mode:
authorMaufeat <sahyno1996@gmail.com>2026-02-07 22:59:38 +0100
committercrueter <crueter@eden-emu.dev>2026-02-07 22:59:38 +0100
commite544cb3cf6702fdec9ce2edc9f601a9e37d91153 (patch)
tree191b12e960651ee6de6d389cb922a30607fe2963 /src/core/loader
parentca9f2d43beeb03ca2127a21ef34ead9f497bcb03 (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')
-rw-r--r--src/core/loader/nso.cpp36
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;
}