From 4e1a29f618d93447d57030b85dc45f538402a57d Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 27 Apr 2018 03:33:44 -0600 Subject: [PATCH] Loader: Finish ldr:ro --- stratosphere/loader/source/ldr_nro.cpp | 1 + .../loader/source/ldr_registration.cpp | 23 +++++++++++++++++++ .../loader/source/ldr_registration.hpp | 1 + stratosphere/loader/source/ldr_ro_service.cpp | 17 ++++++++++++-- 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/stratosphere/loader/source/ldr_nro.cpp b/stratosphere/loader/source/ldr_nro.cpp index 3f95c7a50..120587fd6 100644 --- a/stratosphere/loader/source/ldr_nro.cpp +++ b/stratosphere/loader/source/ldr_nro.cpp @@ -103,6 +103,7 @@ Result NroUtils::LoadNro(Registration::Process *target_proc, Handle process_h, u } Registration::AddNroToProcess(target_proc->index, &mcm_nro, &mcm_bss, nro->text_size, nro->ro_size, nro->rw_size, nro->build_id); + *out_address = mcm_nro.code_memory_address; mcm_nro.Unmap(); mcm_bss.Unmap(); rc = 0x0; diff --git a/stratosphere/loader/source/ldr_registration.cpp b/stratosphere/loader/source/ldr_registration.cpp index 2f9578fb9..ab0fce037 100644 --- a/stratosphere/loader/source/ldr_registration.cpp +++ b/stratosphere/loader/source/ldr_registration.cpp @@ -223,6 +223,29 @@ void Registration::AddNroToProcess(u64 index, MappedCodeMemory *nro, MappedCodeM } } +Result Registration::RemoveNroInfo(u64 index, Handle process_h, u64 nro_heap_address) { + Registration::Process *target_process = GetProcess(index); + if (target_process == NULL) { + return 0xA809; + } + + for (unsigned int i = 0; i < NRR_INFO_MAX; i++) { + if (target_process->nro_infos[i].in_use && target_process->nro_infos[i].nro_heap_address == nro_heap_address) { + NroInfo *info = &target_process->nro_infos[i]; + Result rc = svcUnmapProcessCodeMemory(process_h, info->base_address + info->text_size + info->ro_size + info->rw_size, info->bss_heap_address, info->bss_heap_size); + if (R_SUCCEEDED(rc)) { + rc = svcUnmapProcessCodeMemory(process_h, info->base_address + info->text_size + info->ro_size, nro_heap_address + info->text_size + info->ro_size, info->rw_size); + if (R_SUCCEEDED(rc)) { + rc = svcUnmapProcessCodeMemory(process_h, info->base_address, nro_heap_address, info->text_size + info->ro_size); + } + } + target_process->nro_infos[i] = (const NroInfo ){0}; + return rc; + } + } + return 0xA809; +} + Result Registration::GetNsoInfosForProcessId(Registration::NsoInfo *out, u32 max_out, u64 process_id, u32 *num_written) { Registration::Process *target_process = GetProcessByProcessId(process_id); if (target_process == NULL) { diff --git a/stratosphere/loader/source/ldr_registration.hpp b/stratosphere/loader/source/ldr_registration.hpp index dc79995ec..4df3bd05d 100644 --- a/stratosphere/loader/source/ldr_registration.hpp +++ b/stratosphere/loader/source/ldr_registration.hpp @@ -74,5 +74,6 @@ class Registration { static bool IsNroHashPresent(u64 index, u8 *nro_hash); static bool IsNroAlreadyLoaded(u64 index, u8 *build_id); static void AddNroToProcess(u64 index, MappedCodeMemory *nro, MappedCodeMemory *bss, u32 text_size, u32 ro_size, u32 rw_size, u8 *build_id); + static Result RemoveNroInfo(u64 index, Handle process_h, u64 base_address); static Result GetNsoInfosForProcessId(NsoInfo *out, u32 max_out, u64 process_id, u32 *num_written); }; diff --git a/stratosphere/loader/source/ldr_ro_service.cpp b/stratosphere/loader/source/ldr_ro_service.cpp index 1e6b23206..020db98c1 100644 --- a/stratosphere/loader/source/ldr_ro_service.cpp +++ b/stratosphere/loader/source/ldr_ro_service.cpp @@ -71,8 +71,21 @@ LOAD_NRO_END: } std::tuple RelocatableObjectsService::unload_nro(PidDescriptor pid_desc, u64 nro_address) { - /* TODO */ - return std::make_tuple(0xF601); + Registration::Process *target_proc = NULL; + if (!this->has_initialized || this->process_id != pid_desc.pid) { + return 0xAE09; + } + if (nro_address & 0xFFF) { + return 0xA209; + } + + target_proc = Registration::GetProcessByProcessId(pid_desc.pid); + if (target_proc == NULL || (target_proc->owner_ro_service != NULL && (RelocatableObjectsService *)(target_proc->owner_ro_service) != this)) { + return 0xAC09; + } + target_proc->owner_ro_service = this; + + return Registration::RemoveNroInfo(target_proc->index, this->process_handle, nro_address); } std::tuple RelocatableObjectsService::load_nrr(PidDescriptor pid_desc, u64 nrr_address, u64 nrr_size) {