loader: Use result definitions instead of magic numbers

This commit is contained in:
Michael Scire 2019-03-28 15:06:50 -07:00
parent 2678735f73
commit db19fa0f7f
12 changed files with 96 additions and 92 deletions

@ -1 +1 @@
Subproject commit ea5c0f0174df284c92893561611ea3bb92d31038 Subproject commit 0359681475183bd9c519d8fa680641e185f4de8e

View file

@ -453,7 +453,7 @@ ContentManagement::ExternalContentSource *ContentManagement::GetExternalContentS
Result ContentManagement::SetExternalContentSource(u64 tid, FsFileSystem filesystem) { Result ContentManagement::SetExternalContentSource(u64 tid, FsFileSystem filesystem) {
if (g_external_content_sources.size() >= 16) { if (g_external_content_sources.size() >= 16) {
return 0x409; /* LAUNCH_QUEUE_FULL */ return ResultLoaderTooManyArguments; /* TODO: Is this an appropriate error? */
} }
/* Remove any existing ECS for this title. */ /* Remove any existing ECS for this title. */

View file

@ -15,6 +15,7 @@
*/ */
#include <switch.h> #include <switch.h>
#include <stratosphere.hpp>
#include <algorithm> #include <algorithm>
#include <array> #include <array>
#include <cstdio> #include <cstdio>
@ -24,13 +25,14 @@
static std::array<LaunchQueue::LaunchItem, LAUNCH_QUEUE_SIZE> g_launch_queue = {0}; static std::array<LaunchQueue::LaunchItem, LAUNCH_QUEUE_SIZE> 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) { if (arg_size > LAUNCH_QUEUE_ARG_SIZE_MAX) {
return 0x209; return ResultLoaderTooLongArgument;
} }
int idx = GetFreeIndex(tid); int idx = GetFreeIndex(tid);
if(idx == LAUNCH_QUEUE_FULL) if (idx == LAUNCH_QUEUE_FULL) {
return 0x409; return ResultLoaderTooManyArguments;
}
g_launch_queue[idx].tid = tid; g_launch_queue[idx].tid = tid;
g_launch_queue[idx].arg_size = arg_size; g_launch_queue[idx].arg_size = arg_size;
@ -50,13 +52,14 @@ Result LaunchQueue::AddCopy(u64 tid_base, u64 tid) {
Result LaunchQueue::AddItem(const LaunchItem *item) { Result LaunchQueue::AddItem(const LaunchItem *item) {
if(item->arg_size > LAUNCH_QUEUE_ARG_SIZE_MAX) { if (item->arg_size > LAUNCH_QUEUE_ARG_SIZE_MAX) {
return 0x209; return ResultLoaderTooLongArgument;
} }
int idx = GetFreeIndex(item->tid); int idx = GetFreeIndex(item->tid);
if(idx == LAUNCH_QUEUE_FULL) if (idx == LAUNCH_QUEUE_FULL) {
return 0x409; return ResultLoaderTooManyArguments;
}
g_launch_queue[idx] = *item; g_launch_queue[idx] = *item;
return 0x0; return 0x0;
@ -71,8 +74,8 @@ int LaunchQueue::GetIndex(u64 tid) {
} }
int LaunchQueue::GetFreeIndex(u64 tid) { int LaunchQueue::GetFreeIndex(u64 tid) {
for(unsigned int i = 0; i < LAUNCH_QUEUE_SIZE; i++) { for (unsigned int i = 0; i < LAUNCH_QUEUE_SIZE; i++) {
if(g_launch_queue[i].tid == tid || g_launch_queue[i].tid == 0x0) { if (g_launch_queue[i].tid == tid || g_launch_queue[i].tid == 0x0) {
return i; return i;
} }
} }

View file

@ -136,7 +136,7 @@ Result MapUtils::MapCodeMemoryForProcessModern(Handle process_h, u64 base_addres
} }
if (size > address_space.addspace_size) { if (size > address_space.addspace_size) {
return 0x6609; return ResultLoaderInsufficientAddressSpace;
} }
u64 try_address; u64 try_address;
@ -174,7 +174,7 @@ Result MapUtils::MapCodeMemoryForProcessDeprecated(Handle process_h, bool is_64_
} }
if (size > addspace_size) { if (size > addspace_size) {
return 0x6609; return ResultLoaderInsufficientAddressSpace;
} }
u64 try_address; u64 try_address;

View file

@ -16,6 +16,7 @@
#pragma once #pragma once
#include <switch.h> #include <switch.h>
#include <stratosphere.hpp>
class MapUtils { class MapUtils {
public: public:
@ -103,7 +104,7 @@ struct MappedCodeMemory {
Result Open(Handle process_h, bool is_64_bit_address_space, u64 address, u64 size) { Result Open(Handle process_h, bool is_64_bit_address_space, u64 address, u64 size) {
Result rc; Result rc;
if (this->IsActive()) { if (this->IsActive()) {
return 0x19009; return ResultLoaderInternalError;
} }
this->process_handle = process_h; this->process_handle = process_h;
@ -119,7 +120,7 @@ struct MappedCodeMemory {
Result OpenAtAddress(Handle process_h, u64 address, u64 size, u64 target_code_memory_address) { Result OpenAtAddress(Handle process_h, u64 address, u64 size, u64 target_code_memory_address) {
Result rc; Result rc;
if (this->IsActive()) { if (this->IsActive()) {
return 0x19009; return ResultLoaderInternalError;
} }
this->process_handle = process_h; this->process_handle = process_h;
this->base_address = address; this->base_address = address;
@ -137,7 +138,7 @@ struct MappedCodeMemory {
Result rc; Result rc;
u64 try_address; u64 try_address;
if (this->IsMapped()) { if (this->IsMapped()) {
return 0x19009; return ResultLoaderInternalError;
} }
if (R_FAILED(rc = MapUtils::LocateSpaceForMap(&try_address, size))) { if (R_FAILED(rc = MapUtils::LocateSpaceForMap(&try_address, size))) {
return rc; return rc;

View file

@ -86,7 +86,7 @@ Result NpdmUtils::LoadNpdmInternal(FILE *f_npdm, NpdmUtils::NpdmCache *cache) {
cache->info = (const NpdmUtils::NpdmInfo){0}; cache->info = (const NpdmUtils::NpdmInfo){0};
rc = 0x202; rc = ResultFsPathNotFound;
if (f_npdm == NULL) { if (f_npdm == NULL) {
/* For generic "Couldn't open the file" error, just say the file doesn't exist. */ /* For generic "Couldn't open the file" error, just say the file doesn't exist. */
return rc; return rc;
@ -96,7 +96,7 @@ Result NpdmUtils::LoadNpdmInternal(FILE *f_npdm, NpdmUtils::NpdmCache *cache) {
size_t npdm_size = ftell(f_npdm); size_t npdm_size = ftell(f_npdm);
fseek(f_npdm, 0, SEEK_SET); fseek(f_npdm, 0, SEEK_SET);
rc = 0x609; rc = ResultLoaderTooLargeMeta;
if ((npdm_size > sizeof(cache->buffer)) || (fread(cache->buffer, 1, npdm_size, f_npdm) != npdm_size)) { if ((npdm_size > sizeof(cache->buffer)) || (fread(cache->buffer, 1, npdm_size, f_npdm) != npdm_size)) {
fclose(f_npdm); fclose(f_npdm);
return rc; return rc;
@ -104,7 +104,7 @@ Result NpdmUtils::LoadNpdmInternal(FILE *f_npdm, NpdmUtils::NpdmCache *cache) {
fclose(f_npdm); fclose(f_npdm);
rc = 0x809; rc = ResultLoaderInvalidMeta;
if (npdm_size < sizeof(NpdmUtils::NpdmHeader)) { if (npdm_size < sizeof(NpdmUtils::NpdmHeader)) {
return rc; return rc;
} }
@ -241,7 +241,7 @@ Result NpdmUtils::ValidateCapabilityAgainstRestrictions(u32 *restrict_caps, size
u32 r_desc = 0; u32 r_desc = 0;
switch (low_bits) { switch (low_bits) {
case 3: /* Kernel flags. */ case 3: /* Kernel flags. */
rc = 0xCE09; rc = ResultLoaderInvalidCapabilityKernelFlags;
for (size_t i = 0; i < num_restrict_caps; i++) { for (size_t i = 0; i < num_restrict_caps; i++) {
if ((restrict_caps[i] & 0xF) == 0x7) { if ((restrict_caps[i] & 0xF) == 0x7) {
r_desc = restrict_caps[i] >> 4; r_desc = restrict_caps[i] >> 4;
@ -284,7 +284,7 @@ Result NpdmUtils::ValidateCapabilityAgainstRestrictions(u32 *restrict_caps, size
} }
break; break;
case 4: /* Syscall mask. */ case 4: /* Syscall mask. */
rc = 0xD009; rc = ResultLoaderInvalidCapabilitySyscallMask;
for (size_t i = 0; i < num_restrict_caps; i++) { for (size_t i = 0; i < num_restrict_caps; i++) {
if ((restrict_caps[i] & 0x1F) == 0xF) { if ((restrict_caps[i] & 0x1F) == 0xF) {
r_desc = restrict_caps[i] >> 5; r_desc = restrict_caps[i] >> 5;
@ -305,7 +305,7 @@ Result NpdmUtils::ValidateCapabilityAgainstRestrictions(u32 *restrict_caps, size
} }
break; break;
case 6: /* Map IO/Normal. */ { case 6: /* Map IO/Normal. */ {
rc = 0xD409; rc = ResultLoaderInvalidCapabilityMapRange;
if (caps_remaining == 0) { if (caps_remaining == 0) {
break; break;
} }
@ -360,7 +360,7 @@ Result NpdmUtils::ValidateCapabilityAgainstRestrictions(u32 *restrict_caps, size
} }
break; break;
case 7: /* Map Normal Page. */ case 7: /* Map Normal Page. */
rc = 0xD609; rc = ResultLoaderInvalidCapabilityMapPage;
for (size_t i = 0; i < num_restrict_caps; i++) { for (size_t i = 0; i < num_restrict_caps; i++) {
if ((restrict_caps[i] & 0xFF) == 0x7F) { if ((restrict_caps[i] & 0xFF) == 0x7F) {
r_desc = restrict_caps[i] >> 8; r_desc = restrict_caps[i] >> 8;
@ -391,14 +391,14 @@ Result NpdmUtils::ValidateCapabilityAgainstRestrictions(u32 *restrict_caps, size
} }
} }
if (!found) { if (!found) {
rc = 0xDE09; rc = ResultLoaderInvalidCapabilityInterruptPair;
break; break;
} }
} }
} }
break; break;
case 13: /* App Type. */ case 13: /* App Type. */
rc = 0xE209; rc = ResultLoaderInvalidCapabilityApplicationType;
if (num_restrict_caps) { if (num_restrict_caps) {
for (size_t i = 0; i < num_restrict_caps; i++) { for (size_t i = 0; i < num_restrict_caps; i++) {
if ((restrict_caps[i] & 0x3FFF) == 0x1FFF) { if ((restrict_caps[i] & 0x3FFF) == 0x1FFF) {
@ -415,7 +415,7 @@ Result NpdmUtils::ValidateCapabilityAgainstRestrictions(u32 *restrict_caps, size
} }
break; break;
case 14: /* Kernel Release Version. */ case 14: /* Kernel Release Version. */
rc = 0xE409; rc = ResultLoaderInvalidCapabilityKernelVersion;
if (num_restrict_caps) { if (num_restrict_caps) {
for (size_t i = 0; i < num_restrict_caps; i++) { for (size_t i = 0; i < num_restrict_caps; i++) {
if ((restrict_caps[i] & 0x7FFF) == 0x3FFF) { if ((restrict_caps[i] & 0x7FFF) == 0x3FFF) {
@ -432,7 +432,7 @@ Result NpdmUtils::ValidateCapabilityAgainstRestrictions(u32 *restrict_caps, size
} }
break; break;
case 15: /* Handle Table Size. */ case 15: /* Handle Table Size. */
rc = 0xE609; rc = ResultLoaderInvalidCapabilityHandleTable;
for (size_t i = 0; i < num_restrict_caps; i++) { for (size_t i = 0; i < num_restrict_caps; i++) {
if ((restrict_caps[i] & 0xFFFF) == 0x7FFF) { if ((restrict_caps[i] & 0xFFFF) == 0x7FFF) {
r_desc = restrict_caps[i] >> 16; r_desc = restrict_caps[i] >> 16;
@ -448,7 +448,7 @@ Result NpdmUtils::ValidateCapabilityAgainstRestrictions(u32 *restrict_caps, size
} }
break; break;
case 16: /* Debug Flags. */ case 16: /* Debug Flags. */
rc = 0xE809; rc = ResultLoaderInvalidCapabilityDebugFlags;
if (num_restrict_caps) { if (num_restrict_caps) {
for (size_t i = 0; i < num_restrict_caps; i++) { for (size_t i = 0; i < num_restrict_caps; i++) {
if ((restrict_caps[i] & 0x1FFFF) == 0xFFFF) { if ((restrict_caps[i] & 0x1FFFF) == 0xFFFF) {
@ -468,7 +468,7 @@ Result NpdmUtils::ValidateCapabilityAgainstRestrictions(u32 *restrict_caps, size
rc = 0; rc = 0;
break; break;
default: /* Unrecognized Descriptor. */ default: /* Unrecognized Descriptor. */
rc = 0xC809; rc = ResultLoaderUnknownCapability;
break; break;
} }
return rc; return rc;

View file

@ -28,19 +28,19 @@
Result NroUtils::ValidateNrrHeader(NrrHeader *header, u64 size, u64 title_id_min) { Result NroUtils::ValidateNrrHeader(NrrHeader *header, u64 size, u64 title_id_min) {
if (header->magic != MAGIC_NRR0) { if (header->magic != MAGIC_NRR0) {
return 0x6A09; return ResultLoaderInvalidNrr;
} }
if (header->nrr_size != size) { if (header->nrr_size != size) {
return 0xA409; return ResultLoaderInvalidSize;
} }
/* TODO: Check NRR signature. */ /* TODO: Check NRR signature. */
if (false) { if (false) {
return 0x6C09; return ResultLoaderInvalidSignature;
} }
if (header->title_id_min != title_id_min) { if (header->title_id_min != title_id_min) {
return 0x6A09; return ResultLoaderInvalidNrr;
} }
return 0x0; return 0x0;
@ -65,7 +65,7 @@ Result NroUtils::LoadNro(Registration::Process *target_proc, Handle process_h, u
/* Ensure there is an available NRO slot. */ /* Ensure there is an available NRO slot. */
if (std::all_of(target_proc->nro_infos.begin(), target_proc->nro_infos.end(), std::mem_fn(&Registration::NroInfo::in_use))) { if (std::all_of(target_proc->nro_infos.begin(), target_proc->nro_infos.end(), std::mem_fn(&Registration::NroInfo::in_use))) {
rc = 0x6E09; rc = ResultLoaderInsufficientNroRegistrations;
return rc; return rc;
} }
for (i = 0; i < 0x200; i++) { for (i = 0; i < 0x200; i++) {
@ -78,7 +78,7 @@ Result NroUtils::LoadNro(Registration::Process *target_proc, Handle process_h, u
} }
} }
if (i >= 0x200) { if (i >= 0x200) {
rc = 0x6609; rc = ResultLoaderInsufficientAddressSpace;
return rc; return rc;
} }
@ -92,19 +92,19 @@ Result NroUtils::LoadNro(Registration::Process *target_proc, Handle process_h, u
nro_hdr = *((NroHeader *)mcm_nro.mapped_address); nro_hdr = *((NroHeader *)mcm_nro.mapped_address);
if (nro_hdr.magic != MAGIC_NRO0) { if (nro_hdr.magic != MAGIC_NRO0) {
rc = 0x6809; rc = ResultLoaderInvalidNro;
return rc; return rc;
} }
if (nro_hdr.nro_size != nro_heap_size || nro_hdr.bss_size != bss_heap_size) { if (nro_hdr.nro_size != nro_heap_size || nro_hdr.bss_size != bss_heap_size) {
rc = 0x6809; rc = ResultLoaderInvalidNro;
return rc; return rc;
} }
if ((nro_hdr.text_size & 0xFFF) || (nro_hdr.ro_size & 0xFFF) || (nro_hdr.rw_size & 0xFFF) || (nro_hdr.bss_size & 0xFFF)) { if ((nro_hdr.text_size & 0xFFF) || (nro_hdr.ro_size & 0xFFF) || (nro_hdr.rw_size & 0xFFF) || (nro_hdr.bss_size & 0xFFF)) {
rc = 0x6809; rc = ResultLoaderInvalidNro;
return rc; return rc;
} }
if (nro_hdr.text_offset != 0 || nro_hdr.text_offset + nro_hdr.text_size != nro_hdr.ro_offset || nro_hdr.ro_offset + nro_hdr.ro_size != nro_hdr.rw_offset || nro_hdr.rw_offset + nro_hdr.rw_size != nro_hdr.nro_size) { if (nro_hdr.text_offset != 0 || nro_hdr.text_offset + nro_hdr.text_size != nro_hdr.ro_offset || nro_hdr.ro_offset + nro_hdr.ro_size != nro_hdr.rw_offset || nro_hdr.rw_offset + nro_hdr.rw_size != nro_hdr.nro_size) {
rc = 0x6809; rc = ResultLoaderInvalidNro;
return rc; return rc;
} }
@ -120,12 +120,12 @@ Result NroUtils::LoadNro(Registration::Process *target_proc, Handle process_h, u
} }
if (!Registration::IsNroHashPresent(target_proc->index, nro_hash)) { if (!Registration::IsNroHashPresent(target_proc->index, nro_hash)) {
rc = 0x6C09; rc = ResultLoaderInvalidSignature;
return rc; return rc;
} }
if (Registration::IsNroAlreadyLoaded(target_proc->index, nro_hash)) { if (Registration::IsNroAlreadyLoaded(target_proc->index, nro_hash)) {
rc = 0x7209; rc = ResultLoaderNroAlreadyLoaded;
return rc; return rc;
} }

View file

@ -114,7 +114,7 @@ Result NsoUtils::LoadNsoHeaders(u64 title_id) {
f_nso = OpenNso(i, title_id); f_nso = OpenNso(i, title_id);
if (f_nso != NULL) { if (f_nso != NULL) {
if (fread(&g_nso_headers[i], 1, sizeof(NsoUtils::NsoHeader), f_nso) != sizeof(NsoUtils::NsoHeader)) { if (fread(&g_nso_headers[i], 1, sizeof(NsoUtils::NsoHeader), f_nso) != sizeof(NsoUtils::NsoHeader)) {
return 0xA09; return ResultLoaderInvalidNso;
} }
g_nso_present[i] = true; g_nso_present[i] = true;
fclose(f_nso); fclose(f_nso);
@ -133,7 +133,7 @@ Result NsoUtils::LoadNsoHeaders(u64 title_id) {
Result NsoUtils::ValidateNsoLoadSet() { Result NsoUtils::ValidateNsoLoadSet() {
/* We *must* have a "main" NSO. */ /* We *must* have a "main" NSO. */
if (!g_nso_present[1]) { if (!g_nso_present[1]) {
return 0xA09; return ResultLoaderInvalidNso;
} }
/* Behavior switches depending on whether we have an rtld. */ /* Behavior switches depending on whether we have an rtld. */
@ -141,19 +141,19 @@ Result NsoUtils::ValidateNsoLoadSet() {
/* If we have an rtld, dst offset for .text must be 0 for all other NSOs. */ /* If we have an rtld, dst offset for .text must be 0 for all other NSOs. */
for (unsigned int i = 0; i < NSO_NUM_MAX; i++) { for (unsigned int i = 0; i < NSO_NUM_MAX; i++) {
if (g_nso_present[i] && g_nso_headers[i].segments[0].dst_offset != 0) { if (g_nso_present[i] && g_nso_headers[i].segments[0].dst_offset != 0) {
return 0xA09; return ResultLoaderInvalidNso;
} }
} }
} else { } else {
/* If we don't have an rtld, we must ONLY have a main. */ /* If we don't have an rtld, we must ONLY have a main. */
for (unsigned int i = 2; i < NSO_NUM_MAX; i++) { for (unsigned int i = 2; i < NSO_NUM_MAX; i++) {
if (g_nso_present[i]) { if (g_nso_present[i]) {
return 0xA09; return ResultLoaderInvalidNso;
} }
} }
/* That main's .text must be at dst_offset 0. */ /* That main's .text must be at dst_offset 0. */
if (g_nso_headers[1].segments[0].dst_offset != 0) { if (g_nso_headers[1].segments[0].dst_offset != 0) {
return 0xA09; return ResultLoaderInvalidNso;
} }
} }
@ -250,10 +250,10 @@ Result NsoUtils::LoadNsoSegment(u64 title_id, unsigned int index, unsigned int s
size_t out_size = g_nso_headers[index].segments[segment].decomp_size; size_t out_size = g_nso_headers[index].segments[segment].decomp_size;
size_t size = is_compressed ? g_nso_headers[index].compressed_sizes[segment] : out_size; size_t size = is_compressed ? g_nso_headers[index].compressed_sizes[segment] : out_size;
if (size > out_size) { if (size > out_size) {
return 0xA09; return ResultLoaderInvalidNso;
} }
if ((u32)(size | out_size) >> 31) { if ((u32)(size | out_size) >> 31) {
return 0xA09; return ResultLoaderInvalidNso;
} }
u8 *dst_addr = map_base + g_nso_headers[index].segments[segment].dst_offset; u8 *dst_addr = map_base + g_nso_headers[index].segments[segment].dst_offset;
@ -262,13 +262,13 @@ Result NsoUtils::LoadNsoSegment(u64 title_id, unsigned int index, unsigned int s
fseek(f_nso, g_nso_headers[index].segments[segment].file_offset, SEEK_SET); fseek(f_nso, g_nso_headers[index].segments[segment].file_offset, SEEK_SET);
if (fread(load_addr, 1, size, f_nso) != size) { if (fread(load_addr, 1, size, f_nso) != size) {
return 0xA09; return ResultLoaderInvalidNso;
} }
if (is_compressed) { if (is_compressed) {
if (LZ4_decompress_safe((char *)load_addr, (char *)dst_addr, size, out_size) != (int)out_size) { if (LZ4_decompress_safe((char *)load_addr, (char *)dst_addr, size, out_size) != (int)out_size) {
return 0xA09; return ResultLoaderInvalidNso;
} }
} }
@ -282,7 +282,7 @@ Result NsoUtils::LoadNsoSegment(u64 title_id, unsigned int index, unsigned int s
sha256_finish(&sha_ctx, hash); sha256_finish(&sha_ctx, hash);
if (std::memcmp(g_nso_headers[index].section_hashes[segment], hash, sizeof(hash))) { if (std::memcmp(g_nso_headers[index].section_hashes[segment], hash, sizeof(hash))) {
return 0xA09; return ResultLoaderInvalidNso;
} }
} }
@ -290,7 +290,7 @@ Result NsoUtils::LoadNsoSegment(u64 title_id, unsigned int index, unsigned int s
} }
Result NsoUtils::LoadNsosIntoProcessMemory(Handle process_h, u64 title_id, NsoLoadExtents *extents, u8 *args, u32 args_size) { Result NsoUtils::LoadNsosIntoProcessMemory(Handle process_h, u64 title_id, NsoLoadExtents *extents, u8 *args, u32 args_size) {
Result rc = 0xA09; Result rc = ResultLoaderInvalidNso;
for (unsigned int i = 0; i < NSO_NUM_MAX; i++) { for (unsigned int i = 0; i < NSO_NUM_MAX; i++) {
if (g_nso_present[i]) { if (g_nso_present[i]) {
AutoCloseMap nso_map; AutoCloseMap nso_map;
@ -302,8 +302,8 @@ Result NsoUtils::LoadNsosIntoProcessMemory(Handle process_h, u64 title_id, NsoLo
FILE *f_nso = OpenNso(i, title_id); FILE *f_nso = OpenNso(i, title_id);
if (f_nso == NULL) { if (f_nso == NULL) {
/* Is there a better error to return here? */ /* TODO: Is there a better error to return here? */
return 0xA09; return ResultLoaderInvalidNso;
} }
for (unsigned int seg = 0; seg < 3; seg++) { for (unsigned int seg = 0; seg < 3; seg++) {
if (R_FAILED((rc = LoadNsoSegment(title_id, i, seg, f_nso, map_base, map_base + extents->nso_sizes[i])))) { if (R_FAILED((rc = LoadNsoSegment(title_id, i, seg, f_nso, map_base, map_base + extents->nso_sizes[i])))) {

View file

@ -45,7 +45,7 @@ Result ProcessCreation::InitializeProcessInfo(NpdmUtils::NpdmInfo *npdm, Handle
/* Set IsAddressSpace64Bit, AddressSpaceType. */ /* Set IsAddressSpace64Bit, AddressSpaceType. */
if (npdm->header->mmu_flags & 8) { if (npdm->header->mmu_flags & 8) {
/* Invalid Address Space Type. */ /* Invalid Address Space Type. */
return 0x809; return ResultLoaderInvalidMeta;
} }
out_proc_info->process_flags = (npdm->header->mmu_flags & 0xF); out_proc_info->process_flags = (npdm->header->mmu_flags & 0xF);
@ -66,17 +66,17 @@ Result ProcessCreation::InitializeProcessInfo(NpdmUtils::NpdmInfo *npdm, Handle
/* 3.0.0+ System Resource Size. */ /* 3.0.0+ System Resource Size. */
if (kernelAbove300()) { if (kernelAbove300()) {
if (npdm->header->system_resource_size & 0x1FFFFF) { if (npdm->header->system_resource_size & 0x1FFFFF) {
return 0xA409; return ResultLoaderInvalidSize;
} }
if (npdm->header->system_resource_size) { if (npdm->header->system_resource_size) {
if ((out_proc_info->process_flags & 6) == 0) { if ((out_proc_info->process_flags & 6) == 0) {
return 0x809; return ResultLoaderInvalidMeta;
} }
if (!(((application_type & 3) == 1) || (kernelAbove600() && (application_type & 3) == 2))) { if (!(((application_type & 3) == 1) || (kernelAbove600() && (application_type & 3) == 2))) {
return 0x809; return ResultLoaderInvalidMeta;
} }
if (npdm->header->system_resource_size > 0x1FE00000) { if (npdm->header->system_resource_size > 0x1FE00000) {
return 0x809; return ResultLoaderInvalidMeta;
} }
} }
out_proc_info->system_resource_num_pages = npdm->header->system_resource_size >> 12; out_proc_info->system_resource_num_pages = npdm->header->system_resource_size >> 12;
@ -103,7 +103,7 @@ Result ProcessCreation::InitializeProcessInfo(NpdmUtils::NpdmInfo *npdm, Handle
out_proc_info->process_flags |= 0x180; out_proc_info->process_flags |= 0x180;
break; break;
default: default:
return 0x809; return ResultLoaderInvalidMeta;
} }
} }
@ -123,7 +123,7 @@ Result ProcessCreation::CreateProcess(Handle *out_process_h, u64 index, char *nc
/* Get the process from the registration queue. */ /* Get the process from the registration queue. */
target_process = Registration::GetProcess(index); target_process = Registration::GetProcess(index);
if (target_process == NULL) { if (target_process == NULL) {
return 0x1009; return ResultLoaderProcessNotRegistered;
} }
/* Mount the title's exefs. */ /* Mount the title's exefs. */
@ -147,7 +147,7 @@ Result ProcessCreation::CreateProcess(Handle *out_process_h, u64 index, char *nc
/* Validate the title we're loading is what we expect. */ /* Validate the title we're loading is what we expect. */
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) { 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 = ResultLoaderInvalidProgramId;
goto CREATE_PROCESS_END; goto CREATE_PROCESS_END;
} }

View file

@ -89,11 +89,11 @@ Result ProcessManagerService::GetProgramInfo(OutPointerWithServerSize<ProcessMan
} }
Result ProcessManagerService::RegisterTitle(Out<u64> index, Registration::TidSid tid_sid) { Result ProcessManagerService::RegisterTitle(Out<u64> index, Registration::TidSid tid_sid) {
return Registration::RegisterTidSid(&tid_sid, index.GetPointer()) ? 0 : 0xE09; return Registration::RegisterTidSid(&tid_sid, index.GetPointer()) ? 0 : ResultLoaderTooManyProcesses;
} }
Result ProcessManagerService::UnregisterTitle(u64 index) { Result ProcessManagerService::UnregisterTitle(u64 index) {
return Registration::UnregisterIndex(index) ? 0 : 0x1009; return Registration::UnregisterIndex(index) ? 0 : ResultLoaderProcessNotRegistered;
} }
@ -133,7 +133,7 @@ Result ProcessManagerService::PopulateProgramInfoBuffer(ProcessManagerService::P
out->aci0_fah_size = info.aci0->fah_size; out->aci0_fah_size = info.aci0->fah_size;
size_t offset = 0; size_t offset = 0;
rc = 0x19009; rc = ResultLoaderInternalError;
if (offset + info.acid->sac_size < sizeof(out->ac_buffer)) { if (offset + info.acid->sac_size < sizeof(out->ac_buffer)) {
out->acid_sac_size = info.acid->sac_size; out->acid_sac_size = info.acid->sac_size;
std::memcpy(out->ac_buffer + offset, info.acid_sac, out->acid_sac_size); std::memcpy(out->ac_buffer + offset, info.acid_sac, out->acid_sac_size);

View file

@ -90,7 +90,7 @@ bool Registration::UnregisterIndex(u64 index) {
Result Registration::GetRegisteredTidSid(u64 index, Registration::TidSid *out) { Result Registration::GetRegisteredTidSid(u64 index, Registration::TidSid *out) {
Registration::Process *target_process = GetProcess(index); Registration::Process *target_process = GetProcess(index);
if (target_process == NULL) { if (target_process == NULL) {
return 0x1009; return ResultLoaderProcessNotRegistered;
} }
*out = target_process->tid_sid; *out = target_process->tid_sid;
@ -140,13 +140,13 @@ void Registration::CloseRoService(void *service, Handle process_h) {
Result Registration::AddNrrInfo(u64 index, MappedCodeMemory *nrr_info) { Result Registration::AddNrrInfo(u64 index, MappedCodeMemory *nrr_info) {
Registration::Process *target_process = GetProcess(index); Registration::Process *target_process = GetProcess(index);
if (target_process == NULL) { if (target_process == NULL) {
/* TODO: panic() */ /* TODO: std::abort(); */
return 0x7009; return ResultLoaderProcessNotRegistered;
} }
auto nrr_info_it = std::find_if_not(target_process->nrr_infos.begin(), target_process->nrr_infos.end(), std::mem_fn(&MappedCodeMemory::IsActive)); auto nrr_info_it = std::find_if_not(target_process->nrr_infos.begin(), target_process->nrr_infos.end(), std::mem_fn(&MappedCodeMemory::IsActive));
if (nrr_info_it == target_process->nrr_infos.end()) { if (nrr_info_it == target_process->nrr_infos.end()) {
return 0x7009; return ResultLoaderInsufficientNrrRegistrations;
} }
*nrr_info_it = *nrr_info; *nrr_info_it = *nrr_info;
return 0; return 0;
@ -156,7 +156,7 @@ Result Registration::RemoveNrrInfo(u64 index, u64 base_address) {
Registration::Process *target_process = GetProcess(index); Registration::Process *target_process = GetProcess(index);
if (target_process == NULL) { if (target_process == NULL) {
/* Despite the fact that this should really be a panic condition, Nintendo returns 0x1009 in this case. */ /* Despite the fact that this should really be a panic condition, Nintendo returns 0x1009 in this case. */
return 0x1009; return ResultLoaderProcessNotRegistered;
} }
for (unsigned int i = 0; i < NRR_INFO_MAX; i++) { for (unsigned int i = 0; i < NRR_INFO_MAX; i++) {
@ -165,7 +165,7 @@ Result Registration::RemoveNrrInfo(u64 index, u64 base_address) {
return 0; return 0;
} }
} }
return 0xAA09; return ResultLoaderNotRegistered;
} }
@ -238,7 +238,7 @@ void Registration::AddNroToProcess(u64 index, MappedCodeMemory *nro, MappedCodeM
Result Registration::RemoveNroInfo(u64 index, Handle process_h, u64 nro_heap_address) { Result Registration::RemoveNroInfo(u64 index, Handle process_h, u64 nro_heap_address) {
Registration::Process *target_process = GetProcess(index); Registration::Process *target_process = GetProcess(index);
if (target_process == NULL) { if (target_process == NULL) {
return 0xA809; return ResultLoaderProcessNotRegistered;
} }
for (unsigned int i = 0; i < NRO_INFO_MAX; i++) { for (unsigned int i = 0; i < NRO_INFO_MAX; i++) {
@ -255,13 +255,13 @@ Result Registration::RemoveNroInfo(u64 index, Handle process_h, u64 nro_heap_add
return rc; return rc;
} }
} }
return 0xA809; return ResultLoaderNotLoaded;
} }
Result Registration::GetNsoInfosForProcessId(Registration::NsoInfo *out, u32 max_out, u64 process_id, u32 *num_written) { Result Registration::GetNsoInfosForProcessId(Registration::NsoInfo *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 0x1009; return ResultLoaderProcessNotRegistered;
} }
u32 cur = 0; u32 cur = 0;

View file

@ -27,24 +27,24 @@
Result RelocatableObjectsService::LoadNro(Out<u64> load_address, PidDescriptor pid_desc, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size) { Result RelocatableObjectsService::LoadNro(Out<u64> load_address, PidDescriptor pid_desc, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size) {
Registration::Process *target_proc = NULL; Registration::Process *target_proc = NULL;
if (!this->has_initialized || this->process_id != pid_desc.pid) { if (!this->has_initialized || this->process_id != pid_desc.pid) {
return 0xAE09; return ResultLoaderInvalidProcess;
} }
if (nro_address & 0xFFF) { if (nro_address & 0xFFF) {
return 0xA209; return ResultLoaderInvalidAddress;
} }
if (nro_address + nro_size <= nro_address || !nro_size || (nro_size & 0xFFF)) { if (nro_address + nro_size <= nro_address || !nro_size || (nro_size & 0xFFF)) {
return 0xA409; return ResultLoaderInvalidSize;
} }
if (bss_size && bss_address + bss_size <= bss_address) { if (bss_size && bss_address + bss_size <= bss_address) {
return 0xA409; return ResultLoaderInvalidSize;
} }
/* Ensure no overflow for combined sizes. */ /* Ensure no overflow for combined sizes. */
if (U64_MAX - nro_size < bss_size) { if (U64_MAX - nro_size < bss_size) {
return 0xA409; return ResultLoaderInvalidSize;
} }
target_proc = Registration::GetProcessByProcessId(pid_desc.pid); target_proc = Registration::GetProcessByProcessId(pid_desc.pid);
if (target_proc == NULL || (target_proc->owner_ro_service != NULL && (RelocatableObjectsService *)(target_proc->owner_ro_service) != this)) { if (target_proc == NULL || (target_proc->owner_ro_service != NULL && (RelocatableObjectsService *)(target_proc->owner_ro_service) != this)) {
return 0xAC09; return ResultLoaderInvalidSession;
} }
target_proc->owner_ro_service = this; target_proc->owner_ro_service = this;
@ -54,15 +54,15 @@ Result RelocatableObjectsService::LoadNro(Out<u64> load_address, PidDescriptor p
Result RelocatableObjectsService::UnloadNro(PidDescriptor pid_desc, u64 nro_address) { Result RelocatableObjectsService::UnloadNro(PidDescriptor pid_desc, u64 nro_address) {
Registration::Process *target_proc = NULL; Registration::Process *target_proc = NULL;
if (!this->has_initialized || this->process_id != pid_desc.pid) { if (!this->has_initialized || this->process_id != pid_desc.pid) {
return 0xAE09; return ResultLoaderInvalidProcess;
} }
if (nro_address & 0xFFF) { if (nro_address & 0xFFF) {
return 0xA209; return ResultLoaderInvalidAddress;
} }
target_proc = Registration::GetProcessByProcessId(pid_desc.pid); target_proc = Registration::GetProcessByProcessId(pid_desc.pid);
if (target_proc == NULL || (target_proc->owner_ro_service != NULL && (RelocatableObjectsService *)(target_proc->owner_ro_service) != this)) { if (target_proc == NULL || (target_proc->owner_ro_service != NULL && (RelocatableObjectsService *)(target_proc->owner_ro_service) != this)) {
return 0xAC09; return ResultLoaderInvalidSession;
} }
target_proc->owner_ro_service = this; target_proc->owner_ro_service = this;
@ -80,21 +80,21 @@ Result RelocatableObjectsService::LoadNrr(PidDescriptor pid_desc, u64 nrr_addres
}; };
if (!this->has_initialized || this->process_id != pid_desc.pid) { if (!this->has_initialized || this->process_id != pid_desc.pid) {
rc = 0xAE09; rc = ResultLoaderInvalidProcess;
return rc; return rc;
} }
if (nrr_address & 0xFFF) { if (nrr_address & 0xFFF) {
rc = 0xA209; rc = ResultLoaderInvalidAddress;
return rc; return rc;
} }
if (nrr_address + nrr_size <= nrr_address || !nrr_size || (nrr_size & 0xFFF)) { if (nrr_address + nrr_size <= nrr_address || !nrr_size || (nrr_size & 0xFFF)) {
rc = 0xA409; rc = ResultLoaderInvalidSize;
return rc; return rc;
} }
target_proc = Registration::GetProcessByProcessId(pid_desc.pid); target_proc = Registration::GetProcessByProcessId(pid_desc.pid);
if (target_proc == NULL || (target_proc->owner_ro_service != NULL && (RelocatableObjectsService *)(target_proc->owner_ro_service) != this)) { if (target_proc == NULL || (target_proc->owner_ro_service != NULL && (RelocatableObjectsService *)(target_proc->owner_ro_service) != this)) {
rc = 0xAC09; rc = ResultLoaderInvalidSession;
return rc; return rc;
} }
target_proc->owner_ro_service = this; target_proc->owner_ro_service = this;
@ -118,15 +118,15 @@ Result RelocatableObjectsService::LoadNrr(PidDescriptor pid_desc, u64 nrr_addres
Result RelocatableObjectsService::UnloadNrr(PidDescriptor pid_desc, u64 nrr_address) { Result RelocatableObjectsService::UnloadNrr(PidDescriptor pid_desc, u64 nrr_address) {
Registration::Process *target_proc = NULL; Registration::Process *target_proc = NULL;
if (!this->has_initialized || this->process_id != pid_desc.pid) { if (!this->has_initialized || this->process_id != pid_desc.pid) {
return 0xAE09; return ResultLoaderInvalidProcess;
} }
if (nrr_address & 0xFFF) { if (nrr_address & 0xFFF) {
return 0xA209; return ResultLoaderInvalidAddress;
} }
target_proc = Registration::GetProcessByProcessId(pid_desc.pid); target_proc = Registration::GetProcessByProcessId(pid_desc.pid);
if (target_proc == NULL || (target_proc->owner_ro_service != NULL && (RelocatableObjectsService *)(target_proc->owner_ro_service) != this)) { if (target_proc == NULL || (target_proc->owner_ro_service != NULL && (RelocatableObjectsService *)(target_proc->owner_ro_service) != this)) {
return 0xAC09; return ResultLoaderInvalidSession;
} }
target_proc->owner_ro_service = this; target_proc->owner_ro_service = this;
@ -144,5 +144,5 @@ Result RelocatableObjectsService::Initialize(PidDescriptor pid_desc, CopiedHandl
this->has_initialized = true; this->has_initialized = true;
return 0; return 0;
} }
return 0xAE09; return ResultLoaderInvalidProcess;
} }