From b843938b1a8d14a14cd1deb45540ea96ea9fba6d Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 19 Apr 2018 16:14:48 -0600 Subject: [PATCH] Stratosphere: Implement ldr:dmnt->GetNsoInfos() --- .../loader/source/ldr_debug_monitor.cpp | 12 +++++- .../loader/source/ldr_registration.cpp | 39 +++++++++++++++++-- .../loader/source/ldr_registration.hpp | 10 ++++- 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/stratosphere/loader/source/ldr_debug_monitor.cpp b/stratosphere/loader/source/ldr_debug_monitor.cpp index 17ebf25cd..c4f384120 100644 --- a/stratosphere/loader/source/ldr_debug_monitor.cpp +++ b/stratosphere/loader/source/ldr_debug_monitor.cpp @@ -1,7 +1,10 @@ #include #include +#include + #include "ldr_debug_monitor.hpp" #include "ldr_launch_queue.hpp" +#include "ldr_registration.hpp" Result DebugMonitorService::dispatch(IpcParsedCommand *r, IpcCommand *out_c, u32 *cmd_buf, u32 cmd_id, u32 *in_rawdata, u32 in_rawdata_size, u32 *out_rawdata, u32 *out_raw_data_count) { @@ -64,6 +67,11 @@ Result DebugMonitorService::clear_launch_queue() { } Result DebugMonitorService::get_nso_info(u64 pid, void *out, size_t out_size, u32 *out_num_nsos) { - /* TODO, once I've defined struct NsoInfo elsewhere (in ldr_RegisteredProcesses.hpp) */ - return 0; + u32 max_out = out_size / (sizeof(Registration::NsoInfo)); + + Registration::NsoInfo *nso_out = (Registration::NsoInfo *)out; + + std::fill(nso_out, nso_out + max_out, (const Registration::NsoInfo){0}); + + return Registration::get_nso_infos_for_process_id(nso_out, max_out, pid, out_num_nsos); } \ No newline at end of file diff --git a/stratosphere/loader/source/ldr_registration.cpp b/stratosphere/loader/source/ldr_registration.cpp index 0013a51e8..e6922ef9a 100644 --- a/stratosphere/loader/source/ldr_registration.cpp +++ b/stratosphere/loader/source/ldr_registration.cpp @@ -26,6 +26,16 @@ Registration::Process *Registration::get_process(u64 index) { return &g_registration_list.processes[i]; } +Registration::Process *Registration::get_process_by_process_id(u64 pid) { + unsigned int i; + for (i = 0; !g_registration_list.processes[i].in_use || g_registration_list.processes[i].process_id != pid; i++) { + if (i >= REGISTRATION_LIST_MAX) { + return NULL; + } + } + return &g_registration_list.processes[i]; +} + bool Registration::register_tid_sid(const TidSid *tid_sid, u64 *out_index) { Registration::Process *free_process = get_free_process(); if (free_process == NULL) { @@ -70,11 +80,32 @@ void Registration::add_nso_info(u64 index, u64 base_address, u64 size, const uns for (unsigned int i = 0; i < NSO_INFO_MAX; i++) { if (!target_process->nso_infos[i].in_use) { - target_process->nso_infos[i].base_address = base_address; - target_process->nso_infos[i].size = size; - std::copy(build_id, build_id + sizeof(target_process->nso_infos[i].build_id), target_process->nso_infos[i].build_id); + target_process->nso_infos[i].info.base_address = base_address; + target_process->nso_infos[i].info.size = size; + std::copy(build_id, build_id + sizeof(target_process->nso_infos[i].info.build_id), target_process->nso_infos[i].info.build_id); target_process->nso_infos[i].in_use = true; return; } } -} \ No newline at end of file +} + + +Result Registration::get_nso_infos_for_process_id(Registration::NsoInfo *out, u32 max_out, u64 process_id, u32 *num_written) { + Registration::Process *target_process = get_process_by_process_id(process_id); + if (target_process == NULL) { + return 0x1009; + } + u32 cur = 0; + + if (max_out > 0) { + for (unsigned int i = 0; i < NSO_INFO_MAX && cur < max_out; i++) { + if (target_process->nso_infos[i].in_use) { + out[cur++] = target_process->nso_infos[i].info; + } + } + } + + *num_written = cur; + + return 0; +} diff --git a/stratosphere/loader/source/ldr_registration.hpp b/stratosphere/loader/source/ldr_registration.hpp index fc5774422..7656931be 100644 --- a/stratosphere/loader/source/ldr_registration.hpp +++ b/stratosphere/loader/source/ldr_registration.hpp @@ -8,12 +8,16 @@ class Registration { public: struct NsoInfo { - bool in_use; u64 base_address; u64 size; unsigned char build_id[0x20]; }; + struct NsoInfoHolder { + bool in_use; + NsoInfo info; + }; + struct TidSid { u64 title_id; FsStorageId storage_id; @@ -25,7 +29,7 @@ class Registration { u64 process_id; u64 title_id_min; Registration::TidSid tid_sid; - Registration::NsoInfo nso_infos[NSO_INFO_MAX]; + Registration::NsoInfoHolder nso_infos[NSO_INFO_MAX]; u64 _0x730; }; @@ -36,8 +40,10 @@ class Registration { static Registration::Process *get_free_process(); static Registration::Process *get_process(u64 index); + static Registration::Process *get_process_by_process_id(u64 pid); static bool register_tid_sid(const TidSid *tid_sid, u64 *out_index); static bool unregister_index(u64 index); static void set_process_id_and_tid_min(u64 index, u64 process_id, u64 tid_min); static void add_nso_info(u64 index, u64 base_address, u64 size, const unsigned char *build_id); + static Result get_nso_infos_for_process_id(NsoInfo *out, u32 max_out, u64 process_id, u32 *num_written); };