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/nro.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/core/loader/nro.cpp') 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/nro.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 5 deletions(-) (limited to 'src/core/loader/nro.cpp') 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, {}}; } -- 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/nro.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/loader/nro.cpp') 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 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core/loader/nro.cpp') 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; -- 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/nro.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core/loader/nro.cpp') 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()); -- 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/nro.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/loader/nro.cpp') 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 { -- cgit v1.2.3