mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-10 07:06:34 +00:00
Loader: Implement InitializeProcessInfo()
This commit is contained in:
parent
7227817b99
commit
2d6445d2f9
5 changed files with 128 additions and 22 deletions
|
@ -377,3 +377,22 @@ Result NpdmUtils::ValidateCapabilities(u32 *acid_caps, size_t num_acid_caps, u32
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 NpdmUtils::GetApplicationType(u32 *caps, size_t num_caps) {
|
||||||
|
u32 application_type = 0;
|
||||||
|
for (unsigned int i = 0; i < num_caps; i++) {
|
||||||
|
if ((caps[i] & 0x3FFF) == 0x1FFF) {
|
||||||
|
u16 app_type = (caps[i] >> 14) & 7;
|
||||||
|
if (app_type == 1) {
|
||||||
|
application_type |= 1;
|
||||||
|
} else if (app_type == 2) {
|
||||||
|
application_type |= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* After 1.0.0, allow_debug is used as bit 4. */
|
||||||
|
if (kernelAbove200() && (caps[i] & 0x1FFFF) == 0xFFFF) {
|
||||||
|
application_type |= (caps[i] >> 15) & 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return application_type;
|
||||||
|
}
|
|
@ -17,7 +17,8 @@ class NpdmUtils {
|
||||||
u8 _0xD;
|
u8 _0xD;
|
||||||
u8 main_thread_prio;
|
u8 main_thread_prio;
|
||||||
u8 default_cpuid;
|
u8 default_cpuid;
|
||||||
u64 _0x10;
|
u32 _0x10;
|
||||||
|
u32 system_resource_size;
|
||||||
u32 process_category;
|
u32 process_category;
|
||||||
u32 main_stack_size;
|
u32 main_stack_size;
|
||||||
char title_name[0x50];
|
char title_name[0x50];
|
||||||
|
@ -77,6 +78,8 @@ class NpdmUtils {
|
||||||
static_assert(sizeof(NpdmAcid) == 0x240, "Incorrectly defined NpdmAcid!");
|
static_assert(sizeof(NpdmAcid) == 0x240, "Incorrectly defined NpdmAcid!");
|
||||||
static_assert(sizeof(NpdmAci0) == 0x40, "Incorrectly defined NpdmAci0!");
|
static_assert(sizeof(NpdmAci0) == 0x40, "Incorrectly defined NpdmAci0!");
|
||||||
|
|
||||||
|
static u32 GetApplicationType(u32 *caps, size_t num_caps);
|
||||||
|
|
||||||
static Result ValidateCapabilityAgainstRestrictions(u32 *restrict_caps, size_t num_restrict_caps, u32 *&cur_cap, size_t &caps_remaining);
|
static Result ValidateCapabilityAgainstRestrictions(u32 *restrict_caps, size_t num_restrict_caps, u32 *&cur_cap, size_t &caps_remaining);
|
||||||
static Result ValidateCapabilities(u32 *acid_caps, size_t num_acid_caps, u32 *aci0_caps, size_t num_aci0_caps);
|
static Result ValidateCapabilities(u32 *acid_caps, size_t num_acid_caps, u32 *aci0_caps, size_t num_aci0_caps);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "ldr_process_creation.hpp"
|
#include "ldr_process_creation.hpp"
|
||||||
#include "ldr_registration.hpp"
|
#include "ldr_registration.hpp"
|
||||||
|
@ -7,8 +8,87 @@
|
||||||
#include "ldr_npdm.hpp"
|
#include "ldr_npdm.hpp"
|
||||||
#include "ldr_nso.hpp"
|
#include "ldr_nso.hpp"
|
||||||
|
|
||||||
Result ProcessCreation::CreateProcess(Handle *out_process_h, u64 index, char *nca_path, LaunchQueue::LaunchItem *launch_item, u64 flags, Handle reslimit_h) {
|
Result ProcessCreation::InitializeProcessInfo(NpdmUtils::NpdmInfo *npdm, Handle reslimit_h, u64 arg_flags, ProcessInfo *out_proc_info) {
|
||||||
NpdmUtils::NpdmInfo info;
|
/* Initialize a ProcessInfo using an npdm. */
|
||||||
|
*out_proc_info = (const ProcessCreation::ProcessInfo){0};
|
||||||
|
|
||||||
|
/* Copy all but last char of name, insert NULL terminator. */
|
||||||
|
std::copy(npdm->header->title_name, npdm->header->title_name + sizeof(out_proc_info->name) - 1, out_proc_info->name);
|
||||||
|
out_proc_info->name[sizeof(out_proc_info->name) - 1] = 0;
|
||||||
|
|
||||||
|
/* Set title id. */
|
||||||
|
out_proc_info->title_id = npdm->aci0->title_id;
|
||||||
|
|
||||||
|
/* Set process category. */
|
||||||
|
out_proc_info->process_category = npdm->header->process_category;
|
||||||
|
|
||||||
|
/* Copy reslimit handle raw. */
|
||||||
|
out_proc_info->reslimit_h = reslimit_h;
|
||||||
|
|
||||||
|
/* Set IsAddressSpace64Bit, AddressSpaceType. */
|
||||||
|
if (npdm->header->mmu_flags & 8) {
|
||||||
|
/* Invalid Address Space Type. */
|
||||||
|
return 0x809;
|
||||||
|
}
|
||||||
|
out_proc_info->process_flags = (npdm->header->mmu_flags & 0xF);
|
||||||
|
/* Set Bit 4 (?) and EnableAslr based on argument flags. */
|
||||||
|
out_proc_info->process_flags |= ((arg_flags & 3) << 4) ^ 0x20;
|
||||||
|
/* Set UseSystemMemBlocks if application type is 1. */
|
||||||
|
u32 application_type = NpdmUtils::GetApplicationType((u32 *)npdm->aci0_kac, npdm->aci0->kac_size / sizeof(u32));
|
||||||
|
if ((application_type & 3) == 1) {
|
||||||
|
out_proc_info->process_flags |= 0x40;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 3.0.0+ System Resource Size. */
|
||||||
|
if (kernelAbove300()) {
|
||||||
|
if (npdm->header->system_resource_size & 0x1FFFFF) {
|
||||||
|
return 0xA409;
|
||||||
|
}
|
||||||
|
if (npdm->header->system_resource_size) {
|
||||||
|
if ((out_proc_info->process_flags & 6) == 0) {
|
||||||
|
return 0x809;
|
||||||
|
}
|
||||||
|
if ((application_type & 3) != 1) {
|
||||||
|
return 0x809;
|
||||||
|
}
|
||||||
|
if (npdm->header->system_resource_size > 0x1FE00000) {
|
||||||
|
return 0x809;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out_proc_info->system_resource_num_pages = npdm->header->system_resource_size >> 12;
|
||||||
|
} else {
|
||||||
|
out_proc_info->system_resource_num_pages = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 5.0.0+ Pool Partition. */
|
||||||
|
if (kernelAbove500()) {
|
||||||
|
u32 pool_partition_id = (npdm->acid->is_retail >> 2) & 0xF;
|
||||||
|
switch (pool_partition_id) {
|
||||||
|
case 0: /* Application. */
|
||||||
|
if ((application_type & 3) == 2) {
|
||||||
|
out_proc_info->process_flags |= 0x80;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1: /* Applet. */
|
||||||
|
out_proc_info->process_flags |= 0x80;
|
||||||
|
break;
|
||||||
|
case 2: /* Sysmodule. */
|
||||||
|
out_proc_info->process_flags |= 0x100;
|
||||||
|
break;
|
||||||
|
case 3: /* nvservices. */
|
||||||
|
out_proc_info->process_flags |= 0x180;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0x809;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0x0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ProcessCreation::CreateProcess(Handle *out_process_h, u64 index, char *nca_path, LaunchQueue::LaunchItem *launch_item, u64 arg_flags, Handle reslimit_h) {
|
||||||
|
NpdmUtils::NpdmInfo npdm_info = {0};
|
||||||
|
ProcessInfo process_info = {0};
|
||||||
Registration::Process *target_process;
|
Registration::Process *target_process;
|
||||||
Result rc;
|
Result rc;
|
||||||
|
|
||||||
|
@ -25,25 +105,25 @@ Result ProcessCreation::CreateProcess(Handle *out_process_h, u64 index, char *nc
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load the process's NPDM. */
|
/* Load the process's NPDM. */
|
||||||
rc = NpdmUtils::LoadNpdmFromCache(target_process->tid_sid.title_id, &info);
|
rc = NpdmUtils::LoadNpdmFromCache(target_process->tid_sid.title_id, &npdm_info);
|
||||||
if (R_FAILED(rc)) {
|
if (R_FAILED(rc)) {
|
||||||
goto CREATE_PROCESS_END;
|
goto CREATE_PROCESS_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Validate the title we're loading is what we expect. */
|
/* Validate the title we're loading is what we expect. */
|
||||||
if (info.aci0->title_id < info.acid->title_id_range_min || info.aci0->title_id > info.acid->title_id_range_max) {
|
if (npdm_info.aci0->title_id < npdm_info.acid->title_id_range_min || npdm_info.aci0->title_id > npdm_info.acid->title_id_range_max) {
|
||||||
rc = 0x1209;
|
rc = 0x1209;
|
||||||
goto CREATE_PROCESS_END;
|
goto CREATE_PROCESS_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Validate that the ACI0 Kernel Capabilities are valid and restricted by the ACID Kernel Capabilities. */
|
/* Validate that the ACI0 Kernel Capabilities are valid and restricted by the ACID Kernel Capabilities. */
|
||||||
rc = NpdmUtils::ValidateCapabilities((u32 *)info.acid_kac, info.acid->kac_size/sizeof(u32), (u32 *)info.aci0_kac, info.aci0->kac_size/sizeof(u32));
|
rc = NpdmUtils::ValidateCapabilities((u32 *)npdm_info.acid_kac, npdm_info.acid->kac_size/sizeof(u32), (u32 *)npdm_info.aci0_kac, npdm_info.aci0->kac_size/sizeof(u32));
|
||||||
if (R_FAILED(rc)) {
|
if (R_FAILED(rc)) {
|
||||||
goto CREATE_PROCESS_END;
|
goto CREATE_PROCESS_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read in all NSO headers, see what NSOs are present. */
|
/* Read in all NSO headers, see what NSOs are present. */
|
||||||
rc = NsoUtils::LoadNsoHeaders(info.aci0->title_id);
|
rc = NsoUtils::LoadNsoHeaders(npdm_info.aci0->title_id);
|
||||||
if (R_FAILED(rc)) {
|
if (R_FAILED(rc)) {
|
||||||
goto CREATE_PROCESS_END;
|
goto CREATE_PROCESS_END;
|
||||||
}
|
}
|
||||||
|
@ -54,7 +134,11 @@ Result ProcessCreation::CreateProcess(Handle *out_process_h, u64 index, char *nc
|
||||||
goto CREATE_PROCESS_END;
|
goto CREATE_PROCESS_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Create the CreateProcessInfo. */
|
/* Initialize the ProcessInfo. */
|
||||||
|
rc = ProcessCreation::InitializeProcessInfo(&npdm_info, reslimit_h, arg_flags, &process_info);
|
||||||
|
if (R_FAILED(rc)) {
|
||||||
|
goto CREATE_PROCESS_END;
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: Figure out where NSOs will be mapped, and how much space they (and arguments) will take up. */
|
/* TODO: Figure out where NSOs will be mapped, and how much space they (and arguments) will take up. */
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,22 @@
|
||||||
|
|
||||||
#include "ldr_registration.hpp"
|
#include "ldr_registration.hpp"
|
||||||
#include "ldr_launch_queue.hpp"
|
#include "ldr_launch_queue.hpp"
|
||||||
|
#include "ldr_npdm.hpp"
|
||||||
|
|
||||||
/* Utilities for Process Creation, for Loader. */
|
/* Utilities for Process Creation, for Loader. */
|
||||||
|
|
||||||
class ProcessCreation {
|
class ProcessCreation {
|
||||||
public:
|
public:
|
||||||
static Result CreateProcess(Handle *out_process_h, u64 index, char *nca_path, LaunchQueue::LaunchItem *launch_item, u64 flags, Handle reslimit_h);
|
struct ProcessInfo {
|
||||||
|
u8 name[12];
|
||||||
|
u32 process_category;
|
||||||
|
u64 title_id;
|
||||||
|
u64 code_addr;
|
||||||
|
u32 code_num_pages;
|
||||||
|
u32 process_flags;
|
||||||
|
Handle reslimit_h;
|
||||||
|
u32 system_resource_num_pages;
|
||||||
|
};
|
||||||
|
static Result InitializeProcessInfo(NpdmUtils::NpdmInfo *npdm, Handle reslimit_h, u64 arg_flags, ProcessInfo *out_proc_info);
|
||||||
|
static Result CreateProcess(Handle *out_process_h, u64 index, char *nca_path, LaunchQueue::LaunchItem *launch_item, u64 arg_flags, Handle reslimit_h);
|
||||||
};
|
};
|
|
@ -152,19 +152,7 @@ Result ProcessManagerService::populate_program_info_buffer(ProcessManagerService
|
||||||
|
|
||||||
/* Parse application type. */
|
/* Parse application type. */
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
u32 *kac = (u32 *)info.acid_kac;
|
out->application_type = NpdmUtils::GetApplicationType((u32 *)info.acid_kac, info.acid->kac_size / sizeof(u32));
|
||||||
u32 num_entries = info.acid->kac_size / sizeof(u32);
|
|
||||||
out->application_type = 0;
|
|
||||||
for (unsigned int i = 0; i < num_entries; i++) {
|
|
||||||
if ((kac[i] & 0x3FFF) == 0x1FFF) {
|
|
||||||
u16 app_type = (kac[i] >> 14) & 7;
|
|
||||||
if (app_type == 1) {
|
|
||||||
out->application_type |= 1;
|
|
||||||
} else if (app_type == 2) {
|
|
||||||
out->application_type |= 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue