From c49cfbd6aff40afcc2e39f6e2ed03a1a1a96f958 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 29 Oct 2018 22:33:56 -0700 Subject: [PATCH] loader: update for libstratosphere refactor --- stratosphere/loader/loader.json | 3 + .../loader/source/ldr_debug_monitor.cpp | 40 ++------ .../loader/source/ldr_debug_monitor.hpp | 27 +++--- .../loader/source/ldr_launch_queue.cpp | 28 +++--- .../loader/source/ldr_launch_queue.hpp | 16 ++-- stratosphere/loader/source/ldr_main.cpp | 27 ++++-- .../loader/source/ldr_process_manager.cpp | 60 +++--------- .../loader/source/ldr_process_manager.hpp | 33 +++---- stratosphere/loader/source/ldr_ro_service.cpp | 93 ++++++------------- stratosphere/loader/source/ldr_ro_service.hpp | 31 +++---- stratosphere/loader/source/ldr_shell.cpp | 37 ++------ stratosphere/loader/source/ldr_shell.hpp | 27 +++--- 12 files changed, 150 insertions(+), 272 deletions(-) diff --git a/stratosphere/loader/loader.json b/stratosphere/loader/loader.json index 27544a507..272e9f772 100644 --- a/stratosphere/loader/loader.json +++ b/stratosphere/loader/loader.json @@ -56,6 +56,9 @@ "svcReplyAndReceiveLight" : "0x42", "svcReplyAndReceive" : "0x43", "svcReplyAndReceiveWithUserBuffer" : "0x44", + "svcCreateEvent": "0x45", + "svcReadWriteRegister" : "0x4E", + "svcQueryIoMapping": "0x55", "svcSetProcessMemoryPermission" : "0x73", "svcMapProcessMemory" : "0x74", "svcUnmapProcessMemory" : "0x75", diff --git a/stratosphere/loader/source/ldr_debug_monitor.cpp b/stratosphere/loader/source/ldr_debug_monitor.cpp index a2e12e3f8..01fd0497b 100644 --- a/stratosphere/loader/source/ldr_debug_monitor.cpp +++ b/stratosphere/loader/source/ldr_debug_monitor.cpp @@ -22,42 +22,18 @@ #include "ldr_launch_queue.hpp" #include "ldr_registration.hpp" -Result DebugMonitorService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) { - Result rc = 0xF601; - - switch ((DebugMonitorServiceCmd)cmd_id) { - case Dmnt_Cmd_AddTitleToLaunchQueue: - rc = WrapIpcCommandImpl<&DebugMonitorService::add_title_to_launch_queue>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Dmnt_Cmd_ClearLaunchQueue: - rc = WrapIpcCommandImpl<&DebugMonitorService::clear_launch_queue>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Dmnt_Cmd_GetNsoInfo: - rc = WrapIpcCommandImpl<&DebugMonitorService::get_nso_info>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - default: - break; - } - return rc; -} - -std::tuple DebugMonitorService::add_title_to_launch_queue(u64 args_size, u64 tid, InPointer args) { +Result DebugMonitorService::AddTitleToLaunchQueue(u64 args_size, u64 tid, InPointer args) { fprintf(stderr, "Add to launch queue: %p, %zX\n", args.pointer, std::min(args_size, args.num_elements)); - return {LaunchQueue::add(tid, args.pointer, std::min(args_size, args.num_elements))}; + return LaunchQueue::Add(tid, args.pointer, std::min(args_size, args.num_elements)); } -std::tuple DebugMonitorService::clear_launch_queue(u64 dat) { - fprintf(stderr, "Clear launch queue: %lx\n", dat); - LaunchQueue::clear(); - return {0}; +void DebugMonitorService::ClearLaunchQueue() { + LaunchQueue::Clear(); } -std::tuple DebugMonitorService::get_nso_info(u64 pid, OutPointerWithClientSize out) { - u32 out_num_nsos = 0; - +Result DebugMonitorService::GetNsoInfo(Out count, OutPointerWithClientSize out, u64 pid) { + /* Zero out the output memory. */ std::fill(out.pointer, out.pointer + out.num_elements, (const Registration::NsoInfo){0}); - - Result rc = Registration::GetNsoInfosForProcessId(out.pointer, out.num_elements, pid, &out_num_nsos); - - return {rc, out_num_nsos}; + /* Actually return the nso infos. */ + return Registration::GetNsoInfosForProcessId(out.pointer, out.num_elements, pid, count.GetPointer()); } diff --git a/stratosphere/loader/source/ldr_debug_monitor.hpp b/stratosphere/loader/source/ldr_debug_monitor.hpp index d1b1c4e8a..167b2872f 100644 --- a/stratosphere/loader/source/ldr_debug_monitor.hpp +++ b/stratosphere/loader/source/ldr_debug_monitor.hpp @@ -17,7 +17,7 @@ #pragma once #include -#include +#include #include "ldr_registration.hpp" enum DebugMonitorServiceCmd { @@ -26,21 +26,16 @@ enum DebugMonitorServiceCmd { Dmnt_Cmd_GetNsoInfo = 2 }; -class DebugMonitorService final : public IServiceObject { - public: - Result dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) override; - Result handle_deferred() override { - /* This service will never defer. */ - return 0; - } - - DebugMonitorService *clone() override { - return new DebugMonitorService(); - } - +class DebugMonitorService final : public IServiceObject { private: /* Actual commands. */ - std::tuple add_title_to_launch_queue(u64 args_size, u64 tid, InPointer args); - std::tuple clear_launch_queue(u64 dat); - std::tuple get_nso_info(u64 pid, OutPointerWithClientSize out); + Result AddTitleToLaunchQueue(u64 args_size, u64 tid, InPointer args); + void ClearLaunchQueue(); + Result GetNsoInfo(Out count, OutPointerWithClientSize out, u64 pid); + public: + DEFINE_SERVICE_DISPATCH_TABLE { + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + }; }; diff --git a/stratosphere/loader/source/ldr_launch_queue.cpp b/stratosphere/loader/source/ldr_launch_queue.cpp index 8fda8585b..8f6933e42 100644 --- a/stratosphere/loader/source/ldr_launch_queue.cpp +++ b/stratosphere/loader/source/ldr_launch_queue.cpp @@ -23,12 +23,12 @@ static std::array g_launch_queue = {0}; -Result LaunchQueue::add(u64 tid, const char *args, u64 arg_size) { +Result LaunchQueue::Add(u64 tid, const char *args, u64 arg_size) { if(arg_size > LAUNCH_QUEUE_ARG_SIZE_MAX) { return 0x209; } - int idx = get_free_index(tid); + int idx = GetFreeIndex(tid); if(idx == LAUNCH_QUEUE_FULL) return 0x409; @@ -39,22 +39,22 @@ Result LaunchQueue::add(u64 tid, const char *args, u64 arg_size) { return 0x0; } -Result LaunchQueue::add_copy(u64 tid_base, u64 tid) { - int idx = get_index(tid_base); +Result LaunchQueue::AddCopy(u64 tid_base, u64 tid) { + int idx = GetIndex(tid_base); if (idx == LAUNCH_QUEUE_FULL) { return 0x0; } - return add(tid, g_launch_queue[idx].args, g_launch_queue[idx].arg_size); + return Add(tid, g_launch_queue[idx].args, g_launch_queue[idx].arg_size); } -Result LaunchQueue::add_item(const LaunchItem *item) { +Result LaunchQueue::AddItem(const LaunchItem *item) { if(item->arg_size > LAUNCH_QUEUE_ARG_SIZE_MAX) { return 0x209; } - int idx = get_free_index(item->tid); + int idx = GetFreeIndex(item->tid); if(idx == LAUNCH_QUEUE_FULL) return 0x409; @@ -62,7 +62,7 @@ Result LaunchQueue::add_item(const LaunchItem *item) { return 0x0; } -int LaunchQueue::get_index(u64 tid) { +int LaunchQueue::GetIndex(u64 tid) { auto it = std::find_if(g_launch_queue.begin(), g_launch_queue.end(), member_equals_fn(&LaunchQueue::LaunchItem::tid, tid)); if (it == g_launch_queue.end()) { return LAUNCH_QUEUE_FULL; @@ -70,7 +70,7 @@ int LaunchQueue::get_index(u64 tid) { return std::distance(g_launch_queue.begin(), it); } -int LaunchQueue::get_free_index(u64 tid) { +int LaunchQueue::GetFreeIndex(u64 tid) { for(unsigned int i = 0; i < LAUNCH_QUEUE_SIZE; i++) { if(g_launch_queue[i].tid == tid || g_launch_queue[i].tid == 0x0) { return i; @@ -79,19 +79,19 @@ int LaunchQueue::get_free_index(u64 tid) { return LAUNCH_QUEUE_FULL; } -bool LaunchQueue::contains(u64 tid) { - return get_index(tid) != LAUNCH_QUEUE_FULL; +bool LaunchQueue::Contains(u64 tid) { + return GetIndex(tid) != LAUNCH_QUEUE_FULL; } -void LaunchQueue::clear() { +void LaunchQueue::Clear() { for (unsigned int i = 0; i < LAUNCH_QUEUE_SIZE; i++) { g_launch_queue[i].tid = 0; } } -LaunchQueue::LaunchItem *LaunchQueue::get_item(u64 tid) { - int idx = get_index(tid); +LaunchQueue::LaunchItem *LaunchQueue::GetItem(u64 tid) { + int idx = GetIndex(tid); if (idx == LAUNCH_QUEUE_FULL) { return NULL; } diff --git a/stratosphere/loader/source/ldr_launch_queue.hpp b/stratosphere/loader/source/ldr_launch_queue.hpp index 74a2a03c9..234cd3be5 100644 --- a/stratosphere/loader/source/ldr_launch_queue.hpp +++ b/stratosphere/loader/source/ldr_launch_queue.hpp @@ -30,13 +30,13 @@ class LaunchQueue { char args[LAUNCH_QUEUE_ARG_SIZE_MAX]; }; - static LaunchQueue::LaunchItem *get_item(u64 tid); + static LaunchQueue::LaunchItem *GetItem(u64 tid); - static Result add(u64 tid, const char *args, u64 arg_size); - static Result add_item(const LaunchItem *item); - static Result add_copy(u64 tid_base, u64 new_tid); - static int get_index(u64 tid); - static int get_free_index(u64 tid); - static bool contains(u64 tid); - static void clear(); + static Result Add(u64 tid, const char *args, u64 arg_size); + static Result AddItem(const LaunchItem *item); + static Result AddCopy(u64 tid_base, u64 new_tid); + static int GetIndex(u64 tid); + static int GetFreeIndex(u64 tid); + static bool Contains(u64 tid); + static void Clear(); }; \ No newline at end of file diff --git a/stratosphere/loader/source/ldr_main.cpp b/stratosphere/loader/source/ldr_main.cpp index a074977be..8db791cd0 100644 --- a/stratosphere/loader/source/ldr_main.cpp +++ b/stratosphere/loader/source/ldr_main.cpp @@ -92,24 +92,31 @@ void __appExit(void) { smExit(); } +struct LoaderServerOptions { + static constexpr size_t PointerBufferSize = 0x400; + static constexpr size_t MaxDomains = 0; + static constexpr size_t MaxDomainObjects = 0; +}; + int main(int argc, char **argv) { consoleDebugInit(debugDevice_SVC); + + auto server_manager = new WaitableManager(1); - /* TODO: What's a good timeout value to use here? */ - auto server_manager = std::make_unique(U64_MAX); - /* Add services to manager. */ - server_manager->add_waitable(new ServiceServer("ldr:pm", 1)); - server_manager->add_waitable(new ServiceServer("ldr:shel", 3)); - server_manager->add_waitable(new ServiceServer("ldr:dmnt", 2)); - if (!kernelAbove300()) { + server_manager->AddWaitable(new ServiceServer("ldr:pm", 1)); + server_manager->AddWaitable(new ServiceServer("ldr:shel", 3)); + server_manager->AddWaitable(new ServiceServer("ldr:dmnt", 2)); + if (GetRuntimeFirmwareVersion() < FirmwareVersion_300) { /* On 1.0.0-2.3.0, Loader services ldr:ro instead of ro. */ - server_manager->add_waitable(new ServiceServer("ldr:ro", 0x20)); + server_manager->AddWaitable(new ServiceServer("ldr:ro", 0x20)); } - + /* Loop forever, servicing our services. */ - server_manager->process(); + server_manager->Process(); + + delete server_manager; return 0; } diff --git a/stratosphere/loader/source/ldr_process_manager.cpp b/stratosphere/loader/source/ldr_process_manager.cpp index a1be87408..3f50cf8a2 100644 --- a/stratosphere/loader/source/ldr_process_manager.cpp +++ b/stratosphere/loader/source/ldr_process_manager.cpp @@ -22,68 +22,45 @@ #include "ldr_content_management.hpp" #include "ldr_npdm.hpp" -Result ProcessManagerService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) { - Result rc = 0xF601; - - switch ((ProcessManagerServiceCmd)cmd_id) { - case Pm_Cmd_CreateProcess: - rc = WrapIpcCommandImpl<&ProcessManagerService::create_process>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Pm_Cmd_GetProgramInfo: - rc = WrapIpcCommandImpl<&ProcessManagerService::get_program_info>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Pm_Cmd_RegisterTitle: - rc = WrapIpcCommandImpl<&ProcessManagerService::register_title>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Pm_Cmd_UnregisterTitle: - rc = WrapIpcCommandImpl<&ProcessManagerService::unregister_title>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - default: - break; - } - return rc; -} - -std::tuple ProcessManagerService::create_process(u64 flags, u64 index, CopiedHandle reslimit_h) { +Result ProcessManagerService::CreateProcess(Out proc_h, u64 flags, u64 index, CopiedHandle reslimit_h) { Result rc; Registration::TidSid tid_sid; LaunchQueue::LaunchItem *launch_item; char nca_path[FS_MAX_PATH] = {0}; - Handle process_h = 0; fprintf(stderr, "CreateProcess(%016lx, %016lx, %08x);\n", flags, index, reslimit_h.handle); rc = Registration::GetRegisteredTidSid(index, &tid_sid); if (R_FAILED(rc)) { - return {rc, MovedHandle{process_h}}; + return rc; } if (tid_sid.storage_id != FsStorageId_None) { rc = ContentManagement::ResolveContentPathForTidSid(nca_path, &tid_sid); if (R_FAILED(rc)) { - return {rc, MovedHandle{process_h}}; + return rc; } } - launch_item = LaunchQueue::get_item(tid_sid.title_id); + launch_item = LaunchQueue::GetItem(tid_sid.title_id); - rc = ProcessCreation::CreateProcess(&process_h, index, nca_path, launch_item, flags, reslimit_h.handle); + rc = ProcessCreation::CreateProcess(proc_h.GetHandlePointer(), index, nca_path, launch_item, flags, reslimit_h.handle); if (R_SUCCEEDED(rc)) { ContentManagement::SetCreatedTitle(tid_sid.title_id); } - return {rc, MovedHandle{process_h}}; + return rc; } -std::tuple ProcessManagerService::get_program_info(Registration::TidSid tid_sid, OutPointerWithServerSize out_program_info) { +Result ProcessManagerService::GetProgramInfo(Registration::TidSid tid_sid, OutPointerWithServerSize out_program_info) { Result rc; char nca_path[FS_MAX_PATH] = {0}; /* Zero output. */ std::fill(out_program_info.pointer, out_program_info.pointer + out_program_info.num_elements, (const ProcessManagerService::ProgramInfo){0}); - rc = populate_program_info_buffer(out_program_info.pointer, &tid_sid); + rc = PopulateProgramInfoBuffer(out_program_info.pointer, &tid_sid); if (R_FAILED(rc)) { return {rc}; @@ -100,31 +77,22 @@ std::tuple ProcessManagerService::get_program_info(Registration::TidSid return {rc}; } - rc = LaunchQueue::add_copy(tid_sid.title_id, out_program_info.pointer->title_id); + rc = LaunchQueue::AddCopy(tid_sid.title_id, out_program_info.pointer->title_id); } return {rc}; } -std::tuple ProcessManagerService::register_title(Registration::TidSid tid_sid) { - u64 out_index = 0; - if (Registration::RegisterTidSid(&tid_sid, &out_index)) { - return {0, out_index}; - } else { - return {0xE09, out_index}; - } +Result ProcessManagerService::RegisterTitle(Out index, Registration::TidSid tid_sid) { + return Registration::RegisterTidSid(&tid_sid, index.GetPointer()) ? 0 : 0xE09; } -std::tuple ProcessManagerService::unregister_title(u64 index) { - if (Registration::UnregisterIndex(index)) { - return {0}; - } else { - return {0x1009}; - } +Result ProcessManagerService::UnregisterTitle(u64 index) { + return Registration::UnregisterIndex(index) ? 0 : 0x1009; } -Result ProcessManagerService::populate_program_info_buffer(ProcessManagerService::ProgramInfo *out, Registration::TidSid *tid_sid) { +Result ProcessManagerService::PopulateProgramInfoBuffer(ProcessManagerService::ProgramInfo *out, Registration::TidSid *tid_sid) { NpdmUtils::NpdmInfo info; Result rc; bool mounted_code = false; diff --git a/stratosphere/loader/source/ldr_process_manager.hpp b/stratosphere/loader/source/ldr_process_manager.hpp index c177a03b2..65c68b3e3 100644 --- a/stratosphere/loader/source/ldr_process_manager.hpp +++ b/stratosphere/loader/source/ldr_process_manager.hpp @@ -16,7 +16,7 @@ #pragma once #include -#include +#include #include "ldr_registration.hpp" #include "ldr_process_creation.hpp" @@ -42,26 +42,21 @@ class ProcessManagerService final : public IServiceObject { u8 ac_buffer[0x3E0]; }; - static_assert(sizeof(ProcessManagerService::ProgramInfo) == 0x400, "Incorrect ProgramInfo definition."); - - public: - Result dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) override; - Result handle_deferred() override { - /* This service will never defer. */ - return 0; - } - - ProcessManagerService *clone() override { - return new ProcessManagerService(); - } - + static_assert(sizeof(ProcessManagerService::ProgramInfo) == 0x400, "Incorrect ProgramInfo definition."); private: /* Actual commands. */ - std::tuple create_process(u64 flags, u64 index, CopiedHandle reslimit_h); - std::tuple get_program_info(Registration::TidSid tid_sid, OutPointerWithServerSize out_program_info); - std::tuple register_title(Registration::TidSid tid_sid); - std::tuple unregister_title(u64 index); + Result CreateProcess(Out proc_h, u64 flags, u64 index, CopiedHandle reslimit_h); + Result GetProgramInfo(Registration::TidSid tid_sid, OutPointerWithServerSize out_program_info); + Result RegisterTitle(Out index, Registration::TidSid tid_sid); + Result UnregisterTitle(u64 index); /* Utilities */ - Result populate_program_info_buffer(ProcessManagerService::ProgramInfo *out, Registration::TidSid *tid_sid); + Result PopulateProgramInfoBuffer(ProcessManagerService::ProgramInfo *out, Registration::TidSid *tid_sid); + public: + DEFINE_SERVICE_DISPATCH_TABLE { + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + }; }; diff --git a/stratosphere/loader/source/ldr_ro_service.cpp b/stratosphere/loader/source/ldr_ro_service.cpp index 4529710f9..013476499 100644 --- a/stratosphere/loader/source/ldr_ro_service.cpp +++ b/stratosphere/loader/source/ldr_ro_service.cpp @@ -24,71 +24,34 @@ #include "ldr_map.hpp" #include "ldr_nro.hpp" -Result RelocatableObjectsService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) { - Result rc = 0xF601; - - switch ((RoServiceCmd)cmd_id) { - case Ro_Cmd_LoadNro: - rc = WrapIpcCommandImpl<&RelocatableObjectsService::load_nro>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Ro_Cmd_UnloadNro: - rc = WrapIpcCommandImpl<&RelocatableObjectsService::unload_nro>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Ro_Cmd_LoadNrr: - rc = WrapIpcCommandImpl<&RelocatableObjectsService::load_nrr>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Ro_Cmd_UnloadNrr: - rc = WrapIpcCommandImpl<&RelocatableObjectsService::unload_nrr>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Ro_Cmd_Initialize: - rc = WrapIpcCommandImpl<&RelocatableObjectsService::initialize>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - default: - break; - } - - return rc; -} - - -std::tuple RelocatableObjectsService::load_nro(PidDescriptor pid_desc, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size) { - Result rc; - u64 out_address = 0; +Result RelocatableObjectsService::LoadNro(Out load_address, PidDescriptor pid_desc, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size) { Registration::Process *target_proc = NULL; if (!this->has_initialized || this->process_id != pid_desc.pid) { - rc = 0xAE09; - goto LOAD_NRO_END; + return 0xAE09; } if (nro_address & 0xFFF) { - rc = 0xA209; - goto LOAD_NRO_END; + return 0xA209; } if (nro_address + nro_size <= nro_address || !nro_size || (nro_size & 0xFFF)) { - rc = 0xA409; - goto LOAD_NRO_END; + return 0xA409; } if (bss_size && bss_address + bss_size <= bss_address) { - rc = 0xA409; - goto LOAD_NRO_END; + return 0xA409; } /* Ensure no overflow for combined sizes. */ if (U64_MAX - nro_size < bss_size) { - rc = 0xA409; - goto LOAD_NRO_END; + return 0xA409; } target_proc = Registration::GetProcessByProcessId(pid_desc.pid); if (target_proc == NULL || (target_proc->owner_ro_service != NULL && (RelocatableObjectsService *)(target_proc->owner_ro_service) != this)) { - rc = 0xAC09; - goto LOAD_NRO_END; + return 0xAC09; } target_proc->owner_ro_service = this; - rc = NroUtils::LoadNro(target_proc, this->process_handle, nro_address, nro_size, bss_address, bss_size, &out_address); -LOAD_NRO_END: - return {rc, out_address}; + return NroUtils::LoadNro(target_proc, this->process_handle, nro_address, nro_size, bss_address, bss_size, load_address.GetPointer()); } -std::tuple RelocatableObjectsService::unload_nro(PidDescriptor pid_desc, u64 nro_address) { +Result RelocatableObjectsService::UnloadNro(PidDescriptor pid_desc, u64 nro_address) { Registration::Process *target_proc = NULL; if (!this->has_initialized || this->process_id != pid_desc.pid) { return 0xAE09; @@ -106,37 +69,42 @@ std::tuple RelocatableObjectsService::unload_nro(PidDescriptor pid_desc, 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) { - Result rc; +Result RelocatableObjectsService::LoadNrr(PidDescriptor pid_desc, u64 nrr_address, u64 nrr_size) { + Result rc = 0; Registration::Process *target_proc = NULL; MappedCodeMemory nrr_info = {0}; + ON_SCOPE_EXIT { + if (R_FAILED(rc) && nrr_info.IsActive()) { + nrr_info.Close(); + } + }; if (!this->has_initialized || this->process_id != pid_desc.pid) { rc = 0xAE09; - goto LOAD_NRR_END; + return rc; } if (nrr_address & 0xFFF) { rc = 0xA209; - goto LOAD_NRR_END; + return rc; } if (nrr_address + nrr_size <= nrr_address || !nrr_size || (nrr_size & 0xFFF)) { rc = 0xA409; - goto LOAD_NRR_END; + return rc; } target_proc = Registration::GetProcessByProcessId(pid_desc.pid); if (target_proc == NULL || (target_proc->owner_ro_service != NULL && (RelocatableObjectsService *)(target_proc->owner_ro_service) != this)) { rc = 0xAC09; - goto LOAD_NRR_END; + return rc; } target_proc->owner_ro_service = this; if (R_FAILED((rc = nrr_info.Open(this->process_handle, target_proc->is_64_bit_addspace, nrr_address, nrr_size)))) { - goto LOAD_NRR_END; + return rc; } if (R_FAILED((rc = nrr_info.Map()))) { - goto LOAD_NRR_END; + return rc; } rc = NroUtils::ValidateNrrHeader((NroUtils::NrrHeader *)nrr_info.mapped_address, nrr_size, target_proc->title_id); @@ -144,16 +112,10 @@ std::tuple RelocatableObjectsService::load_nrr(PidDescriptor pid_desc, u Registration::AddNrrInfo(target_proc->index, &nrr_info); } -LOAD_NRR_END: - if (R_FAILED(rc)) { - if (nrr_info.IsActive()) { - nrr_info.Close(); - } - } - return {rc}; + return rc; } -std::tuple RelocatableObjectsService::unload_nrr(PidDescriptor pid_desc, u64 nrr_address) { +Result RelocatableObjectsService::UnloadNrr(PidDescriptor pid_desc, u64 nrr_address) { Registration::Process *target_proc = NULL; if (!this->has_initialized || this->process_id != pid_desc.pid) { return 0xAE09; @@ -171,9 +133,8 @@ std::tuple RelocatableObjectsService::unload_nrr(PidDescriptor pid_desc, return Registration::RemoveNrrInfo(target_proc->index, nrr_address); } -std::tuple RelocatableObjectsService::initialize(PidDescriptor pid_desc, CopiedHandle process_h) { +Result RelocatableObjectsService::Initialize(PidDescriptor pid_desc, CopiedHandle process_h) { u64 handle_pid; - Result rc = 0xAE09; if (R_SUCCEEDED(svcGetProcessId(&handle_pid, process_h.handle)) && handle_pid == pid_desc.pid) { if (this->has_initialized) { svcCloseHandle(this->process_handle); @@ -181,7 +142,7 @@ std::tuple RelocatableObjectsService::initialize(PidDescriptor pid_desc, this->process_handle = process_h.handle; this->process_id = handle_pid; this->has_initialized = true; - rc = 0; + return 0; } - return {rc}; + return 0xAE09; } diff --git a/stratosphere/loader/source/ldr_ro_service.hpp b/stratosphere/loader/source/ldr_ro_service.hpp index 3e622587e..05bd9d058 100644 --- a/stratosphere/loader/source/ldr_ro_service.hpp +++ b/stratosphere/loader/source/ldr_ro_service.hpp @@ -17,7 +17,7 @@ #pragma once #include -#include +#include #include "ldr_registration.hpp" enum RoServiceCmd { @@ -33,27 +33,26 @@ class RelocatableObjectsService final : public IServiceObject { u64 process_id = U64_MAX; bool has_initialized = false; public: - ~RelocatableObjectsService() { + virtual ~RelocatableObjectsService() override { Registration::CloseRoService(this, this->process_handle); if (this->has_initialized) { svcCloseHandle(this->process_handle); } } - Result dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) override; - Result handle_deferred() override { - /* This service will never defer. */ - return 0; - } - - RelocatableObjectsService *clone() override { - return new RelocatableObjectsService(*this); - } private: /* Actual commands. */ - std::tuple load_nro(PidDescriptor pid_desc, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size); - std::tuple unload_nro(PidDescriptor pid_desc, u64 nro_address); - std::tuple load_nrr(PidDescriptor pid_desc, u64 nrr_address, u64 nrr_size); - std::tuple unload_nrr(PidDescriptor pid_desc, u64 nrr_address); - std::tuple initialize(PidDescriptor pid_desc, CopiedHandle process_h); + Result LoadNro(Out load_address, PidDescriptor pid_desc, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size); + Result UnloadNro(PidDescriptor pid_desc, u64 nro_address); + Result LoadNrr(PidDescriptor pid_desc, u64 nrr_address, u64 nrr_size); + Result UnloadNrr(PidDescriptor pid_desc, u64 nrr_address); + Result Initialize(PidDescriptor pid_desc, CopiedHandle process_h); + public: + DEFINE_SERVICE_DISPATCH_TABLE { + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + }; }; diff --git a/stratosphere/loader/source/ldr_shell.cpp b/stratosphere/loader/source/ldr_shell.cpp index 75b884a08..1a7c913eb 100644 --- a/stratosphere/loader/source/ldr_shell.cpp +++ b/stratosphere/loader/source/ldr_shell.cpp @@ -20,49 +20,28 @@ #include "ldr_launch_queue.hpp" #include "ldr_content_management.hpp" -Result ShellService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) { - - Result rc = 0xF601; - - switch ((ShellServiceCmd)cmd_id) { - case Shell_Cmd_AddTitleToLaunchQueue: - rc = WrapIpcCommandImpl<&ShellService::add_title_to_launch_queue>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Shell_Cmd_ClearLaunchQueue: - rc = WrapIpcCommandImpl<&ShellService::clear_launch_queue>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - case Shell_Cmd_AtmosphereSetExternalContentSource: - rc = WrapIpcCommandImpl<&ShellService::set_external_content_source>(this, r, out_c, pointer_buffer, pointer_buffer_size); - break; - default: - break; - } - return rc; -} - -std::tuple ShellService::add_title_to_launch_queue(u64 args_size, u64 tid, InPointer args) { +Result ShellService::AddTitleToLaunchQueue(u64 args_size, u64 tid, InPointer args) { fprintf(stderr, "Add to launch queue: %p, %zX\n", args.pointer, std::min(args_size, args.num_elements)); - return {LaunchQueue::add(tid, args.pointer, std::min(args_size, args.num_elements))}; + return LaunchQueue::Add(tid, args.pointer, std::min(args_size, args.num_elements)); } -std::tuple ShellService::clear_launch_queue(u64 dat) { - fprintf(stderr, "Clear launch queue: %lx\n", dat); - LaunchQueue::clear(); - return {0}; +void ShellService::ClearLaunchQueue() { + LaunchQueue::Clear(); } /* SetExternalContentSource extension */ -std::tuple ShellService::set_external_content_source(u64 tid) { +Result ShellService::SetExternalContentSource(Out out, u64 tid) { Handle server_h; Handle client_h; Result rc; if (R_FAILED(rc = svcCreateSession(&server_h, &client_h, 0, 0))) { - return {rc, 0}; + return rc; } Service service; serviceCreate(&service, client_h); ContentManagement::SetExternalContentSource(tid, FsFileSystem {service}); - return {0, server_h}; + out.SetValue(server_h); + return 0; } diff --git a/stratosphere/loader/source/ldr_shell.hpp b/stratosphere/loader/source/ldr_shell.hpp index 7b1c153d2..1094a9e08 100644 --- a/stratosphere/loader/source/ldr_shell.hpp +++ b/stratosphere/loader/source/ldr_shell.hpp @@ -16,7 +16,7 @@ #pragma once #include -#include +#include enum ShellServiceCmd { Shell_Cmd_AddTitleToLaunchQueue = 0, @@ -26,22 +26,17 @@ enum ShellServiceCmd { }; class ShellService final : public IServiceObject { - public: - Result dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) override; - Result handle_deferred() override { - /* This service will never defer. */ - return 0; - } - - ShellService *clone() override { - return new ShellService(); - } - private: /* Actual commands. */ - std::tuple add_title_to_launch_queue(u64 args_size, u64 tid, InPointer args); - std::tuple clear_launch_queue(u64 dat); - + Result AddTitleToLaunchQueue(u64 args_size, u64 tid, InPointer args); + void ClearLaunchQueue(); + /* Atmosphere commands. */ - std::tuple set_external_content_source(u64 tid); + Result SetExternalContentSource(Out out, u64 tid); + public: + DEFINE_SERVICE_DISPATCH_TABLE { + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + MakeServiceCommandMeta(), + }; };