Results: Implement namespaced, type-safe results.

Because I was working on multiple things at once, this commit also:
- Adds wrappers for/linker flags to wrap CXX exceptions to make them
  abort. This saves ~0x8000 of memory in every system module.
- Broadly replaces lines of the pattern if (cond) { return ResultX; }
  with R_UNLESS(!cond, ResultX());.
- Reworks the R_TRY_CATCH macros (and the result macros in general).
This commit is contained in:
Michael Scire
2019-10-24 01:40:44 -07:00
committed by SciresM
parent 15773e4755
commit 4059dc6187
169 changed files with 2172 additions and 1868 deletions

View File

@@ -49,29 +49,25 @@ namespace sts::ldr::args {
}
Result Set(ncm::TitleId title_id, const void *args, size_t args_size) {
if (args_size >= ArgumentSizeMax) {
return ResultLoaderTooLongArgument;
}
R_UNLESS(args_size < ArgumentSizeMax, ldr::ResultTooLongArgument());
ArgumentInfo *arg_info = FindArgumentInfo(title_id);
if (arg_info == nullptr) {
arg_info = FindFreeArgumentInfo();
}
if (arg_info == nullptr) {
return ResultLoaderTooManyArguments;
}
R_UNLESS(arg_info != nullptr, ldr::ResultTooManyArguments());
arg_info->title_id = title_id;
arg_info->args_size = args_size;
std::memcpy(arg_info->args, args, args_size);
return ResultSuccess;
return ResultSuccess();
}
Result Clear() {
for (size_t i = 0; i < MaxArgumentInfos; i++) {
g_argument_infos[i].title_id = FreeTitleId;
}
return ResultSuccess;
return ResultSuccess();
}
}

View File

@@ -339,9 +339,7 @@ namespace sts::ldr::caps {
#define VALIDATE_CASE(id) \
case CapabilityId::id: \
if (!Capability##id::Decode(cur_cap).IsValid(acid_caps, num_acid_caps)) { \
return ResultLoaderInvalidCapability##id; \
} \
R_UNLESS(Capability##id::Decode(cur_cap).IsValid(acid_caps, num_acid_caps), ldr::ResultInvalidCapability##id()); \
break
switch (id) {
VALIDATE_CASE(KernelFlags);
@@ -356,21 +354,18 @@ namespace sts::ldr::caps {
{
/* Map Range needs extra logic because there it involves two sequential caps. */
i++;
if (i >= num_aci_caps || !CapabilityMapRange::Decode(cur_cap).IsValid(aci_caps[i], acid_caps, num_acid_caps)) {
return ResultLoaderInvalidCapabilityMapRange;
}
R_UNLESS(i < num_aci_caps, ldr::ResultInvalidCapabilityMapRange());
R_UNLESS(CapabilityMapRange::Decode(cur_cap).IsValid(aci_caps[i], acid_caps, num_acid_caps), ldr::ResultInvalidCapabilityMapRange());
}
break;
default:
if (id != CapabilityId::Empty) {
return ResultLoaderUnknownCapability;
}
R_UNLESS(id == CapabilityId::Empty, ldr::ResultUnknownCapability());
break;
}
#undef VALIDATE_CASE
}
return ResultSuccess;
return ResultSuccess();
}
u16 GetProgramInfoFlags(const void *kac, size_t kac_size) {

View File

@@ -84,7 +84,7 @@ namespace sts::ldr {
FsFileSystem fs;
R_TRY(fsOpenFileSystemWithId(&fs, 0, FsFileSystemType_ApplicationPackage, path));
STS_ASSERT(fsdevMountDevice(device_name, fs) >= 0);
return ResultSuccess;
return ResultSuccess();
}
FILE *OpenFile(const char *device_name, const char *relative_path) {
@@ -180,7 +180,7 @@ namespace sts::ldr {
/* Note that we mounted code. */
this->is_code_mounted = true;
return ResultSuccess;
return ResultSuccess();
}
Result ScopedCodeMount::MountSdCardCodeFileSystem(const ncm::TitleLocation &loc) {
@@ -193,7 +193,7 @@ namespace sts::ldr {
/* Note that we mounted code. */
this->is_code_mounted = true;
return ResultSuccess;
return ResultSuccess();
}
Result ScopedCodeMount::MountHblFileSystem() {
@@ -206,7 +206,7 @@ namespace sts::ldr {
/* Note that we mounted HBL. */
this->is_hbl_mounted = true;
return ResultSuccess;
return ResultSuccess();
}
@@ -236,7 +236,7 @@ namespace sts::ldr {
R_TRY(this->MountCodeFileSystem(loc));
}
return ResultSuccess;
return ResultSuccess();
}
Result OpenCodeFile(FILE *&out, ncm::TitleId title_id, const char *relative_path) {
@@ -262,23 +262,19 @@ namespace sts::ldr {
}
/* If nothing worked, we failed to find the path. */
if (f == nullptr) {
return ResultFsPathNotFound;
}
R_UNLESS(f != nullptr, fs::ResultPathNotFound());
out = f;
return ResultSuccess;
return ResultSuccess();
}
Result OpenCodeFileFromBaseExefs(FILE *&out, ncm::TitleId title_id, const char *relative_path) {
/* Open the file. */
FILE *f = OpenBaseExefsFile(title_id, relative_path);
if (f == nullptr) {
return ResultFsPathNotFound;
}
R_UNLESS(f != nullptr, fs::ResultPathNotFound());
out = f;
return ResultSuccess;
return ResultSuccess();
}
/* Redirection API. */
@@ -291,7 +287,7 @@ namespace sts::ldr {
ON_SCOPE_EXIT { serviceClose(&reg.s); };
R_TRY_CATCH(lrRegLrResolveProgramPath(&reg, static_cast<u64>(loc.title_id), path)) {
R_CATCH(ResultLrProgramNotFound) {
R_CATCH(lr::ResultProgramNotFound) {
/* Program wasn't found via registered resolver, fall back to the normal resolver. */
LrLocationResolver lr;
R_TRY(lrOpenLocationResolver(static_cast<FsStorageId>(loc.storage_id), &lr));
@@ -304,7 +300,7 @@ namespace sts::ldr {
std::strncpy(out_path, path, FS_MAX_PATH);
out_path[FS_MAX_PATH - 1] = '\0';
FixFileSystemPath(out_path);
return ResultSuccess;
return ResultSuccess();
}
Result RedirectContentPath(const char *path, const ncm::TitleLocation &loc) {
@@ -324,15 +320,13 @@ namespace sts::ldr {
ON_SCOPE_EXIT { serviceClose(&lr.s); };
/* If there's already a Html Document path, we don't need to set one. */
if (R_SUCCEEDED(lrLrResolveApplicationHtmlDocumentPath(&lr, static_cast<u64>(loc.title_id), path))) {
return ResultSuccess;
}
R_UNLESS(R_FAILED(lrLrResolveApplicationHtmlDocumentPath(&lr, static_cast<u64>(loc.title_id), path)), ResultSuccess());
/* We just need to set this to any valid NCA path. Let's use the executable path. */
R_TRY(lrLrResolveProgramPath(&lr, static_cast<u64>(loc.title_id), path));
R_TRY(lrLrRedirectApplicationHtmlDocumentPath(&lr, static_cast<u64>(loc.title_id), static_cast<u64>(loc.title_id), path));
return ResultSuccess;
return ResultSuccess();
}
}

View File

@@ -60,10 +60,8 @@ namespace sts::ldr::ecs {
}
Result Set(Handle *out, ncm::TitleId title_id) {
if (g_map.size() >= MaxExternalContentSourceCount) {
/* TODO: Is this an appropriate error? */
return ResultLoaderTooManyArguments;
}
/* TODO: Is this an appropriate error? */
R_UNLESS(g_map.size() < MaxExternalContentSourceCount, ldr::ResultTooManyArguments());
/* Clear any sources. */
R_ASSERT(Clear(title_id));
@@ -80,23 +78,22 @@ namespace sts::ldr::ecs {
Service srv;
serviceCreate(&srv, client.Move());
FsFileSystem fs = { srv };
auto fs_guard = SCOPE_GUARD { fsFsClose(&fs); };
/* Try to mount. */
if (fsdevMountDevice(device_name, fs) == -1) {
serviceClose(&srv);
return ResultFsMountNameAlreadyExists;
}
R_UNLESS(fsdevMountDevice(device_name, fs) >= 0, fs::ResultMountNameAlreadyExists());
fs_guard.Cancel();
/* Add to map. */
g_map.emplace(static_cast<u64>(title_id), device_name);
*out = server.Move();
return ResultSuccess;
return ResultSuccess();
}
Result Clear(ncm::TitleId title_id) {
/* Delete if present. */
g_map.erase(static_cast<u64>(title_id));
return ResultSuccess;
return ResultSuccess();
}
}

View File

@@ -45,7 +45,7 @@ namespace sts::pm::info {
Result HasLaunchedTitle(bool *out, ncm::TitleId title_id) {
*out = ldr::HasLaunchedTitle(title_id);
return ResultSuccess;
return ResultSuccess();
}
}

View File

@@ -60,7 +60,7 @@ namespace sts::ldr {
}
}
return ResultSuccess;
return ResultSuccess();
}
Result LoaderService::PinTitle(sf::Out<PinId> out_id, const ncm::TitleLocation &loc) {
@@ -80,10 +80,7 @@ namespace sts::ldr {
}
Result LoaderService::GetProcessModuleInfo(sf::Out<u32> count, const sf::OutPointerArray<ModuleInfo> &out, os::ProcessId process_id) {
if (out.GetSize() > std::numeric_limits<s32>::max()) {
return ResultLoaderInvalidSize;
}
R_UNLESS(out.GetSize() <= std::numeric_limits<s32>::max(), ResultInvalidSize());
return ldr::ro::GetProcessModuleInfo(count.GetPointer(), out.GetPointer(), out.GetSize(), process_id);
}

View File

@@ -54,6 +54,12 @@ namespace sts::ams {
}
namespace sts::result {
bool CallFatalOnResultAssertion = false;
}
using namespace sts;
void __libnx_exception_handler(ThreadExceptionDump *ctx) {

View File

@@ -40,29 +40,24 @@ namespace sts::ldr {
/* Helpers. */
Result ValidateSubregion(size_t allowed_start, size_t allowed_end, size_t start, size_t size, size_t min_size = 0) {
if (!(size >= min_size && allowed_start <= start && start <= allowed_end && start + size <= allowed_end)) {
return ResultLoaderInvalidMeta;
}
return ResultSuccess;
R_UNLESS(size >= min_size, ResultInvalidMeta());
R_UNLESS(allowed_start <= start, ResultInvalidMeta());
R_UNLESS(start <= allowed_end, ResultInvalidMeta());
R_UNLESS(start + size <= allowed_end, ResultInvalidMeta());
return ResultSuccess();
}
Result ValidateNpdm(const Npdm *npdm, size_t size) {
/* Validate magic. */
if (npdm->magic != Npdm::Magic) {
return ResultLoaderInvalidMeta;
}
R_UNLESS(npdm->magic == Npdm::Magic, ResultInvalidMeta());
/* Validate flags. */
if (hos::GetVersion() >= hos::Version_700) {
/* 7.0.0 added 0x10 as a valid bit to NPDM flags. */
if (npdm->flags & ~0x1F) {
return ResultLoaderInvalidMeta;
}
} else {
if (npdm->flags & ~0xF) {
return ResultLoaderInvalidMeta;
}
u32 mask = ~0x1F;
if (hos::GetVersion() < hos::Version_700) {
/* 7.0.0 added 0x10 as a valid bit to NPDM flags, so before that we only check 0xF. */
mask = ~0xF;
}
R_UNLESS(!(npdm->flags & mask), ResultInvalidMeta());
/* Validate Acid extents. */
R_TRY(ValidateSubregion(sizeof(Npdm), size, npdm->acid_offset, npdm->acid_size, sizeof(Acid)));
@@ -70,14 +65,12 @@ namespace sts::ldr {
/* Validate Aci extends. */
R_TRY(ValidateSubregion(sizeof(Npdm), size, npdm->aci_offset, npdm->aci_size, sizeof(Aci)));
return ResultSuccess;
return ResultSuccess();
}
Result ValidateAcid(const Acid *acid, size_t size) {
/* Validate magic. */
if (acid->magic != Acid::Magic) {
return ResultLoaderInvalidMeta;
}
R_UNLESS(acid->magic == Acid::Magic, ResultInvalidMeta());
/* TODO: Check if retail flag is set if not development hardware. */
@@ -86,21 +79,19 @@ namespace sts::ldr {
R_TRY(ValidateSubregion(sizeof(Acid), size, acid->sac_offset, acid->sac_size));
R_TRY(ValidateSubregion(sizeof(Acid), size, acid->kac_offset, acid->kac_size));
return ResultSuccess;
return ResultSuccess();
}
Result ValidateAci(const Aci *aci, size_t size) {
/* Validate magic. */
if (aci->magic != Aci::Magic) {
return ResultLoaderInvalidMeta;
}
R_UNLESS(aci->magic == Aci::Magic, ResultInvalidMeta());
/* Validate Fah, Sac, Kac. */
R_TRY(ValidateSubregion(sizeof(Aci), size, aci->fah_offset, aci->fah_size));
R_TRY(ValidateSubregion(sizeof(Aci), size, aci->sac_offset, aci->sac_size));
R_TRY(ValidateSubregion(sizeof(Aci), size, aci->kac_offset, aci->kac_size));
return ResultSuccess;
return ResultSuccess();
}
Result LoadMetaFromFile(FILE *f, MetaCache *cache) {
@@ -116,15 +107,12 @@ namespace sts::ldr {
fseek(f, 0, SEEK_SET);
/* Read data into cache buffer. */
if (npdm_size > MetaCacheBufferSize || fread(cache->buffer, npdm_size, 1, f) != 1) {
return ResultLoaderTooLargeMeta;
}
R_UNLESS(npdm_size <= MetaCacheBufferSize, ResultTooLargeMeta());
R_UNLESS(fread(cache->buffer, npdm_size, 1, f) == 1, ResultTooLargeMeta());
}
/* Ensure size is big enough. */
if (npdm_size < sizeof(Npdm)) {
return ResultLoaderInvalidMeta;
}
R_UNLESS(npdm_size >= sizeof(Npdm), ResultInvalidMeta());
/* Validate the meta. */
{
@@ -152,7 +140,7 @@ namespace sts::ldr {
meta->aci_kac = reinterpret_cast<u8 *>(aci) + aci->kac_offset;
}
return ResultSuccess;
return ResultSuccess();
}
}
@@ -198,7 +186,7 @@ namespace sts::ldr {
g_cached_title_id = title_id;
*out_meta = *meta;
return ResultSuccess;
return ResultSuccess();
}
Result LoadMetaFromCache(Meta *out_meta, ncm::TitleId title_id) {
@@ -206,7 +194,7 @@ namespace sts::ldr {
return LoadMeta(out_meta, title_id);
}
*out_meta = g_meta_cache.meta;
return ResultSuccess;
return ResultSuccess();
}
void InvalidateMetaCache() {

View File

@@ -196,38 +196,32 @@ namespace sts::ldr {
constexpr size_t g_MinimumTitleVersionsCount900 = util::size(g_MinimumTitleVersions900);
Result ValidateTitleVersion(ncm::TitleId title_id, u32 version) {
if (hos::GetVersion() < hos::Version_810) {
return ResultSuccess;
} else {
R_UNLESS(hos::GetVersion() >= hos::Version_810, ResultSuccess());
#ifdef LDR_VALIDATE_PROCESS_VERSION
const MinimumTitleVersion *entries = nullptr;
size_t num_entries = 0;
switch (hos::GetVersion()) {
case hos::Version_810:
entries = g_MinimumTitleVersions810;
num_entries = g_MinimumTitleVersionsCount810;
break;
case hos::Version_900:
entries = g_MinimumTitleVersions900;
num_entries = g_MinimumTitleVersionsCount900;
break;
default:
entries = nullptr;
num_entries = 0;
break;
}
for (size_t i = 0; i < num_entries; i++) {
if (entries[i].title_id == title_id && entries[i].version > version) {
return ResultLoaderInvalidVersion;
}
}
return ResultSuccess;
#else
return ResultSuccess;
#endif
const MinimumTitleVersion *entries = nullptr;
size_t num_entries = 0;
switch (hos::GetVersion()) {
case hos::Version_810:
entries = g_MinimumTitleVersions810;
num_entries = g_MinimumTitleVersionsCount810;
break;
case hos::Version_900:
entries = g_MinimumTitleVersions900;
num_entries = g_MinimumTitleVersionsCount900;
break;
default:
entries = nullptr;
num_entries = 0;
break;
}
for (size_t i = 0; i < num_entries; i++) {
if (entries[i].title_id == title_id) {
R_UNLESS(entries[i].version <= version, ResultInvalidVersion());
}
}
#endif
return ResultSuccess();
}
/* Helpers. */
@@ -243,9 +237,7 @@ namespace sts::ldr {
#define COPY_ACCESS_CONTROL(source, which) \
({ \
const size_t size = meta->source->which##_size; \
if (offset + size > sizeof(out->ac_buffer)) { \
return ResultLoaderInternalError; \
} \
R_UNLESS(offset + size <= sizeof(out->ac_buffer), ResultInternalError()); \
out->source##_##which##_size = size; \
std::memcpy(out->ac_buffer + offset, meta->source##_##which, size); \
offset += size; \
@@ -260,7 +252,7 @@ namespace sts::ldr {
/* Copy flags. */
out->flags = caps::GetProgramInfoFlags(meta->acid_kac, meta->acid->kac_size);
return ResultSuccess;
return ResultSuccess();
}
bool IsApplet(const Meta *meta) {
@@ -289,39 +281,31 @@ namespace sts::ldr {
if (R_SUCCEEDED(OpenCodeFile(f, title_id, GetNsoName(i)))) {
ON_SCOPE_EXIT { fclose(f); };
/* Read NSO header. */
if (fread(nso_headers + i, sizeof(*nso_headers), 1, f) != 1) {
return ResultLoaderInvalidNso;
}
R_UNLESS(fread(nso_headers + i, sizeof(*nso_headers), 1, f) == 1, ResultInvalidNso());
has_nso[i] = true;
}
}
return ResultSuccess;
return ResultSuccess();
}
Result ValidateNsoHeaders(const NsoHeader *nso_headers, const bool *has_nso) {
/* We must always have a main. */
if (!has_nso[Nso_Main]) {
return ResultLoaderInvalidNso;
}
R_UNLESS(has_nso[Nso_Main], ResultInvalidNso());
/* If we don't have an RTLD, we must only have a main. */
if (!has_nso[Nso_Rtld]) {
for (size_t i = Nso_Main + 1; i < Nso_Count; i++) {
if (has_nso[i]) {
return ResultLoaderInvalidNso;
}
R_UNLESS(!has_nso[i], ResultInvalidNso());
}
}
/* All NSOs must have zero text offset. */
for (size_t i = 0; i < Nso_Count; i++) {
if (nso_headers[i].text_dst_offset != 0) {
return ResultLoaderInvalidNso;
}
R_UNLESS(nso_headers[i].text_dst_offset == 0, ResultInvalidNso());
}
return ResultSuccess;
return ResultSuccess();
}
Result ValidateMeta(const Meta *meta, const ncm::TitleLocation &loc) {
@@ -329,15 +313,14 @@ namespace sts::ldr {
R_TRY(ValidateTitleVersion(loc.title_id, meta->npdm->version));
/* Validate title id. */
if (meta->aci->title_id < meta->acid->title_id_min || meta->aci->title_id > meta->acid->title_id_max) {
return ResultLoaderInvalidProgramId;
}
R_UNLESS(meta->aci->title_id >= meta->acid->title_id_min, ResultInvalidProgramId());
R_UNLESS(meta->aci->title_id <= meta->acid->title_id_max, ResultInvalidProgramId());
/* Validate the kernel capabilities. */
R_TRY(caps::ValidateCapabilities(meta->acid_kac, meta->acid->kac_size, meta->aci_kac, meta->aci->kac_size));
/* All good. */
return ResultSuccess;
return ResultSuccess();
}
Result GetCreateProcessFlags(u32 *out, const Meta *meta, const u32 ldr_flags) {
@@ -365,7 +348,7 @@ namespace sts::ldr {
flags |= svc::CreateProcessFlag_AddressSpace64Bit;
break;
default:
return ResultLoaderInvalidMeta;
return ResultInvalidMeta();
}
/* Set Enable Debug. */
@@ -410,7 +393,7 @@ namespace sts::ldr {
flags |= svc::CreateProcessFlag_PoolPartitionSystemNonSecure;
break;
default:
return ResultLoaderInvalidMeta;
return ResultInvalidMeta();
}
} else if (hos::GetVersion() >= hos::Version_400) {
/* On 4.0.0+, the corresponding bit was simply "UseSecureMemory". */
@@ -420,7 +403,7 @@ namespace sts::ldr {
}
*out = flags;
return ResultSuccess;
return ResultSuccess();
}
Result GetCreateProcessInfo(CreateProcessInfo *out, const Meta *meta, u32 flags, Handle reslimit_h) {
@@ -439,30 +422,23 @@ namespace sts::ldr {
/* 3.0.0+ System Resource Size. */
if (hos::GetVersion() >= hos::Version_300) {
/* Validate size is aligned. */
if (meta->npdm->system_resource_size & (SystemResourceSizeAlignment - 1)) {
return ResultLoaderInvalidSize;
}
R_UNLESS(util::IsAligned(meta->npdm->system_resource_size, SystemResourceSizeAlignment), ResultInvalidSize());
/* Validate system resource usage. */
if (meta->npdm->system_resource_size) {
/* Process must be 64-bit. */
if (!(out->flags & svc::CreateProcessFlag_AddressSpace64Bit)) {
return ResultLoaderInvalidMeta;
}
R_UNLESS((out->flags & svc::CreateProcessFlag_AddressSpace64Bit), ResultInvalidMeta());
/* Process must be application or applet. */
if (!IsApplication(meta) && !IsApplet(meta)) {
return ResultLoaderInvalidMeta;
}
R_UNLESS(IsApplication(meta) || IsApplet(meta), ResultInvalidMeta());
/* Size must be less than or equal to max. */
if (meta->npdm->system_resource_size > SystemResourceSizeMax) {
return ResultLoaderInvalidMeta;
}
R_UNLESS(meta->npdm->system_resource_size <= SystemResourceSizeMax, ResultInvalidMeta());
}
out->system_resource_num_pages = meta->npdm->system_resource_size >> 12;
}
return ResultSuccess;
return ResultSuccess();
}
Result DecideAddressSpaceLayout(ProcessInfo *out, CreateProcessInfo *out_cpi, const NsoHeader *nso_headers, const bool *has_nso, const args::ArgumentInfo *arg_info) {
@@ -527,9 +503,7 @@ namespace sts::ldr {
aslr_size = map::AslrSize32Bit;
}
}
if (total_size > aslr_size) {
return ResultKernelOutOfMemory;
}
R_UNLESS(total_size <= aslr_size, svc::ResultOutOfMemory());
/* Set Create Process output. */
uintptr_t aslr_slide = 0;
@@ -552,7 +526,7 @@ namespace sts::ldr {
out_cpi->code_address = aslr_start;
out_cpi->code_num_pages = total_size >> 12;
return ResultSuccess;
return ResultSuccess();
}
Result CreateProcessImpl(ProcessInfo *out, const Meta *meta, const NsoHeader *nso_headers, const bool *has_nso, const args::ArgumentInfo *arg_info, u32 flags, Handle reslimit_h) {
@@ -574,22 +548,18 @@ namespace sts::ldr {
}
/* Validate size. */
if (file_size > segment->size || file_size > std::numeric_limits<s32>::max() || segment->size > std::numeric_limits<s32>::max()) {
return ResultLoaderInvalidNso;
}
R_UNLESS(file_size <= segment->size, ResultInvalidNso());
R_UNLESS(segment->size <= std::numeric_limits<s32>::max(), ResultInvalidNso());
/* Load data from file. */
uintptr_t load_address = is_compressed ? map_end - file_size : map_base;
fseek(f, segment->file_offset, SEEK_SET);
if (fread(reinterpret_cast<void *>(load_address), file_size, 1, f) != 1) {
return ResultLoaderInvalidNso;
}
R_UNLESS(fread(reinterpret_cast<void *>(load_address), file_size, 1, f) == 1, ResultInvalidNso());
/* Uncompress if necessary. */
if (is_compressed) {
if (util::DecompressLZ4(reinterpret_cast<void *>(map_base), segment->size, reinterpret_cast<const void *>(load_address), file_size) != static_cast<int>(segment->size)) {
return ResultLoaderInvalidNso;
}
bool decompressed = (util::DecompressLZ4(reinterpret_cast<void *>(map_base), segment->size, reinterpret_cast<const void *>(load_address), file_size) == static_cast<int>(segment->size));
R_UNLESS(decompressed, ResultInvalidNso());
}
/* Check hash if necessary. */
@@ -597,12 +567,10 @@ namespace sts::ldr {
u8 hash[SHA256_HASH_SIZE];
sha256CalculateHash(hash, reinterpret_cast<void *>(map_base), segment->size);
if (std::memcmp(hash, file_hash, sizeof(hash)) != 0) {
return ResultLoaderInvalidNso;
}
R_UNLESS(std::memcmp(hash, file_hash, sizeof(hash)) == 0, ResultInvalidNso());
}
return ResultSuccess;
return ResultSuccess();
}
Result LoadNsoIntoProcessMemory(Handle process_handle, FILE *f, uintptr_t map_address, const NsoHeader *nso_header, uintptr_t nso_address, size_t nso_size) {
@@ -646,7 +614,7 @@ namespace sts::ldr {
R_TRY(svcSetProcessMemoryPermission(process_handle, nso_address + nso_header->rw_dst_offset, rw_size, Perm_Rw));
}
return ResultSuccess;
return ResultSuccess();
}
Result LoadNsosIntoProcessMemory(const ProcessInfo *process_info, const ncm::TitleId title_id, const NsoHeader *nso_headers, const bool *has_nso, const args::ArgumentInfo *arg_info) {
@@ -687,7 +655,7 @@ namespace sts::ldr {
R_TRY(svcSetProcessMemoryPermission(process_handle, process_info->args_address, process_info->args_size, Perm_Rw));
}
return ResultSuccess;
return ResultSuccess();
}
}
@@ -754,7 +722,7 @@ namespace sts::ldr {
*out = info.process_handle.Move();
}
return ResultSuccess;
return ResultSuccess();
}
Result GetProgramInfo(ProgramInfo *out, const ncm::TitleLocation &loc) {

View File

@@ -81,9 +81,7 @@ namespace sts::ldr::ro {
Result PinTitle(PinId *out, const ncm::TitleLocation &loc) {
*out = InvalidPinId;
ProcessInfo *info = GetFreeProcessInfo();
if (info == nullptr) {
return ResultLoaderTooManyProcesses;
}
R_UNLESS(info != nullptr, ldr::ResultTooManyProcesses());
static u64 s_cur_pin_id = 1;
@@ -92,46 +90,38 @@ namespace sts::ldr::ro {
info->loc = loc;
info->in_use = true;
*out = info->pin_id;
return ResultSuccess;
return ResultSuccess();
}
Result UnpinTitle(PinId id) {
ProcessInfo *info = GetProcessInfo(id);
if (info == nullptr) {
return ResultLoaderNotPinned;
}
R_UNLESS(info != nullptr, ldr::ResultNotPinned());
info->in_use = false;
return ResultSuccess;
return ResultSuccess();
}
Result GetTitleLocation(ncm::TitleLocation *out, PinId id) {
ProcessInfo *info = GetProcessInfo(id);
if (info == nullptr) {
return ResultLoaderNotPinned;
}
R_UNLESS(info != nullptr, ldr::ResultNotPinned());
*out = info->loc;
return ResultSuccess;
return ResultSuccess();
}
Result RegisterProcess(PinId id, os::ProcessId process_id, ncm::TitleId title_id) {
ProcessInfo *info = GetProcessInfo(id);
if (info == nullptr) {
return ResultLoaderNotPinned;
}
R_UNLESS(info != nullptr, ldr::ResultNotPinned());
info->title_id = title_id;
info->process_id = process_id;
return ResultSuccess;
return ResultSuccess();
}
Result RegisterModule(PinId id, const u8 *build_id, uintptr_t address, size_t size) {
ProcessInfo *info = GetProcessInfo(id);
if (info == nullptr) {
return ResultLoaderNotPinned;
}
R_UNLESS(info != nullptr, ldr::ResultNotPinned());
/* Nintendo doesn't actually care about successful allocation. */
for (size_t i = 0; i < ModuleCountMax; i++) {
@@ -147,14 +137,12 @@ namespace sts::ldr::ro {
break;
}
return ResultSuccess;
return ResultSuccess();
}
Result GetProcessModuleInfo(u32 *out_count, ldr::ModuleInfo *out, size_t max_out_count, os::ProcessId process_id) {
const ProcessInfo *info = GetProcessInfo(process_id);
if (info == nullptr) {
return ResultLoaderNotPinned;
}
R_UNLESS(info != nullptr, ldr::ResultNotPinned());
size_t count = 0;
for (size_t i = 0; i < ModuleCountMax && count < max_out_count; i++) {
@@ -167,7 +155,7 @@ namespace sts::ldr::ro {
}
*out_count = static_cast<u32>(count);
return ResultSuccess;
return ResultSuccess();
}
}