From f2a840908380f876a1b5675e9cae281c8db77776 Mon Sep 17 00:00:00 2001 From: Liam Date: Fri, 17 Nov 2023 21:58:29 +0200 Subject: kernel: Manually specify aslr region start --- src/core/loader/deconstructed_rom_directory.cpp | 2 +- src/core/loader/kip.cpp | 3 ++- src/core/loader/nro.cpp | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src/core/loader') diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index 5c36b71e5..48c0edaea 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp @@ -147,7 +147,7 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect } // Setup the process code layout - if (process.LoadFromMetadata(metadata, code_size, is_hbl).IsError()) { + if (process.LoadFromMetadata(metadata, code_size, 0, is_hbl).IsError()) { return {ResultStatus::ErrorUnableToParseKernelMetadata, {}}; } diff --git a/src/core/loader/kip.cpp b/src/core/loader/kip.cpp index bf56a08b4..cd6982921 100644 --- a/src/core/loader/kip.cpp +++ b/src/core/loader/kip.cpp @@ -91,7 +91,8 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::KProcess& process, // Setup the process code layout if (process - .LoadFromMetadata(FileSys::ProgramMetadata::GetDefault(), program_image.size(), false) + .LoadFromMetadata(FileSys::ProgramMetadata::GetDefault(), program_image.size(), 0, + false) .IsError()) { return {ResultStatus::ErrorNotInitialized, {}}; } diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp index 69f1a54ed..dfed296a5 100644 --- a/src/core/loader/nro.cpp +++ b/src/core/loader/nro.cpp @@ -197,7 +197,8 @@ static bool LoadNroImpl(Kernel::KProcess& process, const std::vector& data) // Setup the process code layout if (process - .LoadFromMetadata(FileSys::ProgramMetadata::GetDefault(), program_image.size(), false) + .LoadFromMetadata(FileSys::ProgramMetadata::GetDefault(), program_image.size(), 0, + false) .IsError()) { return false; } -- cgit v1.2.3 From 9f91ba1f7357c61dd2c7c3b437ea203d467fd400 Mon Sep 17 00:00:00 2001 From: Liam Date: Fri, 17 Nov 2023 23:44:53 +0200 Subject: arm: Implement native code execution backend --- src/core/loader/deconstructed_rom_directory.cpp | 61 +++++++++++++++++++----- src/core/loader/nro.cpp | 62 +++++++++++++++++++++++-- src/core/loader/nro.h | 2 +- src/core/loader/nso.cpp | 56 +++++++++++++++++++--- src/core/loader/nso.h | 7 ++- 5 files changed, 162 insertions(+), 26 deletions(-) (limited to 'src/core/loader') diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index 48c0edaea..e7fc8f438 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp @@ -3,6 +3,7 @@ #include #include "common/logging/log.h" +#include "common/settings.h" #include "core/core.h" #include "core/file_sys/content_archive.h" #include "core/file_sys/control_metadata.h" @@ -14,6 +15,10 @@ #include "core/loader/deconstructed_rom_directory.h" #include "core/loader/nso.h" +#ifdef ARCHITECTURE_arm64 +#include "core/arm/nce/patch.h" +#endif + namespace Loader { AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file_, @@ -124,21 +129,41 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect } metadata.Print(); - const auto static_modules = {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", - "subsdk3", "subsdk4", "subsdk5", "subsdk6", "subsdk7", - "subsdk8", "subsdk9", "sdk"}; + // Enable NCE only for 64-bit programs. + Settings::SetNceEnabled(metadata.Is64BitProgram()); + + const std::array static_modules = {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", + "subsdk3", "subsdk4", "subsdk5", "subsdk6", "subsdk7", + "subsdk8", "subsdk9", "sdk"}; - // Use the NSO module loader to figure out the code layout std::size_t code_size{}; - for (const auto& module : static_modules) { + + // Define an nce patch context for each potential module. +#ifdef ARCHITECTURE_arm64 + std::array module_patchers; +#endif + + const auto GetPatcher = [&](size_t i) -> Core::NCE::Patcher* { +#ifdef ARCHITECTURE_arm64 + if (Settings::IsNceEnabled()) { + return &module_patchers[i]; + } +#endif + return nullptr; + }; + + // Use the NSO module loader to figure out the code layout + for (size_t i = 0; i < static_modules.size(); i++) { + const auto& module = static_modules[i]; const FileSys::VirtualFile module_file{dir->GetFile(module)}; if (!module_file) { continue; } const bool should_pass_arguments = std::strcmp(module, "rtld") == 0; - const auto tentative_next_load_addr = AppLoader_NSO::LoadModule( - process, system, *module_file, code_size, should_pass_arguments, false); + const auto tentative_next_load_addr = + AppLoader_NSO::LoadModule(process, system, *module_file, code_size, + should_pass_arguments, false, {}, GetPatcher(i)); if (!tentative_next_load_addr) { return {ResultStatus::ErrorLoadingNSO, {}}; } @@ -146,8 +171,18 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect code_size = *tentative_next_load_addr; } + // Enable direct memory mapping in case of NCE. + const u64 fastmem_base = [&]() -> size_t { + if (Settings::IsNceEnabled()) { + auto& buffer = system.DeviceMemory().buffer; + buffer.EnableDirectMappedAddress(); + return reinterpret_cast(buffer.VirtualBasePointer()); + } + return 0; + }(); + // Setup the process code layout - if (process.LoadFromMetadata(metadata, code_size, 0, is_hbl).IsError()) { + if (process.LoadFromMetadata(metadata, code_size, fastmem_base, is_hbl).IsError()) { return {ResultStatus::ErrorUnableToParseKernelMetadata, {}}; } @@ -157,7 +192,8 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect VAddr next_load_addr{base_address}; const FileSys::PatchManager pm{metadata.GetTitleID(), system.GetFileSystemController(), system.GetContentProvider()}; - for (const auto& module : static_modules) { + for (size_t i = 0; i < static_modules.size(); i++) { + const auto& module = static_modules[i]; const FileSys::VirtualFile module_file{dir->GetFile(module)}; if (!module_file) { continue; @@ -165,15 +201,16 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect const VAddr load_addr{next_load_addr}; const bool should_pass_arguments = std::strcmp(module, "rtld") == 0; - const auto tentative_next_load_addr = AppLoader_NSO::LoadModule( - process, system, *module_file, load_addr, should_pass_arguments, true, pm); + const auto tentative_next_load_addr = + AppLoader_NSO::LoadModule(process, system, *module_file, load_addr, + should_pass_arguments, true, pm, GetPatcher(i)); if (!tentative_next_load_addr) { return {ResultStatus::ErrorLoadingNSO, {}}; } next_load_addr = *tentative_next_load_addr; modules.insert_or_assign(load_addr, module); - LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr); + LOG_DEBUG(Loader, "loaded module {} @ {:#X}", module, load_addr); } // Find the RomFS by searching for a ".romfs" file in this directory diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp index dfed296a5..49cf90317 100644 --- a/src/core/loader/nro.cpp +++ b/src/core/loader/nro.cpp @@ -22,6 +22,10 @@ #include "core/loader/nso.h" #include "core/memory.h" +#ifdef ARCHITECTURE_arm64 +#include "core/arm/nce/patch.h" +#endif + namespace Loader { struct NroSegmentHeader { @@ -139,7 +143,8 @@ static constexpr u32 PageAlignSize(u32 size) { return static_cast((size + Core::Memory::YUZU_PAGEMASK) & ~Core::Memory::YUZU_PAGEMASK); } -static bool LoadNroImpl(Kernel::KProcess& process, const std::vector& data) { +static bool LoadNroImpl(Core::System& system, Kernel::KProcess& process, + const std::vector& data) { if (data.size() < sizeof(NroHeader)) { return {}; } @@ -195,14 +200,60 @@ static bool LoadNroImpl(Kernel::KProcess& process, const std::vector& data) codeset.DataSegment().size += bss_size; program_image.resize(static_cast(program_image.size()) + bss_size); +#ifdef ARCHITECTURE_arm64 + const auto& code = codeset.CodeSegment(); + + // NROs are always 64-bit programs. + Settings::SetNceEnabled(true); + + // Create NCE patcher + Core::NCE::Patcher patch{}; + size_t image_size = program_image.size(); + + if (Settings::IsNceEnabled()) { + // Patch SVCs and MRS calls in the guest code + patch.PatchText(program_image, code); + + // We only support PostData patching for NROs. + ASSERT(patch.Mode() == Core::NCE::PatchMode::PostData); + + // Update patch section. + auto& patch_segment = codeset.PatchSegment(); + patch_segment.addr = image_size; + patch_segment.size = static_cast(patch.SectionSize()); + + // Add patch section size to the module size. + image_size += patch_segment.size; + } +#endif + + // Enable direct memory mapping in case of NCE. + const u64 fastmem_base = [&]() -> size_t { + if (Settings::IsNceEnabled()) { + auto& buffer = system.DeviceMemory().buffer; + buffer.EnableDirectMappedAddress(); + return reinterpret_cast(buffer.VirtualBasePointer()); + } + return 0; + }(); + // Setup the process code layout if (process - .LoadFromMetadata(FileSys::ProgramMetadata::GetDefault(), program_image.size(), 0, + .LoadFromMetadata(FileSys::ProgramMetadata::GetDefault(), image_size, fastmem_base, false) .IsError()) { return false; } + // Relocate code patch and copy to the program_image if running under NCE. + // This needs to be after LoadFromMetadata so we can use the process entry point. +#ifdef ARCHITECTURE_arm64 + if (Settings::IsNceEnabled()) { + patch.RelocateAndCopy(process.GetEntryPoint(), code, program_image, + &process.GetPostHandlers()); + } +#endif + // Load codeset for current process codeset.memory = std::move(program_image); process.LoadModule(std::move(codeset), process.GetEntryPoint()); @@ -210,8 +261,9 @@ static bool LoadNroImpl(Kernel::KProcess& process, const std::vector& data) return true; } -bool AppLoader_NRO::LoadNro(Kernel::KProcess& process, const FileSys::VfsFile& nro_file) { - return LoadNroImpl(process, nro_file.ReadAllBytes()); +bool AppLoader_NRO::LoadNro(Core::System& system, Kernel::KProcess& process, + const FileSys::VfsFile& nro_file) { + return LoadNroImpl(system, process, nro_file.ReadAllBytes()); } AppLoader_NRO::LoadResult AppLoader_NRO::Load(Kernel::KProcess& process, Core::System& system) { @@ -219,7 +271,7 @@ AppLoader_NRO::LoadResult AppLoader_NRO::Load(Kernel::KProcess& process, Core::S return {ResultStatus::ErrorAlreadyLoaded, {}}; } - if (!LoadNro(process, *file)) { + if (!LoadNro(system, process, *file)) { return {ResultStatus::ErrorLoadingNRO, {}}; } diff --git a/src/core/loader/nro.h b/src/core/loader/nro.h index 8de6eebc6..d2928cba0 100644 --- a/src/core/loader/nro.h +++ b/src/core/loader/nro.h @@ -54,7 +54,7 @@ public: bool IsRomFSUpdatable() const override; private: - bool LoadNro(Kernel::KProcess& process, const FileSys::VfsFile& nro_file); + bool LoadNro(Core::System& system, Kernel::KProcess& process, const FileSys::VfsFile& nro_file); std::vector icon_data; std::unique_ptr nacp; diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index 1350da8dc..34b10ef2e 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp @@ -20,6 +20,10 @@ #include "core/loader/nso.h" #include "core/memory.h" +#ifdef ARCHITECTURE_arm64 +#include "core/arm/nce/patch.h" +#endif + namespace Loader { namespace { struct MODHeader { @@ -72,7 +76,8 @@ FileType AppLoader_NSO::IdentifyType(const FileSys::VirtualFile& in_file) { std::optional AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core::System& system, const FileSys::VfsFile& nso_file, VAddr load_base, bool should_pass_arguments, bool load_into_process, - std::optional pm) { + std::optional pm, + Core::NCE::Patcher* patch) { if (nso_file.GetSize() < sizeof(NSOHeader)) { return std::nullopt; } @@ -86,6 +91,16 @@ std::optional AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core:: return std::nullopt; } + // Allocate some space at the beginning if we are patching in PreText mode. + const size_t module_start = [&]() -> size_t { +#ifdef ARCHITECTURE_arm64 + if (patch && patch->Mode() == Core::NCE::PatchMode::PreText) { + return patch->SectionSize(); + } +#endif + return 0; + }(); + // Build program image Kernel::CodeSet codeset; Kernel::PhysicalMemory program_image; @@ -95,11 +110,12 @@ std::optional AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core:: if (nso_header.IsSegmentCompressed(i)) { data = DecompressSegment(data, nso_header.segments[i]); } - program_image.resize(nso_header.segments[i].location + static_cast(data.size())); - std::memcpy(program_image.data() + nso_header.segments[i].location, data.data(), - data.size()); - codeset.segments[i].addr = nso_header.segments[i].location; - codeset.segments[i].offset = nso_header.segments[i].location; + program_image.resize(module_start + nso_header.segments[i].location + + static_cast(data.size())); + std::memcpy(program_image.data() + module_start + nso_header.segments[i].location, + data.data(), data.size()); + codeset.segments[i].addr = module_start + nso_header.segments[i].location; + codeset.segments[i].offset = module_start + nso_header.segments[i].location; codeset.segments[i].size = nso_header.segments[i].size; } @@ -118,7 +134,7 @@ std::optional AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core:: } codeset.DataSegment().size += nso_header.segments[2].bss_size; - const u32 image_size{ + u32 image_size{ PageAlignSize(static_cast(program_image.size()) + nso_header.segments[2].bss_size)}; program_image.resize(image_size); @@ -139,6 +155,32 @@ std::optional AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core:: std::copy(pi_header.begin() + sizeof(NSOHeader), pi_header.end(), program_image.data()); } +#ifdef ARCHITECTURE_arm64 + // If we are computing the process code layout and using nce backend, patch. + const auto& code = codeset.CodeSegment(); + if (patch && patch->Mode() == Core::NCE::PatchMode::None) { + // Patch SVCs and MRS calls in the guest code + patch->PatchText(program_image, code); + + // Add patch section size to the module size. + image_size += patch->SectionSize(); + } else if (patch) { + // Relocate code patch and copy to the program_image. + patch->RelocateAndCopy(load_base, code, program_image, &process.GetPostHandlers()); + + // Update patch section. + auto& patch_segment = codeset.PatchSegment(); + patch_segment.addr = patch->Mode() == Core::NCE::PatchMode::PreText ? 0 : image_size; + patch_segment.size = static_cast(patch->SectionSize()); + + // Add patch section size to the module size. In PreText mode image_size + // already contains the patch segment as part of module_start. + if (patch->Mode() == Core::NCE::PatchMode::PostData) { + image_size += patch_segment.size; + } + } +#endif + // If we aren't actually loading (i.e. just computing the process code layout), we are done if (!load_into_process) { return load_base + image_size; diff --git a/src/core/loader/nso.h b/src/core/loader/nso.h index 0b53b4ecd..29b86ed4c 100644 --- a/src/core/loader/nso.h +++ b/src/core/loader/nso.h @@ -15,6 +15,10 @@ namespace Core { class System; } +namespace Core::NCE { +class Patcher; +} + namespace Kernel { class KProcess; } @@ -88,7 +92,8 @@ public: static std::optional LoadModule(Kernel::KProcess& process, Core::System& system, const FileSys::VfsFile& nso_file, VAddr load_base, bool should_pass_arguments, bool load_into_process, - std::optional pm = {}); + std::optional pm = {}, + Core::NCE::Patcher* patch = nullptr); LoadResult Load(Kernel::KProcess& process, Core::System& system) override; -- cgit v1.2.3 From 8fab363237083a8130a7b2a023cd9c5dd83f8f4f Mon Sep 17 00:00:00 2001 From: GPUCode Date: Sat, 18 Nov 2023 16:10:39 +0200 Subject: android: Add cpu bakend gui toggle --- src/core/loader/deconstructed_rom_directory.cpp | 6 ++++-- src/core/loader/nro.cpp | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src/core/loader') diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index e7fc8f438..31c00f0a3 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp @@ -129,8 +129,10 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect } metadata.Print(); - // Enable NCE only for 64-bit programs. - Settings::SetNceEnabled(metadata.Is64BitProgram()); + // Enable NCE only for programs with 39-bit address space. + const bool is_39bit = + metadata.GetAddressSpaceType() == FileSys::ProgramAddressSpaceType::Is39Bit; + Settings::SetNceEnabled(is_39bit); const std::array static_modules = {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3", "subsdk4", "subsdk5", "subsdk6", "subsdk7", diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp index 49cf90317..76ff38041 100644 --- a/src/core/loader/nro.cpp +++ b/src/core/loader/nro.cpp @@ -199,6 +199,7 @@ static bool LoadNroImpl(Core::System& system, Kernel::KProcess& process, codeset.DataSegment().size += bss_size; program_image.resize(static_cast(program_image.size()) + bss_size); + size_t image_size = program_image.size(); #ifdef ARCHITECTURE_arm64 const auto& code = codeset.CodeSegment(); @@ -208,7 +209,6 @@ static bool LoadNroImpl(Core::System& system, Kernel::KProcess& process, // Create NCE patcher Core::NCE::Patcher patch{}; - size_t image_size = program_image.size(); if (Settings::IsNceEnabled()) { // Patch SVCs and MRS calls in the guest code -- cgit v1.2.3 From 6de2edcca1624982e99a72741d4fa289dc9d7551 Mon Sep 17 00:00:00 2001 From: GPUCode Date: Sun, 19 Nov 2023 11:21:53 +0200 Subject: Address some review comments --- src/core/loader/nro.cpp | 6 +++--- src/core/loader/nso.cpp | 15 ++++++++------- 2 files changed, 11 insertions(+), 10 deletions(-) (limited to 'src/core/loader') diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp index 76ff38041..49d4d7e43 100644 --- a/src/core/loader/nro.cpp +++ b/src/core/loader/nro.cpp @@ -204,7 +204,7 @@ static bool LoadNroImpl(Core::System& system, Kernel::KProcess& process, #ifdef ARCHITECTURE_arm64 const auto& code = codeset.CodeSegment(); - // NROs are always 64-bit programs. + // NROs always have a 39-bit address space. Settings::SetNceEnabled(true); // Create NCE patcher @@ -215,12 +215,12 @@ static bool LoadNroImpl(Core::System& system, Kernel::KProcess& process, patch.PatchText(program_image, code); // We only support PostData patching for NROs. - ASSERT(patch.Mode() == Core::NCE::PatchMode::PostData); + ASSERT(patch.GetPatchMode() == Core::NCE::PatchMode::PostData); // Update patch section. auto& patch_segment = codeset.PatchSegment(); patch_segment.addr = image_size; - patch_segment.size = static_cast(patch.SectionSize()); + patch_segment.size = static_cast(patch.GetSectionSize()); // Add patch section size to the module size. image_size += patch_segment.size; diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index 34b10ef2e..1ad2e917c 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp @@ -94,8 +94,8 @@ std::optional AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core:: // Allocate some space at the beginning if we are patching in PreText mode. const size_t module_start = [&]() -> size_t { #ifdef ARCHITECTURE_arm64 - if (patch && patch->Mode() == Core::NCE::PatchMode::PreText) { - return patch->SectionSize(); + if (patch && patch->GetPatchMode() == Core::NCE::PatchMode::PreText) { + return patch->GetSectionSize(); } #endif return 0; @@ -158,24 +158,25 @@ std::optional AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core:: #ifdef ARCHITECTURE_arm64 // If we are computing the process code layout and using nce backend, patch. const auto& code = codeset.CodeSegment(); - if (patch && patch->Mode() == Core::NCE::PatchMode::None) { + if (patch && patch->GetPatchMode() == Core::NCE::PatchMode::None) { // Patch SVCs and MRS calls in the guest code patch->PatchText(program_image, code); // Add patch section size to the module size. - image_size += patch->SectionSize(); + image_size += patch->GetSectionSize(); } else if (patch) { // Relocate code patch and copy to the program_image. patch->RelocateAndCopy(load_base, code, program_image, &process.GetPostHandlers()); // Update patch section. auto& patch_segment = codeset.PatchSegment(); - patch_segment.addr = patch->Mode() == Core::NCE::PatchMode::PreText ? 0 : image_size; - patch_segment.size = static_cast(patch->SectionSize()); + patch_segment.addr = + patch->GetPatchMode() == Core::NCE::PatchMode::PreText ? 0 : image_size; + patch_segment.size = static_cast(patch->GetSectionSize()); // Add patch section size to the module size. In PreText mode image_size // already contains the patch segment as part of module_start. - if (patch->Mode() == Core::NCE::PatchMode::PostData) { + if (patch->GetPatchMode() == Core::NCE::PatchMode::PostData) { image_size += patch_segment.size; } } -- cgit v1.2.3 From 3ec3cca4d8d4e1733cbc337b0499ad3bdcdf52b0 Mon Sep 17 00:00:00 2001 From: GPUCode Date: Mon, 20 Nov 2023 15:52:18 +0200 Subject: core: Define HAS_NCE macro --- src/core/loader/deconstructed_rom_directory.cpp | 6 +++--- src/core/loader/nro.cpp | 6 +++--- src/core/loader/nso.cpp | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src/core/loader') diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index 31c00f0a3..a1344f1c4 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp @@ -15,7 +15,7 @@ #include "core/loader/deconstructed_rom_directory.h" #include "core/loader/nso.h" -#ifdef ARCHITECTURE_arm64 +#ifdef HAS_NCE #include "core/arm/nce/patch.h" #endif @@ -141,12 +141,12 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect std::size_t code_size{}; // Define an nce patch context for each potential module. -#ifdef ARCHITECTURE_arm64 +#ifdef HAS_NCE std::array module_patchers; #endif const auto GetPatcher = [&](size_t i) -> Core::NCE::Patcher* { -#ifdef ARCHITECTURE_arm64 +#ifdef HAS_NCE if (Settings::IsNceEnabled()) { return &module_patchers[i]; } diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp index 49d4d7e43..2e7368349 100644 --- a/src/core/loader/nro.cpp +++ b/src/core/loader/nro.cpp @@ -22,7 +22,7 @@ #include "core/loader/nso.h" #include "core/memory.h" -#ifdef ARCHITECTURE_arm64 +#ifdef HAS_NCE #include "core/arm/nce/patch.h" #endif @@ -201,7 +201,7 @@ static bool LoadNroImpl(Core::System& system, Kernel::KProcess& process, program_image.resize(static_cast(program_image.size()) + bss_size); size_t image_size = program_image.size(); -#ifdef ARCHITECTURE_arm64 +#ifdef HAS_NCE const auto& code = codeset.CodeSegment(); // NROs always have a 39-bit address space. @@ -247,7 +247,7 @@ static bool LoadNroImpl(Core::System& system, Kernel::KProcess& process, // Relocate code patch and copy to the program_image if running under NCE. // This needs to be after LoadFromMetadata so we can use the process entry point. -#ifdef ARCHITECTURE_arm64 +#ifdef HAS_NCE if (Settings::IsNceEnabled()) { patch.RelocateAndCopy(process.GetEntryPoint(), code, program_image, &process.GetPostHandlers()); diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index 1ad2e917c..878c1c6cb 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp @@ -20,7 +20,7 @@ #include "core/loader/nso.h" #include "core/memory.h" -#ifdef ARCHITECTURE_arm64 +#ifdef HAS_NCE #include "core/arm/nce/patch.h" #endif @@ -93,7 +93,7 @@ std::optional AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core:: // Allocate some space at the beginning if we are patching in PreText mode. const size_t module_start = [&]() -> size_t { -#ifdef ARCHITECTURE_arm64 +#ifdef HAS_NCE if (patch && patch->GetPatchMode() == Core::NCE::PatchMode::PreText) { return patch->GetSectionSize(); } @@ -155,7 +155,7 @@ std::optional AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core:: std::copy(pi_header.begin() + sizeof(NSOHeader), pi_header.end(), program_image.data()); } -#ifdef ARCHITECTURE_arm64 +#ifdef HAS_NCE // If we are computing the process code layout and using nce backend, patch. const auto& code = codeset.CodeSegment(); if (patch && patch->GetPatchMode() == Core::NCE::PatchMode::None) { -- cgit v1.2.3 From d040b27a35fdf520b17fe6b1cd792058172c8ccc Mon Sep 17 00:00:00 2001 From: Liam Date: Tue, 21 Nov 2023 23:29:40 -0500 Subject: loader: apply nso patch to offset program image --- src/core/loader/nso.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/core/loader') diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index 878c1c6cb..e310c8f0f 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp @@ -145,14 +145,16 @@ std::optional AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core:: // Apply patches if necessary const auto name = nso_file.GetName(); if (pm && (pm->HasNSOPatch(nso_header.build_id, name) || Settings::values.dump_nso)) { - std::vector pi_header(sizeof(NSOHeader) + program_image.size()); + std::span patchable_section(program_image.data() + module_start, + program_image.size() - module_start); + std::vector pi_header(sizeof(NSOHeader) + patchable_section.size()); std::memcpy(pi_header.data(), &nso_header, sizeof(NSOHeader)); - std::memcpy(pi_header.data() + sizeof(NSOHeader), program_image.data(), - program_image.size()); + std::memcpy(pi_header.data() + sizeof(NSOHeader), patchable_section.data(), + patchable_section.size()); pi_header = pm->PatchNSO(pi_header, name); - std::copy(pi_header.begin() + sizeof(NSOHeader), pi_header.end(), program_image.data()); + std::copy(pi_header.begin() + sizeof(NSOHeader), pi_header.end(), patchable_section.data()); } #ifdef HAS_NCE -- cgit v1.2.3 From 7482e03c770332dca12a08467a64192c8179a613 Mon Sep 17 00:00:00 2001 From: Liam Date: Sun, 26 Nov 2023 19:34:00 -0500 Subject: loader: fix gcc compile --- src/core/loader/nso.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/loader') diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index e310c8f0f..ade8f85f8 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp @@ -165,7 +165,7 @@ std::optional AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core:: patch->PatchText(program_image, code); // Add patch section size to the module size. - image_size += patch->GetSectionSize(); + image_size += static_cast(patch->GetSectionSize()); } else if (patch) { // Relocate code patch and copy to the program_image. patch->RelocateAndCopy(load_base, code, program_image, &process.GetPostHandlers()); -- cgit v1.2.3 From 4a3abba16d9821ed163aab427d4c7bc9ef7acb32 Mon Sep 17 00:00:00 2001 From: GPUCode Date: Wed, 29 Nov 2023 23:49:16 +0200 Subject: core: Rename patcher file --- src/core/loader/deconstructed_rom_directory.cpp | 2 +- src/core/loader/nro.cpp | 2 +- src/core/loader/nso.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core/loader') diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index a1344f1c4..60ee78e89 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp @@ -16,7 +16,7 @@ #include "core/loader/nso.h" #ifdef HAS_NCE -#include "core/arm/nce/patch.h" +#include "core/arm/nce/patcher.h" #endif namespace Loader { diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp index 2e7368349..e74697cda 100644 --- a/src/core/loader/nro.cpp +++ b/src/core/loader/nro.cpp @@ -23,7 +23,7 @@ #include "core/memory.h" #ifdef HAS_NCE -#include "core/arm/nce/patch.h" +#include "core/arm/nce/patcher.h" #endif namespace Loader { diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index ade8f85f8..b053a0d14 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp @@ -21,7 +21,7 @@ #include "core/memory.h" #ifdef HAS_NCE -#include "core/arm/nce/patch.h" +#include "core/arm/nce/patcher.h" #endif namespace Loader { -- cgit v1.2.3