loader: refactor to use LoaderModuleInfo

This commit is contained in:
Michael Scire 2019-04-20 18:15:39 -07:00
parent 5c9d0f05b1
commit ed86c44a49
5 changed files with 36 additions and 44 deletions

View file

@ -31,9 +31,9 @@ void DebugMonitorService::ClearLaunchQueue() {
LaunchQueue::Clear(); LaunchQueue::Clear();
} }
Result DebugMonitorService::GetNsoInfo(Out<u32> count, OutPointerWithClientSize<Registration::NsoInfo> out, u64 pid) { Result DebugMonitorService::GetProcessModuleInfo(Out<u32> count, OutPointerWithClientSize<LoaderModuleInfo> out, u64 pid) {
/* Zero out the output memory. */ /* Zero out the output memory. */
std::fill(out.pointer, out.pointer + out.num_elements, Registration::NsoInfo{}); std::memset(out.pointer, 0, out.num_elements * sizeof(LoaderModuleInfo));
/* Actually return the nso infos. */ /* Actually return the nso infos. */
return Registration::GetNsoInfosForProcessId(out.pointer, out.num_elements, pid, count.GetPointer()); return Registration::GetProcessModuleInfo(out.pointer, out.num_elements, pid, count.GetPointer());
} }

View file

@ -18,12 +18,11 @@
#include <switch.h> #include <switch.h>
#include <stratosphere.hpp> #include <stratosphere.hpp>
#include "ldr_registration.hpp"
enum DebugMonitorServiceCmd { enum DebugMonitorServiceCmd {
Dmnt_Cmd_AddTitleToLaunchQueue = 0, Dmnt_Cmd_AddTitleToLaunchQueue = 0,
Dmnt_Cmd_ClearLaunchQueue = 1, Dmnt_Cmd_ClearLaunchQueue = 1,
Dmnt_Cmd_GetNsoInfo = 2 Dmnt_Cmd_GetProcessModuleInfo = 2
}; };
class DebugMonitorService final : public IServiceObject { class DebugMonitorService final : public IServiceObject {
@ -31,11 +30,11 @@ class DebugMonitorService final : public IServiceObject {
/* Actual commands. */ /* Actual commands. */
Result AddTitleToLaunchQueue(u64 tid, InPointer<char> args, u32 args_size); Result AddTitleToLaunchQueue(u64 tid, InPointer<char> args, u32 args_size);
void ClearLaunchQueue(); void ClearLaunchQueue();
Result GetNsoInfo(Out<u32> count, OutPointerWithClientSize<Registration::NsoInfo> out, u64 pid); Result GetProcessModuleInfo(Out<u32> count, OutPointerWithClientSize<LoaderModuleInfo> out, u64 pid);
public: public:
DEFINE_SERVICE_DISPATCH_TABLE { DEFINE_SERVICE_DISPATCH_TABLE {
MakeServiceCommandMeta<Dmnt_Cmd_AddTitleToLaunchQueue, &DebugMonitorService::AddTitleToLaunchQueue>(), MakeServiceCommandMeta<Dmnt_Cmd_AddTitleToLaunchQueue, &DebugMonitorService::AddTitleToLaunchQueue>(),
MakeServiceCommandMeta<Dmnt_Cmd_ClearLaunchQueue, &DebugMonitorService::ClearLaunchQueue>(), MakeServiceCommandMeta<Dmnt_Cmd_ClearLaunchQueue, &DebugMonitorService::ClearLaunchQueue>(),
MakeServiceCommandMeta<Dmnt_Cmd_GetNsoInfo, &DebugMonitorService::GetNsoInfo>(), MakeServiceCommandMeta<Dmnt_Cmd_GetProcessModuleInfo, &DebugMonitorService::GetProcessModuleInfo>(),
}; };
}; };

View file

@ -214,7 +214,7 @@ Result ProcessCreation::CreateProcess(Handle *out_process_h, u64 index, char *nc
Registration::SetProcessIdTidAndIs64BitAddressSpace(index, process_id, npdm_info.aci0->title_id, is_64_bit_addspace); Registration::SetProcessIdTidAndIs64BitAddressSpace(index, process_id, npdm_info.aci0->title_id, is_64_bit_addspace);
for (unsigned int i = 0; i < NSO_NUM_MAX; i++) { for (unsigned int i = 0; i < NSO_NUM_MAX; i++) {
if (NsoUtils::IsNsoPresent(i)) { if (NsoUtils::IsNsoPresent(i)) {
Registration::AddNsoInfo(index, nso_extents.nso_addresses[i], nso_extents.nso_sizes[i], NsoUtils::GetNsoBuildId(i)); Registration::AddModuleInfo(index, nso_extents.nso_addresses[i], nso_extents.nso_sizes[i], NsoUtils::GetNsoBuildId(i));
} }
} }

View file

@ -34,7 +34,7 @@ Registration::Process *Registration::GetFreeProcess() {
} }
Registration::Process *Registration::GetProcess(u64 index) { Registration::Process *Registration::GetProcess(u64 index) {
for (unsigned int i = 0; i < REGISTRATION_LIST_MAX; i++) { for (unsigned int i = 0; i < Registration::MaxProcesses; i++) {
if (g_registration_list.processes[i].in_use && g_registration_list.processes[i].index == index) { if (g_registration_list.processes[i].in_use && g_registration_list.processes[i].index == index) {
return &g_registration_list.processes[i]; return &g_registration_list.processes[i];
} }
@ -43,7 +43,7 @@ Registration::Process *Registration::GetProcess(u64 index) {
} }
Registration::Process *Registration::GetProcessByProcessId(u64 pid) { Registration::Process *Registration::GetProcessByProcessId(u64 pid) {
for (unsigned int i = 0; i < REGISTRATION_LIST_MAX; i++) { for (unsigned int i = 0; i < Registration::MaxProcesses; i++) {
if (g_registration_list.processes[i].in_use && g_registration_list.processes[i].process_id == pid) { if (g_registration_list.processes[i].in_use && g_registration_list.processes[i].process_id == pid) {
return &g_registration_list.processes[i]; return &g_registration_list.processes[i];
} }
@ -52,7 +52,7 @@ Registration::Process *Registration::GetProcessByProcessId(u64 pid) {
} }
Registration::Process *Registration::GetProcessByRoService(void *service) { Registration::Process *Registration::GetProcessByRoService(void *service) {
for (unsigned int i = 0; i < REGISTRATION_LIST_MAX; i++) { for (unsigned int i = 0; i < Registration::MaxProcesses; i++) {
if (g_registration_list.processes[i].in_use && g_registration_list.processes[i].owner_ro_service == service) { if (g_registration_list.processes[i].in_use && g_registration_list.processes[i].owner_ro_service == service) {
return &g_registration_list.processes[i]; return &g_registration_list.processes[i];
} }
@ -109,17 +109,17 @@ void Registration::SetProcessIdTidAndIs64BitAddressSpace(u64 index, u64 process_
target_process->is_64_bit_addspace = is_64_bit_addspace; target_process->is_64_bit_addspace = is_64_bit_addspace;
} }
void Registration::AddNsoInfo(u64 index, u64 base_address, u64 size, const unsigned char *build_id) { void Registration::AddModuleInfo(u64 index, u64 base_address, u64 size, const unsigned char *build_id) {
Registration::Process *target_process = GetProcess(index); Registration::Process *target_process = GetProcess(index);
if (target_process == NULL) { if (target_process == NULL) {
return; return;
} }
auto nso_info_it = std::find_if_not(target_process->nso_infos.begin(), target_process->nso_infos.end(), std::mem_fn(&Registration::NsoInfoHolder::in_use)); auto nso_info_it = std::find_if_not(target_process->module_infos.begin(), target_process->module_infos.end(), std::mem_fn(&Registration::ModuleInfoHolder::in_use));
if (nso_info_it != target_process->nso_infos.end()) { if (nso_info_it != target_process->module_infos.end()) {
nso_info_it->info.base_address = base_address; nso_info_it->info.base_address = base_address;
nso_info_it->info.size = size; nso_info_it->info.size = size;
std::copy(build_id, build_id + sizeof(nso_info_it->info.build_id), nso_info_it->info.build_id); memcpy(nso_info_it->info.build_id, build_id, sizeof(nso_info_it->info.build_id));
nso_info_it->in_use = true; nso_info_it->in_use = true;
} }
} }
@ -129,7 +129,7 @@ void Registration::CloseRoService(void *service, Handle process_h) {
if (target_process == NULL) { if (target_process == NULL) {
return; return;
} }
for (unsigned int i = 0; i < NRR_INFO_MAX; i++) { for (unsigned int i = 0; i < Registration::MaxNrrInfos; i++) {
if (target_process->nrr_infos[i].IsActive() && target_process->nrr_infos[i].process_handle == process_h) { if (target_process->nrr_infos[i].IsActive() && target_process->nrr_infos[i].process_handle == process_h) {
target_process->nrr_infos[i].Close(); target_process->nrr_infos[i].Close();
} }
@ -159,7 +159,7 @@ Result Registration::RemoveNrrInfo(u64 index, u64 base_address) {
return ResultLoaderProcessNotRegistered; return ResultLoaderProcessNotRegistered;
} }
for (unsigned int i = 0; i < NRR_INFO_MAX; i++) { for (unsigned int i = 0; i < Registration::MaxNrrInfos; i++) {
if (target_process->nrr_infos[i].IsActive() && target_process->nrr_infos[i].base_address == base_address) { if (target_process->nrr_infos[i].IsActive() && target_process->nrr_infos[i].base_address == base_address) {
target_process->nrr_infos[i].Close(); target_process->nrr_infos[i].Close();
return ResultSuccess; return ResultSuccess;
@ -176,7 +176,7 @@ bool Registration::IsNroHashPresent(u64 index, u8 *nro_hash) {
return false; return false;
} }
for (unsigned int i = 0; i < NRR_INFO_MAX; i++) { for (unsigned int i = 0; i < Registration::MaxNrrInfos; i++) {
if (target_process->nrr_infos[i].IsActive()) { if (target_process->nrr_infos[i].IsActive()) {
NroUtils::NrrHeader *nrr = (NroUtils::NrrHeader *)target_process->nrr_infos[i].mapped_address; NroUtils::NrrHeader *nrr = (NroUtils::NrrHeader *)target_process->nrr_infos[i].mapped_address;
/* Binary search. */ /* Binary search. */
@ -205,7 +205,7 @@ bool Registration::IsNroAlreadyLoaded(u64 index, u8 *build_id) {
return true; return true;
} }
for (unsigned int i = 0; i < NRO_INFO_MAX; i++) { for (unsigned int i = 0; i < Registration::MaxNroInfos; i++) {
if (target_process->nro_infos[i].in_use && std::equal(build_id, build_id + 0x20, target_process->nro_infos[i].build_id)) { if (target_process->nro_infos[i].in_use && std::equal(build_id, build_id + 0x20, target_process->nro_infos[i].build_id)) {
return true; return true;
} }
@ -241,7 +241,7 @@ Result Registration::RemoveNroInfo(u64 index, Handle process_h, u64 nro_heap_add
return ResultLoaderProcessNotRegistered; return ResultLoaderProcessNotRegistered;
} }
for (unsigned int i = 0; i < NRO_INFO_MAX; i++) { for (unsigned int i = 0; i < Registration::MaxNroInfos; i++) {
if (target_process->nro_infos[i].in_use && target_process->nro_infos[i].nro_heap_address == nro_heap_address) { 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]; 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); 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);
@ -258,16 +258,16 @@ Result Registration::RemoveNroInfo(u64 index, Handle process_h, u64 nro_heap_add
return ResultLoaderNotLoaded; return ResultLoaderNotLoaded;
} }
Result Registration::GetNsoInfosForProcessId(Registration::NsoInfo *out, u32 max_out, u64 process_id, u32 *num_written) { Result Registration::GetProcessModuleInfo(LoaderModuleInfo *out, u32 max_out, u64 process_id, u32 *num_written) {
Registration::Process *target_process = GetProcessByProcessId(process_id); Registration::Process *target_process = GetProcessByProcessId(process_id);
if (target_process == NULL) { if (target_process == NULL) {
return ResultLoaderProcessNotRegistered; return ResultLoaderProcessNotRegistered;
} }
u32 cur = 0; u32 cur = 0;
for (unsigned int i = 0; i < NSO_INFO_MAX && cur < max_out; i++) { for (unsigned int i = 0; i < Registration::MaxModuleInfos && cur < max_out; i++) {
if (target_process->nso_infos[i].in_use) { if (target_process->module_infos[i].in_use) {
out[cur++] = target_process->nso_infos[i].info; out[cur++] = target_process->module_infos[i].info;
} }
} }

View file

@ -20,23 +20,16 @@
#include "ldr_map.hpp" #include "ldr_map.hpp"
#define REGISTRATION_LIST_MAX (0x40)
#define NSO_INFO_MAX (0x20)
#define NRR_INFO_MAX (0x40)
#define NRO_INFO_MAX (0x40)
class Registration { class Registration {
public: public:
struct NsoInfo { static constexpr size_t MaxProcesses = 0x40;
u64 base_address; static constexpr size_t MaxModuleInfos = 0x20;
u64 size; static constexpr size_t MaxNrrInfos = 0x40;
unsigned char build_id[0x20]; static constexpr size_t MaxNroInfos = 0x40;
}; public:
struct ModuleInfoHolder {
struct NsoInfoHolder {
bool in_use; bool in_use;
NsoInfo info; LoaderModuleInfo info;
}; };
struct NroInfo { struct NroInfo {
@ -65,14 +58,14 @@ class Registration {
u64 process_id; u64 process_id;
u64 title_id; u64 title_id;
Registration::TidSid tid_sid; Registration::TidSid tid_sid;
std::array<Registration::NsoInfoHolder, NSO_INFO_MAX> nso_infos; std::array<Registration::ModuleInfoHolder, MaxModuleInfos> module_infos;
std::array<Registration::NroInfo, NRO_INFO_MAX> nro_infos; std::array<Registration::NroInfo, MaxNroInfos> nro_infos;
std::array<MappedCodeMemory, NRR_INFO_MAX> nrr_infos; std::array<MappedCodeMemory, MaxNrrInfos> nrr_infos;
void *owner_ro_service; void *owner_ro_service;
}; };
struct List { struct List {
std::array<Registration::Process, REGISTRATION_LIST_MAX> processes; std::array<Registration::Process, MaxProcesses> processes;
u64 num_processes; u64 num_processes;
}; };
@ -84,7 +77,7 @@ class Registration {
static bool RegisterTidSid(const TidSid *tid_sid, u64 *out_index); static bool RegisterTidSid(const TidSid *tid_sid, u64 *out_index);
static bool UnregisterIndex(u64 index); static bool UnregisterIndex(u64 index);
static void SetProcessIdTidAndIs64BitAddressSpace(u64 index, u64 process_id, u64 tid, bool is_64_bit_addspace); static void SetProcessIdTidAndIs64BitAddressSpace(u64 index, u64 process_id, u64 tid, bool is_64_bit_addspace);
static void AddNsoInfo(u64 index, u64 base_address, u64 size, const unsigned char *build_id); static void AddModuleInfo(u64 index, u64 base_address, u64 size, const unsigned char *build_id);
static void CloseRoService(void *service, Handle process_h); static void CloseRoService(void *service, Handle process_h);
static Result AddNrrInfo(u64 index, MappedCodeMemory *nrr_info); static Result AddNrrInfo(u64 index, MappedCodeMemory *nrr_info);
static Result RemoveNrrInfo(u64 index, u64 base_address); static Result RemoveNrrInfo(u64 index, u64 base_address);
@ -92,7 +85,7 @@ class Registration {
static bool IsNroAlreadyLoaded(u64 index, u8 *build_id); 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 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 RemoveNroInfo(u64 index, Handle process_h, u64 base_address);
static Result GetNsoInfosForProcessId(NsoInfo *out, u32 max_out, u64 process_id, u32 *num_written); static Result GetProcessModuleInfo(LoaderModuleInfo *out, u32 max_out, u64 process_id, u32 *num_written);
/* Atmosphere MitM Extension. */ /* Atmosphere MitM Extension. */
static void AssociatePidTidForMitM(u64 index); static void AssociatePidTidForMitM(u64 index);