Loader: Implement all remaining parts of CreateProcess except LoadNsoSegment.

This commit is contained in:
Michael Scire 2018-04-24 06:25:31 -06:00
parent ee9bfd514c
commit 80fedc51c1
3 changed files with 32 additions and 9 deletions

View file

@ -34,6 +34,14 @@ bool NsoUtils::IsNsoPresent(unsigned int index) {
return g_nso_present[index]; return g_nso_present[index];
} }
unsigned char *NsoUtils::GetNsoBuildId(unsigned int index) {
if (g_nso_present[index]) {
return g_nso_headers[index].build_id;
}
return NULL;
}
Result NsoUtils::LoadNsoHeaders(u64 title_id) { Result NsoUtils::LoadNsoHeaders(u64 title_id) {
FILE *f_nso; FILE *f_nso;
@ -234,6 +242,7 @@ Result NsoUtils::LoadNsosIntoProcessMemory(Handle process_h, u64 title_id, NsoLo
} }
} }
/* Map in arguments. */
if (args != NULL && args_size) { if (args != NULL && args_size) {
u64 arg_map_addr = 0; u64 arg_map_addr = 0;
if (R_FAILED((rc = MapUtils::LocateSpaceForMap(&arg_map_addr, extents->args_size)))) { if (R_FAILED((rc = MapUtils::LocateSpaceForMap(&arg_map_addr, extents->args_size)))) {
@ -259,5 +268,6 @@ Result NsoUtils::LoadNsosIntoProcessMemory(Handle process_h, u64 title_id, NsoLo
return rc; return rc;
} }
} }
return rc; return rc;
} }

View file

@ -86,6 +86,7 @@ class NsoUtils {
static FILE *OpenNso(unsigned int index, u64 title_id); static FILE *OpenNso(unsigned int index, u64 title_id);
static bool IsNsoPresent(unsigned int index); static bool IsNsoPresent(unsigned int index);
static unsigned char *GetNsoBuildId(unsigned int index);
static Result LoadNsoHeaders(u64 title_id); static Result LoadNsoHeaders(u64 title_id);
static Result ValidateNsoLoadSet(); static Result ValidateNsoLoadSet();
static Result CalculateNsoLoadExtents(u32 addspace_type, u32 args_size, NsoLoadExtents *extents); static Result CalculateNsoLoadExtents(u32 addspace_type, u32 args_size, NsoLoadExtents *extents);

View file

@ -92,6 +92,7 @@ Result ProcessCreation::CreateProcess(Handle *out_process_h, u64 index, char *nc
NsoUtils::NsoLoadExtents nso_extents = {0}; NsoUtils::NsoLoadExtents nso_extents = {0};
Registration::Process *target_process; Registration::Process *target_process;
Handle process_h = 0; Handle process_h = 0;
u64 process_id = 0;
Result rc; Result rc;
/* Get the process from the registration queue. */ /* Get the process from the registration queue. */
@ -161,17 +162,23 @@ Result ProcessCreation::CreateProcess(Handle *out_process_h, u64 index, char *nc
/* Load all NSOs into Process memory, and set permissions accordingly. */ /* Load all NSOs into Process memory, and set permissions accordingly. */
if (launch_item == NULL) { if (launch_item == NULL) {
NsoUtils::LoadNsosIntoProcessMemory(process_h, npdm_info.aci0->title_id, &nso_extents, (u8 *)launch_item->args, launch_item->arg_size); rc = NsoUtils::LoadNsosIntoProcessMemory(process_h, npdm_info.aci0->title_id, &nso_extents, (u8 *)launch_item->args, launch_item->arg_size);
} else { } else {
NsoUtils::LoadNsosIntoProcessMemory(process_h, npdm_info.aci0->title_id, &nso_extents, NULL, 0); rc = NsoUtils::LoadNsosIntoProcessMemory(process_h, npdm_info.aci0->title_id, &nso_extents, NULL, 0);
}
if (R_FAILED(rc)) {
svcCloseHandle(process_h);
goto CREATE_PROCESS_END;
} }
/* TODO: For each NSO, call svcMapProcessMemory, load the NSO into memory there (validating it), and then svcUnmapProcessMemory. */
/* TODO: svcSetProcessMemoryPermission for each memory segment in the new process. */ /* Update the list of registered processes with the new process. */
svcGetProcessId(&process_id, process_h);
/* TODO: Map and load arguments to the process, if relevant. */ Registration::set_process_id_and_tid_min(index, process_id, npdm_info.aci0->title_id);
for (unsigned int i = 0; i < NSO_NUM_MAX; i++) {
/* TODO: Update the list of registered processes with the new process. */ if (NsoUtils::IsNsoPresent(i)) {
Registration::add_nso_info(index, nso_extents.nso_addresses[i], nso_extents.nso_sizes[i], NsoUtils::GetNsoBuildId(i));
}
}
rc = 0; rc = 0;
CREATE_PROCESS_END: CREATE_PROCESS_END:
@ -180,5 +187,10 @@ CREATE_PROCESS_END:
} else { } else {
ContentManagement::UnmountCode(); ContentManagement::UnmountCode();
} }
if (R_SUCCEEDED(rc)) {
*out_process_h = process_h;
} else {
svcCloseHandle(process_h);
}
return rc; return rc;
} }