From 4059dc6187244c7644dd1bf0a94314d4c098aadd Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 24 Oct 2019 01:40:44 -0700 Subject: [PATCH] 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). --- stratosphere/ams_mitm/Makefile | 14 +- .../source/bpc_mitm/bpc_ams_service.cpp | 2 +- .../source/bpc_mitm/bpc_mitm_service.cpp | 2 +- .../bpc_mitm/bpcmitm_reboot_manager.cpp | 4 +- .../ams_mitm/source/fs_mitm/fs_dir_utils.cpp | 6 +- .../ams_mitm/source/fs_mitm/fs_dir_utils.hpp | 4 +- .../fs_directory_redirection_filesystem.cpp | 4 +- .../fs_directory_savedata_filesystem.cpp | 8 +- .../source/fs_mitm/fs_file_storage.cpp | 12 +- .../ams_mitm/source/fs_mitm/fs_idirectory.hpp | 4 +- .../ams_mitm/source/fs_mitm/fs_ifile.hpp | 8 +- .../source/fs_mitm/fs_ifilesystem.hpp | 12 +- .../ams_mitm/source/fs_mitm/fs_istorage.hpp | 2 +- .../ams_mitm/source/fs_mitm/fs_path_utils.cpp | 14 +- .../ams_mitm/source/fs_mitm/fs_save_utils.cpp | 6 +- .../fs_mitm/fs_subdirectory_filesystem.cpp | 2 +- .../source/fs_mitm/fsmitm_boot0storage.cpp | 4 +- .../source/fs_mitm/fsmitm_boot0storage.hpp | 4 +- .../source/fs_mitm/fsmitm_layeredrom.cpp | 8 +- .../source/fs_mitm/fsmitm_romstorage.hpp | 2 +- .../source/fs_mitm/fsmitm_service.cpp | 16 +- .../source/ns_mitm/nsmitm_am_service.cpp | 2 +- .../source/ns_mitm/nsmitm_web_service.cpp | 4 +- .../source/set_mitm/set_mitm_service.cpp | 6 +- .../set_mitm/setsys_firmware_version.cpp | 2 +- .../source/set_mitm/setsys_mitm_service.cpp | 6 +- .../source/set_mitm/setsys_settings_items.cpp | 12 +- stratosphere/ams_mitm/source/utils.cpp | 6 +- stratosphere/boot/Makefile | 14 +- .../boot/source/boot_battery_driver.cpp | 24 +- stratosphere/boot/source/boot_calibration.cpp | 13 +- .../boot/source/boot_charger_driver.cpp | 8 +- stratosphere/boot/source/boot_i2c_utils.cpp | 18 +- stratosphere/boot/source/boot_main.cpp | 6 + stratosphere/boot/source/boot_pcv.cpp | 10 +- stratosphere/boot/source/boot_pmic_driver.cpp | 4 +- .../boot/source/i2c/driver/i2c_api.cpp | 8 +- .../i2c/driver/impl/i2c_bus_accessor.cpp | 53 ++-- .../source/i2c/driver/impl/i2c_session.cpp | 15 +- .../boot/source/i2c/i2c_command_list.cpp | 12 +- stratosphere/boot2/Makefile | 14 +- stratosphere/boot2/source/boot2_main.cpp | 6 + stratosphere/creport/Makefile | 14 +- .../creport/source/creport_crash_report.cpp | 16 +- .../creport/source/creport_crash_report.hpp | 4 +- stratosphere/creport/source/creport_main.cpp | 8 +- stratosphere/dmnt/Makefile | 14 +- .../dmnt/source/cheat/dmnt_cheat_service.cpp | 46 +-- .../dmnt/source/cheat/impl/dmnt_cheat_api.cpp | 96 +++--- .../dmnt/source/cheat/impl/dmnt_cheat_vm.cpp | 2 +- stratosphere/dmnt/source/dmnt_main.cpp | 6 + .../dmnt/source/dmnt_service_debug.cpp | 6 +- .../dmnt/source/dmnt_service_target_io.cpp | 34 +-- stratosphere/eclct.stub/Makefile | 14 +- stratosphere/eclct.stub/source/eclct_stub.cpp | 6 + stratosphere/fatal/Makefile | 14 +- stratosphere/fatal/source/fatal_debug.cpp | 8 +- .../fatal/source/fatal_event_manager.cpp | 6 +- stratosphere/fatal/source/fatal_main.cpp | 6 + stratosphere/fatal/source/fatal_repair.cpp | 4 +- stratosphere/fatal/source/fatal_service.cpp | 46 ++- stratosphere/fatal/source/fatal_service.hpp | 6 +- .../fatal/source/fatal_task_clock.cpp | 4 +- .../fatal/source/fatal_task_error_report.cpp | 4 +- .../fatal/source/fatal_task_power.cpp | 6 +- .../fatal/source/fatal_task_screen.cpp | 26 +- .../fatal/source/fatal_task_sound.cpp | 2 +- stratosphere/libstratosphere/Makefile | 2 +- .../stratosphere/ams/ams_exosphere_api.hpp | 2 +- .../include/stratosphere/defines.hpp | 1 + .../stratosphere/fatal/fatal_types.hpp | 13 +- .../stratosphere/kvdb/kvdb_auto_buffer.hpp | 6 +- .../kvdb/kvdb_file_key_value_cache.hpp | 22 +- .../kvdb/kvdb_file_key_value_store.hpp | 2 +- .../kvdb/kvdb_memory_key_value_store.hpp | 30 +- .../include/stratosphere/os/os_thread.hpp | 4 +- .../include/stratosphere/results.hpp | 7 +- .../stratosphere/results/ams_results.hpp | 25 +- .../stratosphere/results/cal_results.hpp | 26 ++ .../stratosphere/results/creport_results.hpp | 30 +- .../stratosphere/results/debug_results.hpp | 14 +- .../stratosphere/results/dmnt_results.hpp | 44 ++- .../stratosphere/results/err_results.hpp | 12 +- .../stratosphere/results/fatal_results.hpp | 20 +- .../stratosphere/results/fs_results.hpp | 121 +++++--- .../stratosphere/results/hipc_results.hpp | 28 +- .../stratosphere/results/i2c_results.hpp | 18 +- .../stratosphere/results/kernel_results.hpp | 64 ---- .../stratosphere/results/kvdb_results.hpp | 22 +- .../stratosphere/results/loader_results.hpp | 76 ++--- .../stratosphere/results/lr_results.hpp | 24 +- .../stratosphere/results/ncm_results.hpp | 58 ++-- .../stratosphere/results/os_results.hpp | 17 +- .../stratosphere/results/pm_results.hpp | 20 +- .../stratosphere/results/results_common.hpp | 288 ++++++++++++++++++ .../stratosphere/results/ro_results.hpp | 39 +-- .../stratosphere/results/settings_results.hpp | 40 +-- .../stratosphere/results/sf_results.hpp | 45 ++- .../stratosphere/results/sm_results.hpp | 26 +- .../stratosphere/results/spl_results.hpp | 39 +-- .../stratosphere/results/svc_results.hpp | 73 +++++ .../stratosphere/results/updater_results.hpp | 18 +- .../include/stratosphere/results/utilities.h | 132 -------- .../stratosphere/results/vi_results.hpp | 14 +- .../sf/hipc/sf_hipc_server_manager.hpp | 2 +- .../hipc/sf_hipc_server_session_manager.hpp | 4 +- .../sf/impl/sf_impl_command_serialization.hpp | 41 +-- .../include/stratosphere/sf/sf_out.hpp | 3 + .../stratosphere/sm/sm_scoped_holder.hpp | 6 +- .../include/stratosphere/spl/spl_types.hpp | 21 +- .../stratosphere/util/util_alignment.hpp | 36 ++- .../source/ams/ams_environment.cpp | 17 +- .../source/ams/ams_exosphere_api.cpp | 4 +- .../source/boot2/boot2_api.cpp | 15 +- .../source/cfg/cfg_sd_card.cpp | 6 +- .../source/dd/dd_io_mappings.cpp | 2 +- .../libstratosphere/source/hid/hid_api.cpp | 4 +- .../source/kvdb/kvdb_archive.cpp | 24 +- .../source/kvdb/kvdb_file_key_value_store.cpp | 48 ++- .../libstratosphere/source/map/map_api.cpp | 36 +-- .../source/os/impl/os_inter_process_event.cpp | 22 +- .../os/impl/os_waitable_manager_impl.cpp | 12 +- .../source/os/os_interrupt_event.cpp | 16 +- .../source/os/os_system_event.cpp | 15 +- .../libstratosphere/source/pm/pm_dmnt_api.cpp | 2 +- .../libstratosphere/source/pm/pm_info_api.cpp | 4 +- .../source/result/result_on_assertion.cpp | 38 +++ .../source/sf/cmif/sf_cmif_domain_manager.cpp | 4 +- .../sf/cmif/sf_cmif_domain_service_object.cpp | 26 +- .../sf/cmif/sf_cmif_service_dispatch.cpp | 24 +- .../source/sf/hipc/sf_hipc_api.cpp | 24 +- .../sf_hipc_server_domain_session_manager.cpp | 20 +- .../source/sf/hipc/sf_hipc_server_manager.cpp | 21 +- .../hipc/sf_hipc_server_session_manager.cpp | 40 +-- .../libstratosphere/source/sm/sm_api.cpp | 2 +- .../source/updater/updater_api.cpp | 80 +++-- .../source/updater/updater_bis_management.cpp | 14 +- .../source/updater/updater_bis_management.hpp | 2 +- .../source/updater/updater_bis_save.cpp | 2 +- .../source/updater/updater_files.cpp | 8 +- stratosphere/loader/Makefile | 14 +- stratosphere/loader/source/ldr_arguments.cpp | 12 +- .../loader/source/ldr_capabilities.cpp | 15 +- .../loader/source/ldr_content_management.cpp | 32 +- stratosphere/loader/source/ldr_ecs.cpp | 17 +- .../loader/source/ldr_launch_record.cpp | 2 +- .../loader/source/ldr_loader_service.cpp | 7 +- stratosphere/loader/source/ldr_main.cpp | 6 + stratosphere/loader/source/ldr_meta.cpp | 56 ++-- .../loader/source/ldr_process_creation.cpp | 144 ++++----- stratosphere/loader/source/ldr_ro_manager.cpp | 36 +-- stratosphere/pm/Makefile | 14 +- .../pm/source/impl/pm_process_manager.cpp | 127 ++++---- .../pm/source/impl/pm_resource_manager.cpp | 27 +- .../pm/source/pm_debug_monitor_service.cpp | 8 +- stratosphere/pm/source/pm_main.cpp | 6 + stratosphere/ro/Makefile | 12 +- stratosphere/ro/source/impl/ro_nro_utils.cpp | 18 +- stratosphere/ro/source/impl/ro_nrr_utils.cpp | 46 +-- .../ro/source/impl/ro_service_impl.cpp | 162 +++++----- stratosphere/ro/source/ro_debug_monitor.cpp | 4 +- stratosphere/ro/source/ro_main.cpp | 6 + stratosphere/sm/Makefile | 15 +- .../sm/source/impl/sm_service_manager.cpp | 200 +++++------- stratosphere/sm/source/sm_main.cpp | 7 + stratosphere/sm/source/sm_user_service.cpp | 6 +- stratosphere/spl/Makefile | 14 +- stratosphere/spl/source/spl_api_impl.cpp | 175 ++++------- stratosphere/spl/source/spl_main.cpp | 6 + 169 files changed, 2172 insertions(+), 1868 deletions(-) create mode 100644 stratosphere/libstratosphere/include/stratosphere/results/cal_results.hpp delete mode 100644 stratosphere/libstratosphere/include/stratosphere/results/kernel_results.hpp create mode 100644 stratosphere/libstratosphere/include/stratosphere/results/results_common.hpp create mode 100644 stratosphere/libstratosphere/include/stratosphere/results/svc_results.hpp delete mode 100644 stratosphere/libstratosphere/include/stratosphere/results/utilities.h create mode 100644 stratosphere/libstratosphere/source/result/result_on_assertion.cpp diff --git a/stratosphere/ams_mitm/Makefile b/stratosphere/ams_mitm/Makefile index 1501fca9e..80cdb7332 100644 --- a/stratosphere/ams_mitm/Makefile +++ b/stratosphere/ams_mitm/Makefile @@ -31,7 +31,7 @@ DATA := data INCLUDES := include ../../common/include EXEFS_SRC := exefs_src -DEFINES := -DRESULT_ABORT_ON_ASSERT -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\" +DEFINES := -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\" #--------------------------------------------------------------------------------- # options for code generation @@ -45,8 +45,18 @@ CFLAGS += $(INCLUDE) -D__SWITCH__ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17 +CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \ + -Wl,--wrap,__cxa_throw \ + -Wl,--wrap,__cxa_rethrow \ + -Wl,--wrap,__cxa_allocate_exception \ + -Wl,--wrap,__cxa_begin_catch \ + -Wl,--wrap,__cxa_end_catch \ + -Wl,--wrap,__cxa_call_unexpected \ + -Wl,--wrap,__cxa_call_terminate \ + -Wl,--wrap,__gxx_personality_v0 + ASFLAGS := -g $(ARCH) -LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) +LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map) LIBS := -lstratosphere -lnx diff --git a/stratosphere/ams_mitm/source/bpc_mitm/bpc_ams_service.cpp b/stratosphere/ams_mitm/source/bpc_mitm/bpc_ams_service.cpp index 1e589967e..222566f10 100644 --- a/stratosphere/ams_mitm/source/bpc_mitm/bpc_ams_service.cpp +++ b/stratosphere/ams_mitm/source/bpc_mitm/bpc_ams_service.cpp @@ -28,5 +28,5 @@ Result BpcAtmosphereService::RebootToFatalError(InBuffer Result { /* On File */ /* Just copy the file to the new fs. */ @@ -113,5 +113,5 @@ Result FsDirUtils::EnsureDirectoryExists(IFileSystem *fs, const FsPath &path) { } } R_END_TRY_CATCH; - return ResultSuccess; + return ResultSuccess(); } diff --git a/stratosphere/ams_mitm/source/fs_mitm/fs_dir_utils.hpp b/stratosphere/ams_mitm/source/fs_mitm/fs_dir_utils.hpp index 814cdc47b..955542854 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fs_dir_utils.hpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fs_dir_utils.hpp @@ -71,7 +71,7 @@ class FsDirUtils { work_path.str[parent_len] = 0; } - return ResultSuccess; + return ResultSuccess(); } public: @@ -137,6 +137,6 @@ class FsDirUtils { } R_END_TRY_CATCH; } - return ResultSuccess; + return ResultSuccess(); } }; diff --git a/stratosphere/ams_mitm/source/fs_mitm/fs_directory_redirection_filesystem.cpp b/stratosphere/ams_mitm/source/fs_mitm/fs_directory_redirection_filesystem.cpp index 564b40a7e..8853ede40 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fs_directory_redirection_filesystem.cpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fs_directory_redirection_filesystem.cpp @@ -54,7 +54,7 @@ Result DirectoryRedirectionFileSystem::Initialize(const char *before, const char this->before_dir_len = strlen(this->before_dir); this->after_dir_len = strlen(this->after_dir); - return ResultSuccess; + return ResultSuccess(); } Result DirectoryRedirectionFileSystem::GetFullPath(char *out, size_t out_size, const char *relative_path) { @@ -79,7 +79,7 @@ Result DirectoryRedirectionFileSystem::GetFullPath(char *out, size_t out_size, c } std::strncpy(out, this->after_dir, out_size); out[out_size - 1] = 0; - return ResultSuccess; + return ResultSuccess(); } else { return FsPathUtils::Normalize(out, out_size, relative_path, nullptr); } diff --git a/stratosphere/ams_mitm/source/fs_mitm/fs_directory_savedata_filesystem.cpp b/stratosphere/ams_mitm/source/fs_mitm/fs_directory_savedata_filesystem.cpp index 54f1aa66a..f1883a48c 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fs_directory_savedata_filesystem.cpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fs_directory_savedata_filesystem.cpp @@ -114,7 +114,7 @@ Result DirectorySaveDataFileSystem::AllocateWorkBuffer(void **out_buf, size_t *o if (buf != nullptr) { *out_buf = buf; *out_size = try_size; - return ResultSuccess; + return ResultSuccess(); } /* Divide size by two. */ @@ -162,7 +162,7 @@ Result DirectorySaveDataFileSystem::CopySaveFromProxy() { R_TRY(FsDirUtils::CopyDirectoryRecursively(this, this->proxy_save_fs.get(), FsPathUtils::RootPath, FsPathUtils::RootPath, work_buf, work_buf_size)); return this->Commit(); } - return ResultSuccess; + return ResultSuccess(); } /* ================================================================================================ */ @@ -258,7 +258,7 @@ Result DirectorySaveDataFileSystem::OpenFileImpl(std::unique_ptr &out_fil this->open_writable_files++; } - return ResultSuccess; + return ResultSuccess(); } Result DirectorySaveDataFileSystem::OpenDirectoryImpl(std::unique_ptr &out_dir, const FsPath &path, DirectoryOpenMode mode) { @@ -303,7 +303,7 @@ Result DirectorySaveDataFileSystem::CommitImpl() { R_TRY(FsDirUtils::RetryUntilTargetNotLocked(std::move(RenameSynchDir))); /* TODO: Should I call this->fs->Commit()? Nintendo does not. */ - return ResultSuccess; + return ResultSuccess(); } Result DirectorySaveDataFileSystem::GetFreeSpaceSizeImpl(uint64_t *out, const FsPath &path) { diff --git a/stratosphere/ams_mitm/source/fs_mitm/fs_file_storage.cpp b/stratosphere/ams_mitm/source/fs_mitm/fs_file_storage.cpp index 351389100..ae300465d 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fs_file_storage.cpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fs_file_storage.cpp @@ -25,14 +25,14 @@ Result FileStorage::UpdateSize() { if (this->size == InvalidSize) { return this->file->GetSize(&this->size); } - return ResultSuccess; + return ResultSuccess(); } Result FileStorage::Read(void *buffer, size_t size, u64 offset) { u64 read_size; if (size == 0) { - return ResultSuccess; + return ResultSuccess(); } if (buffer == nullptr) { return ResultFsNullptrArgument; @@ -47,12 +47,12 @@ Result FileStorage::Read(void *buffer, size_t size, u64 offset) { if (read_size != size && read_size) { return this->Read(reinterpret_cast(reinterpret_cast(buffer) + read_size), size - read_size, offset + read_size); } - return ResultSuccess; + return ResultSuccess(); } Result FileStorage::Write(void *buffer, size_t size, u64 offset) { if (size == 0) { - return ResultSuccess; + return ResultSuccess(); } if (buffer == nullptr) { return ResultFsNullptrArgument; @@ -72,7 +72,7 @@ Result FileStorage::Flush() { Result FileStorage::GetSize(u64 *out_size) { R_TRY(this->UpdateSize()); *out_size = this->size; - return ResultSuccess; + return ResultSuccess(); } Result FileStorage::SetSize(u64 size) { @@ -92,7 +92,7 @@ Result FileStorage::OperateRange(FsOperationId operation_type, u64 offset, u64 s /* N checks for size == sizeof(*out_range_info) here, but that's because their wrapper api is bad. */ std::memset(out_range_info, 0, sizeof(*out_range_info)); } - return ResultSuccess; + return ResultSuccess(); } R_TRY(this->UpdateSize()); /* N checks for positivity + signed overflow on offset/size here, but we're using unsigned types... */ diff --git a/stratosphere/ams_mitm/source/fs_mitm/fs_idirectory.hpp b/stratosphere/ams_mitm/source/fs_mitm/fs_idirectory.hpp index ff977b3fe..354df82ba 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fs_idirectory.hpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fs_idirectory.hpp @@ -28,7 +28,7 @@ class IDirectory { } if (max_entries == 0) { *out_count = 0; - return ResultSuccess; + return ResultSuccess(); } if (out_entries == nullptr) { return ResultFsNullptrArgument; @@ -107,7 +107,7 @@ class ProxyDirectory : public IDirectory { R_TRY(fsDirRead(this->base_dir.get(), 0, &count, max_entries, out_entries)); *out_count = count; - return ResultSuccess; + return ResultSuccess(); } virtual Result GetEntryCountImpl(uint64_t *count) { return fsDirGetEntryCount(this->base_dir.get(), count); diff --git a/stratosphere/ams_mitm/source/fs_mitm/fs_ifile.hpp b/stratosphere/ams_mitm/source/fs_mitm/fs_ifile.hpp index 303945e8e..d97669d88 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fs_ifile.hpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fs_ifile.hpp @@ -31,7 +31,7 @@ class IFile { } if (size == 0) { *out = 0; - return ResultSuccess; + return ResultSuccess(); } if (buffer == nullptr) { return ResultFsNullptrArgument; @@ -56,7 +56,7 @@ class IFile { Result Write(uint64_t offset, void *buffer, uint64_t size, uint32_t flags) { if (size == 0) { - return ResultSuccess; + return ResultSuccess(); } if (buffer == nullptr) { return ResultFsNullptrArgument; @@ -66,7 +66,7 @@ class IFile { Result Write(uint64_t offset, void *buffer, uint64_t size, bool flush = false) { if (size == 0) { - return ResultSuccess; + return ResultSuccess(); } if (buffer == nullptr) { return ResultFsNullptrArgument; @@ -175,7 +175,7 @@ class ProxyFile : public IFile { R_TRY(fsFileRead(this->base_file.get(), offset, buffer, size, FS_READOPTION_NONE, &out_sz)); *out = out_sz; - return ResultSuccess; + return ResultSuccess(); } virtual Result GetSizeImpl(u64 *out) override { return fsFileGetSize(this->base_file.get(), out); diff --git a/stratosphere/ams_mitm/source/fs_mitm/fs_ifilesystem.hpp b/stratosphere/ams_mitm/source/fs_mitm/fs_ifilesystem.hpp index 9b7c05e23..bbe7192e0 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fs_ifilesystem.hpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fs_ifilesystem.hpp @@ -276,7 +276,7 @@ class IFileSystemInterface : public IServiceObject { R_TRY(this->base_fs->GetEntryType(&type, path)); out_type.SetValue(type); - return ResultSuccess; + return ResultSuccess(); } virtual Result OpenFile(Out> out_intf, InPointer in_path, uint32_t mode) final { @@ -287,7 +287,7 @@ class IFileSystemInterface : public IServiceObject { R_TRY(this->base_fs->OpenFile(out_file, path, static_cast(mode))); out_intf.SetValue(std::make_shared(std::move(out_file))); - return ResultSuccess; + return ResultSuccess(); } virtual Result OpenDirectory(Out> out_intf, InPointer in_path, uint32_t mode) final { @@ -298,7 +298,7 @@ class IFileSystemInterface : public IServiceObject { R_TRY(this->base_fs->OpenDirectory(out_dir, path, static_cast(mode))); out_intf.SetValue(std::make_shared(std::move(out_dir))); - return ResultSuccess; + return ResultSuccess(); } virtual Result Commit() final { @@ -419,14 +419,14 @@ class ProxyFileSystem : public IFileSystem { R_TRY(fsFsGetEntryType(this->base_fs.get(), path.str, &type)); *out = static_cast(static_cast(type)); - return ResultSuccess; + return ResultSuccess(); } virtual Result OpenFileImpl(std::unique_ptr &out_file, const FsPath &path, OpenMode mode) { FsFile f; R_TRY(fsFsOpenFile(this->base_fs.get(), path.str, static_cast(mode), &f)); out_file = std::make_unique(f); - return ResultSuccess; + return ResultSuccess(); } virtual Result OpenDirectoryImpl(std::unique_ptr &out_dir, const FsPath &path, DirectoryOpenMode mode) { @@ -434,7 +434,7 @@ class ProxyFileSystem : public IFileSystem { R_TRY(fsFsOpenDirectory(this->base_fs.get(), path.str, static_cast(mode), &d)); out_dir = std::make_unique(d); - return ResultSuccess; + return ResultSuccess(); } virtual Result CommitImpl() { diff --git a/stratosphere/ams_mitm/source/fs_mitm/fs_istorage.hpp b/stratosphere/ams_mitm/source/fs_mitm/fs_istorage.hpp index 5ea138326..eaff9c663 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fs_istorage.hpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fs_istorage.hpp @@ -102,7 +102,7 @@ class IROStorage : public IStorage { return ResultFsUnsupportedOperation; }; virtual Result Flush() final { - return ResultSuccess; + return ResultSuccess(); }; virtual Result SetSize(u64 size) final { (void)(size); diff --git a/stratosphere/ams_mitm/source/fs_mitm/fs_path_utils.cpp b/stratosphere/ams_mitm/source/fs_mitm/fs_path_utils.cpp index 32c587695..4409e87b4 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fs_path_utils.cpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fs_path_utils.cpp @@ -28,7 +28,7 @@ Result FsPathUtils::VerifyPath(const char *path, size_t max_path_len, size_t max const char c = *(cur++); /* If terminated, we're done. */ if (c == 0) { - return ResultSuccess; + return ResultSuccess(); } /* TODO: Nintendo converts the path from utf-8 to utf-32, one character at a time. */ @@ -110,7 +110,7 @@ Result FsPathUtils::IsNormalized(bool *out, const char *path) { /* It is unclear why first separator and separator are separate states... */ if (c == '/') { *out = false; - return ResultSuccess; + return ResultSuccess(); } else if (c == '.') { state = PathState::CurrentDir; } else { @@ -120,7 +120,7 @@ Result FsPathUtils::IsNormalized(bool *out, const char *path) { case PathState::CurrentDir: if (c == '/') { *out = false; - return ResultSuccess; + return ResultSuccess(); } else if (c == '.') { state = PathState::ParentDir; } else { @@ -130,7 +130,7 @@ Result FsPathUtils::IsNormalized(bool *out, const char *path) { case PathState::ParentDir: if (c == '/') { *out = false; - return ResultSuccess; + return ResultSuccess(); } else { state = PathState::Normal; } @@ -138,7 +138,7 @@ Result FsPathUtils::IsNormalized(bool *out, const char *path) { case PathState::WindowsDriveLetter: if (c == ':') { *out = true; - return ResultSuccess; + return ResultSuccess(); } else { return ResultFsInvalidPathFormat; } @@ -161,7 +161,7 @@ Result FsPathUtils::IsNormalized(bool *out, const char *path) { break; } - return ResultSuccess; + return ResultSuccess(); } Result FsPathUtils::Normalize(char *out, size_t max_out_size, const char *src, size_t *out_len) { @@ -263,5 +263,5 @@ Result FsPathUtils::Normalize(char *out, size_t max_out_size, const char *src, s R_ASSERT(FsPathUtils::IsNormalized(&normalized, out)); STS_ASSERT(normalized); - return ResultSuccess; + return ResultSuccess(); } diff --git a/stratosphere/ams_mitm/source/fs_mitm/fs_save_utils.cpp b/stratosphere/ams_mitm/source/fs_mitm/fs_save_utils.cpp index 2390f6816..a1855ec40 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fs_save_utils.cpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fs_save_utils.cpp @@ -53,7 +53,7 @@ Result FsSaveUtils::GetSaveDataSpaceIdString(const char **out_str, u8 space_id) *out_str = str; } - return ResultSuccess; + return ResultSuccess(); } Result FsSaveUtils::GetSaveDataTypeString(const char **out_str, u8 save_data_type) { @@ -95,7 +95,7 @@ Result FsSaveUtils::GetSaveDataTypeString(const char **out_str, u8 save_data_typ *out_str = str; } - return ResultSuccess; + return ResultSuccess(); } Result FsSaveUtils::GetSaveDataDirectoryPath(FsPath &out_path, u8 space_id, u8 save_data_type, u64 title_id, u128 user_id, u64 save_id) { @@ -121,5 +121,5 @@ Result FsSaveUtils::GetSaveDataDirectoryPath(FsPath &out_path, u8 space_id, u8 s return ResultFsTooLongPath; } - return ResultSuccess; + return ResultSuccess(); } diff --git a/stratosphere/ams_mitm/source/fs_mitm/fs_subdirectory_filesystem.cpp b/stratosphere/ams_mitm/source/fs_mitm/fs_subdirectory_filesystem.cpp index 9a7cc9793..c7a737fb0 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fs_subdirectory_filesystem.cpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fs_subdirectory_filesystem.cpp @@ -49,7 +49,7 @@ Result SubDirectoryFileSystem::Initialize(const char *bp) { std::strncpy(this->base_path, normal_path, this->base_path_len); this->base_path[this->base_path_len-1] = 0; - return ResultSuccess; + return ResultSuccess(); } Result SubDirectoryFileSystem::GetFullPath(char *out, size_t out_size, const char *relative_path) { diff --git a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_boot0storage.cpp b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_boot0storage.cpp index dae04da02..06148bcb4 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_boot0storage.cpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_boot0storage.cpp @@ -67,7 +67,7 @@ Result Boot0Storage::Write(void *_buffer, size_t size, u64 offset) { if (offset < EksEnd) { if (offset + size < EksEnd) { /* Ignore writes falling strictly within the region. */ - return ResultSuccess; + return ResultSuccess(); } else { /* Only write past the end of the keyblob region. */ buffer = buffer + (EksEnd - offset); @@ -80,7 +80,7 @@ Result Boot0Storage::Write(void *_buffer, size_t size, u64 offset) { } if (size == 0) { - return ResultSuccess; + return ResultSuccess(); } /* We care about protecting autorcm from NS. */ diff --git a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_boot0storage.hpp b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_boot0storage.hpp index 5dd1c046b..d15a2bdbb 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_boot0storage.hpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_boot0storage.hpp @@ -72,7 +72,7 @@ class SectoredProxyStorage : public ProxyStorage { } } - return ResultSuccess; + return ResultSuccess(); } virtual Result Write(void *_buffer, size_t size, u64 offset) override { @@ -112,7 +112,7 @@ class SectoredProxyStorage : public ProxyStorage { } } - return ResultSuccess; + return ResultSuccess(); } }; diff --git a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_layeredrom.cpp b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_layeredrom.cpp index 2378445d2..44f35ae71 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_layeredrom.cpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_layeredrom.cpp @@ -48,7 +48,7 @@ LayeredRomFS::LayeredRomFS(std::shared_ptr s_r, std::shared_ptrp_source_infos)[this->p_source_infos->size() - 1].virtual_offset + (*this->p_source_infos)[this->p_source_infos->size() - 1].size; - return ResultSuccess; + return ResultSuccess(); } Result LayeredRomFS::OperateRange(FsOperationId operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) { /* TODO: How should I implement this for a virtual romfs? */ if (operation_type == FsOperationId_QueryRange) { *out_range_info = {0}; } - return ResultSuccess; + return ResultSuccess(); } diff --git a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romstorage.hpp b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romstorage.hpp index a9dc70e24..4c9c144b0 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romstorage.hpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romstorage.hpp @@ -42,7 +42,7 @@ class RomFileStorage : public IROStorage { if (out_sz != size && out_sz) { R_TRY(this->Read((void *)((uintptr_t)buffer + out_sz), size - out_sz, offset + out_sz)); } - return ResultSuccess; + return ResultSuccess(); }; Result GetSize(u64 *out_size) override { return fsFileGetSize(this->base_file, out_size); diff --git a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_service.cpp b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_service.cpp index ea49b659b..35c1ecea1 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_service.cpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_service.cpp @@ -92,7 +92,7 @@ Result FsMitmService::OpenHblWebContentFileSystem(Out> out_fs, u64 title_id, u32 filesystem_type) { @@ -163,7 +163,7 @@ Result FsMitmService::OpenSdCardFileSystem(Out> out_fs, u8 space_id, FsSave save_struct) { @@ -222,7 +222,7 @@ Result FsMitmService::OpenSaveDataFileSystem(Out> out out_storage.ChangeObjectId(bis_storage.s.object_id); } - return ResultSuccess; + return ResultSuccess(); } /* Add redirection for RomFS to the SD card. */ @@ -299,7 +299,7 @@ Result FsMitmService::OpenDataStorageByCurrentProcess(Out(this->title_id)) && Utils::IsHblTid(title_id)) { nsamResolveApplicationContentPathFwd(this->forward_service.get(), title_id, static_cast(storage_type)); - return ResultSuccess; + return ResultSuccess(); } return nsamResolveApplicationContentPathFwd(this->forward_service.get(), title_id, static_cast(storage_type)); diff --git a/stratosphere/ams_mitm/source/ns_mitm/nsmitm_web_service.cpp b/stratosphere/ams_mitm/source/ns_mitm/nsmitm_web_service.cpp index 6eed885ff..094341c2d 100644 --- a/stratosphere/ams_mitm/source/ns_mitm/nsmitm_web_service.cpp +++ b/stratosphere/ams_mitm/source/ns_mitm/nsmitm_web_service.cpp @@ -34,7 +34,7 @@ Result NsWebMitmService::GetDocumentInterface(Out out_path, u64 app_id, u8 storage_type) { @@ -45,7 +45,7 @@ Result NsDocumentService::ResolveApplicationContentPath(u64 title_id, u8 storage /* Always succeed for web applet asking about HBL. */ if (Utils::IsWebAppletTid(static_cast(this->title_id)) && Utils::IsHblTid(title_id)) { nswebResolveApplicationContentPath(this->srv.get(), title_id, static_cast(storage_type)); - return ResultSuccess; + return ResultSuccess(); } return nswebResolveApplicationContentPath(this->srv.get(), title_id, static_cast(storage_type)); diff --git a/stratosphere/ams_mitm/source/set_mitm/set_mitm_service.cpp b/stratosphere/ams_mitm/source/set_mitm/set_mitm_service.cpp index 434a88f0c..df381b878 100644 --- a/stratosphere/ams_mitm/source/set_mitm/set_mitm_service.cpp +++ b/stratosphere/ams_mitm/source/set_mitm/set_mitm_service.cpp @@ -79,7 +79,7 @@ Result SetMitmService::EnsureLocale() { } } - return ResultSuccess; + return ResultSuccess(); } Result SetMitmService::GetLanguageCode(Out out_lang_code) { @@ -90,7 +90,7 @@ Result SetMitmService::GetLanguageCode(Out out_lang_code) { } out_lang_code.SetValue(this->locale.language_code); - return ResultSuccess; + return ResultSuccess(); } Result SetMitmService::GetRegionCode(Out out_region_code) { @@ -101,5 +101,5 @@ Result SetMitmService::GetRegionCode(Out out_region_code) { } out_region_code.SetValue(this->locale.region_code); - return ResultSuccess; + return ResultSuccess(); } diff --git a/stratosphere/ams_mitm/source/set_mitm/setsys_firmware_version.cpp b/stratosphere/ams_mitm/source/set_mitm/setsys_firmware_version.cpp index 43b32d57f..c037e547b 100644 --- a/stratosphere/ams_mitm/source/set_mitm/setsys_firmware_version.cpp +++ b/stratosphere/ams_mitm/source/set_mitm/setsys_firmware_version.cpp @@ -75,5 +75,5 @@ Result VersionManager::GetFirmwareVersion(sts::ncm::TitleId title_id, SetSysFirm *out = g_fw_version; } - return ResultSuccess; + return ResultSuccess(); } \ No newline at end of file diff --git a/stratosphere/ams_mitm/source/set_mitm/setsys_mitm_service.cpp b/stratosphere/ams_mitm/source/set_mitm/setsys_mitm_service.cpp index d0091f0a5..9821e6542 100644 --- a/stratosphere/ams_mitm/source/set_mitm/setsys_mitm_service.cpp +++ b/stratosphere/ams_mitm/source/set_mitm/setsys_mitm_service.cpp @@ -32,7 +32,7 @@ Result SetSysMitmService::GetFirmwareVersion(OutPointerWithServerSizerevision_major = 0; out.pointer->revision_minor = 0; - return ResultSuccess; + return ResultSuccess(); } Result SetSysMitmService::GetFirmwareVersion2(OutPointerWithServerSize out) { @@ -64,7 +64,7 @@ Result SetSysMitmService::GetSettingsItemValueSize(Out out_size, InPointer< R_TRY(setsysGetSettingsItemValueSize(name, key, out_size.GetPointer())); } - return ResultSuccess; + return ResultSuccess(); } Result SetSysMitmService::GetSettingsItemValue(Out out_size, OutBuffer out_value, InPointer in_name, InPointer in_key) { @@ -96,5 +96,5 @@ Result SetSysMitmService::GetSettingsItemValue(Out out_size, OutBuffer R_TRY(setsysGetSettingsItemValueFwd(this->forward_service.get(), name, key, out_value.buffer, out_value.num_elements, out_size.GetPointer())); } - return ResultSuccess; + return ResultSuccess(); } diff --git a/stratosphere/ams_mitm/source/set_mitm/setsys_settings_items.cpp b/stratosphere/ams_mitm/source/set_mitm/setsys_settings_items.cpp index 273c74604..9fb787db9 100644 --- a/stratosphere/ams_mitm/source/set_mitm/setsys_settings_items.cpp +++ b/stratosphere/ams_mitm/source/set_mitm/setsys_settings_items.cpp @@ -84,7 +84,7 @@ Result SettingsItemManager::ValidateName(const char *name, size_t max_size) { return ResultSettingsItemNameInvalidFormat; } - return ResultSuccess; + return ResultSuccess(); } Result SettingsItemManager::ValidateName(const char *name) { @@ -107,7 +107,7 @@ Result SettingsItemManager::ValidateKey(const char *key, size_t max_size) { return ResultSettingsItemKeyInvalidFormat; } - return ResultSuccess; + return ResultSuccess(); } Result SettingsItemManager::ValidateKey(const char *key) { @@ -219,7 +219,7 @@ static Result ParseValue(const char *name, const char *key, const char *val_tup) } g_settings_items[kv] = value; - return ResultSuccess; + return ResultSuccess(); } static Result ParseSettingsItemValue(const char *name, const char *key, const char *value) { @@ -227,7 +227,7 @@ static Result ParseSettingsItemValue(const char *name, const char *key, const ch R_TRY(SettingsItemManager::ValidateName(name)); R_TRY(SettingsItemManager::ValidateKey(name)); R_TRY(ParseValue(name, key, value)); - return ResultSuccess; + return ResultSuccess(); } static int SettingsItemIniHandler(void *user, const char *name, const char *key, const char *value) { @@ -282,7 +282,7 @@ Result SettingsItemManager::GetValueSize(const char *name, const char *key, u64 } *out_size = it->second.size; - return ResultSuccess; + return ResultSuccess(); } Result SettingsItemManager::GetValue(const char *name, const char *key, void *out, size_t max_size, u64 *out_size) { @@ -300,5 +300,5 @@ Result SettingsItemManager::GetValue(const char *name, const char *key, void *ou *out_size = copy_size; memcpy(out, it->second.data, copy_size); - return ResultSuccess; + return ResultSuccess(); } diff --git a/stratosphere/ams_mitm/source/utils.cpp b/stratosphere/ams_mitm/source/utils.cpp index 0f53fe6b0..38781d1be 100644 --- a/stratosphere/ams_mitm/source/utils.cpp +++ b/stratosphere/ams_mitm/source/utils.cpp @@ -451,7 +451,7 @@ Result Utils::SaveSdFileForAtmosphere(u64 title_id, const char *fn, void *data, /* Try to write the data. */ R_TRY(fsFileWrite(&f, 0, data, size, FS_WRITEOPTION_FLUSH)); - return ResultSuccess; + return ResultSuccess(); } bool Utils::IsHblTid(u64 _tid) { @@ -539,7 +539,7 @@ Result Utils::GetKeysHeld(u64 *keys) { *keys |= hidKeysHeld((HidControllerID) controller); } - return ResultSuccess; + return ResultSuccess(); } static bool HasOverrideKey(OverrideKey *cfg) { @@ -793,7 +793,7 @@ Result Utils::GetSettingsItemBooleanValue(const char *name, const char *key, boo if (out) { *out = val != 0; } - return ResultSuccess; + return ResultSuccess(); } void Utils::RebootToFatalError(AtmosphereFatalErrorContext *ctx) { diff --git a/stratosphere/boot/Makefile b/stratosphere/boot/Makefile index 8714afa85..cd7f519cd 100644 --- a/stratosphere/boot/Makefile +++ b/stratosphere/boot/Makefile @@ -38,7 +38,7 @@ DATA := data INCLUDES := include ../../common/include EXEFS_SRC := exefs_src -DEFINES := -DRESULT_ABORT_ON_ASSERT -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\" +DEFINES := -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\" #--------------------------------------------------------------------------------- # options for code generation @@ -52,8 +52,18 @@ CFLAGS += $(INCLUDE) -D__SWITCH__ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17 +CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \ + -Wl,--wrap,__cxa_throw \ + -Wl,--wrap,__cxa_rethrow \ + -Wl,--wrap,__cxa_allocate_exception \ + -Wl,--wrap,__cxa_begin_catch \ + -Wl,--wrap,__cxa_end_catch \ + -Wl,--wrap,__cxa_call_unexpected \ + -Wl,--wrap,__cxa_call_terminate \ + -Wl,--wrap,__gxx_personality_v0 + ASFLAGS := -g $(ARCH) -LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) +LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map) LIBS := -lstratosphere -lnx diff --git a/stratosphere/boot/source/boot_battery_driver.cpp b/stratosphere/boot/source/boot_battery_driver.cpp index 298d80bc3..b89ec5f3f 100644 --- a/stratosphere/boot/source/boot_battery_driver.cpp +++ b/stratosphere/boot/source/boot_battery_driver.cpp @@ -67,7 +67,7 @@ namespace sts::boot { const u16 new_val = (cur_val & ~mask) | val; R_TRY(this->Write(addr, new_val)); - return ResultSuccess; + return ResultSuccess(); } bool BatteryDriver::WriteValidate(u8 addr, u16 val) { @@ -99,20 +99,20 @@ namespace sts::boot { Result BatteryDriver::LockModelTable() { R_TRY(this->Write(Max17050ModelAccess0, 0x0000)); R_TRY(this->Write(Max17050ModelAccess1, 0x0000)); - return ResultSuccess; + return ResultSuccess(); } Result BatteryDriver::UnlockModelTable() { R_TRY(this->Write(Max17050ModelAccess0, 0x0059)); R_TRY(this->Write(Max17050ModelAccess1, 0x00C4)); - return ResultSuccess; + return ResultSuccess(); } Result BatteryDriver::SetModelTable(const u16 *model_table) { for (size_t i = 0; i < Max17050ModelChrTblSize; i++) { R_TRY(this->Write(Max17050ModelChrTblStart + i, model_table[i])); } - return ResultSuccess; + return ResultSuccess(); } bool BatteryDriver::IsModelTableLocked() { @@ -173,7 +173,7 @@ namespace sts::boot { if (lock_i >= 8) { /* This is regarded as guaranteed success. */ - return ResultSuccess; + return ResultSuccess(); } } @@ -235,7 +235,7 @@ namespace sts::boot { R_TRY(this->Write(Max17050CGain, 0x7FFF)); } - return ResultSuccess; + return ResultSuccess(); } Result BatteryDriver::IsBatteryRemoved(bool *out) { @@ -243,28 +243,28 @@ namespace sts::boot { u16 val = 0; R_TRY(this->Read(Max17050Status, &val)); *out = (val & 0x0008) == 0x0008; - return ResultSuccess; + return ResultSuccess(); } Result BatteryDriver::GetTemperature(double *out) { u16 val = 0; R_TRY(this->Read(Max17050Temperature, &val)); *out = static_cast(val) * double(0.00390625); - return ResultSuccess; + return ResultSuccess(); } Result BatteryDriver::GetAverageVCell(u32 *out) { u16 val = 0; R_TRY(this->Read(Max17050AverageVCell, &val)); *out = (625 * u32(val >> 3)) / 1000; - return ResultSuccess; + return ResultSuccess(); } Result BatteryDriver::GetSocRep(double *out) { u16 val = 0; R_TRY(this->Read(Max17050SocRep, &val)); *out = static_cast(val) * double(0.00390625); - return ResultSuccess; + return ResultSuccess(); } Result BatteryDriver::GetBatteryPercentage(size_t *out) { @@ -278,7 +278,7 @@ namespace sts::boot { } else { *out = static_cast(converted_percentage); } - return ResultSuccess; + return ResultSuccess(); } Result BatteryDriver::SetShutdownTimer() { @@ -289,7 +289,7 @@ namespace sts::boot { u16 val = 0; R_TRY(this->Read(Max17050Config, &val)); *out = (val & 0x0040) != 0; - return ResultSuccess; + return ResultSuccess(); } Result BatteryDriver::SetShutdownEnabled(bool enabled) { diff --git a/stratosphere/boot/source/boot_calibration.cpp b/stratosphere/boot/source/boot_calibration.cpp index 06d2105c2..84e4c9eed 100644 --- a/stratosphere/boot/source/boot_calibration.cpp +++ b/stratosphere/boot/source/boot_calibration.cpp @@ -29,8 +29,6 @@ namespace sts::boot { constexpr u32 DefaultBatteryVendor = static_cast('A'); constexpr u32 DefaultBatteryVersion = 0; - constexpr Result ResultCalInvalidCrc = 0xCAC6; /* TODO: Verify this really is cal, move to libstrat results. */ - /* Helpers. */ constexpr u16 GetCrc16(const void *data, size_t size) { constexpr u16 s_crc_table[0x10] = { @@ -51,10 +49,9 @@ namespace sts::boot { Result ValidateCalibrationCrc16(const void *data, size_t size) { const u8 *data_u8 = reinterpret_cast(data); - if (GetCrc16(data, size - sizeof(u16)) != *(reinterpret_cast(&data_u8[size - sizeof(u16)]))) { - return ResultCalInvalidCrc; - } - return ResultSuccess; + const bool crc_valid = GetCrc16(data, size - sizeof(u16)) == *(reinterpret_cast(&data_u8[size - sizeof(u16)])); + R_UNLESS(crc_valid, cal::ResultCalibrationDataCrcError()); + return ResultSuccess(); } Result GetBatteryVendorImpl(u32 *vendor) { @@ -68,7 +65,7 @@ namespace sts::boot { R_TRY(ValidateCalibrationCrc16(battery_lot, sizeof(battery_lot))); *vendor = battery_lot[7]; - return ResultSuccess; + return ResultSuccess(); } Result GetBatteryVersionImpl(u32 *version) { @@ -82,7 +79,7 @@ namespace sts::boot { R_TRY(ValidateCalibrationCrc16(battery_version, sizeof(battery_version))); *version = battery_version[0]; - return ResultSuccess; + return ResultSuccess(); } } diff --git a/stratosphere/boot/source/boot_charger_driver.cpp b/stratosphere/boot/source/boot_charger_driver.cpp index 1a5a4929a..2cd2916c4 100644 --- a/stratosphere/boot/source/boot_charger_driver.cpp +++ b/stratosphere/boot/source/boot_charger_driver.cpp @@ -35,7 +35,7 @@ namespace sts::boot { const u8 new_val = (cur_val & ~mask) | val; R_TRY(this->Write(addr, new_val)); - return ResultSuccess; + return ResultSuccess(); } Result ChargerDriver::Initialize() { @@ -59,7 +59,7 @@ namespace sts::boot { R_TRY(this->SetBoostModeCurrentLimit(bq24193::BoostModeCurrentLimit_500mA)); R_TRY(this->SetHiZEnabled(false)); - return ResultSuccess; + return ResultSuccess(); } Result ChargerDriver::SetChargeEnabled(bool enabled) { @@ -123,14 +123,14 @@ namespace sts::boot { u8 limit; R_TRY(this->Read(bq24193::InputSourceControl, &limit)); *out = static_cast(limit); - return ResultSuccess; + return ResultSuccess(); } Result ChargerDriver::GetChargeVoltageLimit(u32 *out) { u8 reg; R_TRY(this->Read(bq24193::ChargeVoltageControl, ®)); *out = bq24193::DecodeChargeVoltageLimit(reg); - return ResultSuccess; + return ResultSuccess(); } } \ No newline at end of file diff --git a/stratosphere/boot/source/boot_i2c_utils.cpp b/stratosphere/boot/source/boot_i2c_utils.cpp index 86138ad1f..9627b4013 100644 --- a/stratosphere/boot/source/boot_i2c_utils.cpp +++ b/stratosphere/boot/source/boot_i2c_utils.cpp @@ -27,14 +27,16 @@ namespace sts::boot { u64 cur_time = 0; while (true) { - R_TRY_CLEANUP(f(), { - cur_time += retry_interval; - if (cur_time < timeout) { - svcSleepThread(retry_interval); - continue; - } - }); - return ResultSuccess; + const auto retry_result = f(); + R_UNLESS(R_FAILED(retry_result), ResultSuccess()); + + cur_time += retry_interval; + if (cur_time < timeout) { + svcSleepThread(retry_interval); + continue; + } + + return retry_result; } } diff --git a/stratosphere/boot/source/boot_main.cpp b/stratosphere/boot/source/boot_main.cpp index 696416b39..952c42767 100644 --- a/stratosphere/boot/source/boot_main.cpp +++ b/stratosphere/boot/source/boot_main.cpp @@ -72,6 +72,12 @@ namespace sts::ams { } +namespace sts::result { + + bool CallFatalOnResultAssertion = false; + +} + using namespace sts; void __libnx_exception_handler(ThreadExceptionDump *ctx) { diff --git a/stratosphere/boot/source/boot_pcv.cpp b/stratosphere/boot/source/boot_pcv.cpp index 52ded29ef..01390e3cd 100644 --- a/stratosphere/boot/source/boot_pcv.cpp +++ b/stratosphere/boot/source/boot_pcv.cpp @@ -44,19 +44,19 @@ namespace sts::pcv { reg::ReadWrite(regs.clk_src_reg, 0, 0xE0000000); svcSleepThread(2000ul); - return ResultSuccess; + return ResultSuccess(); } Result SetClockEnabled(PcvModule module, bool enabled) { - return ResultSuccess; + return ResultSuccess(); } Result SetVoltageEnabled(u32 domain, bool enabled) { - return ResultSuccess; + return ResultSuccess(); } Result SetVoltageValue(u32 domain, u32 voltage) { - return ResultSuccess; + return ResultSuccess(); } Result SetReset(PcvModule module, bool reset) { @@ -71,7 +71,7 @@ namespace sts::pcv { reg::ClearBits(regs.rst_reg, regs.mask); } - return ResultSuccess; + return ResultSuccess(); } } diff --git a/stratosphere/boot/source/boot_pmic_driver.cpp b/stratosphere/boot/source/boot_pmic_driver.cpp index d1de3c678..9550a19e9 100644 --- a/stratosphere/boot/source/boot_pmic_driver.cpp +++ b/stratosphere/boot/source/boot_pmic_driver.cpp @@ -34,7 +34,7 @@ namespace sts::boot { u8 power_status; R_TRY(this->GetPowerStatus(&power_status)); *out = (power_status & 0x02) != 0; - return ResultSuccess; + return ResultSuccess(); } Result PmicDriver::GetPowerIntr(u8 *out) { @@ -56,7 +56,7 @@ namespace sts::boot { u8 power_intr; R_TRY(this->GetPowerIntr(&power_intr)); *out = (power_intr & 0x08) != 0; - return ResultSuccess; + return ResultSuccess(); } Result PmicDriver::ShutdownSystem(bool reboot) { diff --git a/stratosphere/boot/source/i2c/driver/i2c_api.cpp b/stratosphere/boot/source/i2c/driver/i2c_api.cpp index 21f959e81..6b9a99132 100644 --- a/stratosphere/boot/source/i2c/driver/i2c_api.cpp +++ b/stratosphere/boot/source/i2c/driver/i2c_api.cpp @@ -40,7 +40,7 @@ namespace sts::i2c::driver { R_TRY(Send(session, *cur_cmd, num_bytes, option)); (*cur_cmd) += num_bytes; - return ResultSuccess; + return ResultSuccess(); } Result ReceiveHandler(const u8 **cur_cmd, u8 **cur_dst, Session& session) { @@ -55,7 +55,7 @@ namespace sts::i2c::driver { R_TRY(Receive(session, *cur_dst, num_bytes, option)); (*cur_dst) += num_bytes; - return ResultSuccess; + return ResultSuccess(); } Result SubCommandHandler(const u8 **cur_cmd, u8 **cur_dst, Session& session) { @@ -72,7 +72,7 @@ namespace sts::i2c::driver { break; STS_UNREACHABLE_DEFAULT_CASE(); } - return ResultSuccess; + return ResultSuccess(); } /* Command handler list. */ @@ -155,7 +155,7 @@ namespace sts::i2c::driver { R_TRY(g_cmd_handlers[static_cast(cmd)](&cur_cmd, &cur_dst, session)); } - return ResultSuccess; + return ResultSuccess(); } /* Power management. */ diff --git a/stratosphere/boot/source/i2c/driver/impl/i2c_bus_accessor.cpp b/stratosphere/boot/source/i2c/driver/impl/i2c_bus_accessor.cpp index 2a7ea42dc..87791bc0a 100644 --- a/stratosphere/boot/source/i2c/driver/impl/i2c_bus_accessor.cpp +++ b/stratosphere/boot/source/i2c/driver/impl/i2c_bus_accessor.cpp @@ -118,7 +118,7 @@ namespace sts::i2c::driver::impl { Result BusAccessor::StartTransaction(Command command, AddressingMode addressing_mode, u32 slave_address) { /* Nothing actually happens here... */ - return ResultSuccess; + return ResultSuccess(); } Result BusAccessor::Send(const u8 *data, size_t num_bytes, I2cTransactionOption option, AddressingMode addressing_mode, u32 slave_address) { @@ -158,9 +158,9 @@ namespace sts::i2c::driver::impl { this->interrupt_event.Reset(); if (!this->interrupt_event.TimedWait(InterruptTimeout)) { - this->HandleTransactionResult(ResultI2cBusBusy); + this->HandleTransactionResult(i2c::ResultBusBusy()); this->interrupt_event.Reset(); - return ResultI2cTimedOut; + return i2c::ResultTimedOut(); } R_TRY(this->GetAndHandleTransactionResult()); @@ -181,13 +181,13 @@ namespace sts::i2c::driver::impl { this->interrupt_event.Reset(); if (!this->interrupt_event.TimedWait(InterruptTimeout)) { - this->HandleTransactionResult(ResultI2cBusBusy); + this->HandleTransactionResult(i2c::ResultBusBusy()); this->interrupt_event.Reset(); - return ResultI2cTimedOut; + return i2c::ResultTimedOut(); } } - return ResultSuccess; + return ResultSuccess(); } Result BusAccessor::Receive(u8 *out_data, size_t num_bytes, I2cTransactionOption option, AddressingMode addressing_mode, u32 slave_address) { @@ -206,10 +206,10 @@ namespace sts::i2c::driver::impl { while (remaining > 0) { this->interrupt_event.Reset(); if (!this->interrupt_event.TimedWait(InterruptTimeout)) { - this->HandleTransactionResult(ResultI2cBusBusy); + this->HandleTransactionResult(i2c::ResultBusBusy()); this->ClearInterruptMask(); this->interrupt_event.Reset(); - return ResultI2cTimedOut; + return i2c::ResultTimedOut(); } R_TRY(this->GetAndHandleTransactionResult()); @@ -230,7 +230,7 @@ namespace sts::i2c::driver::impl { } /* N doesn't do ClearInterruptMask. */ - return ResultSuccess; + return ResultSuccess(); } void BusAccessor::SetBus(Bus bus) { @@ -383,13 +383,11 @@ namespace sts::i2c::driver::impl { /* Wait for flush to finish, check every ms for 5 ms. */ for (size_t i = 0; i < 5; i++) { - if (!(reg::Read(&this->i2c_registers->I2C_FIFO_CONTROL_0) & 3)) { - return ResultSuccess; - } + R_UNLESS((reg::Read(&this->i2c_registers->I2C_FIFO_CONTROL_0) & 3), ResultSuccess()); svcSleepThread(1'000'000ul); } - return ResultI2cBusBusy; + return i2c::ResultBusBusy(); } Result BusAccessor::GetTransactionResult() const { @@ -397,22 +395,23 @@ namespace sts::i2c::driver::impl { const u32 interrupt_status = reg::Read(&this->i2c_registers->I2C_INTERRUPT_STATUS_REGISTER_0); /* Check for no ack. */ - if ((packet_status & 0xC) || (interrupt_status & 0x8)) { - return ResultI2cNoAck; - } + R_UNLESS(!(packet_status & 0xC), i2c::ResultNoAck()); + R_UNLESS(!(interrupt_status & 0x8), i2c::ResultNoAck()); /* Check for arb lost. */ - if ((packet_status & 0x2) || (interrupt_status & 0x4)) { - this->ClearBus(); - return ResultI2cBusBusy; + { + auto bus_guard = SCOPE_GUARD { this->ClearBus(); }; + R_UNLESS(!(packet_status & 0x2), i2c::ResultBusBusy()); + R_UNLESS(!(interrupt_status & 0x4), i2c::ResultBusBusy()); + bus_guard.Cancel(); } - return ResultSuccess; + return ResultSuccess(); } void BusAccessor::HandleTransactionResult(Result result) { R_TRY_CATCH(result) { - R_CATCH_MANY(ResultI2cNoAck, ResultI2cBusBusy) { + R_CATCH(i2c::ResultNoAck, i2c::ResultBusBusy) { this->ResetController(); this->SetClock(this->speed_mode); this->SetPacketMode(); @@ -422,12 +421,12 @@ namespace sts::i2c::driver::impl { } Result BusAccessor::GetAndHandleTransactionResult() { - R_TRY_CLEANUP(this->GetTransactionResult(), { - this->HandleTransactionResult(R_CLEANUP_RESULT); - this->ClearInterruptMask(); - this->interrupt_event.Reset(); - }); - return ResultSuccess; + const auto transaction_result = this->GetTransactionResult(); + R_UNLESS(R_FAILED(transaction_result), ResultSuccess()); + this->HandleTransactionResult(transaction_result); + this->ClearInterruptMask(); + this->interrupt_event.Reset(); + return transaction_result; } void BusAccessor::WriteTransferHeader(TransferMode transfer_mode, I2cTransactionOption option, AddressingMode addressing_mode, u32 slave_address, size_t num_bytes) { diff --git a/stratosphere/boot/source/i2c/driver/impl/i2c_session.cpp b/stratosphere/boot/source/i2c/driver/impl/i2c_session.cpp index 4e39dd106..f9641e757 100644 --- a/stratosphere/boot/source/i2c/driver/impl/i2c_session.cpp +++ b/stratosphere/boot/source/i2c/driver/impl/i2c_session.cpp @@ -60,9 +60,7 @@ namespace sts::i2c::driver::impl { Result Session::DoTransaction(void *dst, const void *src, size_t num_bytes, I2cTransactionOption option, Command command) { std::scoped_lock lk(this->bus_accessor_mutex); - if (this->bus_accessor->GetBusy()) { - return ResultI2cBusBusy; - } + R_UNLESS(!this->bus_accessor->GetBusy(), i2c::ResultBusBusy()); this->bus_accessor->OnStartTransaction(); ON_SCOPE_EXIT { this->bus_accessor->OnStopTransaction(); }; @@ -79,23 +77,22 @@ namespace sts::i2c::driver::impl { STS_UNREACHABLE_DEFAULT_CASE(); } - return ResultSuccess; + return ResultSuccess(); } Result Session::DoTransactionWithRetry(void *dst, const void *src, size_t num_bytes, I2cTransactionOption option, Command command) { size_t i = 0; while (true) { R_TRY_CATCH(this->DoTransaction(dst, src, num_bytes, option, command)) { - R_CATCH(ResultI2cTimedOut) { - i++; - if (i <= this->max_retries) { + R_CATCH(i2c::ResultTimedOut) { + if ((++i) <= this->max_retries) { svcSleepThread(this->retry_wait_time); continue; } - return ResultI2cBusBusy; + return i2c::ResultBusBusy(); } } R_END_TRY_CATCH; - return ResultSuccess; + return ResultSuccess(); } } diff --git a/stratosphere/boot/source/i2c/i2c_command_list.cpp b/stratosphere/boot/source/i2c/i2c_command_list.cpp index 838246e39..27bdd4422 100644 --- a/stratosphere/boot/source/i2c/i2c_command_list.cpp +++ b/stratosphere/boot/source/i2c/i2c_command_list.cpp @@ -32,10 +32,8 @@ namespace sts::i2c { } Result CommandListFormatter::CanEnqueue(size_t size) const { - if (this->cmd_list_size - this->cur_index < size) { - return ResultI2cFullCommandList; - } - return ResultSuccess; + R_UNLESS(this->cmd_list_size - this->cur_index >= size, ResultFullCommandList()); + return ResultSuccess(); } Result CommandListFormatter::EnqueueSendCommand(I2cTransactionOption option, const void *src, size_t size) { @@ -52,7 +50,7 @@ namespace sts::i2c { for (size_t i = 0; i < size; i++) { this->cmd_list[this->cur_index++] = src_u8[i]; } - return ResultSuccess; + return ResultSuccess(); } Result CommandListFormatter::EnqueueReceiveCommand(I2cTransactionOption option, size_t size) { @@ -64,7 +62,7 @@ namespace sts::i2c { this->cur_index++; this->cmd_list[this->cur_index++] = size; - return ResultSuccess; + return ResultSuccess(); } Result CommandListFormatter::EnqueueSleepCommand(size_t us) { @@ -75,7 +73,7 @@ namespace sts::i2c { this->cur_index++; this->cmd_list[this->cur_index++] = us; - return ResultSuccess; + return ResultSuccess(); } } diff --git a/stratosphere/boot2/Makefile b/stratosphere/boot2/Makefile index 2d3bf2862..52911803e 100644 --- a/stratosphere/boot2/Makefile +++ b/stratosphere/boot2/Makefile @@ -31,7 +31,7 @@ DATA := data INCLUDES := include ../../common/include EXEFS_SRC := exefs_src -DEFINES := -DDISABLE_IPC -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\" -DINI_MAX_LINE=768 +DEFINES := -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\" -DINI_MAX_LINE=768 #--------------------------------------------------------------------------------- # options for code generation @@ -45,8 +45,18 @@ CFLAGS += $(INCLUDE) -D__SWITCH__ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17 +CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \ + -Wl,--wrap,__cxa_throw \ + -Wl,--wrap,__cxa_rethrow \ + -Wl,--wrap,__cxa_allocate_exception \ + -Wl,--wrap,__cxa_begin_catch \ + -Wl,--wrap,__cxa_end_catch \ + -Wl,--wrap,__cxa_call_unexpected \ + -Wl,--wrap,__cxa_call_terminate \ + -Wl,--wrap,__gxx_personality_v0 + ASFLAGS := -g $(ARCH) -LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) +LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map) LIBS := -lstratosphere -lnx diff --git a/stratosphere/boot2/source/boot2_main.cpp b/stratosphere/boot2/source/boot2_main.cpp index 35fda6872..58a2d4fe8 100644 --- a/stratosphere/boot2/source/boot2_main.cpp +++ b/stratosphere/boot2/source/boot2_main.cpp @@ -46,6 +46,12 @@ namespace sts::ams { } +namespace sts::result { + + bool CallFatalOnResultAssertion = false; + +} + using namespace sts; void __libnx_exception_handler(ThreadExceptionDump *ctx) { diff --git a/stratosphere/creport/Makefile b/stratosphere/creport/Makefile index 71c014dc5..4b06622de 100644 --- a/stratosphere/creport/Makefile +++ b/stratosphere/creport/Makefile @@ -31,7 +31,7 @@ DATA := data INCLUDES := include ../../common/include EXEFS_SRC := exefs_src -DEFINES := -DDISABLE_IPC -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\" +DEFINES := -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\" #--------------------------------------------------------------------------------- # options for code generation @@ -45,8 +45,18 @@ CFLAGS += $(INCLUDE) -D__SWITCH__ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17 +CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \ + -Wl,--wrap,__cxa_throw \ + -Wl,--wrap,__cxa_rethrow \ + -Wl,--wrap,__cxa_allocate_exception \ + -Wl,--wrap,__cxa_begin_catch \ + -Wl,--wrap,__cxa_end_catch \ + -Wl,--wrap,__cxa_call_unexpected \ + -Wl,--wrap,__cxa_call_terminate \ + -Wl,--wrap,__gxx_personality_v0 + ASFLAGS := -g $(ARCH) -LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) +LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map) LIBS := -lstratosphere -lnx diff --git a/stratosphere/creport/source/creport_crash_report.cpp b/stratosphere/creport/source/creport_crash_report.cpp index 17244659f..f9d4c2508 100644 --- a/stratosphere/creport/source/creport_crash_report.cpp +++ b/stratosphere/creport/source/creport_crash_report.cpp @@ -212,29 +212,29 @@ namespace sts::creport { void CrashReport::HandleDebugEventInfoException(const svc::DebugEventInfo &d) { switch (d.info.exception.type) { case svc::DebugExceptionType::UndefinedInstruction: - this->result = ResultCreportUndefinedInstruction; + this->result = ResultUndefinedInstruction(); break; case svc::DebugExceptionType::InstructionAbort: - this->result = ResultCreportInstructionAbort; + this->result = ResultInstructionAbort(); break; case svc::DebugExceptionType::DataAbort: - this->result = ResultCreportDataAbort; + this->result = ResultDataAbort(); break; case svc::DebugExceptionType::AlignmentFault: - this->result = ResultCreportAlignmentFault; + this->result = ResultAlignmentFault(); break; case svc::DebugExceptionType::UserBreak: - this->result = ResultCreportUserBreak; + this->result = ResultUserBreak(); /* Try to parse out the user break result. */ if (hos::GetVersion() >= hos::Version_500) { svcReadDebugProcessMemory(&this->result, this->debug_handle, d.info.exception.specific.user_break.address, sizeof(this->result)); } break; case svc::DebugExceptionType::UndefinedSystemCall: - this->result = ResultCreportUndefinedSystemCall; + this->result = ResultUndefinedSystemCall(); break; case svc::DebugExceptionType::SystemMemoryError: - this->result = ResultCreportSystemMemoryError; + this->result = ResultSystemMemoryError(); break; case svc::DebugExceptionType::DebuggerAttached: case svc::DebugExceptionType::BreakPoint: @@ -306,7 +306,7 @@ namespace sts::creport { void CrashReport::SaveToFile(FILE *f_report) { fprintf(f_report, "Atmosphère Crash Report (v1.4):\n"); - fprintf(f_report, "Result: 0x%X (2%03d-%04d)\n\n", this->result, R_MODULE(this->result), R_DESCRIPTION(this->result)); + fprintf(f_report, "Result: 0x%X (2%03d-%04d)\n\n", this->result.GetValue(), this->result.GetModule(), this->result.GetDescription()); /* Process Info. */ char name_buf[0x10] = {}; diff --git a/stratosphere/creport/source/creport_crash_report.hpp b/stratosphere/creport/source/creport_crash_report.hpp index 41216d49b..c5959c141 100644 --- a/stratosphere/creport/source/creport_crash_report.hpp +++ b/stratosphere/creport/source/creport_crash_report.hpp @@ -30,7 +30,7 @@ namespace sts::creport { private: Handle debug_handle = INVALID_HANDLE; bool has_extra_info = true; - Result result = ResultCreportIncompleteReport; + Result result = ResultIncompleteReport(); /* Attach process info. */ svc::DebugInfoAttachProcess process_info = {}; @@ -55,7 +55,7 @@ namespace sts::creport { } bool IsComplete() const { - return this->result != ResultCreportIncompleteReport; + return !ResultIncompleteReport::Includes(this->result); } bool IsOpen() const { diff --git a/stratosphere/creport/source/creport_main.cpp b/stratosphere/creport/source/creport_main.cpp index 8de1a3c0e..a53b4438a 100644 --- a/stratosphere/creport/source/creport_main.cpp +++ b/stratosphere/creport/source/creport_main.cpp @@ -52,6 +52,12 @@ namespace sts::ams { } +namespace sts::result { + + bool CallFatalOnResultAssertion = true; + +} + using namespace sts; void __libnx_exception_handler(ThreadExceptionDump *ctx) { @@ -136,5 +142,5 @@ int main(int argc, char **argv) { /* Throw fatal error. */ FatalContext ctx; g_crash_report.GetFatalContext(&ctx); - fatalWithContext(g_crash_report.GetResult(), FatalType_ErrorScreen, &ctx); + fatalWithContext(g_crash_report.GetResult().GetValue(), FatalType_ErrorScreen, &ctx); } diff --git a/stratosphere/dmnt/Makefile b/stratosphere/dmnt/Makefile index 61cc0123e..5e65198ed 100644 --- a/stratosphere/dmnt/Makefile +++ b/stratosphere/dmnt/Makefile @@ -31,7 +31,7 @@ DATA := data INCLUDES := include ../../common/include EXEFS_SRC := exefs_src -DEFINES := -DDISABLE_IPC -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\" +DEFINES := -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\" #--------------------------------------------------------------------------------- # options for code generation @@ -45,8 +45,18 @@ CFLAGS += $(INCLUDE) -D__SWITCH__ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17 +CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \ + -Wl,--wrap,__cxa_throw \ + -Wl,--wrap,__cxa_rethrow \ + -Wl,--wrap,__cxa_allocate_exception \ + -Wl,--wrap,__cxa_begin_catch \ + -Wl,--wrap,__cxa_end_catch \ + -Wl,--wrap,__cxa_call_unexpected \ + -Wl,--wrap,__cxa_call_terminate \ + -Wl,--wrap,__gxx_personality_v0 + ASFLAGS := -g $(ARCH) -LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) +LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map) LIBS := -lstratosphere -lnx diff --git a/stratosphere/dmnt/source/cheat/dmnt_cheat_service.cpp b/stratosphere/dmnt/source/cheat/dmnt_cheat_service.cpp index f7024bdc2..76f3dc56c 100644 --- a/stratosphere/dmnt/source/cheat/dmnt_cheat_service.cpp +++ b/stratosphere/dmnt/source/cheat/dmnt_cheat_service.cpp @@ -37,11 +37,8 @@ namespace sts::dmnt::cheat { } Result CheatService::ForceOpenCheatProcess() { - if (R_FAILED(dmnt::cheat::impl::ForceOpenCheatProcess())) { - return ResultDmntCheatNotAttached; - } - - return ResultSuccess; + R_UNLESS(R_SUCCEEDED(dmnt::cheat::impl::ForceOpenCheatProcess()), ResultCheatNotAttached()); + return ResultSuccess(); } /* ========================================================================================= */ @@ -53,26 +50,17 @@ namespace sts::dmnt::cheat { } Result CheatService::GetCheatProcessMappings(const sf::OutArray &mappings, sf::Out out_count, u64 offset) { - if (mappings.GetPointer() == nullptr) { - return ResultDmntCheatNullBuffer; - } - + R_UNLESS(mappings.GetPointer() != nullptr, ResultCheatNullBuffer()); return dmnt::cheat::impl::GetCheatProcessMappings(mappings.GetPointer(), mappings.GetSize(), out_count.GetPointer(), offset); } Result CheatService::ReadCheatProcessMemory(const sf::OutBuffer &buffer, u64 address, u64 out_size) { - if (buffer.GetPointer() == nullptr) { - return ResultDmntCheatNullBuffer; - } - + R_UNLESS(buffer.GetPointer() != nullptr, ResultCheatNullBuffer()); return dmnt::cheat::impl::ReadCheatProcessMemory(address, buffer.GetPointer(), std::min(out_size, buffer.GetSize())); } Result CheatService::WriteCheatProcessMemory(const sf::InBuffer &buffer, u64 address, u64 in_size) { - if (buffer.GetPointer() == nullptr) { - return ResultDmntCheatNullBuffer; - } - + R_UNLESS(buffer.GetPointer() != nullptr, ResultCheatNullBuffer()); return dmnt::cheat::impl::WriteCheatProcessMemory(address, buffer.GetPointer(), std::min(in_size, buffer.GetSize())); } @@ -89,10 +77,7 @@ namespace sts::dmnt::cheat { } Result CheatService::GetCheats(const sf::OutArray &cheats, sf::Out out_count, u64 offset) { - if (cheats.GetPointer() == nullptr) { - return ResultDmntCheatNullBuffer; - } - + R_UNLESS(cheats.GetPointer() != nullptr, ResultCheatNullBuffer()); return dmnt::cheat::impl::GetCheats(cheats.GetPointer(), cheats.GetSize(), out_count.GetPointer(), offset); } @@ -121,10 +106,7 @@ namespace sts::dmnt::cheat { } Result CheatService::GetFrozenAddresses(const sf::OutArray &addresses, sf::Out out_count, u64 offset) { - if (addresses.GetPointer() == nullptr) { - return ResultDmntCheatNullBuffer; - } - + R_UNLESS(addresses.GetPointer() != nullptr, ResultCheatNullBuffer()); return dmnt::cheat::impl::GetFrozenAddresses(addresses.GetPointer(), addresses.GetSize(), out_count.GetPointer(), offset); } @@ -133,16 +115,10 @@ namespace sts::dmnt::cheat { } Result CheatService::EnableFrozenAddress(sf::Out out_value, u64 address, u64 width) { - switch (width) { - case 1: - case 2: - case 4: - case 8: - break; - default: - return ResultDmntCheatInvalidFreezeWidth; - } - + /* Width needs to be a power of two <= 8. */ + R_UNLESS(width > 0, ResultFrozenAddressInvalidWidth()); + R_UNLESS(width <= sizeof(u64), ResultFrozenAddressInvalidWidth()); + R_UNLESS((width & (width - 1)) == 0, ResultFrozenAddressInvalidWidth()); return dmnt::cheat::impl::EnableFrozenAddress(out_value.GetPointer(), address, width); } diff --git a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp index 56700d6f0..6d8e2a66a 100644 --- a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp +++ b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp @@ -169,10 +169,8 @@ namespace sts::dmnt::cheat::impl { } Result EnsureCheatProcess() { - if (!this->HasActiveCheatProcess()) { - return ResultDmntCheatNotAttached; - } - return ResultSuccess; + R_UNLESS(this->HasActiveCheatProcess(), ResultCheatNotAttached()); + return ResultSuccess(); } Handle GetCheatProcessHandle() const { @@ -235,7 +233,7 @@ namespace sts::dmnt::cheat::impl { R_TRY(this->EnsureCheatProcess()); std::memcpy(out, &this->cheat_process_metadata, sizeof(*out)); - return ResultSuccess; + return ResultSuccess(); } Result ForceOpenCheatProcess() { @@ -263,7 +261,7 @@ namespace sts::dmnt::cheat::impl { } } - return ResultSuccess; + return ResultSuccess(); } Result GetCheatProcessMappingCount(u64 *out_count) { @@ -288,7 +286,7 @@ namespace sts::dmnt::cheat::impl { } while (address != 0); *out_count = count; - return ResultSuccess; + return ResultSuccess(); } Result GetCheatProcessMappings(MemoryInfo *mappings, size_t max_count, u64 *out_count, u64 offset) { @@ -316,7 +314,7 @@ namespace sts::dmnt::cheat::impl { } while (address != 0 && written_count < max_count); *out_count = written_count; - return ResultSuccess; + return ResultSuccess(); } Result ReadCheatProcessMemory(u64 proc_addr, void *out_data, size_t size) { @@ -357,7 +355,7 @@ namespace sts::dmnt::cheat::impl { } *out_count = count; - return ResultSuccess; + return ResultSuccess(); } Result GetCheats(CheatEntry *out_cheats, size_t max_count, u64 *out_count, u64 offset) { @@ -376,7 +374,7 @@ namespace sts::dmnt::cheat::impl { } *out_count = count; - return ResultSuccess; + return ResultSuccess(); } Result GetCheatById(CheatEntry *out_cheat, u32 cheat_id) { @@ -385,12 +383,11 @@ namespace sts::dmnt::cheat::impl { R_TRY(this->EnsureCheatProcess()); const CheatEntry *entry = this->GetCheatEntryById(cheat_id); - if (entry == nullptr || entry->definition.num_opcodes == 0) { - return ResultDmntCheatUnknownChtId; - } + R_UNLESS(entry != nullptr, ResultCheatUnknownId()); + R_UNLESS(entry->definition.num_opcodes != 0, ResultCheatUnknownId()); *out_cheat = *entry; - return ResultSuccess; + return ResultSuccess(); } Result ToggleCheat(u32 cheat_id) { @@ -399,20 +396,17 @@ namespace sts::dmnt::cheat::impl { R_TRY(this->EnsureCheatProcess()); CheatEntry *entry = this->GetCheatEntryById(cheat_id); - if (entry == nullptr || entry->definition.num_opcodes == 0) { - return ResultDmntCheatUnknownChtId; - } + R_UNLESS(entry != nullptr, ResultCheatUnknownId()); + R_UNLESS(entry->definition.num_opcodes != 0, ResultCheatUnknownId()); - if (cheat_id == 0) { - return ResultDmntCheatCannotDisableMasterCheat; - } + R_UNLESS(cheat_id != 0, ResultCheatCannotDisable()); entry->enabled = !entry->enabled; /* Trigger a VM reload. */ this->SetNeedsReloadVm(true); - return ResultSuccess; + return ResultSuccess(); } Result AddCheat(u32 *out_id, const CheatDefinition &def, bool enabled) { @@ -420,14 +414,11 @@ namespace sts::dmnt::cheat::impl { R_TRY(this->EnsureCheatProcess()); - if (def.num_opcodes == 0 || def.num_opcodes > util::size(def.opcodes)) { - return ResultDmntCheatInvalidCheat; - } + R_UNLESS(def.num_opcodes != 0, ResultCheatInvalid()); + R_UNLESS(def.num_opcodes <= util::size(def.opcodes), ResultCheatInvalid()); CheatEntry *new_entry = this->GetFreeCheatEntry(); - if (new_entry == nullptr) { - return ResultDmntCheatOutOfCheats; - } + R_UNLESS(new_entry != nullptr, ResultCheatOutOfResource()); new_entry->enabled = enabled; new_entry->definition = def; @@ -435,24 +426,21 @@ namespace sts::dmnt::cheat::impl { /* Trigger a VM reload. */ this->SetNeedsReloadVm(true); - return ResultSuccess; + return ResultSuccess(); } Result RemoveCheat(u32 cheat_id) { std::scoped_lock lk(this->cheat_lock); R_TRY(this->EnsureCheatProcess()); - - if (cheat_id >= MaxCheatCount) { - return ResultDmntCheatUnknownChtId; - } + R_UNLESS(cheat_id < MaxCheatCount, ResultCheatUnknownId()); this->ResetCheatEntry(cheat_id); /* Trigger a VM reload. */ this->SetNeedsReloadVm(true); - return ResultSuccess; + return ResultSuccess(); } Result GetFrozenAddressCount(u64 *out_count) { @@ -461,7 +449,7 @@ namespace sts::dmnt::cheat::impl { R_TRY(this->EnsureCheatProcess()); *out_count = this->frozen_addresses_map.size(); - return ResultSuccess; + return ResultSuccess(); } Result GetFrozenAddresses(FrozenAddressEntry *frz_addrs, size_t max_count, u64 *out_count, u64 offset) { @@ -484,7 +472,7 @@ namespace sts::dmnt::cheat::impl { } *out_count = written_count; - return ResultSuccess; + return ResultSuccess(); } Result GetFrozenAddress(FrozenAddressEntry *frz_addr, u64 address) { @@ -493,13 +481,11 @@ namespace sts::dmnt::cheat::impl { R_TRY(this->EnsureCheatProcess()); const auto it = this->frozen_addresses_map.find(address); - if (it == this->frozen_addresses_map.end()) { - return ResultDmntCheatAddressNotFrozen; - } + R_UNLESS(it != this->frozen_addresses_map.end(), ResultFrozenAddressNotFound()); frz_addr->address = it->first; frz_addr->value = it->second; - return ResultSuccess; + return ResultSuccess(); } Result EnableFrozenAddress(u64 *out_value, u64 address, u64 width) { @@ -507,14 +493,10 @@ namespace sts::dmnt::cheat::impl { R_TRY(this->EnsureCheatProcess()); - if (this->frozen_addresses_map.size() >= MaxFrozenAddressCount) { - return ResultDmntCheatTooManyFrozenAddresses; - } + R_UNLESS(this->frozen_addresses_map.size() < MaxFrozenAddressCount, ResultFrozenAddressOutOfResource()); const auto it = this->frozen_addresses_map.find(address); - if (it != this->frozen_addresses_map.end()) { - return ResultDmntCheatAddressAlreadyFrozen; - } + R_UNLESS(it == this->frozen_addresses_map.end(), ResultFrozenAddressAlreadyExists()); FrozenAddressValue value = {}; value.width = width; @@ -522,7 +504,7 @@ namespace sts::dmnt::cheat::impl { this->frozen_addresses_map[address] = value; *out_value = value.value; - return ResultSuccess; + return ResultSuccess(); } Result DisableFrozenAddress(u64 address) { @@ -531,12 +513,10 @@ namespace sts::dmnt::cheat::impl { R_TRY(this->EnsureCheatProcess()); const auto it = this->frozen_addresses_map.find(address); - if (it == this->frozen_addresses_map.end()) { - return ResultDmntCheatAddressNotFrozen; - } + R_UNLESS(it != this->frozen_addresses_map.end(), ResultFrozenAddressNotFound()); this->frozen_addresses_map.erase(it); - return ResultSuccess; + return ResultSuccess(); } }; @@ -626,9 +606,7 @@ namespace sts::dmnt::cheat::impl { { if (this->HasActiveCheatProcess()) { /* When forcing attach, we're done. */ - if (!on_process_launch) { - return ResultSuccess; - } + R_UNLESS(on_process_launch, ResultSuccess()); } /* Detach from the current process, if it's open. */ @@ -667,9 +645,7 @@ namespace sts::dmnt::cheat::impl { /* If new process launch, we may not want to actually attach. */ if (on_process_launch) { - if (!cfg::IsCheatEnableKeyHeld(this->cheat_process_metadata.title_id)) { - return ResultDmntCheatNotAttached; - } + R_UNLESS(cfg::IsCheatEnableKeyHeld(this->cheat_process_metadata.title_id), ResultCheatNotAttached()); } /* Get module information from loader. */ @@ -689,7 +665,7 @@ namespace sts::dmnt::cheat::impl { } else if (num_modules == 1 && !on_process_launch) { proc_module = &proc_modules[0]; } else { - return ResultDmntCheatNotAttached; + return ResultCheatNotAttached(); } this->cheat_process_metadata.main_nso_extents.base = proc_module->base_address; @@ -701,9 +677,7 @@ namespace sts::dmnt::cheat::impl { if (!this->LoadCheats(this->cheat_process_metadata.title_id, this->cheat_process_metadata.main_nso_build_id) || !this->LoadCheatToggles(this->cheat_process_metadata.title_id)) { /* If new process launch, require success. */ - if (on_process_launch) { - return ResultDmntCheatNotAttached; - } + R_UNLESS(!on_process_launch, ResultCheatNotAttached()); } /* Open a debug handle. */ @@ -723,7 +697,7 @@ namespace sts::dmnt::cheat::impl { /* Signal to our fans. */ this->cheat_process_event.Signal(); - return ResultSuccess; + return ResultSuccess(); } #undef R_ASSERT_IF_NEW_PROCESS diff --git a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp index 9d889892b..a6e818758 100644 --- a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp +++ b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp @@ -631,7 +631,7 @@ namespace sts::dmnt::cheat::impl { /* However, I don't actually believe it is possible for this to happen. */ /* I guess we'll throw a fatal error here, so as to encourage me to fix the VM */ /* in the event that someone triggers it? I don't know how you'd do that. */ - fatalSimple(ResultDmntCheatVmInvalidCondDepth); + R_ASSERT(ResultVirtualMachineInvalidConditionDepth()); } } diff --git a/stratosphere/dmnt/source/dmnt_main.cpp b/stratosphere/dmnt/source/dmnt_main.cpp index 1eec25cf0..63350b25f 100644 --- a/stratosphere/dmnt/source/dmnt_main.cpp +++ b/stratosphere/dmnt/source/dmnt_main.cpp @@ -49,6 +49,12 @@ namespace sts::ams { } +namespace sts::result { + + bool CallFatalOnResultAssertion = true; + +} + using namespace sts; void __libnx_initheap(void) { diff --git a/stratosphere/dmnt/source/dmnt_service_debug.cpp b/stratosphere/dmnt/source/dmnt_service_debug.cpp index ad049af2c..09fc53d30 100644 --- a/stratosphere/dmnt/source/dmnt_service_debug.cpp +++ b/stratosphere/dmnt/source/dmnt_service_debug.cpp @@ -41,12 +41,10 @@ namespace sts::dmnt { Result DebugMonitorService::GetProcessHandle(sf::Out out_hnd, os::ProcessId pid) { R_TRY_CATCH(svcDebugActiveProcess(out_hnd.GetPointer(), static_cast(pid))) { - R_CATCH(ResultKernelAlreadyExists) { - return ResultDebugAlreadyAttached; - } + R_CONVERT(svc::ResultBusy, dbg::ResultAlreadyAttached()); } R_END_TRY_CATCH; - return ResultSuccess; + return ResultSuccess(); } Result DebugMonitorService::WaitSynchronization(Handle hnd, u64 ns) { diff --git a/stratosphere/dmnt/source/dmnt_service_target_io.cpp b/stratosphere/dmnt/source/dmnt_service_target_io.cpp index 4cac9cf10..6893cbb07 100644 --- a/stratosphere/dmnt/source/dmnt_service_target_io.cpp +++ b/stratosphere/dmnt/source/dmnt_service_target_io.cpp @@ -51,13 +51,11 @@ namespace sts::dmnt { Result EnsureSdInitialized() { std::scoped_lock lk(g_sd_lock); - if (g_sd_initialized) { - return ResultSuccess; - } + R_UNLESS(!g_sd_initialized, ResultSuccess()); R_TRY(fsOpenSdCardFileSystem(&g_sd_fs)); g_sd_initialized = true; - return ResultSuccess; + return ResultSuccess(); } TargetIOFileHandle GetNewFileHandle(FsFile f) { @@ -73,10 +71,10 @@ namespace sts::dmnt { if (g_file_handles.find(handle) != g_file_handles.end()) { *out = g_file_handles[handle]; - return ResultSuccess; + return ResultSuccess(); } - return ResultFsInvalidArgument; + return fs::ResultInvalidArgument(); } Result CloseFileByHandle(TargetIOFileHandle handle) { @@ -85,10 +83,10 @@ namespace sts::dmnt { if (g_file_handles.find(handle) != g_file_handles.end()) { fsFileClose(&g_file_handles[handle]); g_file_handles.erase(handle); - return ResultSuccess; + return ResultSuccess(); } - return ResultFsInvalidArgument; + return fs::ResultInvalidArgument(); } void FixPath(char *dst, size_t dst_size, const sf::InBuffer &path) { @@ -139,9 +137,7 @@ namespace sts::dmnt { /* Open the file, guard to prevent failure to close. */ FsFile f; R_TRY(fsFsOpenFile(&g_sd_fs, fs_path, open_mode, &f)); - auto file_guard = SCOPE_GUARD { - fsFileClose(&f); - }; + auto file_guard = SCOPE_GUARD { fsFileClose(&f); }; /* Set size if needed. */ if (create_mode == TIOCreateOption_ResetSize) { @@ -152,7 +148,7 @@ namespace sts::dmnt { file_guard.Cancel(); out_hnd.SetValue(GetNewFileHandle(f)); - return ResultSuccess; + return ResultSuccess(); } Result DebugMonitorService::TargetIO_FileClose(TargetIOFileHandle hnd) { @@ -167,7 +163,7 @@ namespace sts::dmnt { R_TRY(fsFileRead(&f, offset, out_data.GetPointer(), out_data.GetSize(), FsReadOption_None, &read)); out_read.SetValue(static_cast(read)); - return ResultSuccess; + return ResultSuccess(); } Result DebugMonitorService::TargetIO_FileWrite(TargetIOFileHandle hnd, const sf::InNonSecureBuffer &data, sf::Out out_written, u64 offset) { @@ -177,13 +173,13 @@ namespace sts::dmnt { R_TRY(fsFileWrite(&f, offset, data.GetPointer(), data.GetSize(), FsWriteOption_None)); out_written.SetValue(data.GetSize()); - return ResultSuccess; + return ResultSuccess(); } Result DebugMonitorService::TargetIO_FileSetAttributes(const sf::InBuffer &path, const sf::InBuffer &attributes) { /* I don't really know why this command exists, Horizon doesn't allow you to set any attributes. */ /* N just returns ResultSuccess unconditionally here. */ - return ResultSuccess; + return ResultSuccess(); } Result DebugMonitorService::TargetIO_FileGetInformation(const sf::InBuffer &path, const sf::OutArray &out_info, sf::Out is_directory) { @@ -214,12 +210,12 @@ namespace sts::dmnt { is_directory.SetValue(1); } - return ResultSuccess; + return ResultSuccess(); } Result DebugMonitorService::TargetIO_FileSetTime(const sf::InBuffer &path, u64 create, u64 access, u64 modify) { /* This is another function that doesn't really need to exist, because Horizon doesn't let you set anything. */ - return ResultSuccess; + return ResultSuccess(); } Result DebugMonitorService::TargetIO_FileSetSize(const sf::InBuffer &input, u64 size) { @@ -229,9 +225,7 @@ namespace sts::dmnt { /* We will try to be better than N, here. N only treats input as a path. */ FsFile f; if (input.GetSize() == sizeof(TargetIOFileHandle)) { - if (R_SUCCEEDED(GetFileByHandle(&f, *reinterpret_cast(input.GetPointer())))) { - return fsFileSetSize(&f, size); - } + R_UNLESS(R_FAILED(GetFileByHandle(&f, *reinterpret_cast(input.GetPointer()))), fsFileSetSize(&f, size)); } char fs_path[FS_MAX_PATH]; diff --git a/stratosphere/eclct.stub/Makefile b/stratosphere/eclct.stub/Makefile index 2d3bf2862..52911803e 100644 --- a/stratosphere/eclct.stub/Makefile +++ b/stratosphere/eclct.stub/Makefile @@ -31,7 +31,7 @@ DATA := data INCLUDES := include ../../common/include EXEFS_SRC := exefs_src -DEFINES := -DDISABLE_IPC -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\" -DINI_MAX_LINE=768 +DEFINES := -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\" -DINI_MAX_LINE=768 #--------------------------------------------------------------------------------- # options for code generation @@ -45,8 +45,18 @@ CFLAGS += $(INCLUDE) -D__SWITCH__ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17 +CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \ + -Wl,--wrap,__cxa_throw \ + -Wl,--wrap,__cxa_rethrow \ + -Wl,--wrap,__cxa_allocate_exception \ + -Wl,--wrap,__cxa_begin_catch \ + -Wl,--wrap,__cxa_end_catch \ + -Wl,--wrap,__cxa_call_unexpected \ + -Wl,--wrap,__cxa_call_terminate \ + -Wl,--wrap,__gxx_personality_v0 + ASFLAGS := -g $(ARCH) -LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) +LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map) LIBS := -lstratosphere -lnx diff --git a/stratosphere/eclct.stub/source/eclct_stub.cpp b/stratosphere/eclct.stub/source/eclct_stub.cpp index 53cc76625..2a96ffa27 100644 --- a/stratosphere/eclct.stub/source/eclct_stub.cpp +++ b/stratosphere/eclct.stub/source/eclct_stub.cpp @@ -48,6 +48,12 @@ namespace sts::ams { } +namespace sts::result { + + bool CallFatalOnResultAssertion = false; + +} + using namespace sts; void __libnx_exception_handler(ThreadExceptionDump *ctx) { diff --git a/stratosphere/fatal/Makefile b/stratosphere/fatal/Makefile index ad916c1c4..8d7dca879 100644 --- a/stratosphere/fatal/Makefile +++ b/stratosphere/fatal/Makefile @@ -31,7 +31,7 @@ DATA := data INCLUDES := include ../../common/include EXEFS_SRC := exefs_src -DEFINES := -DRESULT_ABORT_ON_ASSERT -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\" +DEFINES := -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\" #--------------------------------------------------------------------------------- # options for code generation @@ -45,8 +45,18 @@ CFLAGS += $(INCLUDE) -D__SWITCH__ `freetype-config --cflags` CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17 +CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \ + -Wl,--wrap,__cxa_throw \ + -Wl,--wrap,__cxa_rethrow \ + -Wl,--wrap,__cxa_allocate_exception \ + -Wl,--wrap,__cxa_begin_catch \ + -Wl,--wrap,__cxa_end_catch \ + -Wl,--wrap,__cxa_call_unexpected \ + -Wl,--wrap,__cxa_call_terminate \ + -Wl,--wrap,__gxx_personality_v0 + ASFLAGS := -g $(ARCH) -LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) +LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map) LIBS := `freetype-config --libs` -lstratosphere -lnx diff --git a/stratosphere/fatal/source/fatal_debug.cpp b/stratosphere/fatal/source/fatal_debug.cpp index 25b74135a..812ad7523 100644 --- a/stratosphere/fatal/source/fatal_debug.cpp +++ b/stratosphere/fatal/source/fatal_debug.cpp @@ -28,7 +28,7 @@ namespace sts::fatal::srv { u64 lr; }; - bool IsThreadFatalCaller(u32 error_code, u32 debug_handle, u64 thread_id, u64 thread_tls_addr, ThreadContext *thread_ctx) { + bool IsThreadFatalCaller(Result result, u32 debug_handle, u64 thread_id, u64 thread_tls_addr, ThreadContext *thread_ctx) { /* Verify that the thread is running or waiting. */ { u64 _; @@ -71,7 +71,7 @@ namespace sts::fatal::srv { const struct { CmifInHeader header; - u32 error_code; + Result result; } *in_data = decltype(in_data)(request.data.data_words); static_assert(sizeof(*in_data) == 0x14, "InData!"); @@ -112,7 +112,7 @@ namespace sts::fatal::srv { return false; } - if (in_data->error_code != error_code) { + if (in_data->result.GetValue() != result.GetValue()) { return false; } } @@ -226,7 +226,7 @@ namespace sts::fatal::srv { continue; } - if (IsThreadFatalCaller(ctx->error_code, debug_handle.Get(), cur_thread_id, thread_id_to_tls[cur_thread_id], &thread_ctx)) { + if (IsThreadFatalCaller(ctx->result, debug_handle.Get(), cur_thread_id, thread_id_to_tls[cur_thread_id], &thread_ctx)) { thread_id = cur_thread_id; found_fatal_caller = true; break; diff --git a/stratosphere/fatal/source/fatal_event_manager.cpp b/stratosphere/fatal/source/fatal_event_manager.cpp index fc6d300e4..d581dda44 100644 --- a/stratosphere/fatal/source/fatal_event_manager.cpp +++ b/stratosphere/fatal/source/fatal_event_manager.cpp @@ -29,12 +29,10 @@ namespace sts::fatal::srv { std::scoped_lock lk{this->lock}; /* Only allow GetEvent to succeed NumFatalEvents times. */ - if (this->num_events_gotten >= FatalEventManager::NumFatalEvents) { - return ResultFatalTooManyEvents; - } + R_UNLESS(this->num_events_gotten < FatalEventManager::NumFatalEvents, ResultTooManyEvents()); *out = this->events[this->num_events_gotten++].revent; - return ResultSuccess; + return ResultSuccess(); } void FatalEventManager::SignalEvents() { diff --git a/stratosphere/fatal/source/fatal_main.cpp b/stratosphere/fatal/source/fatal_main.cpp index 1fbb77572..566e9f267 100644 --- a/stratosphere/fatal/source/fatal_main.cpp +++ b/stratosphere/fatal/source/fatal_main.cpp @@ -57,6 +57,12 @@ namespace sts::ams { } +namespace sts::result { + + bool CallFatalOnResultAssertion = false; + +} + using namespace sts; void __libnx_exception_handler(ThreadExceptionDump *ctx) { diff --git a/stratosphere/fatal/source/fatal_repair.cpp b/stratosphere/fatal/source/fatal_repair.cpp index 39d587a7e..496799db4 100644 --- a/stratosphere/fatal/source/fatal_repair.cpp +++ b/stratosphere/fatal/source/fatal_repair.cpp @@ -106,11 +106,11 @@ namespace sts::fatal::srv { void CheckRepairStatus() { if (IsInRepairWithoutVolHeld()) { - ThrowFatalForSelf(ResultFatalInRepairWithoutVolHeld); + ThrowFatalForSelf(ResultInRepairWithoutVolHeld()); } if (IsInRepairWithoutTimeReviserCartridge()) { - ThrowFatalForSelf(ResultFatalInRepairWithoutTimeReviserCartridge); + ThrowFatalForSelf(ResultInRepairWithoutTimeReviserCartridge()); } } diff --git a/stratosphere/fatal/source/fatal_service.cpp b/stratosphere/fatal/source/fatal_service.cpp index af80725e6..e17a6d0d4 100644 --- a/stratosphere/fatal/source/fatal_service.cpp +++ b/stratosphere/fatal/source/fatal_service.cpp @@ -33,11 +33,9 @@ namespace sts::fatal::srv { bool has_thrown; private: Result TrySetHasThrown() { - if (this->has_thrown) { - return ResultFatalAlreadyThrown; - } + R_UNLESS(!this->has_thrown, ResultAlreadyThrown()); this->has_thrown = true; - return ResultSuccess; + return ResultSuccess(); } public: ServiceContext() { @@ -51,32 +49,30 @@ namespace sts::fatal::srv { return this->event_manager.GetEvent(out); } - Result ThrowFatal(u32 error_code, os::ProcessId process_id) { - return this->ThrowFatalWithCpuContext(error_code, process_id, FatalType_ErrorReportAndErrorScreen, {}); + Result ThrowFatal(Result result, os::ProcessId process_id) { + return this->ThrowFatalWithCpuContext(result, process_id, FatalType_ErrorReportAndErrorScreen, {}); } - Result ThrowFatalWithPolicy(u32 error_code, os::ProcessId process_id, FatalType policy) { - return this->ThrowFatalWithCpuContext(error_code, process_id, policy, {}); + Result ThrowFatalWithPolicy(Result result, os::ProcessId process_id, FatalType policy) { + return this->ThrowFatalWithCpuContext(result, process_id, policy, {}); } - Result ThrowFatalWithCpuContext(u32 error_code, os::ProcessId process_id, FatalType policy, const CpuContext &cpu_ctx); + Result ThrowFatalWithCpuContext(Result result, os::ProcessId process_id, FatalType policy, const CpuContext &cpu_ctx); }; /* Context global. */ ServiceContext g_context; /* Throw implementation. */ - Result ServiceContext::ThrowFatalWithCpuContext(u32 error_code, os::ProcessId process_id, FatalType policy, const CpuContext &cpu_ctx) { + Result ServiceContext::ThrowFatalWithCpuContext(Result result, os::ProcessId process_id, FatalType policy, const CpuContext &cpu_ctx) { /* We don't support Error Report only fatals. */ - if (policy == FatalType_ErrorReport) { - return ResultSuccess; - } + R_UNLESS(policy != FatalType_ErrorReport, ResultSuccess()); /* Note that we've thrown fatal. */ R_TRY(this->TrySetHasThrown()); /* At this point we have exclusive access to this->context. */ - this->context.error_code = error_code; + this->context.result = result; this->context.cpu_ctx = cpu_ctx; /* Cap the stack trace to a sane limit. */ @@ -108,8 +104,8 @@ namespace sts::fatal::srv { this->context.generate_error_report = (policy == FatalType_ErrorReportAndErrorScreen); /* Adjust error code (2000-0000 -> 2162-0002). */ - if (this->context.error_code == ResultSuccess) { - this->context.error_code = ResultErrSystemModuleAborted; + if (R_SUCCEEDED(this->context.result)) { + this->context.result = err::ResultSystemModuleAborted(); } switch (policy) { @@ -126,25 +122,25 @@ namespace sts::fatal::srv { STS_UNREACHABLE_DEFAULT_CASE(); } - return ResultSuccess; + return ResultSuccess(); } } - Result ThrowFatalForSelf(Result error_code) { - return g_context.ThrowFatalWithPolicy(static_cast(error_code), os::GetCurrentProcessId(), FatalType_ErrorScreen); + Result ThrowFatalForSelf(Result result) { + return g_context.ThrowFatalWithPolicy(result, os::GetCurrentProcessId(), FatalType_ErrorScreen); } - Result UserService::ThrowFatal(u32 error, const sf::ClientProcessId &client_pid) { - return g_context.ThrowFatal(error, client_pid.GetValue()); + Result UserService::ThrowFatal(Result result, const sf::ClientProcessId &client_pid) { + return g_context.ThrowFatal(result, client_pid.GetValue()); } - Result UserService::ThrowFatalWithPolicy(u32 error, const sf::ClientProcessId &client_pid, FatalType policy) { - return g_context.ThrowFatalWithPolicy(error, client_pid.GetValue(), policy); + Result UserService::ThrowFatalWithPolicy(Result result, const sf::ClientProcessId &client_pid, FatalType policy) { + return g_context.ThrowFatalWithPolicy(result, client_pid.GetValue(), policy); } - Result UserService::ThrowFatalWithCpuContext(u32 error, const sf::ClientProcessId &client_pid, FatalType policy, const CpuContext &cpu_ctx) { - return g_context.ThrowFatalWithCpuContext(error, client_pid.GetValue(), policy, cpu_ctx); + Result UserService::ThrowFatalWithCpuContext(Result result, const sf::ClientProcessId &client_pid, FatalType policy, const CpuContext &cpu_ctx) { + return g_context.ThrowFatalWithCpuContext(result, client_pid.GetValue(), policy, cpu_ctx); } Result PrivateService::GetFatalEvent(sf::OutCopyHandle out_h) { diff --git a/stratosphere/fatal/source/fatal_service.hpp b/stratosphere/fatal/source/fatal_service.hpp index a57149993..2b3bcde41 100644 --- a/stratosphere/fatal/source/fatal_service.hpp +++ b/stratosphere/fatal/source/fatal_service.hpp @@ -29,9 +29,9 @@ namespace sts::fatal::srv { }; private: /* Actual commands. */ - Result ThrowFatal(u32 error, const sf::ClientProcessId &client_pid); - Result ThrowFatalWithPolicy(u32 error, const sf::ClientProcessId &client_pid, FatalType policy); - Result ThrowFatalWithCpuContext(u32 error, const sf::ClientProcessId &client_pid, FatalType policy, const CpuContext &cpu_ctx); + Result ThrowFatal(Result error, const sf::ClientProcessId &client_pid); + Result ThrowFatalWithPolicy(Result error, const sf::ClientProcessId &client_pid, FatalType policy); + Result ThrowFatalWithCpuContext(Result error, const sf::ClientProcessId &client_pid, FatalType policy, const CpuContext &cpu_ctx); public: DEFINE_SERVICE_DISPATCH_TABLE { MAKE_SERVICE_COMMAND_META(ThrowFatal), diff --git a/stratosphere/fatal/source/fatal_task_clock.cpp b/stratosphere/fatal/source/fatal_task_clock.cpp index ce56dda35..5e34dcae4 100644 --- a/stratosphere/fatal/source/fatal_task_clock.cpp +++ b/stratosphere/fatal/source/fatal_task_clock.cpp @@ -53,7 +53,7 @@ namespace sts::fatal::srv { R_TRY(pcvSetClockRate(module, hz)); } - return ResultSuccess; + return ResultSuccess(); } Result AdjustClockTask::AdjustClock() { @@ -66,7 +66,7 @@ namespace sts::fatal::srv { R_TRY(AdjustClockForModule(PcvModule_GPU, GPU_CLOCK_307MHZ)); R_TRY(AdjustClockForModule(PcvModule_EMC, EMC_CLOCK_1331MHZ)); - return ResultSuccess; + return ResultSuccess(); } Result AdjustClockTask::Run() { diff --git a/stratosphere/fatal/source/fatal_task_error_report.cpp b/stratosphere/fatal/source/fatal_task_error_report.cpp index 3a0d9b27d..1397114a2 100644 --- a/stratosphere/fatal/source/fatal_task_error_report.cpp +++ b/stratosphere/fatal/source/fatal_task_error_report.cpp @@ -86,7 +86,7 @@ namespace sts::fatal::srv { ON_SCOPE_EXIT { fclose(f_report); }; fprintf(f_report, "Atmosphère Fatal Report (v1.0):\n"); - fprintf(f_report, "Result: 0x%X (2%03d-%04d)\n\n", this->context->error_code, R_MODULE(this->context->error_code), R_DESCRIPTION(this->context->error_code)); + fprintf(f_report, "Result: 0x%X (2%03d-%04d)\n\n", this->context->result.GetValue(), this->context->result.GetModule(), this->context->result.GetDescription()); fprintf(f_report, "Title ID: %016lx\n", static_cast(this->context->title_id)); if (strlen(this->context->proc_name)) { fprintf(f_report, "Process Name: %s\n", this->context->proc_name); @@ -144,7 +144,7 @@ namespace sts::fatal::srv { /* Signal we're done with our job. */ eventFire(const_cast(&this->context->erpt_event)); - return ResultSuccess; + return ResultSuccess(); } } diff --git a/stratosphere/fatal/source/fatal_task_power.cpp b/stratosphere/fatal/source/fatal_task_power.cpp index 93d74bc05..19ad485b4 100644 --- a/stratosphere/fatal/source/fatal_task_power.cpp +++ b/stratosphere/fatal/source/fatal_task_power.cpp @@ -178,18 +178,18 @@ namespace sts::fatal::srv { Result PowerControlTask::Run() { this->MonitorBatteryState(); - return ResultSuccess; + return ResultSuccess(); } Result PowerButtonObserveTask::Run() { this->WaitForPowerButton(); - return ResultSuccess; + return ResultSuccess(); } Result StateTransitionStopTask::Run() { /* Nintendo ignores the output of this call... */ spsmPutErrorState(); - return ResultSuccess; + return ResultSuccess(); } } diff --git a/stratosphere/fatal/source/fatal_task_screen.cpp b/stratosphere/fatal/source/fatal_task_screen.cpp index ac72778f5..81e864092 100644 --- a/stratosphere/fatal/source/fatal_task_screen.cpp +++ b/stratosphere/fatal/source/fatal_task_screen.cpp @@ -90,9 +90,7 @@ namespace sts::fatal::srv { ViDisplay temp_display; /* Try to open the display. */ R_TRY_CATCH(viOpenDisplay("Internal", &temp_display)) { - R_CATCH(ResultViNotFound) { - return ResultSuccess; - } + R_CONVERT(vi::ResultNotFound, ResultSuccess()); } R_END_TRY_CATCH; /* Guarantee we close the display. */ @@ -109,16 +107,14 @@ namespace sts::fatal::srv { /* Set alpha to 1.0f. */ R_TRY(viSetDisplayAlpha(&temp_display, 1.0f)); - return ResultSuccess; + return ResultSuccess(); } Result ShowFatalTask::SetupDisplayExternal() { ViDisplay temp_display; /* Try to open the display. */ R_TRY_CATCH(viOpenDisplay("External", &temp_display)) { - R_CATCH(ResultViNotFound) { - return ResultSuccess; - } + R_CONVERT(vi::ResultNotFound, ResultSuccess()); } R_END_TRY_CATCH; /* Guarantee we close the display. */ @@ -127,7 +123,7 @@ namespace sts::fatal::srv { /* Set alpha to 1.0f. */ R_TRY(viSetDisplayAlpha(&temp_display, 1.0f)); - return ResultSuccess; + return ResultSuccess(); } Result ShowFatalTask::PrepareScreenForDrawing() { @@ -182,7 +178,7 @@ namespace sts::fatal::srv { R_TRY(framebufferCreate(&this->fb, &this->win, raw_width, raw_height, PIXEL_FORMAT_RGB_565, 1)); } - return ResultSuccess; + return ResultSuccess(); } Result ShowFatalTask::ShowFatal() { @@ -195,9 +191,7 @@ namespace sts::fatal::srv { /* Dequeue a buffer. */ u16 *tiled_buf = reinterpret_cast(framebufferBegin(&this->fb, NULL)); - if (tiled_buf == nullptr) { - return ResultFatalNullGraphicsBuffer; - } + R_UNLESS(tiled_buf != nullptr, ResultNullGraphicsBuffer()); /* Let the font manager know about our framebuffer. */ font::ConfigureFontFramebuffer(tiled_buf, GetPixelOffset); @@ -218,13 +212,13 @@ namespace sts::fatal::srv { /* TODO: Actually draw meaningful shit here. */ font::SetPosition(32, 64); font::SetFontSize(16.0f); - font::PrintFormat(config.GetErrorMessage(), R_MODULE(this->context->error_code), R_DESCRIPTION(this->context->error_code), this->context->error_code); + font::PrintFormat(config.GetErrorMessage(), this->context->result.GetModule(), this->context->result.GetDescription(), this->context->result.GetValue()); font::AddSpacingLines(0.5f); font::PrintFormatLine("Title: %016lX", static_cast(this->context->title_id)); font::AddSpacingLines(0.5f); font::PrintFormatLine(u8"Firmware: %s (Atmosphère %u.%u.%u-%s)", config.GetFirmwareVersion().display_version, ATMOSPHERE_RELEASE_VERSION, ams::GetGitRevision()); font::AddSpacingLines(1.5f); - if (this->context->error_code != ResultAtmosphereVersionMismatch) { + if (!ams::ResultVersionMismatch::Includes(this->context->result)) { font::Print(config.GetErrorDescription()); } else { /* Print a special message for atmosphere version mismatch. */ @@ -415,7 +409,7 @@ namespace sts::fatal::srv { /* Enqueue the buffer. */ framebufferEnd(&fb); - return ResultSuccess; + return ResultSuccess(); } Result ShowFatalTask::Run() { @@ -431,7 +425,7 @@ namespace sts::fatal::srv { Result BacklightControlTask::Run() { TurnOnBacklight(); - return ResultSuccess; + return ResultSuccess(); } } diff --git a/stratosphere/fatal/source/fatal_task_sound.cpp b/stratosphere/fatal/source/fatal_task_sound.cpp index 45bae8b4b..9b0463eac 100644 --- a/stratosphere/fatal/source/fatal_task_sound.cpp +++ b/stratosphere/fatal/source/fatal_task_sound.cpp @@ -86,7 +86,7 @@ namespace sts::fatal::srv { Result StopSoundTask::Run() { StopSound(); - return ResultSuccess; + return ResultSuccess(); } } diff --git a/stratosphere/libstratosphere/Makefile b/stratosphere/libstratosphere/Makefile index 57b967733..81873295e 100644 --- a/stratosphere/libstratosphere/Makefile +++ b/stratosphere/libstratosphere/Makefile @@ -16,7 +16,7 @@ include $(DEVKITPRO)/libnx/switch_rules # INCLUDES is a list of directories containing header files #--------------------------------------------------------------------------------- TARGET := $(notdir $(CURDIR)) -SOURCES := source source/ams source/os source/os/impl source/dd source/sf source/sf/cmif source/sf/hipc source/dmnt source/spl source/spl/smc source/updater source/patcher source/map source/rnd source/util source/sm source/cfg source/pm source/hid source/ldr source/kvdb source/boot2 +SOURCES := source source/ams source/result source/os source/os/impl source/dd source/sf source/sf/cmif source/sf/hipc source/dmnt source/spl source/spl/smc source/updater source/patcher source/map source/rnd source/util source/sm source/cfg source/pm source/hid source/ldr source/kvdb source/boot2 DATA := data INCLUDES := include diff --git a/stratosphere/libstratosphere/include/stratosphere/ams/ams_exosphere_api.hpp b/stratosphere/libstratosphere/include/stratosphere/ams/ams_exosphere_api.hpp index 7dbcbedf4..1c1dc7eba 100644 --- a/stratosphere/libstratosphere/include/stratosphere/ams/ams_exosphere_api.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/ams/ams_exosphere_api.hpp @@ -40,7 +40,7 @@ namespace sts::ams { const u32 build_version = GetVersion(ATMOSPHERE_RELEASE_VERSION); if (runtime_version < build_version) { - R_ASSERT(ResultAtmosphereVersionMismatch); + R_ASSERT(ams::ResultVersionMismatch()); } } diff --git a/stratosphere/libstratosphere/include/stratosphere/defines.hpp b/stratosphere/libstratosphere/include/stratosphere/defines.hpp index 2f381820b..79c7d7ec9 100644 --- a/stratosphere/libstratosphere/include/stratosphere/defines.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/defines.hpp @@ -33,6 +33,7 @@ cls& operator=(cls&&) = delete #define ALIGNED(algn) __attribute__((aligned(algn))) +#define NORETURN __attribute__((noreturn)) #define WEAK __attribute__((weak)) diff --git a/stratosphere/libstratosphere/include/stratosphere/fatal/fatal_types.hpp b/stratosphere/libstratosphere/include/stratosphere/fatal/fatal_types.hpp index 2a6b19a56..c464a7b48 100644 --- a/stratosphere/libstratosphere/include/stratosphere/fatal/fatal_types.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/fatal/fatal_types.hpp @@ -320,7 +320,7 @@ namespace sts::fatal { namespace srv { struct ThrowContext { - u32 error_code; + Result result; ncm::TitleId title_id; char proc_name[0xD]; bool is_creport; @@ -332,7 +332,16 @@ namespace sts::fatal { u8 stack_dump[0x100]; void ClearState() { - std::memset(this, 0, sizeof(*this)); + this->result = ResultSuccess(); + this->title_id = ncm::TitleId::Invalid; + std::memset(this->proc_name, 0, sizeof(this->proc_name)); + this->is_creport = false; + std::memset(&this->cpu_ctx, 0, sizeof(this->cpu_ctx)); + this->generate_error_report = false; + std::memset(&this->erpt_event, 0, sizeof(this->erpt_event)); + std::memset(&this->battery_event, 0, sizeof(this->battery_event)); + this->stack_dump_size = 0; + std::memset(this->stack_dump, 0, sizeof(this->stack_dump)); } }; diff --git a/stratosphere/libstratosphere/include/stratosphere/kvdb/kvdb_auto_buffer.hpp b/stratosphere/libstratosphere/include/stratosphere/kvdb/kvdb_auto_buffer.hpp index f731f8f76..dd5df0986 100644 --- a/stratosphere/libstratosphere/include/stratosphere/kvdb/kvdb_auto_buffer.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/kvdb/kvdb_auto_buffer.hpp @@ -73,10 +73,10 @@ namespace sts::kvdb { /* Allocate a buffer. */ this->buffer = static_cast(std::malloc(size)); if (this->buffer == nullptr) { - return ResultKvdbAllocationFailed; + return ResultAllocationFailed(); } this->size = size; - return ResultSuccess; + return ResultSuccess(); } Result Initialize(const void *buf, size_t size) { @@ -86,7 +86,7 @@ namespace sts::kvdb { /* Copy the input data in. */ std::memcpy(this->buffer, buf, size); - return ResultSuccess; + return ResultSuccess(); } }; } \ No newline at end of file diff --git a/stratosphere/libstratosphere/include/stratosphere/kvdb/kvdb_file_key_value_cache.hpp b/stratosphere/libstratosphere/include/stratosphere/kvdb/kvdb_file_key_value_cache.hpp index 920bddb8b..dc5a3f56e 100644 --- a/stratosphere/libstratosphere/include/stratosphere/kvdb/kvdb_file_key_value_cache.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/kvdb/kvdb_file_key_value_cache.hpp @@ -56,7 +56,7 @@ namespace sts::kvdb { return fsdevGetLastResult(); } - return ResultSuccess; + return ResultSuccess(); } private: void RemoveIndex(size_t i) { @@ -105,7 +105,7 @@ namespace sts::kvdb { } } - return ResultSuccess; + return ResultSuccess(); } Result Save() { @@ -129,7 +129,7 @@ namespace sts::kvdb { /* Flush. */ fflush(fp); - return ResultSuccess; + return ResultSuccess(); } size_t GetCount() const { @@ -235,7 +235,7 @@ namespace sts::kvdb { R_CATCH(ResultFsPathNotFound) { /* If the path doesn't exist, nothing has gone wrong. */ *out = false; - return ResultSuccess; + return ResultSuccess(); } } R_END_TRY_CATCH; } @@ -246,7 +246,7 @@ namespace sts::kvdb { } *out = true; - return ResultSuccess; + return ResultSuccess(); } static Result DirectoryExists(bool *out, const char *path) { @@ -264,7 +264,7 @@ namespace sts::kvdb { return fsdevGetLastResult(); } - return ResultSuccess; + return ResultSuccess(); } static Result ValidateExistingCache(const char *dir) { @@ -283,7 +283,7 @@ namespace sts::kvdb { return ResultKvdbInvalidFilesystemState; } - return ResultSuccess; + return ResultSuccess(); } private: void RemoveOldestKey() { @@ -305,7 +305,7 @@ namespace sts::kvdb { /* layout it can't really be fixed without breaking existing devices... */ R_TRY(this->kvs.Initialize(dir)); - return ResultSuccess; + return ResultSuccess(); } size_t GetCount() const { @@ -380,7 +380,7 @@ namespace sts::kvdb { /* Save the list. */ R_TRY(this->lru_list.Save()); - return ResultSuccess; + return ResultSuccess(); } template @@ -394,7 +394,7 @@ namespace sts::kvdb { R_TRY(this->kvs.Remove(key)); R_TRY(this->lru_list.Save()); - return ResultSuccess; + return ResultSuccess(); } Result RemoveAll() { @@ -404,7 +404,7 @@ namespace sts::kvdb { } R_TRY(this->lru_list.Save()); - return ResultSuccess; + return ResultSuccess(); } }; diff --git a/stratosphere/libstratosphere/include/stratosphere/kvdb/kvdb_file_key_value_store.hpp b/stratosphere/libstratosphere/include/stratosphere/kvdb/kvdb_file_key_value_store.hpp index 745bcdb41..a58f89d4c 100644 --- a/stratosphere/libstratosphere/include/stratosphere/kvdb/kvdb_file_key_value_store.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/kvdb/kvdb_file_key_value_store.hpp @@ -97,7 +97,7 @@ namespace sts::kvdb { size_t size = 0; R_TRY(this->Get(&size, out_value, sizeof(Value), key)); STS_ASSERT(size >= sizeof(Value)); - return ResultSuccess; + return ResultSuccess(); } template diff --git a/stratosphere/libstratosphere/include/stratosphere/kvdb/kvdb_memory_key_value_store.hpp b/stratosphere/libstratosphere/include/stratosphere/kvdb/kvdb_memory_key_value_store.hpp index 926a2d1ea..dfdb5c676 100644 --- a/stratosphere/libstratosphere/include/stratosphere/kvdb/kvdb_memory_key_value_store.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/kvdb/kvdb_memory_key_value_store.hpp @@ -128,7 +128,7 @@ namespace sts::kvdb { return ResultKvdbAllocationFailed; } this->capacity = capacity; - return ResultSuccess; + return ResultSuccess(); } Result Set(const Key &key, const void *value, size_t value_size) { @@ -156,7 +156,7 @@ namespace sts::kvdb { /* Save the new Entry in the map. */ *it = Entry(key, new_value, value_size); - return ResultSuccess; + return ResultSuccess(); } Result AddUnsafe(const Key &key, void *value, size_t value_size) { @@ -165,7 +165,7 @@ namespace sts::kvdb { } this->entries[this->count++] = Entry(key, value, value_size); - return ResultSuccess; + return ResultSuccess(); } Result Remove(const Key &key) { @@ -178,7 +178,7 @@ namespace sts::kvdb { std::free(it->GetValuePointer()); std::memmove(it, it + 1, sizeof(*it) * (this->end() - (it + 1))); this->count--; - return ResultSuccess; + return ResultSuccess(); } /* If it's not, we didn't remove it. */ @@ -292,7 +292,7 @@ namespace sts::kvdb { /* Initialize our index. */ R_TRY(this->index.Initialize(capacity)); - return ResultSuccess; + return ResultSuccess(); } Result Initialize(size_t capacity) { @@ -303,7 +303,7 @@ namespace sts::kvdb { /* Initialize our index. */ R_TRY(this->index.Initialize(capacity)); - return ResultSuccess; + return ResultSuccess(); } size_t GetCount() const { @@ -323,7 +323,7 @@ namespace sts::kvdb { AutoBuffer buffer; R_TRY_CATCH(this->ReadArchiveFile(&buffer)) { R_CATCH(ResultFsPathNotFound) { - return ResultSuccess; + return ResultSuccess(); } } R_END_TRY_CATCH; @@ -356,7 +356,7 @@ namespace sts::kvdb { } } - return ResultSuccess; + return ResultSuccess(); } Result Save() { @@ -406,7 +406,7 @@ namespace sts::kvdb { size_t size = std::min(max_out_size, it->GetValueSize()); std::memcpy(out_value, it->GetValuePointer(), size); *out_size = size; - return ResultSuccess; + return ResultSuccess(); } template @@ -418,7 +418,7 @@ namespace sts::kvdb { } *out_value = it->template GetValuePointer(); - return ResultSuccess; + return ResultSuccess(); } template @@ -430,7 +430,7 @@ namespace sts::kvdb { } *out_value = it->template GetValuePointer(); - return ResultSuccess; + return ResultSuccess(); } template @@ -442,7 +442,7 @@ namespace sts::kvdb { } *out_value = it->template GetValue(); - return ResultSuccess; + return ResultSuccess(); } Result GetValueSize(size_t *out_size, const Key &key) const { @@ -453,7 +453,7 @@ namespace sts::kvdb { } *out_size = it->GetValueSize(); - return ResultSuccess; + return ResultSuccess(); } Result Remove(const Key &key) { @@ -528,7 +528,7 @@ namespace sts::kvdb { return fsdevGetLastResult(); } - return ResultSuccess; + return ResultSuccess(); } size_t GetArchiveSize() const { @@ -560,7 +560,7 @@ namespace sts::kvdb { return fsdevGetLastResult(); } - return ResultSuccess; + return ResultSuccess(); } }; diff --git a/stratosphere/libstratosphere/include/stratosphere/os/os_thread.hpp b/stratosphere/libstratosphere/include/stratosphere/os/os_thread.hpp index a866d66f0..a647e571a 100644 --- a/stratosphere/libstratosphere/include/stratosphere/os/os_thread.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/os/os_thread.hpp @@ -50,7 +50,7 @@ namespace sts::os { Result Join() { R_TRY(threadWaitForExit(&this->thr)); R_TRY(threadClose(&this->thr)); - return ResultSuccess; + return ResultSuccess(); } Result CancelSynchronization() { @@ -92,7 +92,7 @@ namespace sts::os { Result Join() { R_TRY(threadWaitForExit(&this->thr)); R_TRY(threadClose(&this->thr)); - return ResultSuccess; + return ResultSuccess(); } Result CancelSynchronization() { diff --git a/stratosphere/libstratosphere/include/stratosphere/results.hpp b/stratosphere/libstratosphere/include/stratosphere/results.hpp index ef1a7c116..b3f113549 100644 --- a/stratosphere/libstratosphere/include/stratosphere/results.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/results.hpp @@ -17,9 +17,10 @@ #pragma once /* Utilities. */ -#include "results/utilities.h" +#include "results/results_common.hpp" /* Official. */ +#include "results/cal_results.hpp" #include "results/creport_results.hpp" #include "results/debug_results.hpp" #include "results/dmnt_results.hpp" @@ -28,7 +29,6 @@ #include "results/fs_results.hpp" #include "results/hipc_results.hpp" #include "results/i2c_results.hpp" -#include "results/kernel_results.hpp" #include "results/kvdb_results.hpp" #include "results/loader_results.hpp" #include "results/lr_results.hpp" @@ -40,10 +40,9 @@ #include "results/sf_results.hpp" #include "results/sm_results.hpp" #include "results/spl_results.hpp" +#include "results/svc_results.hpp" #include "results/updater_results.hpp" #include "results/vi_results.hpp" /* Unofficial. */ #include "results/ams_results.hpp" - -static constexpr Result ResultSuccess = 0; diff --git a/stratosphere/libstratosphere/include/stratosphere/results/ams_results.hpp b/stratosphere/libstratosphere/include/stratosphere/results/ams_results.hpp index 245d7d2d4..beb605e45 100644 --- a/stratosphere/libstratosphere/include/stratosphere/results/ams_results.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/results/ams_results.hpp @@ -15,17 +15,24 @@ */ #pragma once -#include +#include "results_common.hpp" -/* Please note: These results are all custom, and not official. */ +namespace sts::ams { -static constexpr u32 Module_Atmosphere = 444; + /* Please note: These results are all custom, and not official. */ + R_DEFINE_NAMESPACE_RESULT_MODULE(444); -/* Result 1-1000 reserved for Atmosphere. */ -static constexpr Result ResultAtmosphereExosphereNotPresent = MAKERESULT(Module_Atmosphere, 1); -static constexpr Result ResultAtmosphereVersionMismatch = MAKERESULT(Module_Atmosphere, 2); -/* Results 1000-2000 reserved for Atmosphere Mitm. */ -static constexpr Result ResultAtmosphereMitmShouldForwardToSession = MAKERESULT(Module_Atmosphere, 1000); -static constexpr Result ResultAtmosphereMitmProcessNotAssociated = MAKERESULT(Module_Atmosphere, 1100); + /* Result 1-1000 reserved for Atmosphere. */ + R_DEFINE_ERROR_RESULT(ExosphereNotPresent, 1); + R_DEFINE_ERROR_RESULT(VersionMismatch, 2); + /* Results 1000-2000 reserved for Atmosphere Mitm. */ + namespace mitm { + + R_DEFINE_ERROR_RESULT(ShouldForwardToSession, 1000); + R_DEFINE_ERROR_RESULT(ProcessNotAssociated, 1100); + + } + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/results/cal_results.hpp b/stratosphere/libstratosphere/include/stratosphere/results/cal_results.hpp new file mode 100644 index 000000000..cdb7c81cf --- /dev/null +++ b/stratosphere/libstratosphere/include/stratosphere/results/cal_results.hpp @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include "results_common.hpp" + +namespace sts::cal { + + R_DEFINE_NAMESPACE_RESULT_MODULE(198); + + R_DEFINE_ERROR_RESULT(CalibrationDataCrcError, 101); + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/results/creport_results.hpp b/stratosphere/libstratosphere/include/stratosphere/results/creport_results.hpp index 2ac115cad..eb3d0bc3b 100644 --- a/stratosphere/libstratosphere/include/stratosphere/results/creport_results.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/results/creport_results.hpp @@ -15,19 +15,23 @@ */ #pragma once -#include +#include "results_common.hpp" -static constexpr u32 Module_Creport = 168; +namespace sts::creport { -static constexpr Result ResultCreportUndefinedInstruction = MAKERESULT(Module_Creport, 0); -static constexpr Result ResultCreportInstructionAbort = MAKERESULT(Module_Creport, 1); -static constexpr Result ResultCreportDataAbort = MAKERESULT(Module_Creport, 2); -static constexpr Result ResultCreportAlignmentFault = MAKERESULT(Module_Creport, 3); -static constexpr Result ResultCreportDebuggerAttached = MAKERESULT(Module_Creport, 4); -static constexpr Result ResultCreportBreakPoint = MAKERESULT(Module_Creport, 5); -static constexpr Result ResultCreportUserBreak = MAKERESULT(Module_Creport, 6); -static constexpr Result ResultCreportDebuggerBreak = MAKERESULT(Module_Creport, 7); -static constexpr Result ResultCreportUndefinedSystemCall = MAKERESULT(Module_Creport, 8); -static constexpr Result ResultCreportSystemMemoryError = MAKERESULT(Module_Creport, 9); + R_DEFINE_NAMESPACE_RESULT_MODULE(168); -static constexpr Result ResultCreportIncompleteReport = MAKERESULT(Module_Creport, 99); + R_DEFINE_ERROR_RESULT(UndefinedInstruction, 0); + R_DEFINE_ERROR_RESULT(InstructionAbort, 1); + R_DEFINE_ERROR_RESULT(DataAbort, 2); + R_DEFINE_ERROR_RESULT(AlignmentFault, 3); + R_DEFINE_ERROR_RESULT(DebuggerAttached, 4); + R_DEFINE_ERROR_RESULT(BreakPoint, 5); + R_DEFINE_ERROR_RESULT(UserBreak, 6); + R_DEFINE_ERROR_RESULT(DebuggerBreak, 7); + R_DEFINE_ERROR_RESULT(UndefinedSystemCall, 8); + R_DEFINE_ERROR_RESULT(SystemMemoryError, 9); + + R_DEFINE_ERROR_RESULT(IncompleteReport, 99); + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/results/debug_results.hpp b/stratosphere/libstratosphere/include/stratosphere/results/debug_results.hpp index 6a8f3b5b5..868df16fb 100644 --- a/stratosphere/libstratosphere/include/stratosphere/results/debug_results.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/results/debug_results.hpp @@ -15,10 +15,14 @@ */ #pragma once -#include +#include "results_common.hpp" -static constexpr u32 Module_Debug = 183; +namespace sts::dbg { -static constexpr Result ResultDebugCannotDebug = MAKERESULT(Module_Debug, 1); -static constexpr Result ResultDebugAlreadyAttached = MAKERESULT(Module_Debug, 2); -static constexpr Result ResultDebugCancelled = MAKERESULT(Module_Debug, 3); + R_DEFINE_NAMESPACE_RESULT_MODULE(183); + + R_DEFINE_ERROR_RESULT(CannotDebug, 1); + R_DEFINE_ERROR_RESULT(AlreadyAttached, 2); + R_DEFINE_ERROR_RESULT(Cancelled, 3); + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/results/dmnt_results.hpp b/stratosphere/libstratosphere/include/stratosphere/results/dmnt_results.hpp index ff3dec2ce..ec2fdd693 100644 --- a/stratosphere/libstratosphere/include/stratosphere/results/dmnt_results.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/results/dmnt_results.hpp @@ -15,24 +15,36 @@ */ #pragma once -#include +#include "results_common.hpp" -static constexpr u32 Module_Dmnt = 13; +namespace sts::dmnt { -static constexpr Result ResultDmntUnknown = MAKERESULT(Module_Dmnt, 1); -static constexpr Result ResultDmntDebuggingDisabled = MAKERESULT(Module_Dmnt, 2); + R_DEFINE_NAMESPACE_RESULT_MODULE(13); -static constexpr Result ResultDmntCheatNotAttached = MAKERESULT(Module_Dmnt, 6500); -static constexpr Result ResultDmntCheatNullBuffer = MAKERESULT(Module_Dmnt, 6501); -static constexpr Result ResultDmntCheatInvalidBuffer = MAKERESULT(Module_Dmnt, 6502); -static constexpr Result ResultDmntCheatUnknownChtId = MAKERESULT(Module_Dmnt, 6503); -static constexpr Result ResultDmntCheatOutOfCheats = MAKERESULT(Module_Dmnt, 6504); -static constexpr Result ResultDmntCheatInvalidCheat = MAKERESULT(Module_Dmnt, 6505); -static constexpr Result ResultDmntCheatCannotDisableMasterCheat = MAKERESULT(Module_Dmnt, 6505); + R_DEFINE_ERROR_RESULT(Unknown, 1); + R_DEFINE_ERROR_RESULT(DebuggingDisabled, 2); -static constexpr Result ResultDmntCheatInvalidFreezeWidth = MAKERESULT(Module_Dmnt, 6600); -static constexpr Result ResultDmntCheatAddressAlreadyFrozen = MAKERESULT(Module_Dmnt, 6601); -static constexpr Result ResultDmntCheatAddressNotFrozen = MAKERESULT(Module_Dmnt, 6602); -static constexpr Result ResultDmntCheatTooManyFrozenAddresses = MAKERESULT(Module_Dmnt, 6603); + /* Atmosphere extension. */ + namespace cheat { -static constexpr Result ResultDmntCheatVmInvalidCondDepth = MAKERESULT(Module_Dmnt, 6700); \ No newline at end of file + R_DEFINE_ABSTRACT_ERROR_RANGE(CheatError, 6500, 6599); + R_DEFINE_ERROR_RESULT(CheatNotAttached, 6500); + R_DEFINE_ERROR_RESULT(CheatNullBuffer, 6501); + R_DEFINE_ERROR_RESULT(CheatInvalidBuffer, 6502); + R_DEFINE_ERROR_RESULT(CheatUnknownId, 6503); + R_DEFINE_ERROR_RESULT(CheatOutOfResource, 6504); + R_DEFINE_ERROR_RESULT(CheatInvalid, 6505); + R_DEFINE_ERROR_RESULT(CheatCannotDisable, 6506); + + R_DEFINE_ABSTRACT_ERROR_RANGE(FrozenAddressError, 6600, 6699); + R_DEFINE_ERROR_RESULT(FrozenAddressInvalidWidth, 6600); + R_DEFINE_ERROR_RESULT(FrozenAddressAlreadyExists, 6601); + R_DEFINE_ERROR_RESULT(FrozenAddressNotFound, 6602); + R_DEFINE_ERROR_RESULT(FrozenAddressOutOfResource, 6603); + + R_DEFINE_ABSTRACT_ERROR_RANGE(VirtualMachineError, 6700, 6799); + R_DEFINE_ERROR_RESULT(VirtualMachineInvalidConditionDepth, 6700); + + } + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/results/err_results.hpp b/stratosphere/libstratosphere/include/stratosphere/results/err_results.hpp index 3aa146c0b..05612b493 100644 --- a/stratosphere/libstratosphere/include/stratosphere/results/err_results.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/results/err_results.hpp @@ -15,9 +15,13 @@ */ #pragma once -#include +#include "results_common.hpp" -static constexpr u32 Module_Err = 162; +namespace sts::err { -static constexpr Result ResultErrApplicationAborted = MAKERESULT(Module_Err, 1); -static constexpr Result ResultErrSystemModuleAborted = MAKERESULT(Module_Err, 2); + R_DEFINE_NAMESPACE_RESULT_MODULE(162); + + R_DEFINE_ERROR_RESULT(ApplicationAborted, 1); + R_DEFINE_ERROR_RESULT(SystemModuleAborted, 2); + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/results/fatal_results.hpp b/stratosphere/libstratosphere/include/stratosphere/results/fatal_results.hpp index 29e09eb61..fda9db86b 100644 --- a/stratosphere/libstratosphere/include/stratosphere/results/fatal_results.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/results/fatal_results.hpp @@ -15,13 +15,17 @@ */ #pragma once -#include +#include "results_common.hpp" -static constexpr u32 Module_Fatal = 163; +namespace sts::fatal { -static constexpr Result ResultFatalAllocationFailed = MAKERESULT(Module_Fatal, 1); -static constexpr Result ResultFatalNullGraphicsBuffer = MAKERESULT(Module_Fatal, 2); -static constexpr Result ResultFatalAlreadyThrown = MAKERESULT(Module_Fatal, 3); -static constexpr Result ResultFatalTooManyEvents = MAKERESULT(Module_Fatal, 4); -static constexpr Result ResultFatalInRepairWithoutVolHeld = MAKERESULT(Module_Fatal, 5); -static constexpr Result ResultFatalInRepairWithoutTimeReviserCartridge = MAKERESULT(Module_Fatal, 6); + R_DEFINE_NAMESPACE_RESULT_MODULE(163); + + R_DEFINE_ERROR_RESULT(AllocationFailed, 1); + R_DEFINE_ERROR_RESULT(NullGraphicsBuffer, 2); + R_DEFINE_ERROR_RESULT(AlreadyThrown, 3); + R_DEFINE_ERROR_RESULT(TooManyEvents, 4); + R_DEFINE_ERROR_RESULT(InRepairWithoutVolHeld, 5); + R_DEFINE_ERROR_RESULT(InRepairWithoutTimeReviserCartridge, 6); + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/results/fs_results.hpp b/stratosphere/libstratosphere/include/stratosphere/results/fs_results.hpp index 4bb0b89a0..821a3e200 100644 --- a/stratosphere/libstratosphere/include/stratosphere/results/fs_results.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/results/fs_results.hpp @@ -15,53 +15,102 @@ */ #pragma once -#include +#include "results_common.hpp" -static constexpr u32 Module_Fs = 2; +namespace sts::fs { -static constexpr Result ResultFsPathNotFound = MAKERESULT(Module_Fs, 1); -static constexpr Result ResultFsPathAlreadyExists = MAKERESULT(Module_Fs, 2); + R_DEFINE_NAMESPACE_RESULT_MODULE(2); -static constexpr Result ResultFsTargetLocked = MAKERESULT(Module_Fs, 7); -static constexpr Result ResultFsDirectoryNotEmpty = MAKERESULT(Module_Fs, 8); + R_DEFINE_ERROR_RESULT(PathNotFound, 1); + R_DEFINE_ERROR_RESULT(PathAlreadyExists, 2); -static constexpr Result ResultFsNotEnoughFreeSpaceRangeStart = MAKERESULT(Module_Fs, 30); - static constexpr Result ResultFsNotEnoughFreeSpaceBisRangeStart = MAKERESULT(Module_Fs, 34); - static constexpr Result ResultFsNotEnoughFreeSpaceBisCalibration = MAKERESULT(Module_Fs, 35); - static constexpr Result ResultFsNotEnoughFreeSpaceBisSafe = MAKERESULT(Module_Fs, 36); - static constexpr Result ResultFsNotEnoughFreeSpaceBisUser = MAKERESULT(Module_Fs, 37); - static constexpr Result ResultFsNotEnoughFreeSpaceBisSystem = MAKERESULT(Module_Fs, 38); - static constexpr Result ResultFsNotEnoughFreeSpaceBisRangeEnd = MAKERESULT(Module_Fs, 39); - static constexpr Result ResultFsNotEnoughFreeSpaceSdCard = MAKERESULT(Module_Fs, 39); -static constexpr Result ResultFsNotEnoughFreeSpaceRangeEnd = MAKERESULT(Module_Fs, 45); + R_DEFINE_ERROR_RESULT(TargetLocked, 7); + R_DEFINE_ERROR_RESULT(DirectoryNotEmpty, 8); -static constexpr Result ResultFsMountNameAlreadyExists = MAKERESULT(Module_Fs, 60); + R_DEFINE_ERROR_RANGE (NotEnoughFreeSpace, 30, 45); + R_DEFINE_ERROR_RANGE(NotEnoughFreeSpaceBis, 34, 38); + R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisCalibration, 35); + R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisSafe, 36); + R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisUser, 37); + R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisSystem, 38); + R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceSdCard, 39); -static constexpr Result ResultFsTargetNotFound = MAKERESULT(Module_Fs, 1002); + R_DEFINE_ERROR_RESULT(MountNameAlreadyExists, 60); -static constexpr Result ResultFsSdCardNotPresent = MAKERESULT(Module_Fs, 2001); + R_DEFINE_ERROR_RESULT(TargetNotFound, 1002); -static constexpr Result ResultFsNotImplemented = MAKERESULT(Module_Fs, 3001); -static constexpr Result ResultFsOutOfRange = MAKERESULT(Module_Fs, 3005); + R_DEFINE_ERROR_RANGE(SdCardAccessFailed, 2000, 2499); + R_DEFINE_ERROR_RESULT(SdCardNotPresent, 2001); -static constexpr Result ResultFsAllocationFailureInDirectorySaveDataFileSystem = MAKERESULT(Module_Fs, 3321); -static constexpr Result ResultFsAllocationFailureInSubDirectoryFileSystem = MAKERESULT(Module_Fs, 3355); + R_DEFINE_ERROR_RANGE(GameCardAccessFailed, 2500, 2999); -static constexpr Result ResultFsPreconditionViolation = MAKERESULT(Module_Fs, 6000); -static constexpr Result ResultFsInvalidArgument = MAKERESULT(Module_Fs, 6001); -static constexpr Result ResultFsInvalidPath = MAKERESULT(Module_Fs, 6002); -static constexpr Result ResultFsTooLongPath = MAKERESULT(Module_Fs, 6003); -static constexpr Result ResultFsInvalidCharacter = MAKERESULT(Module_Fs, 6004); -static constexpr Result ResultFsInvalidPathFormat = MAKERESULT(Module_Fs, 6005); -static constexpr Result ResultFsDirectoryUnobtainable = MAKERESULT(Module_Fs, 6006); -static constexpr Result ResultFsNotNormalized = MAKERESULT(Module_Fs, 6007); + R_DEFINE_ERROR_RESULT(NotImplemented, 3001); + R_DEFINE_ERROR_RESULT(OutOfRange, 3005); -static constexpr Result ResultFsInvalidOffset = MAKERESULT(Module_Fs, 6061); -static constexpr Result ResultFsInvalidSize = MAKERESULT(Module_Fs, 6062); -static constexpr Result ResultFsNullptrArgument = MAKERESULT(Module_Fs, 6063); + R_DEFINE_ERROR_RANGE(AllocationFailure, 3200, 3499); + R_DEFINE_ERROR_RESULT(AllocationFailureInDirectorySaveDataFileSystem, 3321); + R_DEFINE_ERROR_RESULT(AllocationFailureInSubDirectoryFileSystem, 3355); -static constexpr Result ResultFsInvalidSaveDataSpaceId = MAKERESULT(Module_Fs, 6082); + R_DEFINE_ERROR_RANGE(MmcAccessFailed, 3500, 3999); -static constexpr Result ResultFsUnsupportedOperation = MAKERESULT(Module_Fs, 6300); + R_DEFINE_ERROR_RANGE(DataCorrupted, 4000, 4999); + R_DEFINE_ERROR_RANGE(RomCorrupted, 4001, 4299); + R_DEFINE_ERROR_RANGE(SaveDataCorrupted, 4301, 4499); + R_DEFINE_ERROR_RANGE(NcaCorrupted, 4501, 4599); + R_DEFINE_ERROR_RANGE(IntegrityVerificationStorageCorrupted, 4601, 4639); + R_DEFINE_ERROR_RANGE(PartitionFileSystemCorrupted, 4641, 4659); + R_DEFINE_ERROR_RANGE(BuiltInStorageCorrupted, 4661, 4679); + R_DEFINE_ERROR_RANGE(HostFileSystemCorrupted, 4701, 4719); + R_DEFINE_ERROR_RANGE(DatabaseCorrupted, 4721, 4739); + R_DEFINE_ERROR_RANGE(AesXtsFileSystemCorrupted, 4741, 4759); + R_DEFINE_ERROR_RANGE(SaveDataTransferDataCorrupted, 4761, 4769); + R_DEFINE_ERROR_RANGE(SignedSystemPartitionDataCorrupted, 4771, 4779); -static constexpr Result ResultFsPermissionDenied = MAKERESULT(Module_Fs, 6400); + R_DEFINE_ERROR_RESULT(GameCardLogoDataCorrupted, 4781); + + R_DEFINE_ERROR_RANGE(Unexpected, 5000, 5999); + + R_DEFINE_ERROR_RANGE(PreconditionViolation, 6000, 6499); + R_DEFINE_ERROR_RANGE(InvalidArgument, 6001, 6199); + R_DEFINE_ERROR_RANGE(InvalidPath, 6002, 6029); + R_DEFINE_ERROR_RESULT(TooLongPath, 6003); + R_DEFINE_ERROR_RESULT(InvalidCharacter, 6004); + R_DEFINE_ERROR_RESULT(InvalidPathFormat, 6005); + R_DEFINE_ERROR_RESULT(DirectoryUnobtainable, 6006); + R_DEFINE_ERROR_RESULT(NotNormalized, 6007); + + R_DEFINE_ERROR_RESULT(InvalidOffset, 6061); + R_DEFINE_ERROR_RESULT(InvalidSize, 6062); + R_DEFINE_ERROR_RESULT(NullptrArgument, 6063); + R_DEFINE_ERROR_RESULT(InvalidAlignment, 6064); + R_DEFINE_ERROR_RESULT(InvalidMountName, 6065); + + R_DEFINE_ERROR_RESULT(ExtensionSizeTooLarge, 6066); + R_DEFINE_ERROR_RESULT(ExtensionSizeInvalid, 6067); + + R_DEFINE_ERROR_RANGE(InvalidEnumValue, 6080, 6099); + R_DEFINE_ERROR_RESULT(InvalidSaveDataState, 6081); + R_DEFINE_ERROR_RESULT(InvalidSaveDataSpaceId, 6082); + + R_DEFINE_ERROR_RANGE(InvalidOperationForOpenMode, 6200, 6299); + R_DEFINE_ERROR_RESULT(FileExtensionWithoutOpenModeAllowAppend, 6201); + + R_DEFINE_ERROR_RANGE(UnsupportedOperation, 6300, 6399); + + R_DEFINE_ERROR_RANGE(PermissionDenied, 6400, 6449); + + R_DEFINE_ERROR_RESULT(WriteModeFileNotClosed, 6457); + R_DEFINE_ERROR_RESULT(AllocatorAlignmentViolation, 6461); + R_DEFINE_ERROR_RESULT(UserNotExist, 6465); + + R_DEFINE_ERROR_RANGE(OutOfResource, 6700, 6799); + R_DEFINE_ERROR_RESULT(MappingTableFull, 6706); + R_DEFINE_ERROR_RESULT(OpenCountLimit, 6709); + + R_DEFINE_ERROR_RANGE(MappingFailed, 6800, 6899); + R_DEFINE_ERROR_RESULT(MapFull, 6811); + + R_DEFINE_ERROR_RANGE(BadState, 6900, 6999); + R_DEFINE_ERROR_RESULT(NotMounted, 6905); + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/results/hipc_results.hpp b/stratosphere/libstratosphere/include/stratosphere/results/hipc_results.hpp index 5406123a7..930bdf66d 100644 --- a/stratosphere/libstratosphere/include/stratosphere/results/hipc_results.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/results/hipc_results.hpp @@ -15,23 +15,27 @@ */ #pragma once -#include +#include "results_common.hpp" -static constexpr u32 Module_Hipc = 11; +namespace sts::sf::hipc { -static constexpr Result ResultHipcSessionAllocationFailure = MAKERESULT(Module_Hipc, 102); + R_DEFINE_NAMESPACE_RESULT_MODULE(11); -static constexpr Result ResultHipcOutOfSessions = MAKERESULT(Module_Hipc, 131); -static constexpr Result ResultHipcPointerBufferTooSmall = MAKERESULT(Module_Hipc, 141); + R_DEFINE_ABSTRACT_ERROR_RANGE(OutOfResource, 100, 299); + R_DEFINE_ERROR_RESULT(OutOfSessionMemory, 102); + R_DEFINE_ERROR_RANGE (OutOfSessions, 131, 139); + R_DEFINE_ERROR_RESULT(PointerBufferTooSmall, 141); -static constexpr Result ResultHipcOutOfDomains = MAKERESULT(Module_Hipc, 200); + R_DEFINE_ERROR_RESULT(OutOfDomains, 200); -static constexpr Result ResultHipcSessionClosed = MAKERESULT(Module_Hipc, 301); + R_DEFINE_ERROR_RESULT(SessionClosed, 301); -static constexpr Result ResultHipcInvalidRequestSize = MAKERESULT(Module_Hipc, 402); -static constexpr Result ResultHipcUnknownCommandType = MAKERESULT(Module_Hipc, 403); + R_DEFINE_ERROR_RESULT(InvalidRequestSize, 402); + R_DEFINE_ERROR_RESULT(UnknownCommandType, 403); -static constexpr Result ResultHipcInvalidRequest = MAKERESULT(Module_Hipc, 420); + R_DEFINE_ERROR_RESULT(InvalidCmifRequest, 420); -static constexpr Result ResultHipcTargetNotDomain = MAKERESULT(Module_Hipc, 491); -static constexpr Result ResultHipcDomainObjectNotFound = MAKERESULT(Module_Hipc, 492); + R_DEFINE_ERROR_RESULT(TargetNotDomain, 491); + R_DEFINE_ERROR_RESULT(DomainObjectNotFound, 492); + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/results/i2c_results.hpp b/stratosphere/libstratosphere/include/stratosphere/results/i2c_results.hpp index 5ce74b63d..c25a7e9a5 100644 --- a/stratosphere/libstratosphere/include/stratosphere/results/i2c_results.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/results/i2c_results.hpp @@ -15,12 +15,16 @@ */ #pragma once -#include +#include "results_common.hpp" -static constexpr u32 Module_I2c = 101; +namespace sts::i2c { -static constexpr Result ResultI2cNoAck = MAKERESULT(Module_I2c, 1); -static constexpr Result ResultI2cBusBusy = MAKERESULT(Module_I2c, 2); -static constexpr Result ResultI2cFullCommandList = MAKERESULT(Module_I2c, 3); -static constexpr Result ResultI2cTimedOut = MAKERESULT(Module_I2c, 4); -static constexpr Result ResultI2cUnknownDevice = MAKERESULT(Module_I2c, 5); + R_DEFINE_NAMESPACE_RESULT_MODULE(101); + + R_DEFINE_ERROR_RESULT(NoAck, 1); + R_DEFINE_ERROR_RESULT(BusBusy, 2); + R_DEFINE_ERROR_RESULT(FullCommandList, 3); + R_DEFINE_ERROR_RESULT(TimedOut, 4); + R_DEFINE_ERROR_RESULT(UnknownDevice, 5); + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/results/kernel_results.hpp b/stratosphere/libstratosphere/include/stratosphere/results/kernel_results.hpp deleted file mode 100644 index 1482f5db9..000000000 --- a/stratosphere/libstratosphere/include/stratosphere/results/kernel_results.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2018-2019 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once -#include - -/* libnx already has: static constexpr u32 Module_Kernel = 1; */ - -static constexpr Result ResultKernelOutOfSessions = MAKERESULT(Module_Kernel, KernelError_OutOfSessions); - -static constexpr Result ResultKernelInvalidCapabilityDescriptor = MAKERESULT(Module_Kernel, KernelError_InvalidCapabilityDescriptor); - -static constexpr Result ResultKernelNotImplemented = MAKERESULT(Module_Kernel, KernelError_NotImplemented); -static constexpr Result ResultKernelThreadTerminating = MAKERESULT(Module_Kernel, KernelError_ThreadTerminating); - -static constexpr Result ResultKernelOutOfDebugEvents = MAKERESULT(Module_Kernel, KernelError_OutOfDebugEvents); - -static constexpr Result ResultKernelInvalidSize = MAKERESULT(Module_Kernel, KernelError_InvalidSize); -static constexpr Result ResultKernelInvalidAddress = MAKERESULT(Module_Kernel, KernelError_InvalidAddress); -static constexpr Result ResultKernelResourceExhausted = MAKERESULT(Module_Kernel, KernelError_ResourceExhausted); -static constexpr Result ResultKernelOutOfMemory = MAKERESULT(Module_Kernel, KernelError_OutOfMemory); -static constexpr Result ResultKernelOutOfHandles = MAKERESULT(Module_Kernel, KernelError_OutOfHandles); -static constexpr Result ResultKernelInvalidMemoryState = MAKERESULT(Module_Kernel, KernelError_InvalidMemoryState); -static constexpr Result ResultKernelInvalidMemoryPermissions = MAKERESULT(Module_Kernel, KernelError_InvalidMemoryPermissions); -static constexpr Result ResultKernelInvalidMemoryRange = MAKERESULT(Module_Kernel, KernelError_InvalidMemoryRange); -static constexpr Result ResultKernelInvalidPriority = MAKERESULT(Module_Kernel, KernelError_InvalidPriority); -static constexpr Result ResultKernelInvalidCoreId = MAKERESULT(Module_Kernel, KernelError_InvalidCoreId); -static constexpr Result ResultKernelInvalidHandle = MAKERESULT(Module_Kernel, KernelError_InvalidHandle); -static constexpr Result ResultKernelInvalidUserBuffer = MAKERESULT(Module_Kernel, KernelError_InvalidUserBuffer); -static constexpr Result ResultKernelInvalidCombination = MAKERESULT(Module_Kernel, KernelError_InvalidCombination); -static constexpr Result ResultKernelTimedOut = MAKERESULT(Module_Kernel, KernelError_TimedOut); -static constexpr Result ResultKernelCancelled = MAKERESULT(Module_Kernel, KernelError_Cancelled); -static constexpr Result ResultKernelOutOfRange = MAKERESULT(Module_Kernel, KernelError_OutOfRange); -static constexpr Result ResultKernelInvalidEnumValue = MAKERESULT(Module_Kernel, KernelError_InvalidEnumValue); -static constexpr Result ResultKernelNotFound = MAKERESULT(Module_Kernel, KernelError_NotFound); -static constexpr Result ResultKernelAlreadyExists = MAKERESULT(Module_Kernel, KernelError_AlreadyExists); -static constexpr Result ResultKernelConnectionClosed = MAKERESULT(Module_Kernel, KernelError_ConnectionClosed); -static constexpr Result ResultKernelUnhandledUserInterrupt = MAKERESULT(Module_Kernel, KernelError_UnhandledUserInterrupt); -static constexpr Result ResultKernelInvalidState = MAKERESULT(Module_Kernel, KernelError_InvalidState); -static constexpr Result ResultKernelReservedValue = MAKERESULT(Module_Kernel, KernelError_ReservedValue); -static constexpr Result ResultKernelInvalidHwBreakpoint = MAKERESULT(Module_Kernel, KernelError_InvalidHwBreakpoint); -static constexpr Result ResultKernelFatalUserException = MAKERESULT(Module_Kernel, KernelError_FatalUserException); -static constexpr Result ResultKernelOwnedByAnotherProcess = MAKERESULT(Module_Kernel, KernelError_OwnedByAnotherProcess); -static constexpr Result ResultKernelConnectionRefused = MAKERESULT(Module_Kernel, KernelError_ConnectionRefused); -static constexpr Result ResultKernelLimitReached = MAKERESULT(Module_Kernel, 132 /* KernelError_OutOfResource */); - -static constexpr Result ResultKernelReceiveListBroken = MAKERESULT(Module_Kernel, 258); -static constexpr Result ResultKernelIpcMapFailed = MAKERESULT(Module_Kernel, KernelError_IpcMapFailed); -static constexpr Result ResultKernelIpcCmdBufTooSmall = MAKERESULT(Module_Kernel, KernelError_IpcCmdbufTooSmall); - -static constexpr Result ResultKernelNotDebugged = MAKERESULT(Module_Kernel, KernelError_NotDebugged); diff --git a/stratosphere/libstratosphere/include/stratosphere/results/kvdb_results.hpp b/stratosphere/libstratosphere/include/stratosphere/results/kvdb_results.hpp index 9aef93a82..3a4528016 100644 --- a/stratosphere/libstratosphere/include/stratosphere/results/kvdb_results.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/results/kvdb_results.hpp @@ -15,15 +15,19 @@ */ #pragma once -#include +#include "results_common.hpp" -static constexpr u32 Module_Kvdb = 20; +namespace sts::kvdb { -static constexpr Result ResultKvdbKeyCapacityInsufficient = MAKERESULT(Module_Kvdb, 1); -static constexpr Result ResultKvdbKeyNotFound = MAKERESULT(Module_Kvdb, 2); -static constexpr Result ResultKvdbAllocationFailed = MAKERESULT(Module_Kvdb, 4); -static constexpr Result ResultKvdbInvalidKeyValue = MAKERESULT(Module_Kvdb, 5); -static constexpr Result ResultKvdbBufferInsufficient = MAKERESULT(Module_Kvdb, 6); + R_DEFINE_NAMESPACE_RESULT_MODULE(20); -static constexpr Result ResultKvdbInvalidFilesystemState = MAKERESULT(Module_Kvdb, 8); -static constexpr Result ResultKvdbNotCreated = MAKERESULT(Module_Kvdb, 9); \ No newline at end of file + R_DEFINE_ERROR_RESULT(KeyCapacityInsufficient, 1); + R_DEFINE_ERROR_RESULT(KeyNotFound, 2); + R_DEFINE_ERROR_RESULT(AllocationFailed, 4); + R_DEFINE_ERROR_RESULT(InvalidKeyValue, 5); + R_DEFINE_ERROR_RESULT(BufferInsufficient, 6); + + R_DEFINE_ERROR_RESULT(InvalidFilesystemState, 8); + R_DEFINE_ERROR_RESULT(NotCreated, 9); + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/results/loader_results.hpp b/stratosphere/libstratosphere/include/stratosphere/results/loader_results.hpp index 7803a68c2..01cb0a443 100644 --- a/stratosphere/libstratosphere/include/stratosphere/results/loader_results.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/results/loader_results.hpp @@ -15,45 +15,49 @@ */ #pragma once -#include +#include "results_common.hpp" -static constexpr u32 Module_Loader = 9; +namespace sts::ldr { -static constexpr Result ResultLoaderTooLongArgument = MAKERESULT(Module_Loader, 1); -static constexpr Result ResultLoaderTooManyArguments = MAKERESULT(Module_Loader, 2); -static constexpr Result ResultLoaderTooLargeMeta = MAKERESULT(Module_Loader, 3); -static constexpr Result ResultLoaderInvalidMeta = MAKERESULT(Module_Loader, 4); -static constexpr Result ResultLoaderInvalidNso = MAKERESULT(Module_Loader, 5); -static constexpr Result ResultLoaderInvalidPath = MAKERESULT(Module_Loader, 6); -static constexpr Result ResultLoaderTooManyProcesses = MAKERESULT(Module_Loader, 7); -static constexpr Result ResultLoaderNotPinned = MAKERESULT(Module_Loader, 8); -static constexpr Result ResultLoaderInvalidProgramId = MAKERESULT(Module_Loader, 9); -static constexpr Result ResultLoaderInvalidVersion = MAKERESULT(Module_Loader, 10); + R_DEFINE_NAMESPACE_RESULT_MODULE(9); -static constexpr Result ResultLoaderInsufficientAddressSpace = MAKERESULT(Module_Loader, 51); -static constexpr Result ResultLoaderInvalidNro = MAKERESULT(Module_Loader, 52); -static constexpr Result ResultLoaderInvalidNrr = MAKERESULT(Module_Loader, 53); -static constexpr Result ResultLoaderInvalidSignature = MAKERESULT(Module_Loader, 54); -static constexpr Result ResultLoaderInsufficientNroRegistrations = MAKERESULT(Module_Loader, 55); -static constexpr Result ResultLoaderInsufficientNrrRegistrations = MAKERESULT(Module_Loader, 56); -static constexpr Result ResultLoaderNroAlreadyLoaded = MAKERESULT(Module_Loader, 57); + R_DEFINE_ERROR_RESULT(TooLongArgument, 1); + R_DEFINE_ERROR_RESULT(TooManyArguments, 2); + R_DEFINE_ERROR_RESULT(TooLargeMeta, 3); + R_DEFINE_ERROR_RESULT(InvalidMeta, 4); + R_DEFINE_ERROR_RESULT(InvalidNso, 5); + R_DEFINE_ERROR_RESULT(InvalidPath, 6); + R_DEFINE_ERROR_RESULT(TooManyProcesses, 7); + R_DEFINE_ERROR_RESULT(NotPinned, 8); + R_DEFINE_ERROR_RESULT(InvalidProgramId, 9); + R_DEFINE_ERROR_RESULT(InvalidVersion, 10); -static constexpr Result ResultLoaderInvalidAddress = MAKERESULT(Module_Loader, 81); -static constexpr Result ResultLoaderInvalidSize = MAKERESULT(Module_Loader, 82); -static constexpr Result ResultLoaderNotLoaded = MAKERESULT(Module_Loader, 84); -static constexpr Result ResultLoaderNotRegistered = MAKERESULT(Module_Loader, 85); -static constexpr Result ResultLoaderInvalidSession = MAKERESULT(Module_Loader, 86); -static constexpr Result ResultLoaderInvalidProcess = MAKERESULT(Module_Loader, 87); + R_DEFINE_ERROR_RESULT(InsufficientAddressSpace, 51); + R_DEFINE_ERROR_RESULT(InvalidNro, 52); + R_DEFINE_ERROR_RESULT(InvalidNrr, 53); + R_DEFINE_ERROR_RESULT(InvalidSignature, 54); + R_DEFINE_ERROR_RESULT(InsufficientNroRegistrations, 55); + R_DEFINE_ERROR_RESULT(InsufficientNrrRegistrations, 56); + R_DEFINE_ERROR_RESULT(NroAlreadyLoaded, 57); -static constexpr Result ResultLoaderUnknownCapability = MAKERESULT(Module_Loader, 100); -static constexpr Result ResultLoaderInvalidCapabilityKernelFlags = MAKERESULT(Module_Loader, 103); -static constexpr Result ResultLoaderInvalidCapabilitySyscallMask = MAKERESULT(Module_Loader, 104); -static constexpr Result ResultLoaderInvalidCapabilityMapRange = MAKERESULT(Module_Loader, 106); -static constexpr Result ResultLoaderInvalidCapabilityMapPage = MAKERESULT(Module_Loader, 107); -static constexpr Result ResultLoaderInvalidCapabilityInterruptPair = MAKERESULT(Module_Loader, 111); -static constexpr Result ResultLoaderInvalidCapabilityApplicationType = MAKERESULT(Module_Loader, 113); -static constexpr Result ResultLoaderInvalidCapabilityKernelVersion = MAKERESULT(Module_Loader, 114); -static constexpr Result ResultLoaderInvalidCapabilityHandleTable = MAKERESULT(Module_Loader, 115); -static constexpr Result ResultLoaderInvalidCapabilityDebugFlags = MAKERESULT(Module_Loader, 116); + R_DEFINE_ERROR_RESULT(InvalidAddress, 81); + R_DEFINE_ERROR_RESULT(InvalidSize, 82); + R_DEFINE_ERROR_RESULT(NotLoaded, 84); + R_DEFINE_ERROR_RESULT(NotRegistered, 85); + R_DEFINE_ERROR_RESULT(InvalidSession, 86); + R_DEFINE_ERROR_RESULT(InvalidProcess, 87); -static constexpr Result ResultLoaderInternalError = MAKERESULT(Module_Loader, 200); + R_DEFINE_ERROR_RESULT(UnknownCapability, 100); + R_DEFINE_ERROR_RESULT(InvalidCapabilityKernelFlags, 103); + R_DEFINE_ERROR_RESULT(InvalidCapabilitySyscallMask, 104); + R_DEFINE_ERROR_RESULT(InvalidCapabilityMapRange, 106); + R_DEFINE_ERROR_RESULT(InvalidCapabilityMapPage, 107); + R_DEFINE_ERROR_RESULT(InvalidCapabilityInterruptPair, 111); + R_DEFINE_ERROR_RESULT(InvalidCapabilityApplicationType, 113); + R_DEFINE_ERROR_RESULT(InvalidCapabilityKernelVersion, 114); + R_DEFINE_ERROR_RESULT(InvalidCapabilityHandleTable, 115); + R_DEFINE_ERROR_RESULT(InvalidCapabilityDebugFlags, 116); + + R_DEFINE_ERROR_RESULT(InternalError, 200); + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/results/lr_results.hpp b/stratosphere/libstratosphere/include/stratosphere/results/lr_results.hpp index 5b2a01b97..615d52393 100644 --- a/stratosphere/libstratosphere/include/stratosphere/results/lr_results.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/results/lr_results.hpp @@ -15,16 +15,20 @@ */ #pragma once -#include +#include "results_common.hpp" -static constexpr u32 Module_Lr = 8; +namespace sts::lr { -static constexpr Result ResultLrProgramNotFound = MAKERESULT(Module_Lr, 2); -static constexpr Result ResultLrDataNotFound = MAKERESULT(Module_Lr, 3); -static constexpr Result ResultLrUnknownStorageId = MAKERESULT(Module_Lr, 4); -static constexpr Result ResultLrHtmlDocumentNotFound = MAKERESULT(Module_Lr, 6); -static constexpr Result ResultLrAddOnContentNotFound = MAKERESULT(Module_Lr, 7); -static constexpr Result ResultLrControlNotFound = MAKERESULT(Module_Lr, 8); -static constexpr Result ResultLrLegalInformationNotFound = MAKERESULT(Module_Lr, 9); + R_DEFINE_NAMESPACE_RESULT_MODULE(8); -static constexpr Result ResultLrTooManyRegisteredPaths = MAKERESULT(Module_Lr, 90); + R_DEFINE_ERROR_RESULT(ProgramNotFound, 2); + R_DEFINE_ERROR_RESULT(DataNotFound, 3); + R_DEFINE_ERROR_RESULT(UnknownStorageId, 4); + R_DEFINE_ERROR_RESULT(HtmlDocumentNotFound, 6); + R_DEFINE_ERROR_RESULT(AddOnContentNotFound, 7); + R_DEFINE_ERROR_RESULT(ControlNotFound, 8); + R_DEFINE_ERROR_RESULT(LegalInformationNotFound, 9); + + R_DEFINE_ERROR_RESULT(TooManyRegisteredPaths, 90); + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/results/ncm_results.hpp b/stratosphere/libstratosphere/include/stratosphere/results/ncm_results.hpp index 87cc115e9..5406064d8 100644 --- a/stratosphere/libstratosphere/include/stratosphere/results/ncm_results.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/results/ncm_results.hpp @@ -15,37 +15,41 @@ */ #pragma once -#include +#include "results_common.hpp" -static constexpr u32 Module_Ncm = 5; +namespace sts::ncm { -static constexpr Result ResultNcmPlaceHolderAlreadyExists = MAKERESULT(Module_Ncm, 2); -static constexpr Result ResultNcmPlaceHolderNotFound = MAKERESULT(Module_Ncm, 3); -static constexpr Result ResultNcmContentAlreadyExists = MAKERESULT(Module_Ncm, 4); -static constexpr Result ResultNcmContentNotFound = MAKERESULT(Module_Ncm, 5); -static constexpr Result ResultNcmContentMetaNotFound = MAKERESULT(Module_Ncm, 7); -static constexpr Result ResultNcmAllocationFailed = MAKERESULT(Module_Ncm, 8); -static constexpr Result ResultNcmUnknownStorage = MAKERESULT(Module_Ncm, 12); + R_DEFINE_NAMESPACE_RESULT_MODULE(5); -static constexpr Result ResultNcmInvalidContentStorage = MAKERESULT(Module_Ncm, 100); -static constexpr Result ResultNcmInvalidContentMetaDatabase = MAKERESULT(Module_Ncm, 110); + R_DEFINE_ERROR_RESULT(PlaceHolderAlreadyExists, 2); + R_DEFINE_ERROR_RESULT(PlaceHolderNotFound, 3); + R_DEFINE_ERROR_RESULT(ContentAlreadyExists, 4); + R_DEFINE_ERROR_RESULT(ContentNotFound, 5); + R_DEFINE_ERROR_RESULT(ContentMetaNotFound, 7); + R_DEFINE_ERROR_RESULT(AllocationFailed, 8); + R_DEFINE_ERROR_RESULT(UnknownStorage, 12); -static constexpr Result ResultNcmBufferInsufficient = MAKERESULT(Module_Ncm, 180); -static constexpr Result ResultNcmInvalidContentMetaKey = MAKERESULT(Module_Ncm, 240); + R_DEFINE_ERROR_RESULT(InvalidContentStorage, 100); + R_DEFINE_ERROR_RESULT(InvalidContentMetaDatabase, 110); -static constexpr Result ResultNcmContentStorageNotActive = MAKERESULT(Module_Ncm, 250); -static constexpr Result ResultNcmGameCardContentStorageNotActive = MAKERESULT(Module_Ncm, 251); -static constexpr Result ResultNcmNandSystemContentStorageNotActive = MAKERESULT(Module_Ncm, 252); -static constexpr Result ResultNcmNandUserContentStorageNotActive = MAKERESULT(Module_Ncm, 253); -static constexpr Result ResultNcmSdCardContentStorageNotActive = MAKERESULT(Module_Ncm, 254); -static constexpr Result ResultNcmUnknownContentStorageNotActive = MAKERESULT(Module_Ncm, 258); + R_DEFINE_ERROR_RESULT(BufferInsufficient, 180); + R_DEFINE_ERROR_RESULT(InvalidContentMetaKey, 240); -static constexpr Result ResultNcmContentMetaDatabaseNotActive = MAKERESULT(Module_Ncm, 260); -static constexpr Result ResultNcmGameCardContentMetaDatabaseNotActive = MAKERESULT(Module_Ncm, 261); -static constexpr Result ResultNcmNandSystemContentMetaDatabaseNotActive = MAKERESULT(Module_Ncm, 262); -static constexpr Result ResultNcmNandUserContentMetaDatabaseNotActive = MAKERESULT(Module_Ncm, 263); -static constexpr Result ResultNcmSdCardContentMetaDatabaseNotActive = MAKERESULT(Module_Ncm, 264); -static constexpr Result ResultNcmUnknownContentMetaDatabaseNotActive = MAKERESULT(Module_Ncm, 268); + R_DEFINE_ERROR_RANGE(ContentStorageNotActive, 250, 258); + R_DEFINE_ERROR_RESULT(GameCardContentStorageNotActive, 251); + R_DEFINE_ERROR_RESULT(NandSystemContentStorageNotActive, 252); + R_DEFINE_ERROR_RESULT(NandUserContentStorageNotActive, 253); + R_DEFINE_ERROR_RESULT(SdCardContentStorageNotActive, 254); + R_DEFINE_ERROR_RESULT(UnknownContentStorageNotActive, 258); -static constexpr Result ResultNcmInvalidArgument = MAKERESULT(Module_Ncm, 8181); -static constexpr Result ResultNcmInvalidOffset = MAKERESULT(Module_Ncm, 8182); + R_DEFINE_ERROR_RANGE(ContentMetaDatabaseNotActive, 260, 268); + R_DEFINE_ERROR_RESULT(GameCardContentMetaDatabaseNotActive, 261); + R_DEFINE_ERROR_RESULT(NandSystemContentMetaDatabaseNotActive, 262); + R_DEFINE_ERROR_RESULT(NandUserContentMetaDatabaseNotActive, 263); + R_DEFINE_ERROR_RESULT(SdCardContentMetaDatabaseNotActive, 264); + R_DEFINE_ERROR_RESULT(UnknownContentMetaDatabaseNotActive, 268); + + R_DEFINE_ERROR_RANGE(InvalidArgument, 8181, 8191); + R_DEFINE_ERROR_RESULT(InvalidOffset, 8182); + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/results/os_results.hpp b/stratosphere/libstratosphere/include/stratosphere/results/os_results.hpp index 81acaf05e..93ff349a0 100644 --- a/stratosphere/libstratosphere/include/stratosphere/results/os_results.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/results/os_results.hpp @@ -15,9 +15,18 @@ */ #pragma once -#include +#include "results_common.hpp" -static constexpr u32 Module_Os = 3; +namespace sts::os { -static constexpr Result ResultOsOutOfMemory = MAKERESULT(Module_Os, 8); -static constexpr Result ResultOsResourceExhausted = MAKERESULT(Module_Os, 9); + R_DEFINE_NAMESPACE_RESULT_MODULE(3); + + R_DEFINE_ERROR_RESULT(Busy, 4); + + R_DEFINE_ERROR_RESULT(OutOfMemory, 8); + R_DEFINE_ERROR_RESULT(OutOfResource, 9); + + R_DEFINE_ERROR_RESULT(OutOfVirtualAddressSpace, 12); + R_DEFINE_ERROR_RESULT(ResourceLimit, 13); + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/results/pm_results.hpp b/stratosphere/libstratosphere/include/stratosphere/results/pm_results.hpp index 0293b4e65..463ce62db 100644 --- a/stratosphere/libstratosphere/include/stratosphere/results/pm_results.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/results/pm_results.hpp @@ -15,13 +15,17 @@ */ #pragma once -#include +#include "results_common.hpp" -static constexpr u32 Module_Pm = 15; +namespace sts::pm { -static constexpr Result ResultPmProcessNotFound = MAKERESULT(Module_Pm, 1); -static constexpr Result ResultPmAlreadyStarted = MAKERESULT(Module_Pm, 2); -static constexpr Result ResultPmNotExited = MAKERESULT(Module_Pm, 3); -static constexpr Result ResultPmDebugHookInUse = MAKERESULT(Module_Pm, 4); -static constexpr Result ResultPmApplicationRunning = MAKERESULT(Module_Pm, 5); -static constexpr Result ResultPmInvalidSize = MAKERESULT(Module_Pm, 6); + R_DEFINE_NAMESPACE_RESULT_MODULE(15); + + R_DEFINE_ERROR_RESULT(ProcessNotFound, 1); + R_DEFINE_ERROR_RESULT(AlreadyStarted, 2); + R_DEFINE_ERROR_RESULT(NotExited, 3); + R_DEFINE_ERROR_RESULT(DebugHookInUse, 4); + R_DEFINE_ERROR_RESULT(ApplicationRunning, 5); + R_DEFINE_ERROR_RESULT(InvalidSize, 6); + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/results/results_common.hpp b/stratosphere/libstratosphere/include/stratosphere/results/results_common.hpp new file mode 100644 index 000000000..00d0d6581 --- /dev/null +++ b/stratosphere/libstratosphere/include/stratosphere/results/results_common.hpp @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include +#include +#include "../defines.hpp" + +namespace sts { + + namespace result::impl { + + class ResultTraits { + public: + using BaseType = u32; + static_assert(std::is_same::value, "std::is_same::value"); + static constexpr BaseType SuccessValue = BaseType(); + static constexpr BaseType ModuleBits = 9; + static constexpr BaseType DescriptionBits = 13; + static constexpr BaseType ReservedBits = 10; + static_assert(ModuleBits + DescriptionBits + ReservedBits == sizeof(BaseType) * CHAR_BIT, "ModuleBits + DescriptionBits + ReservedBits == sizeof(BaseType) * CHAR_BIT"); + public: + NX_CONSTEXPR BaseType MakeValue(BaseType module, BaseType description) { + return (module) | (description << ModuleBits); + } + + template + struct MakeStaticValue : public std::integral_constant { + static_assert(module < (1 << ModuleBits), "Invalid Module"); + static_assert(description < (1 << DescriptionBits), "Invalid Description"); + }; + + NX_CONSTEXPR BaseType GetModuleFromValue(BaseType value) { + return value & ~(~BaseType() << ModuleBits); + } + + NX_CONSTEXPR BaseType GetDescriptionFromValue(BaseType value) { + return ((value >> ModuleBits) & ~(~BaseType() << DescriptionBits)); + } + }; + + /* Use CRTP for Results. */ + template + class ResultBase { + public: + using BaseType = typename ResultTraits::BaseType; + static constexpr BaseType SuccessValue = ResultTraits::SuccessValue; + public: + constexpr inline BaseType GetModule() const { return ResultTraits::GetModuleFromValue(static_cast(this)->GetValue()); } + constexpr inline BaseType GetDescription() const { return ResultTraits::GetDescriptionFromValue(static_cast(this)->GetValue()); } + }; + + class ResultConstructor; + + } + + class ResultSuccess; + + class Result final : public result::impl::ResultBase { + friend class ResultConstructor; + public: + using Base = typename result::impl::ResultBase; + private: + typename Base::BaseType value; + private: + /* TODO: Maybe one-day, the result constructor. */ + public: + Result() { /* ... */ } + + /* TODO: It sure would be nice to make this private. */ + constexpr Result(typename Base::BaseType v) : value(v) { static_assert(std::is_same::value); } + + constexpr inline operator ResultSuccess() const; + NX_CONSTEXPR bool CanAccept(Result result) { return true; } + + constexpr inline bool IsSuccess() const { return this->GetValue() == Base::SuccessValue; } + constexpr inline bool IsFailure() const { return !this->IsSuccess(); } + constexpr inline typename Base::BaseType GetModule() const { return Base::GetModule(); } + constexpr inline typename Base::BaseType GetDescription() const { return Base::GetDescription(); } + + constexpr inline typename Base::BaseType GetValue() const { return this->value; } + }; + static_assert(sizeof(Result) == sizeof(Result::Base::BaseType), "sizeof(Result) == sizeof(Result::Base::BaseType)"); + static_assert(std::is_trivially_destructible::value, "std::is_trivially_destructible::value"); + + namespace result::impl { + + class ResultConstructor { + public: + static constexpr inline Result MakeResult(ResultTraits::BaseType value) { + return Result(value); + } + }; + + constexpr inline Result MakeResult(ResultTraits::BaseType value) { + return ResultConstructor::MakeResult(value); + } + + } + + class ResultSuccess final : public result::impl::ResultBase { + public: + using Base = typename result::impl::ResultBase; + public: + constexpr operator Result() const { return result::impl::MakeResult(Base::SuccessValue); } + NX_CONSTEXPR bool CanAccept(Result result) { return result.IsSuccess(); } + + constexpr inline bool IsSuccess() const { return true; } + constexpr inline bool IsFailure() const { return !this->IsSuccess(); } + constexpr inline typename Base::BaseType GetModule() const { return Base::GetModule(); } + constexpr inline typename Base::BaseType GetDescription() const { return Base::GetDescription(); } + + constexpr inline typename Base::BaseType GetValue() const { return Base::SuccessValue; } + }; + + namespace result::impl { + + NORETURN void OnResultAssertion(Result result); + + } + + constexpr inline Result::operator ResultSuccess() const { + if (!ResultSuccess::CanAccept(*this)) { + result::impl::OnResultAssertion(*this); + } + return ResultSuccess(); + } + + namespace result::impl { + + template + class ResultErrorBase : public ResultBase> { + public: + using Base = typename result::impl::ResultBase>; + static constexpr typename Base::BaseType Module = _Module; + static constexpr typename Base::BaseType Description = _Description; + static constexpr typename Base::BaseType Value = ResultTraits::MakeStaticValue::value; + static_assert(Value != Base::SuccessValue, "Value != Base::SuccessValue"); + public: + constexpr operator Result() const { return MakeResult(Value); } + constexpr operator ResultSuccess() const { OnResultAssertion(Value); } + + constexpr inline bool IsSuccess() const { return false; } + constexpr inline bool IsFailure() const { return !this->IsSuccess(); } + + constexpr inline typename Base::BaseType GetValue() const { return Value; } + }; + + template + class ResultErrorRangeBase { + public: + static constexpr ResultTraits::BaseType Module = _Module; + static constexpr ResultTraits::BaseType DescriptionStart = DescStart; + static constexpr ResultTraits::BaseType DescriptionEnd = DescEnd; + static_assert(DescriptionStart <= DescriptionEnd, "DescriptionStart <= DescriptionEnd"); + static constexpr typename ResultTraits::BaseType StartValue = ResultTraits::MakeStaticValue::value; + static constexpr typename ResultTraits::BaseType EndValue = ResultTraits::MakeStaticValue::value; + public: + NX_CONSTEXPR bool Includes(Result result) { + return StartValue <= result.GetValue() && result.GetValue() <= EndValue; + } + }; + + } + +} + +/* Macros for defining new results. */ +#define R_DEFINE_NAMESPACE_RESULT_MODULE(value) namespace impl::result { static constexpr inline ::sts::result::impl::ResultTraits::BaseType ResultModuleId = value; } +#define R_CURRENT_NAMESPACE_RESULT_MODULE impl::result::ResultModuleId +#define R_NAMESPACE_MODULE_ID(nmspc) nmspc::R_CURRENT_NAMESPACE_RESULT_MODULE + +#define R_MAKE_NAMESPACE_RESULT(nmspc, desc) static_cast<::sts::Result>(::sts::result::impl::ResultTraits::MakeValue(R_NAMESPACE_MODULE_ID(nmspc), desc)) + +#define R_DEFINE_ERROR_RESULT_IMPL(name, desc_start, desc_end) \ + class Result##name final : public ::sts::result::impl::ResultErrorBase, public ::sts::result::impl::ResultErrorRangeBase {} + +#define R_DEFINE_ABSTRACT_ERROR_RESULT_IMPL(name, desc_start, desc_end) \ + class Result##name final : public ::sts::result::impl::ResultErrorRangeBase {} + + +#define R_DEFINE_ERROR_RESULT(name, desc) R_DEFINE_ERROR_RESULT_IMPL(name, desc, desc) +#define R_DEFINE_ERROR_RANGE(name, start, end) R_DEFINE_ERROR_RESULT_IMPL(name, start, end) + +#define R_DEFINE_ABSTRACT_ERROR_RESULT(name, desc) R_DEFINE_ABSTRACT_ERROR_RESULT_IMPL(name, desc, desc) +#define R_DEFINE_ABSTRACT_ERROR_RANGE(name, start, end) R_DEFINE_ABSTRACT_ERROR_RESULT_IMPL(name, start, end) + +/* Remove libnx macros, replace with our own. */ +#ifndef R_SUCCEEDED +#error "R_SUCCEEDED not defined." +#endif + +#undef R_SUCCEEDED + +#ifndef R_FAILED +#error "R_FAILED not defined" +#endif + +#undef R_FAILED + +#define R_SUCCEEDED(res) (static_cast<::sts::Result>(res).IsSuccess()) +#define R_FAILED(res) (static_cast<::sts::Result>(res).IsFailure()) + + +/// Evaluates an expression that returns a result, and returns the result if it would fail. +#define R_TRY(res_expr) \ + ({ \ + const auto _tmp_r_try_rc = res_expr; \ + if (R_FAILED(_tmp_r_try_rc)) { \ + return _tmp_r_try_rc; \ + } \ + }) + +/// Evaluates an expression that returns a result, and fatals the result if it would fail. +#define R_ASSERT(res_expr) \ + ({ \ + const auto _tmp_r_assert_rc = res_expr; \ + if (R_FAILED(_tmp_r_assert_rc)) { \ + ::sts::result::impl::OnResultAssertion(_tmp_r_assert_rc); \ + } \ + }) + +/// Evaluates a boolean expression, and returns a result unless that expression is true. +#define R_UNLESS(expr, res) \ + ({ \ + if (!(expr)) { \ + return static_cast<::sts::Result>(res); \ + } \ + }) + +/// Helpers for pattern-matching on a result expression, if the result would fail. +#define R_CURRENT_RESULT _tmp_r_current_result + +#define R_TRY_CATCH(res_expr) \ + ({ \ + const auto R_CURRENT_RESULT = res_expr; \ + if (R_FAILED(R_CURRENT_RESULT)) { \ + if (false) + +namespace sts::result::impl { + + template + NX_CONSTEXPR bool AnyIncludes(Result result) { + return (Rs::Includes(result) || ...); + } + +} + +#define R_CATCH(...) \ + } else if (::sts::result::impl::AnyIncludes<__VA_ARGS__>(R_CURRENT_RESULT)) { \ + if (true) + +#define R_CONVERT(catch_type, convert_type) \ + R_CATCH(catch_type) { return static_cast<::sts::Result>(convert_type); } + +#define R_CATCH_ALL() \ + } else if (R_FAILED(R_CURRENT_RESULT)) { \ + if (true) + +#define R_CONVERT_ALL(convert_type) \ + R_CATCH_ALL() { return static_cast<::sts::Result>(convert_type); } + +#define R_END_TRY_CATCH \ + else if (R_FAILED(R_CURRENT_RESULT)) { \ + return R_CURRENT_RESULT; \ + } \ + } \ + }) + +#define R_END_TRY_CATCH_WITH_ASSERT \ + else { \ + R_ASSERT(R_CURRENT_RESULT); \ + } \ + } \ + }) diff --git a/stratosphere/libstratosphere/include/stratosphere/results/ro_results.hpp b/stratosphere/libstratosphere/include/stratosphere/results/ro_results.hpp index f5ed217e9..a83a809f0 100644 --- a/stratosphere/libstratosphere/include/stratosphere/results/ro_results.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/results/ro_results.hpp @@ -15,26 +15,31 @@ */ #pragma once -#include +#include "results_common.hpp" -static constexpr u32 Module_Ro = 22; +namespace sts::ro { -static constexpr Result ResultRoInsufficientAddressSpace = MAKERESULT(Module_Ro, 2); -static constexpr Result ResultRoAlreadyLoaded = MAKERESULT(Module_Ro, 3); -static constexpr Result ResultRoInvalidNro = MAKERESULT(Module_Ro, 4); + R_DEFINE_NAMESPACE_RESULT_MODULE(22); -static constexpr Result ResultRoInvalidNrr = MAKERESULT(Module_Ro, 6); -static constexpr Result ResultRoTooManyNro = MAKERESULT(Module_Ro, 7); -static constexpr Result ResultRoTooManyNrr = MAKERESULT(Module_Ro, 8); -static constexpr Result ResultRoNotAuthorized = MAKERESULT(Module_Ro, 9); -static constexpr Result ResultRoInvalidNrrType = MAKERESULT(Module_Ro, 10); + R_DEFINE_ERROR_RANGE(RoError, 1, 1023); + R_DEFINE_ERROR_RESULT(OutOfAddressSpace, 2); + R_DEFINE_ERROR_RESULT(AlreadyLoaded, 3); + R_DEFINE_ERROR_RESULT(InvalidNro, 4); -static constexpr Result ResultRoInternalError = MAKERESULT(Module_Ro, 1023); + R_DEFINE_ERROR_RESULT(InvalidNrr, 6); + R_DEFINE_ERROR_RESULT(TooManyNro, 7); + R_DEFINE_ERROR_RESULT(TooManyNrr, 8); + R_DEFINE_ERROR_RESULT(NotAuthorized, 9); + R_DEFINE_ERROR_RESULT(InvalidNrrType, 10); -static constexpr Result ResultRoInvalidAddress = MAKERESULT(Module_Ro, 1025); -static constexpr Result ResultRoInvalidSize = MAKERESULT(Module_Ro, 1026); + R_DEFINE_ERROR_RESULT(InternalError, 1023); -static constexpr Result ResultRoNotLoaded = MAKERESULT(Module_Ro, 1028); -static constexpr Result ResultRoNotRegistered = MAKERESULT(Module_Ro, 1029); -static constexpr Result ResultRoInvalidSession = MAKERESULT(Module_Ro, 1030); -static constexpr Result ResultRoInvalidProcess = MAKERESULT(Module_Ro, 1031); + R_DEFINE_ERROR_RESULT(InvalidAddress, 1025); + R_DEFINE_ERROR_RESULT(InvalidSize, 1026); + + R_DEFINE_ERROR_RESULT(NotLoaded, 1028); + R_DEFINE_ERROR_RESULT(NotRegistered, 1029); + R_DEFINE_ERROR_RESULT(InvalidSession, 1030); + R_DEFINE_ERROR_RESULT(InvalidProcess, 1031); + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/results/settings_results.hpp b/stratosphere/libstratosphere/include/stratosphere/results/settings_results.hpp index c153169ce..a72325103 100644 --- a/stratosphere/libstratosphere/include/stratosphere/results/settings_results.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/results/settings_results.hpp @@ -15,27 +15,33 @@ */ #pragma once -#include +#include "results_common.hpp" -static constexpr u32 Module_Settings = 105; +namespace sts::settings { -static constexpr Result ResultSettingsItemNotFound = MAKERESULT(Module_Settings, 11); + R_DEFINE_NAMESPACE_RESULT_MODULE(105); -static constexpr Result ResultSettingsItemKeyAllocationFailed = MAKERESULT(Module_Settings, 101); -static constexpr Result ResultSettingsItemValueAllocationFailed = MAKERESULT(Module_Settings, 102); + R_DEFINE_ERROR_RESULT(ItemNotFound, 11); -static constexpr Result ResultSettingsItemNameNull = MAKERESULT(Module_Settings, 201); -static constexpr Result ResultSettingsItemKeyNull = MAKERESULT(Module_Settings, 202); -static constexpr Result ResultSettingsItemValueNull = MAKERESULT(Module_Settings, 203); -static constexpr Result ResultSettingsItemKeyBufferNull = MAKERESULT(Module_Settings, 204); -static constexpr Result ResultSettingsItemValueBufferNull = MAKERESULT(Module_Settings, 205); + R_DEFINE_ERROR_RANGE(InternalError, 100, 149); + R_DEFINE_ERROR_RESULT(ItemKeyAllocationFailed, 101); + R_DEFINE_ERROR_RESULT(ItemValueAllocationFailed, 102); -static constexpr Result ResultSettingsItemNameEmpty = MAKERESULT(Module_Settings, 221); -static constexpr Result ResultSettingsItemKeyEmpty = MAKERESULT(Module_Settings, 222); + R_DEFINE_ERROR_RANGE(InvalidArgument, 200, 399); + R_DEFINE_ERROR_RESULT(SettingsNameNull, 201); + R_DEFINE_ERROR_RESULT(SettingsItemKeyNull, 202); + R_DEFINE_ERROR_RESULT(SettingsItemValueNull, 203); + R_DEFINE_ERROR_RESULT(SettingsItemKeyBufferNull, 204); + R_DEFINE_ERROR_RESULT(SettingsItemValueBufferNull, 205); -static constexpr Result ResultSettingsItemNameTooLong = MAKERESULT(Module_Settings, 241); -static constexpr Result ResultSettingsItemKeyTooLong = MAKERESULT(Module_Settings, 242); + R_DEFINE_ERROR_RESULT(SettingsNameEmpty, 221); + R_DEFINE_ERROR_RESULT(SettingsItemKeyEmpty, 222); -static constexpr Result ResultSettingsItemNameInvalidFormat = MAKERESULT(Module_Settings, 261); -static constexpr Result ResultSettingsItemKeyInvalidFormat = MAKERESULT(Module_Settings, 262); -static constexpr Result ResultSettingsItemValueInvalidFormat = MAKERESULT(Module_Settings, 263); + R_DEFINE_ERROR_RESULT(SettingsNameTooLong, 241); + R_DEFINE_ERROR_RESULT(SettingsItemKeyTooLong, 242); + + R_DEFINE_ERROR_RESULT(SettingsNameInvalidFormat, 261); + R_DEFINE_ERROR_RESULT(SettingsItemKeyInvalidFormat, 262); + R_DEFINE_ERROR_RESULT(SettingsItemValueInvalidFormat, 263); + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/results/sf_results.hpp b/stratosphere/libstratosphere/include/stratosphere/results/sf_results.hpp index fc0810c43..ceb635bcb 100644 --- a/stratosphere/libstratosphere/include/stratosphere/results/sf_results.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/results/sf_results.hpp @@ -15,25 +15,40 @@ */ #pragma once -#include +#include "results_common.hpp" -static constexpr u32 Module_ServiceFramework = 10; +namespace sts::sf { -static constexpr Result ResultServiceFrameworkNotSupported = MAKERESULT(Module_ServiceFramework, 1); -static constexpr Result ResultServiceFrameworkPreconditionViolation = MAKERESULT(Module_ServiceFramework, 3); + R_DEFINE_NAMESPACE_RESULT_MODULE(10); -static constexpr Result ResultServiceFrameworkInvalidCmifHeaderSize = MAKERESULT(Module_ServiceFramework, 202); -static constexpr Result ResultServiceFrameworkInvalidCmifInHeader = MAKERESULT(Module_ServiceFramework, 211); -static constexpr Result ResultServiceFrameworkUnknownCmifCommandId = MAKERESULT(Module_ServiceFramework, 221); -static constexpr Result ResultServiceFrameworkInvalidCmifOutRawSize = MAKERESULT(Module_ServiceFramework, 232); -static constexpr Result ResultServiceFrameworkInvalidCmifNumInObjects = MAKERESULT(Module_ServiceFramework, 235); -static constexpr Result ResultServiceFrameworkInvalidCmifNumOutObjects = MAKERESULT(Module_ServiceFramework, 236); -static constexpr Result ResultServiceFrameworkInvalidCmifInObject = MAKERESULT(Module_ServiceFramework, 239); + R_DEFINE_ERROR_RESULT(NotSupported, 1); + R_DEFINE_ERROR_RESULT(PreconditionViolation, 3); -static constexpr Result ResultServiceFrameworkTargetNotFound = MAKERESULT(Module_ServiceFramework, 261); + namespace cmif { -static constexpr Result ResultServiceFrameworkOutOfDomainEntries = MAKERESULT(Module_ServiceFramework, 301); + R_DEFINE_ERROR_RESULT(InvalidHeaderSize, 202); + R_DEFINE_ERROR_RESULT(InvalidInHeader, 211); + R_DEFINE_ERROR_RESULT(UnknownCommandId, 221); + R_DEFINE_ERROR_RESULT(InvalidOutRawSize, 232); + R_DEFINE_ERROR_RESULT(InvalidNumInObjects, 235); + R_DEFINE_ERROR_RESULT(InvalidNumOutObjects, 236); + R_DEFINE_ERROR_RESULT(InvalidInObject, 239); + R_DEFINE_ERROR_RESULT(TargetNotFound, 261); -static constexpr Result ResultServiceFrameworkRequestDeferred = MAKERESULT(Module_ServiceFramework, 811); -static constexpr Result ResultServiceFrameworkRequestDeferredByUser = MAKERESULT(Module_ServiceFramework, 812); + R_DEFINE_ERROR_RESULT(OutOfDomainEntries, 301); + + } + + namespace impl { + + R_DEFINE_ABSTRACT_ERROR_RANGE(RequestContextChanged, 800, 899); + R_DEFINE_ABSTRACT_ERROR_RANGE(RequestInvalidated, 801, 809); + R_DEFINE_ERROR_RESULT(RequestInvalidatedByUser, 802); + + } + + R_DEFINE_ABSTRACT_ERROR_RANGE(RequestDeferred, 811, 819); + R_DEFINE_ERROR_RESULT(RequestDeferredByUser, 812); + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/results/sm_results.hpp b/stratosphere/libstratosphere/include/stratosphere/results/sm_results.hpp index 41d99cc17..0a66c81c6 100644 --- a/stratosphere/libstratosphere/include/stratosphere/results/sm_results.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/results/sm_results.hpp @@ -15,16 +15,20 @@ */ #pragma once -#include +#include "results_common.hpp" -static constexpr u32 Module_Sm = 21; +namespace sts::sm { -static constexpr Result ResultSmInsufficientProcesses = MAKERESULT(Module_Sm, 1); -static constexpr Result ResultSmInvalidClient = MAKERESULT(Module_Sm, 2); -static constexpr Result ResultSmInsufficientSessions = MAKERESULT(Module_Sm, 3); -static constexpr Result ResultSmAlreadyRegistered = MAKERESULT(Module_Sm, 4); -static constexpr Result ResultSmInsufficientServices = MAKERESULT(Module_Sm, 5); -static constexpr Result ResultSmInvalidServiceName = MAKERESULT(Module_Sm, 6); -static constexpr Result ResultSmNotRegistered = MAKERESULT(Module_Sm, 7); -static constexpr Result ResultSmNotAllowed = MAKERESULT(Module_Sm, 8); -static constexpr Result ResultSmTooLargeAccessControl = MAKERESULT(Module_Sm, 9); + R_DEFINE_NAMESPACE_RESULT_MODULE(21); + + R_DEFINE_ERROR_RESULT(OutOfProcesses, 1); + R_DEFINE_ERROR_RESULT(InvalidClient, 2); + R_DEFINE_ERROR_RESULT(OutOfSessions, 3); + R_DEFINE_ERROR_RESULT(AlreadyRegistered, 4); + R_DEFINE_ERROR_RESULT(OutOfServices, 5); + R_DEFINE_ERROR_RESULT(InvalidServiceName, 6); + R_DEFINE_ERROR_RESULT(NotRegistered, 7); + R_DEFINE_ERROR_RESULT(NotAllowed, 8); + R_DEFINE_ERROR_RESULT(TooLargeAccessControl, 9); + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/results/spl_results.hpp b/stratosphere/libstratosphere/include/stratosphere/results/spl_results.hpp index 002c07d53..c54c3671d 100644 --- a/stratosphere/libstratosphere/include/stratosphere/results/spl_results.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/results/spl_results.hpp @@ -15,25 +15,28 @@ */ #pragma once -#include +#include "results_common.hpp" -static constexpr u32 Module_Spl = 26; +namespace sts::spl { -/* Results 1-99 are converted smc results. */ -static constexpr Result ResultSplSmcNotImplemented = MAKERESULT(Module_Spl, 1); -static constexpr Result ResultSplSmcInvalidArgument = MAKERESULT(Module_Spl, 2); -static constexpr Result ResultSplSmcInProgress = MAKERESULT(Module_Spl, 3); -static constexpr Result ResultSplSmcNoAsyncOperation = MAKERESULT(Module_Spl, 4); -static constexpr Result ResultSplSmcInvalidAsyncOperation = MAKERESULT(Module_Spl, 5); -static constexpr Result ResultSplSmcBlacklisted = MAKERESULT(Module_Spl, 6); + R_DEFINE_NAMESPACE_RESULT_MODULE(26); -/* Results 100+ are spl results. */ -static constexpr Result ResultSplInvalidSize = MAKERESULT(Module_Spl, 100); -static constexpr Result ResultSplUnknownSmcResult = MAKERESULT(Module_Spl, 101); -static constexpr Result ResultSplDecryptionFailed = MAKERESULT(Module_Spl, 102); + R_DEFINE_ERROR_RANGE(SecureMonitorError, 0, 99); + R_DEFINE_ERROR_RESULT(SecureMonitorNotImplemented, 1); + R_DEFINE_ERROR_RESULT(SecureMonitorInvalidArgument, 2); + R_DEFINE_ERROR_RESULT(SecureMonitorBusy, 3); + R_DEFINE_ERROR_RESULT(SecureMonitorNoAsyncOperation, 4); + R_DEFINE_ERROR_RESULT(SecureMonitorInvalidAsyncOperation, 5); + R_DEFINE_ERROR_RESULT(SecureMonitorNotPermitted, 6); -static constexpr Result ResultSplOutOfKeyslots = MAKERESULT(Module_Spl, 104); -static constexpr Result ResultSplInvalidKeyslot = MAKERESULT(Module_Spl, 105); -static constexpr Result ResultSplBootReasonAlreadySet = MAKERESULT(Module_Spl, 106); -static constexpr Result ResultSplBootReasonNotSet = MAKERESULT(Module_Spl, 107); -static constexpr Result ResultSplInvalidArgument = MAKERESULT(Module_Spl, 108); + R_DEFINE_ERROR_RESULT(InvalidSize, 100); + R_DEFINE_ERROR_RESULT(UnknownSecureMonitorError, 101); + R_DEFINE_ERROR_RESULT(DecryptionFailed, 102); + + R_DEFINE_ERROR_RESULT(OutOfKeyslots, 104); + R_DEFINE_ERROR_RESULT(InvalidKeyslot, 105); + R_DEFINE_ERROR_RESULT(BootReasonAlreadySet, 106); + R_DEFINE_ERROR_RESULT(BootReasonNotSet, 107); + R_DEFINE_ERROR_RESULT(InvalidArgument, 108); + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/results/svc_results.hpp b/stratosphere/libstratosphere/include/stratosphere/results/svc_results.hpp new file mode 100644 index 000000000..29acd1aa6 --- /dev/null +++ b/stratosphere/libstratosphere/include/stratosphere/results/svc_results.hpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include "results_common.hpp" + +namespace sts::svc { + + R_DEFINE_NAMESPACE_RESULT_MODULE(1); + + R_DEFINE_ERROR_RESULT(OutOfSessions, 7); + + R_DEFINE_ERROR_RESULT(InvalidArgument, 14); + + R_DEFINE_ERROR_RESULT(NotImplemented, 33); + + R_DEFINE_ERROR_RESULT(ThreadTerminating, 59); + + R_DEFINE_ERROR_RESULT(NoEvent, 70); + + R_DEFINE_ERROR_RESULT(InvalidSize, 101); + R_DEFINE_ERROR_RESULT(InvalidAddress, 102); + R_DEFINE_ERROR_RESULT(OutOfResource, 103); + R_DEFINE_ERROR_RESULT(OutOfMemory, 104); + R_DEFINE_ERROR_RESULT(OutOfHandles, 105); + R_DEFINE_ERROR_RESULT(InvalidCurrentMemoryState, 106); + + R_DEFINE_ERROR_RESULT(InvalidNewMemoryPermissions, 108); + + R_DEFINE_ERROR_RESULT(InvalidMemoryRegion, 110); + + R_DEFINE_ERROR_RESULT(InvalidPriority, 112); + R_DEFINE_ERROR_RESULT(InvalidCoreId, 113); + R_DEFINE_ERROR_RESULT(InvalidHandle, 114); + R_DEFINE_ERROR_RESULT(InvalidPointer, 115); + R_DEFINE_ERROR_RESULT(InvalidCombination, 116); + R_DEFINE_ERROR_RESULT(TimedOut, 117); + R_DEFINE_ERROR_RESULT(Cancelled, 118); + R_DEFINE_ERROR_RESULT(OutOfRange, 119); + R_DEFINE_ERROR_RESULT(InvalidEnumValue, 120); + R_DEFINE_ERROR_RESULT(NotFound, 121); + R_DEFINE_ERROR_RESULT(Busy, 122); + R_DEFINE_ERROR_RESULT(SessionClosed, 123); + R_DEFINE_ERROR_RESULT(NotHandled, 124); + R_DEFINE_ERROR_RESULT(InvalidState, 125); + R_DEFINE_ERROR_RESULT(ReservedValue, 126); + R_DEFINE_ERROR_RESULT(NotSupported, 127); + R_DEFINE_ERROR_RESULT(Debug, 128); + R_DEFINE_ERROR_RESULT(ThreadNotOwned, 129); + + R_DEFINE_ERROR_RESULT(PortClosed, 131); + R_DEFINE_ERROR_RESULT(LimitReached, 132); + + R_DEFINE_ERROR_RESULT(ReceiveListBroken, 258); + R_DEFINE_ERROR_RESULT(OutOfAddressSpace, 259); + R_DEFINE_ERROR_RESULT(MessageTooLarge, 260); + + R_DEFINE_ERROR_RESULT(ProcessTerminated, 520); + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/results/updater_results.hpp b/stratosphere/libstratosphere/include/stratosphere/results/updater_results.hpp index 24717acbf..160284412 100644 --- a/stratosphere/libstratosphere/include/stratosphere/results/updater_results.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/results/updater_results.hpp @@ -15,12 +15,16 @@ */ #pragma once -#include +#include "results_common.hpp" -static constexpr u32 Module_Updater = 158; +namespace sts::updater { -static constexpr Result ResultUpdaterBootImagePackageNotFound = MAKERESULT(Module_Updater, 2); -static constexpr Result ResultUpdaterInvalidBootImagePackage = MAKERESULT(Module_Updater, 3); -static constexpr Result ResultUpdaterTooSmallWorkBuffer = MAKERESULT(Module_Updater, 4); -static constexpr Result ResultUpdaterMisalignedWorkBuffer = MAKERESULT(Module_Updater, 5); -static constexpr Result ResultUpdaterNeedsRepairBootImages = MAKERESULT(Module_Updater, 6); + R_DEFINE_NAMESPACE_RESULT_MODULE(158); + + R_DEFINE_ERROR_RESULT(BootImagePackageNotFound, 2); + R_DEFINE_ERROR_RESULT(InvalidBootImagePackage, 3); + R_DEFINE_ERROR_RESULT(TooSmallWorkBuffer, 4); + R_DEFINE_ERROR_RESULT(NotAlignedWorkBuffer, 5); + R_DEFINE_ERROR_RESULT(NeedsRepairBootImages, 6); + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/results/utilities.h b/stratosphere/libstratosphere/include/stratosphere/results/utilities.h deleted file mode 100644 index 7768d4860..000000000 --- a/stratosphere/libstratosphere/include/stratosphere/results/utilities.h +++ /dev/null @@ -1,132 +0,0 @@ -/** - * @file result_utilities.h - * @brief Utilities for handling Results. - * @author SciresM - * @copyright libnx Authors - */ -#pragma once -#include - -#ifdef __cplusplus -#include -extern "C" { -#endif - -/// Evaluates an expression that returns a result, and returns the result if it would fail. -#define R_TRY(res_expr) \ - ({ \ - const Result _tmp_r_try_rc = res_expr; \ - if (R_FAILED(_tmp_r_try_rc)) { \ - return _tmp_r_try_rc; \ - } \ - }) - -/// Evaluates an expression that returns a result, and fatals the result if it would fail. -#ifdef RESULT_ABORT_ON_ASSERT -#define R_ASSERT_IMPL(res) std::abort() -#else -#define R_ASSERT_IMPL(res) fatalSimple(res) -#endif - -/// Evaluates a boolean expression, and returns a result unless that expression is true. -#define R_UNLESS(expr, res) \ - ({ \ - if (!(expr)) { \ - return static_cast(res); \ - } \ - }) - -#define R_ASSERT(res_expr) \ - ({ \ - const Result _tmp_r_assert_rc = res_expr; \ - if (R_FAILED(_tmp_r_assert_rc)) { \ - R_ASSERT_IMPL(_tmp_r_assert_rc); \ - } \ - }) - -/// Helpers for pattern-matching on a result expression, if the result would fail. -#define R_TRY_CATCH_RESULT _tmp_r_try_catch_rc - -#define R_TRY_CATCH(res_expr) \ - ({ \ - const Result R_TRY_CATCH_RESULT = res_expr; \ - if (R_FAILED(R_TRY_CATCH_RESULT)) { \ - if (false) - -#define R_CATCH(catch_result) \ - } else if (R_TRY_CATCH_RESULT == catch_result) { \ - _Static_assert(R_FAILED(catch_result), "Catch result must be constexpr error Result!"); \ - if (false) { } \ - else - -#define R_GET_CATCH_RANGE_IMPL(_1, _2, NAME, ...) NAME - -#define R_CATCH_RANGE_IMPL_2(catch_result_start, catch_result_end) \ - } else if (catch_result_start <= R_TRY_CATCH_RESULT && R_TRY_CATCH_RESULT <= catch_result_end) { \ - _Static_assert(R_FAILED(catch_result_start), "Catch start result must be constexpr error Result!"); \ - _Static_assert(R_FAILED(catch_result_end), "Catch end result must be constexpr error Result!"); \ - _Static_assert(R_MODULE(catch_result_start) == R_MODULE(catch_result_end), "Catch range modules must be equal!"); \ - if (false) { } \ - else - -#define R_CATCH_RANGE_IMPL_1(catch_result) R_CATCH_RANGE_IMPL_2(catch_result##RangeStart, catch_result##RangeEnd) - -#define R_CATCH_RANGE(...) R_GET_CATCH_RANGE_IMPL(__VA_ARGS__, R_CATCH_RANGE_IMPL_2, R_CATCH_RANGE_IMPL_1)(__VA_ARGS__) - -#define R_CATCH_MODULE(module) \ - } else if (R_MODULE(R_TRY_CATCH_RESULT) == module) { \ - _Static_assert(module != 0, "Catch module must be error!"); \ - if (false) { } \ - else - -#define R_CATCH_ALL() \ - } else if (R_FAILED(R_TRY_CATCH_RESULT)) { \ - if (false) { } \ - else - -#define R_END_TRY_CATCH \ - else if (R_FAILED(R_TRY_CATCH_RESULT)) { \ - return R_TRY_CATCH_RESULT; \ - } \ - } \ - }) - -#define R_END_TRY_CATCH_WITH_ASSERT \ - else { \ - R_ASSERT(R_TRY_CATCH_RESULT); \ - } \ - } \ - }) - - -/// Evaluates an expression that returns a result, and returns the result (after evaluating a cleanup expression) if it would fail. -#define R_CLEANUP_RESULT _tmp_r_try_cleanup_rc - -#define R_TRY_CLEANUP(res_expr, cleanup_expr) \ - ({ \ - const Result R_CLEANUP_RESULT = res_expr; \ - if (R_FAILED(R_CLEANUP_RESULT)) { \ - ({ cleanup_expr }); \ - return R_CLEANUP_RESULT; \ - } \ - }) - -#ifdef __cplusplus -} -#endif - -// For C++, also define R_CATCH_MANY helper. -#ifdef __cplusplus - -template -constexpr inline bool _CheckResultsForMultiTryCatch(const Result &rc) { - static_assert((R_FAILED(rs) && ...), "Multi try catch result must be constexpr error Result!"); - return ((rs == rc) || ...); -} - -#define R_CATCH_MANY(...) \ - } else if (_CheckResultsForMultiTryCatch<__VA_ARGS__>(_tmp_r_try_catch_rc)) { \ - if (false) { } \ - else - -#endif diff --git a/stratosphere/libstratosphere/include/stratosphere/results/vi_results.hpp b/stratosphere/libstratosphere/include/stratosphere/results/vi_results.hpp index 6449b3671..7c5e5c0c5 100644 --- a/stratosphere/libstratosphere/include/stratosphere/results/vi_results.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/results/vi_results.hpp @@ -15,10 +15,14 @@ */ #pragma once -#include +#include "results_common.hpp" -static constexpr u32 Module_Vi = 114; +namespace sts::vi { -static constexpr Result ResultViOperationFailed = MAKERESULT(Module_Vi, 1); -static constexpr Result ResultViNotSupported = MAKERESULT(Module_Vi, 6); -static constexpr Result ResultViNotFound = MAKERESULT(Module_Vi, 7); + R_DEFINE_NAMESPACE_RESULT_MODULE(114); + + R_DEFINE_ERROR_RESULT(OperationFailed, 1); + R_DEFINE_ERROR_RESULT(NotSupported, 6); + R_DEFINE_ERROR_RESULT(NotFound, 7); + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/sf/hipc/sf_hipc_server_manager.hpp b/stratosphere/libstratosphere/include/stratosphere/sf/hipc/sf_hipc_server_manager.hpp index c1b938453..fffeebc4d 100644 --- a/stratosphere/libstratosphere/include/stratosphere/sf/hipc/sf_hipc_server_manager.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/sf/hipc/sf_hipc_server_manager.hpp @@ -200,7 +200,7 @@ namespace sts::sf::hipc { static_holder = cmif::ServiceObjectHolder(std::move(static_object)); } this->RegisterServerImpl(port_handle, service_name, true, std::move(static_holder)); - return ResultSuccess; + return ResultSuccess(); } /* Processing. */ diff --git a/stratosphere/libstratosphere/include/stratosphere/sf/hipc/sf_hipc_server_session_manager.hpp b/stratosphere/libstratosphere/include/stratosphere/sf/hipc/sf_hipc_server_session_manager.hpp index 77e2c4f35..2cb74f602 100644 --- a/stratosphere/libstratosphere/include/stratosphere/sf/hipc/sf_hipc_server_session_manager.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/sf/hipc/sf_hipc_server_session_manager.hpp @@ -90,7 +90,7 @@ namespace sts::sf::hipc { Result CreateSessionImpl(ServerSession **out, const Constructor &ctor) { /* Allocate session. */ ServerSession *session_memory = this->AllocateSession(); - R_UNLESS(session_memory != nullptr, ResultHipcSessionAllocationFailure); + R_UNLESS(session_memory != nullptr, sf::hipc::ResultOutOfSessionMemory()); /* Register session. */ bool succeeded = false; ON_SCOPE_EXIT { @@ -102,7 +102,7 @@ namespace sts::sf::hipc { /* Save new session to output. */ succeeded = true; *out = session_memory; - return ResultSuccess; + return ResultSuccess(); } void DestroySession(ServerSession *session); diff --git a/stratosphere/libstratosphere/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp b/stratosphere/libstratosphere/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp index bba5d3545..e2cfc1a2f 100644 --- a/stratosphere/libstratosphere/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp @@ -52,14 +52,14 @@ namespace sts::sf { constexpr inline Result MarshalProcessId(ClientProcessId &client, const os::ProcessId &client_process_id) { client.SetValue(client_process_id); - return ResultSuccess; + return ResultSuccess(); } constexpr inline Result MarshalProcessId(ClientAppletResourceUserId &client, const os::ProcessId &client_process_id) { if (client.GetValue() != client_process_id && client.GetValue() != os::ProcessId{}) { - return ResultServiceFrameworkPreconditionViolation; + return sf::ResultPreconditionViolation(); } - return ResultSuccess; + return ResultSuccess(); } } @@ -167,6 +167,8 @@ namespace sts::sf::impl { return ArgumentType::OutData; } else if constexpr (std::is_trivial::value && !std::is_pointer::value) { return ArgumentType::InData; + } else if constexpr (std::is_same::value) { + return ArgumentType::InData; } else { static_assert(!std::is_same::value, "Invalid ArgumentType"); } @@ -675,7 +677,7 @@ namespace sts::sf::impl { if constexpr (NumInObjects > 0) { R_TRY(processor->GetInObjects(this->in_object_holders.data())); } - return ResultSuccess; + return ResultSuccess(); } template @@ -685,7 +687,7 @@ namespace sts::sf::impl { if constexpr (NumInObjects > n) { \ using SharedPtrToServiceImplType = typename std::tuple_element::type; \ using ServiceImplType = typename SharedPtrToServiceImplType::element_type; \ - R_UNLESS((this->in_object_holders[n].template IsServiceObjectValid()), ResultServiceFrameworkInvalidCmifInObject); \ + R_UNLESS((this->in_object_holders[n].template IsServiceObjectValid()), sf::cmif::ResultInvalidInObject()); \ } \ } while (0) _SF_IN_OUT_HOLDER_VALIDATE_IN_OBJECT(0); @@ -696,7 +698,8 @@ namespace sts::sf::impl { _SF_IN_OUT_HOLDER_VALIDATE_IN_OBJECT(5); _SF_IN_OUT_HOLDER_VALIDATE_IN_OBJECT(6); _SF_IN_OUT_HOLDER_VALIDATE_IN_OBJECT(7); - return ResultSuccess; + #undef _SF_IN_OUT_HOLDER_VALIDATE_IN_OBJECT + return ResultSuccess(); } template @@ -740,8 +743,8 @@ namespace sts::sf::impl { const size_t command_raw_size = util::AlignUp(runtime_metadata.GetUnfixedOutPointerSizeOffset() + (CommandMeta::NumUnfixedSizeOutHipcPointerBuffers * sizeof(u16)), alignof(u32)); is_request_valid &= meta_raw_size >= command_raw_size; - R_UNLESS(is_request_valid, ResultHipcInvalidRequest); - return ResultSuccess; + R_UNLESS(is_request_valid, sf::hipc::ResultInvalidCmifRequest()); + return ResultSuccess(); } virtual HipcRequest PrepareForReply(const cmif::ServiceDispatchContext &ctx, cmif::PointerAndSize &out_raw_data, const cmif::ServerMessageRuntimeMetadata runtime_metadata) override final { @@ -768,7 +771,7 @@ namespace sts::sf::impl { virtual Result GetInObjects(cmif::ServiceObjectHolder *in_objects) const override final { /* By default, InObjects aren't supported. */ - return ResultServiceFrameworkNotSupported; + return sf::ResultNotSupported(); } virtual void SetOutObjects(const cmif::ServiceDispatchContext &ctx, const HipcRequest &response, cmif::ServiceObjectHolder *out_objects, cmif::DomainObjectId *ids) override final { @@ -949,11 +952,11 @@ namespace sts::sf::impl { _SF_IMPL_PROCESSOR_PROCESS_BUFFER_IMPL(6); _SF_IMPL_PROCESSOR_PROCESS_BUFFER_IMPL(7); #undef _SF_IMPL_PROCESSOR_PROCESS_BUFFER_IMPL - R_UNLESS(map_alias_buffers_valid, ResultHipcInvalidRequest); + R_UNLESS(map_alias_buffers_valid, sf::hipc::ResultInvalidCmifRequest()); if constexpr (CommandMeta::NumOutHipcPointerBuffers > 0) { - R_UNLESS(pointer_buffer_tail <= pointer_buffer_head, ResultHipcPointerBufferTooSmall); + R_UNLESS(pointer_buffer_tail <= pointer_buffer_head, sf::hipc::ResultPointerBufferTooSmall()); } - return ResultSuccess; + return ResultSuccess(); } NX_CONSTEXPR void SetOutBuffers(const HipcRequest &response, const BufferArrayType &buffers, const std::array &is_buffer_map_alias) { @@ -1045,10 +1048,10 @@ namespace sts::sf::impl { constexpr Result GetCmifOutHeaderPointer(CmifOutHeader **out_header_ptr, cmif::PointerAndSize &out_raw_data) { CmifOutHeader *header = reinterpret_cast(out_raw_data.GetPointer()); - R_UNLESS(out_raw_data.GetSize() >= sizeof(*header), ResultServiceFrameworkInvalidCmifHeaderSize); + R_UNLESS(out_raw_data.GetSize() >= sizeof(*header), sf::cmif::ResultInvalidHeaderSize()); out_raw_data = cmif::PointerAndSize(out_raw_data.GetAddress() + sizeof(*header), out_raw_data.GetSize() - sizeof(*header)); *out_header_ptr = header; - return ResultSuccess; + return ResultSuccess(); } template @@ -1101,11 +1104,13 @@ namespace sts::sf::impl { } if constexpr (CommandMeta::ReturnsResult) { - R_TRY_CLEANUP(std::apply([=](auto&&... args) { return (this_ptr->*ServiceCommandImpl)(args...); }, args_tuple), { + const auto command_result = std::apply([=](auto&&... args) { return (this_ptr->*ServiceCommandImpl)(args...); }, args_tuple); + if (R_FAILED(command_result)) { cmif::PointerAndSize out_raw_data; ctx.processor->PrepareForErrorReply(ctx, out_raw_data, runtime_metadata); R_TRY(GetCmifOutHeaderPointer(out_header_ptr, out_raw_data)); - }); + return command_result; + } } else { std::apply([=](auto&&... args) { (this_ptr->*ServiceCommandImpl)(args...); }, args_tuple); } @@ -1117,7 +1122,7 @@ namespace sts::sf::impl { R_TRY(GetCmifOutHeaderPointer(out_header_ptr, out_raw_data)); /* Copy raw data output struct. */ - R_UNLESS(out_raw_data.GetSize() >= OutRawHolderType::Size, ResultServiceFrameworkInvalidCmifOutRawSize); + R_UNLESS(out_raw_data.GetSize() >= OutRawHolderType::Size, sf::cmif::ResultInvalidOutRawSize()); out_raw_holder.CopyTo(out_raw_data.GetPointer()); /* Set output recvlist buffers. */ @@ -1129,7 +1134,7 @@ namespace sts::sf::impl { /* Set output objects. */ in_out_objects_holder.SetOutObjects(ctx, response); - return ResultSuccess; + return ResultSuccess(); } } diff --git a/stratosphere/libstratosphere/include/stratosphere/sf/sf_out.hpp b/stratosphere/libstratosphere/include/stratosphere/sf/sf_out.hpp index 89f976c45..ea6877f4c 100644 --- a/stratosphere/libstratosphere/include/stratosphere/sf/sf_out.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/sf/sf_out.hpp @@ -29,6 +29,9 @@ namespace sts::sf { template struct IsOutForceEnabled : public std::false_type{}; + template<> + struct IsOutForceEnabled<::sts::Result> : public std::true_type{}; + template using IsOutEnabled = typename std::enable_if::value || IsOutForceEnabled::value>::type; diff --git a/stratosphere/libstratosphere/include/stratosphere/sm/sm_scoped_holder.hpp b/stratosphere/libstratosphere/include/stratosphere/sm/sm_scoped_holder.hpp index a7ffb724e..ae416dd8c 100644 --- a/stratosphere/libstratosphere/include/stratosphere/sm/sm_scoped_holder.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/sm/sm_scoped_holder.hpp @@ -21,14 +21,14 @@ namespace sts::sm { /* Utility, for scoped access to libnx services. */ - template + template class ScopedServiceHolder { NON_COPYABLE(ScopedServiceHolder); private: Result result; bool has_initialized; public: - ScopedServiceHolder(bool initialize = true) : result(ResultSuccess), has_initialized(false) { + ScopedServiceHolder(bool initialize = true) : result(ResultSuccess()), has_initialized(false) { if (initialize) { this->Initialize(); } @@ -43,7 +43,7 @@ namespace sts::sm { ScopedServiceHolder(ScopedServiceHolder&& rhs) { this->result = rhs.result; this->has_initialized = rhs.has_initialized; - rhs.result = ResultSuccess; + rhs.result = ResultSuccess(); rhs.has_initialized = false; } diff --git a/stratosphere/libstratosphere/include/stratosphere/spl/spl_types.hpp b/stratosphere/libstratosphere/include/stratosphere/spl/spl_types.hpp index 664811e2c..4dd0d285f 100644 --- a/stratosphere/libstratosphere/include/stratosphere/spl/spl_types.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/spl/spl_types.hpp @@ -61,19 +61,20 @@ namespace sts::spl { InProgress = 3, NoAsyncOperation = 4, InvalidAsyncOperation = 5, - Blacklisted = 6, - - Max = 99, + NotPermitted = 6, }; - inline ::Result ConvertResult(Result result) { - if (result == Result::Success) { - return ResultSuccess; + constexpr inline ::sts::Result ConvertResult(Result smc_result) { + /* smc::Result::Success becomes ResultSuccess() directly. */ + R_UNLESS(smc_result != Result::Success, ResultSuccess()); + + /* Convert to the list of known SecureMonitorErrors. */ + const auto converted = R_MAKE_NAMESPACE_RESULT(::sts::spl, static_cast(smc_result)); + if (spl::ResultSecureMonitorError::Includes(converted)) { + return converted; } - if (result < Result::Max) { - return MAKERESULT(Module_Spl, static_cast(result)); - } - return ResultSplUnknownSmcResult; + + return spl::ResultUnknownSecureMonitorError(); } enum class CipherMode { diff --git a/stratosphere/libstratosphere/include/stratosphere/util/util_alignment.hpp b/stratosphere/libstratosphere/include/stratosphere/util/util_alignment.hpp index c7d9b4c0a..90a482db3 100644 --- a/stratosphere/libstratosphere/include/stratosphere/util/util_alignment.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/util/util_alignment.hpp @@ -24,24 +24,54 @@ namespace sts::util { /* Utilities for alignment to power of two. */ template - static constexpr inline T AlignUp(T value, size_t alignment) { + constexpr inline T AlignUp(T value, size_t alignment) { using U = typename std::make_unsigned::type; const U invmask = static_cast(alignment - 1); return static_cast((value + invmask) & ~invmask); } template - static constexpr inline T AlignDown(T value, size_t alignment) { + constexpr inline T AlignDown(T value, size_t alignment) { using U = typename std::make_unsigned::type; const U invmask = static_cast(alignment - 1); return static_cast(value & ~invmask); } template - static constexpr inline bool IsAligned(T value, size_t alignment) { + constexpr inline bool IsAligned(T value, size_t alignment) { using U = typename std::make_unsigned::type; const U invmask = static_cast(alignment - 1); return (value & invmask) == 0; } + template<> + constexpr inline void *AlignUp(void *value, size_t alignment) { + return reinterpret_cast(AlignUp(reinterpret_cast(value), alignment)); + } + + template<> + constexpr inline const void *AlignUp(const void *value, size_t alignment) { + return reinterpret_cast(AlignUp(reinterpret_cast(value), alignment)); + } + + template<> + constexpr inline void *AlignDown(void *value, size_t alignment) { + return reinterpret_cast(AlignDown(reinterpret_cast(value), alignment)); + } + + template<> + constexpr inline const void *AlignDown(const void *value, size_t alignment) { + return reinterpret_cast(AlignDown(reinterpret_cast(value), alignment)); + } + + template<> + constexpr inline bool IsAligned(void *value, size_t alignment) { + return IsAligned(reinterpret_cast(value), alignment); + } + + template<> + constexpr inline bool IsAligned(const void *value, size_t alignment) { + return IsAligned(reinterpret_cast(value), alignment); + } + } \ No newline at end of file diff --git a/stratosphere/libstratosphere/source/ams/ams_environment.cpp b/stratosphere/libstratosphere/source/ams/ams_environment.cpp index 77d3d8e64..c28e8d461 100644 --- a/stratosphere/libstratosphere/source/ams/ams_environment.cpp +++ b/stratosphere/libstratosphere/source/ams/ams_environment.cpp @@ -125,7 +125,7 @@ namespace sts::ams { ::sts::ams::ExceptionHandler(&ams_ctx); } - inline __attribute((noreturn)) void AbortImpl() { + inline NORETURN void AbortImpl() { /* Just perform a data abort. */ register u64 addr __asm__("x27") = FatalErrorContext::StdAbortMagicAddress; register u64 val __asm__("x28") = FatalErrorContext::StdAbortMagicValue; @@ -145,9 +145,24 @@ extern "C" { /* Redefine abort to trigger these handlers. */ void abort(); + /* Redefine C++ exception handlers. Requires wrap linker flag. */ + void __wrap___cxa_pure_virtual(void) { abort(); } + void __wrap___cxa_throw(void) { abort(); } + void __wrap___cxa_rethrow(void) { abort(); } + void __wrap___cxa_allocate_exception(void) { abort(); } + void __wrap___cxa_begin_catch(void) { abort(); } + void __wrap___cxa_end_catch(void) { abort(); } + void __wrap___cxa_call_unexpected(void) { abort(); } + void __wrap___cxa_call_terminate(void) { abort(); } + void __wrap___gxx_personality_v0(void) { abort(); } + } /* Custom abort handler, so that std::abort will trigger these. */ void abort() { sts::ams::AbortImpl(); +} + +void *__cxa_allocate_ecxeption(size_t thrown_size) { + abort(); } \ No newline at end of file diff --git a/stratosphere/libstratosphere/source/ams/ams_exosphere_api.cpp b/stratosphere/libstratosphere/source/ams/ams_exosphere_api.cpp index 39c8f60af..2ad9d9974 100644 --- a/stratosphere/libstratosphere/source/ams/ams_exosphere_api.cpp +++ b/stratosphere/libstratosphere/source/ams/ams_exosphere_api.cpp @@ -23,7 +23,7 @@ namespace sts::ams { ApiInfo GetApiInfo() { u64 exosphere_cfg; if (spl::smc::GetConfig(&exosphere_cfg, 1, SplConfigItem_ExosphereApiVersion) != spl::smc::Result::Success) { - R_ASSERT(ResultAtmosphereExosphereNotPresent); + R_ASSERT(ResultExosphereNotPresent()); } return ApiInfo{ @@ -61,7 +61,7 @@ namespace sts::ams { u64 tmp; R_TRY(spl::smc::ConvertResult(spl::smc::GetConfig(&tmp, 1, SplConfigItem_ExosphereHasRcmBugPatch))); *out = (tmp != 0); - return ResultSuccess; + return ResultSuccess(); } } diff --git a/stratosphere/libstratosphere/source/boot2/boot2_api.cpp b/stratosphere/libstratosphere/source/boot2/boot2_api.cpp index b6808826d..e81ce6195 100644 --- a/stratosphere/libstratosphere/source/boot2/boot2_api.cpp +++ b/stratosphere/libstratosphere/source/boot2/boot2_api.cpp @@ -142,17 +142,14 @@ namespace sts::boot2 { void LaunchTitle(os::ProcessId *out_process_id, const ncm::TitleLocation &loc, u32 launch_flags) { os::ProcessId process_id = os::InvalidProcessId; - switch (pm::shell::LaunchTitle(&process_id, loc, launch_flags)) { - case ResultKernelResourceExhausted: - case ResultKernelOutOfMemory: - case ResultKernelLimitReached: - STS_ASSERT(false); - default: - /* We don't care about other issues. */ - break; + /* Launch, lightly validate result. */ + { + const auto launch_result = pm::shell::LaunchTitle(&process_id, loc, launch_flags); + STS_ASSERT(!(svc::ResultOutOfResource::Includes(launch_result))); + STS_ASSERT(!(svc::ResultOutOfMemory::Includes(launch_result))); + STS_ASSERT(!(svc::ResultLimitReached::Includes(launch_result))); } - if (out_process_id) { *out_process_id = process_id; } diff --git a/stratosphere/libstratosphere/source/cfg/cfg_sd_card.cpp b/stratosphere/libstratosphere/source/cfg/cfg_sd_card.cpp index feada310f..6aaeccc2f 100644 --- a/stratosphere/libstratosphere/source/cfg/cfg_sd_card.cpp +++ b/stratosphere/libstratosphere/source/cfg/cfg_sd_card.cpp @@ -43,11 +43,11 @@ namespace sts::cfg { bool service_present = false; R_TRY(sm::HasService(&service_present, RequiredServicesForSdCardAccess[i])); if (!service_present) { - return ResultFsSdCardNotPresent; + return fs::ResultSdCardNotPresent(); } } - return ResultSuccess; + return ResultSuccess(); } void WaitSdCardServicesReadyImpl() { @@ -60,7 +60,7 @@ namespace sts::cfg { R_TRY(CheckSdCardServicesReady()); R_ASSERT(fsOpenSdCardFileSystem(&g_sd_card_filesystem)); g_sd_card_initialized = true; - return ResultSuccess; + return ResultSuccess(); } void InitializeSdCard() { diff --git a/stratosphere/libstratosphere/source/dd/dd_io_mappings.cpp b/stratosphere/libstratosphere/source/dd/dd_io_mappings.cpp index 5bb6b2ae6..7bc09ab50 100644 --- a/stratosphere/libstratosphere/source/dd/dd_io_mappings.cpp +++ b/stratosphere/libstratosphere/source/dd/dd_io_mappings.cpp @@ -24,7 +24,7 @@ namespace sts::dd { const u64 aligned_size = size + offset; R_TRY_CATCH(svcQueryIoMapping(&virtual_addr, aligned_addr, aligned_size)) { /* Official software handles this by returning 0. */ - R_CATCH(ResultKernelNotFound) { return 0; } + R_CATCH(svc::ResultNotFound) { return 0; } } R_END_TRY_CATCH_WITH_ASSERT; return static_cast(virtual_addr + offset); diff --git a/stratosphere/libstratosphere/source/hid/hid_api.cpp b/stratosphere/libstratosphere/source/hid/hid_api.cpp index 7f1fc7f5a..4ee4db6b7 100644 --- a/stratosphere/libstratosphere/source/hid/hid_api.cpp +++ b/stratosphere/libstratosphere/source/hid/hid_api.cpp @@ -47,7 +47,7 @@ namespace sts::hid { g_initialized_hid = true; } - return ResultSuccess; + return ResultSuccess(); } } @@ -64,7 +64,7 @@ namespace sts::hid { *out |= hidKeysHeld(static_cast(controller)); } - return ResultSuccess; + return ResultSuccess(); } } diff --git a/stratosphere/libstratosphere/source/kvdb/kvdb_archive.cpp b/stratosphere/libstratosphere/source/kvdb/kvdb_archive.cpp index be3cd6e2d..3dce172df 100644 --- a/stratosphere/libstratosphere/source/kvdb/kvdb_archive.cpp +++ b/stratosphere/libstratosphere/source/kvdb/kvdb_archive.cpp @@ -33,9 +33,9 @@ namespace sts::kvdb { Result Validate() const { if (std::memcmp(this->magic, ArchiveHeaderMagic, sizeof(ArchiveHeaderMagic)) != 0) { - return ResultKvdbInvalidKeyValue; + return ResultInvalidKeyValue(); } - return ResultSuccess; + return ResultSuccess(); } static ArchiveHeader Make(size_t entry_count) { @@ -54,9 +54,9 @@ namespace sts::kvdb { Result Validate() const { if (std::memcmp(this->magic, ArchiveEntryMagic, sizeof(ArchiveEntryMagic)) != 0) { - return ResultKvdbInvalidKeyValue; + return ResultInvalidKeyValue(); } - return ResultSuccess; + return ResultSuccess(); } static ArchiveEntryHeader Make(size_t ksz, size_t vsz) { @@ -75,17 +75,17 @@ namespace sts::kvdb { Result ArchiveReader::Peek(void *dst, size_t size) { /* Bounds check. */ if (this->offset + size > this->buffer.GetSize() || this->offset + size <= this->offset) { - return ResultKvdbInvalidKeyValue; + return ResultInvalidKeyValue(); } std::memcpy(dst, this->buffer.Get() + this->offset, size); - return ResultSuccess; + return ResultSuccess(); } Result ArchiveReader::Read(void *dst, size_t size) { R_TRY(this->Peek(dst, size)); this->offset += size; - return ResultSuccess; + return ResultSuccess(); } Result ArchiveReader::ReadEntryCount(size_t *out) { @@ -98,7 +98,7 @@ namespace sts::kvdb { R_TRY(header.Validate()); *out = header.entry_count; - return ResultSuccess; + return ResultSuccess(); } Result ArchiveReader::GetEntrySize(size_t *out_key_size, size_t *out_value_size) { @@ -112,7 +112,7 @@ namespace sts::kvdb { *out_key_size = header.key_size; *out_value_size = header.value_size; - return ResultSuccess; + return ResultSuccess(); } Result ArchiveReader::ReadEntry(void *out_key, size_t key_size, void *out_value, size_t value_size) { @@ -130,19 +130,19 @@ namespace sts::kvdb { R_ASSERT(this->Read(out_key, key_size)); R_ASSERT(this->Read(out_value, value_size)); - return ResultSuccess; + return ResultSuccess(); } /* Writer functionality. */ Result ArchiveWriter::Write(const void *src, size_t size) { /* Bounds check. */ if (this->offset + size > this->buffer.GetSize() || this->offset + size <= this->offset) { - return ResultKvdbInvalidKeyValue; + return ResultInvalidKeyValue(); } std::memcpy(this->buffer.Get() + this->offset, src, size); this->offset += size; - return ResultSuccess; + return ResultSuccess(); } void ArchiveWriter::WriteHeader(size_t entry_count) { diff --git a/stratosphere/libstratosphere/source/kvdb/kvdb_file_key_value_store.cpp b/stratosphere/libstratosphere/source/kvdb/kvdb_file_key_value_store.cpp index 3853c2f68..d4ec971cb 100644 --- a/stratosphere/libstratosphere/source/kvdb/kvdb_file_key_value_store.cpp +++ b/stratosphere/libstratosphere/source/kvdb/kvdb_file_key_value_store.cpp @@ -41,11 +41,11 @@ namespace sts::kvdb { if (this->backing_buffer != nullptr) { this->entries = static_castentries)>(this->Allocate(sizeof(*this->entries) * this->capacity)); if (this->entries == nullptr) { - return ResultKvdbBufferInsufficient; + return ResultBufferInsufficient(); } } - return ResultSuccess; + return ResultSuccess(); } void FileKeyValueStore::Cache::Invalidate() { @@ -159,13 +159,13 @@ namespace sts::kvdb { const size_t file_name_len = file_name.GetLength(); const size_t key_name_len = file_name_len - FileExtensionLength; if (file_name_len < FileExtensionLength + 2 || !file_name.EndsWith(FileExtension) || key_name_len % 2 != 0) { - return ResultKvdbInvalidKeyValue; + return ResultInvalidKeyValue(); } /* Validate that we have space for the converted key. */ const size_t key_size = key_name_len / 2; if (key_size > max_out_size) { - return ResultKvdbBufferInsufficient; + return ResultBufferInsufficient(); } /* Convert the hex key back. */ @@ -177,7 +177,7 @@ namespace sts::kvdb { } *out_size = key_size; - return ResultSuccess; + return ResultSuccess(); } Result FileKeyValueStore::Initialize(const char *dir) { @@ -189,7 +189,7 @@ namespace sts::kvdb { { struct stat st; if (stat(dir, &st) != 0 || !(S_ISDIR(st.st_mode))) { - return ResultFsPathNotFound; + return fs::ResultPathNotFound(); } } @@ -198,7 +198,7 @@ namespace sts::kvdb { /* Initialize our cache. */ R_TRY(this->cache.Initialize(cache_buffer, cache_buffer_size, cache_capacity)); - return ResultSuccess; + return ResultSuccess(); } Result FileKeyValueStore::Get(size_t *out_size, void *out_value, size_t max_out_size, const void *key, size_t key_size) { @@ -206,7 +206,7 @@ namespace sts::kvdb { /* Ensure key size is small enough. */ if (key_size > MaxKeySize) { - return ResultKvdbKeyCapacityInsufficient; + return ResultKeyCapacityInsufficient(); } /* Try to get from cache. */ @@ -214,7 +214,7 @@ namespace sts::kvdb { auto size = this->cache.TryGet(out_value, max_out_size, key, key_size); if (size) { *out_size = *size; - return ResultSuccess; + return ResultSuccess(); } } @@ -222,9 +222,7 @@ namespace sts::kvdb { FILE *fp = fopen(this->GetPath(key, key_size), "rb"); if (fp == nullptr) { R_TRY_CATCH(fsdevGetLastResult()) { - R_CATCH(ResultFsPathNotFound) { - return ResultKvdbKeyNotFound; - } + R_CONVERT(fs::ResultPathNotFound, ResultKeyNotFound()) } R_END_TRY_CATCH; } ON_SCOPE_EXIT { fclose(fp); }; @@ -236,7 +234,7 @@ namespace sts::kvdb { /* Ensure there's enough space for the value. */ if (max_out_size < value_size) { - return ResultKvdbBufferInsufficient; + return ResultBufferInsufficient(); } /* Read the value. */ @@ -247,7 +245,7 @@ namespace sts::kvdb { /* Cache the newly read value. */ this->cache.Set(key, key_size, out_value, value_size); - return ResultSuccess; + return ResultSuccess(); } Result FileKeyValueStore::GetSize(size_t *out_size, const void *key, size_t key_size) { @@ -255,7 +253,7 @@ namespace sts::kvdb { /* Ensure key size is small enough. */ if (key_size > MaxKeySize) { - return ResultKvdbKeyCapacityInsufficient; + return ResultKeyCapacityInsufficient(); } /* Try to get from cache. */ @@ -263,7 +261,7 @@ namespace sts::kvdb { auto size = this->cache.TryGetSize(key, key_size); if (size) { *out_size = *size; - return ResultSuccess; + return ResultSuccess(); } } @@ -271,9 +269,7 @@ namespace sts::kvdb { FILE *fp = fopen(this->GetPath(key, key_size), "rb"); if (fp == nullptr) { R_TRY_CATCH(fsdevGetLastResult()) { - R_CATCH(ResultFsPathNotFound) { - return ResultKvdbKeyNotFound; - } + R_CONVERT(fs::ResultPathNotFound, ResultKeyNotFound()) } R_END_TRY_CATCH; } ON_SCOPE_EXIT { fclose(fp); }; @@ -281,7 +277,7 @@ namespace sts::kvdb { /* Get the value size. */ fseek(fp, 0, SEEK_END); *out_size = ftell(fp); - return ResultSuccess; + return ResultSuccess(); } Result FileKeyValueStore::Set(const void *key, size_t key_size, const void *value, size_t value_size) { @@ -289,7 +285,7 @@ namespace sts::kvdb { /* Ensure key size is small enough. */ if (key_size > MaxKeySize) { - return ResultKvdbKeyCapacityInsufficient; + return ResultKeyCapacityInsufficient(); } /* When the cache contains the key being set, Nintendo invalidates the cache. */ @@ -316,7 +312,7 @@ namespace sts::kvdb { /* Flush the value file. */ fflush(fp); - return ResultSuccess; + return ResultSuccess(); } Result FileKeyValueStore::Remove(const void *key, size_t key_size) { @@ -324,7 +320,7 @@ namespace sts::kvdb { /* Ensure key size is small enough. */ if (key_size > MaxKeySize) { - return ResultKvdbKeyCapacityInsufficient; + return ResultKeyCapacityInsufficient(); } /* When the cache contains the key being set, Nintendo invalidates the cache. */ @@ -335,13 +331,11 @@ namespace sts::kvdb { /* Remove the file. */ if (std::remove(this->GetPath(key, key_size)) != 0) { R_TRY_CATCH(fsdevGetLastResult()) { - R_CATCH(ResultFsPathNotFound) { - return ResultKvdbKeyNotFound; - } + R_CONVERT(fs::ResultPathNotFound, ResultKeyNotFound()) } R_END_TRY_CATCH; } - return ResultSuccess; + return ResultSuccess(); } } \ No newline at end of file diff --git a/stratosphere/libstratosphere/source/map/map_api.cpp b/stratosphere/libstratosphere/source/map/map_api.cpp index d82dcf606..11fb68426 100644 --- a/stratosphere/libstratosphere/source/map/map_api.cpp +++ b/stratosphere/libstratosphere/source/map/map_api.cpp @@ -41,12 +41,12 @@ namespace sts::map { if (mem_info.type == MemType_Unmapped && mem_info.addr - cur_base + mem_info.size >= size) { *out_address = cur_base; - return ResultSuccess; + return ResultSuccess(); } const uintptr_t mem_end = mem_info.addr + mem_info.size; if (mem_info.type == MemType_Reserved || mem_end < cur_base || (mem_end >> 31)) { - return ResultKernelOutOfMemory; + return svc::ResultOutOfMemory(); } cur_base = mem_end; @@ -64,39 +64,39 @@ namespace sts::map { cur_end = cur_base + size; if (cur_end <= cur_base) { - return ResultKernelOutOfMemory; + return svc::ResultOutOfMemory(); } while (true) { if (address_space.heap_size && (address_space.heap_base <= cur_end - 1 && cur_base <= address_space.heap_end - 1)) { /* If we overlap the heap region, go to the end of the heap region. */ if (cur_base == address_space.heap_end) { - return ResultKernelOutOfMemory; + return svc::ResultOutOfMemory(); } cur_base = address_space.heap_end; } else if (address_space.alias_size && (address_space.alias_base <= cur_end - 1 && cur_base <= address_space.alias_end - 1)) { /* If we overlap the alias region, go to the end of the alias region. */ if (cur_base == address_space.alias_end) { - return ResultKernelOutOfMemory; + return svc::ResultOutOfMemory(); } cur_base = address_space.alias_end; } else { R_ASSERT(svcQueryMemory(&mem_info, &page_info, cur_base)); if (mem_info.type == 0 && mem_info.addr - cur_base + mem_info.size >= size) { *out_address = cur_base; - return ResultSuccess; + return ResultSuccess(); } if (mem_info.addr + mem_info.size <= cur_base) { - return ResultKernelOutOfMemory; + return svc::ResultOutOfMemory(); } cur_base = mem_info.addr + mem_info.size; if (cur_base >= address_space.aslr_end) { - return ResultKernelOutOfMemory; + return svc::ResultOutOfMemory(); } } cur_end = cur_base + size; if (cur_base + size <= cur_base) { - return ResultKernelOutOfMemory; + return svc::ResultOutOfMemory(); } } } @@ -106,7 +106,7 @@ namespace sts::map { R_TRY(GetProcessAddressSpaceInfo(&address_space, process_handle)); if (size > address_space.aslr_size) { - return ResultRoInsufficientAddressSpace; + return ro::ResultInsufficientAddressSpace(); } uintptr_t try_address; @@ -115,7 +115,7 @@ namespace sts::map { MappedCodeMemory tmp_mcm(process_handle, try_address, base_address, size); R_TRY_CATCH(tmp_mcm.GetResult()) { - R_CATCH(ResultKernelInvalidMemoryState) { + R_CATCH(svc::ResultInvalidCurrentMemoryState) { continue; } } R_END_TRY_CATCH; @@ -126,10 +126,10 @@ namespace sts::map { /* We're done searching. */ out_mcm = std::move(tmp_mcm); - return ResultSuccess; + return ResultSuccess(); } - return ResultRoInsufficientAddressSpace; + return ro::ResultInsufficientAddressSpace();; } Result MapCodeMemoryInProcessModern(MappedCodeMemory &out_mcm, Handle process_handle, uintptr_t base_address, size_t size) { @@ -137,7 +137,7 @@ namespace sts::map { R_TRY(GetProcessAddressSpaceInfo(&address_space, process_handle)); if (size > address_space.aslr_size) { - return ResultRoInsufficientAddressSpace; + return ro::ResultInsufficientAddressSpace();; } uintptr_t try_address; @@ -155,7 +155,7 @@ namespace sts::map { MappedCodeMemory tmp_mcm(process_handle, try_address, base_address, size); R_TRY_CATCH(tmp_mcm.GetResult()) { - R_CATCH(ResultKernelInvalidMemoryState) { + R_CATCH(svc::ResultInvalidCurrentMemoryState) { continue; } } R_END_TRY_CATCH; @@ -166,10 +166,10 @@ namespace sts::map { /* We're done searching. */ out_mcm = std::move(tmp_mcm); - return ResultSuccess; + return ResultSuccess(); } - return ResultRoInsufficientAddressSpace; + return ro::ResultInsufficientAddressSpace();; } } @@ -201,7 +201,7 @@ namespace sts::map { out->heap_end = out->heap_base + out->heap_size; out->alias_end = out->alias_base + out->alias_size; out->aslr_end = out->aslr_base + out->aslr_size; - return ResultSuccess; + return ResultSuccess(); } Result LocateMappableSpace(uintptr_t *out_address, size_t size) { diff --git a/stratosphere/libstratosphere/source/os/impl/os_inter_process_event.cpp b/stratosphere/libstratosphere/source/os/impl/os_inter_process_event.cpp index 2b7377f62..a96a13166 100644 --- a/stratosphere/libstratosphere/source/os/impl/os_inter_process_event.cpp +++ b/stratosphere/libstratosphere/source/os/impl/os_inter_process_event.cpp @@ -23,12 +23,10 @@ namespace sts::os::impl { Result CreateEventHandles(Handle *out_readable, Handle *out_writable) { /* Create the event handles. */ R_TRY_CATCH(svcCreateEvent(out_writable, out_readable)) { - R_CATCH(ResultKernelResourceExhausted) { - return ResultOsResourceExhausted; - } + R_CONVERT(svc::ResultOutOfResource, ResultOutOfResource()); } R_END_TRY_CATCH_WITH_ASSERT; - return ResultSuccess; + return ResultSuccess(); } } @@ -46,7 +44,7 @@ namespace sts::os::impl { Handle rh, wh; R_TRY(CreateEventHandles(&rh, &wh)); this->Initialize(rh, true, wh, true, autoclear); - return ResultSuccess; + return ResultSuccess(); } void InterProcessEvent::Initialize(Handle read_handle, bool manage_read_handle, Handle write_handle, bool manage_write_handle, bool autoclear) { @@ -122,14 +120,14 @@ namespace sts::os::impl { while (true) { /* Continuously wait, until success. */ R_TRY_CATCH(svcWaitSynchronizationSingle(handle, U64_MAX)) { - R_CATCH(ResultKernelCancelled) { continue; } + R_CATCH(svc::ResultCancelled) { continue; } } R_END_TRY_CATCH_WITH_ASSERT; /* Clear, if we must. */ if (this->auto_clear) { R_TRY_CATCH(svcResetSignal(handle)) { /* Some other thread might have caught this before we did. */ - R_CATCH(ResultKernelInvalidState) { continue; } + R_CATCH(svc::ResultInvalidState) { continue; } } R_END_TRY_CATCH_WITH_ASSERT; } return; @@ -147,8 +145,8 @@ namespace sts::os::impl { while (true) { /* Continuously wait, until success or timeout. */ R_TRY_CATCH(svcWaitSynchronizationSingle(handle, 0)) { - R_CATCH(ResultKernelTimedOut) { return false; } - R_CATCH(ResultKernelCancelled) { continue; } + R_CATCH(svc::ResultTimedOut) { return false; } + R_CATCH(svc::ResultCancelled) { continue; } } R_END_TRY_CATCH_WITH_ASSERT; /* We succeeded, so we're signaled. */ @@ -164,15 +162,15 @@ namespace sts::os::impl { while (true) { /* Continuously wait, until success or timeout. */ R_TRY_CATCH(svcWaitSynchronizationSingle(handle, timeout_helper.NsUntilTimeout())) { - R_CATCH(ResultKernelTimedOut) { return false; } - R_CATCH(ResultKernelCancelled) { continue; } + R_CATCH(svc::ResultTimedOut) { return false; } + R_CATCH(svc::ResultCancelled) { continue; } } R_END_TRY_CATCH_WITH_ASSERT; /* Clear, if we must. */ if (this->auto_clear) { R_TRY_CATCH(svcResetSignal(handle)) { /* Some other thread might have caught this before we did. */ - R_CATCH(ResultKernelInvalidState) { continue; } + R_CATCH(svc::ResultInvalidState) { continue; } } R_END_TRY_CATCH_WITH_ASSERT; } diff --git a/stratosphere/libstratosphere/source/os/impl/os_waitable_manager_impl.cpp b/stratosphere/libstratosphere/source/os/impl/os_waitable_manager_impl.cpp index 85b89e2c8..a30f36bc5 100644 --- a/stratosphere/libstratosphere/source/os/impl/os_waitable_manager_impl.cpp +++ b/stratosphere/libstratosphere/source/os/impl/os_waitable_manager_impl.cpp @@ -98,13 +98,13 @@ namespace sts::os::impl{ s32 index = WaitInvalid; R_TRY_CATCH(svcWaitSynchronization(&index, handles, count, timeout)) { - R_CATCH(ResultKernelTimedOut) { return WaitTimedOut; } - R_CATCH(ResultKernelCancelled) { return WaitCancelled; } + R_CATCH(svc::ResultTimedOut) { return WaitTimedOut; } + R_CATCH(svc::ResultCancelled) { return WaitCancelled; } /* All other results are critical errors. */ - /* 7601: Thread termination requested. */ - /* E401: Handle is dead. */ - /* E601: Handle list address invalid. */ - /* EE01: Too many handles. */ + /* svc::ResultThreadTerminating */ + /* svc::ResultInvalidHandle. */ + /* svc::ResultInvalidPointer */ + /* svc::ResultOutOfRange */ } R_END_TRY_CATCH_WITH_ASSERT; return index; diff --git a/stratosphere/libstratosphere/source/os/os_interrupt_event.cpp b/stratosphere/libstratosphere/source/os/os_interrupt_event.cpp index 96201ff92..624e14a99 100644 --- a/stratosphere/libstratosphere/source/os/os_interrupt_event.cpp +++ b/stratosphere/libstratosphere/source/os/os_interrupt_event.cpp @@ -26,7 +26,7 @@ namespace sts::os { R_TRY(svcCreateInterruptEvent(this->handle.GetPointer(), interrupt_id, type)); this->is_initialized = true; - return ResultSuccess; + return ResultSuccess(); } void InterruptEvent::Finalize() { @@ -51,14 +51,14 @@ namespace sts::os { while (true) { /* Continuously wait, until success. */ R_TRY_CATCH(svcWaitSynchronizationSingle(this->handle.Get(), U64_MAX)) { - R_CATCH(ResultKernelCancelled) { continue; } + R_CATCH(svc::ResultCancelled) { continue; } } R_END_TRY_CATCH_WITH_ASSERT; /* Clear, if we must. */ if (this->auto_clear) { R_TRY_CATCH(svcResetSignal(this->handle.Get())) { /* Some other thread might have caught this before we did. */ - R_CATCH(ResultKernelInvalidState) { continue; } + R_CATCH(svc::ResultInvalidState) { continue; } } R_END_TRY_CATCH_WITH_ASSERT; } return; @@ -76,8 +76,8 @@ namespace sts::os { while (true) { /* Continuously wait, until success or timeout. */ R_TRY_CATCH(svcWaitSynchronizationSingle(this->handle.Get(), 0)) { - R_CATCH(ResultKernelTimedOut) { return false; } - R_CATCH(ResultKernelCancelled) { continue; } + R_CATCH(svc::ResultTimedOut) { return false; } + R_CATCH(svc::ResultCancelled) { continue; } } R_END_TRY_CATCH_WITH_ASSERT; /* We succeeded, so we're signaled. */ @@ -93,15 +93,15 @@ namespace sts::os { while (true) { /* Continuously wait, until success or timeout. */ R_TRY_CATCH(svcWaitSynchronizationSingle(this->handle.Get(), timeout_helper.NsUntilTimeout())) { - R_CATCH(ResultKernelTimedOut) { return false; } - R_CATCH(ResultKernelCancelled) { continue; } + R_CATCH(svc::ResultTimedOut) { return false; } + R_CATCH(svc::ResultCancelled) { continue; } } R_END_TRY_CATCH_WITH_ASSERT; /* Clear, if we must. */ if (this->auto_clear) { R_TRY_CATCH(svcResetSignal(this->handle.Get())) { /* Some other thread might have caught this before we did. */ - R_CATCH(ResultKernelInvalidState) { continue; } + R_CATCH(svc::ResultInvalidState) { continue; } } R_END_TRY_CATCH_WITH_ASSERT; } diff --git a/stratosphere/libstratosphere/source/os/os_system_event.cpp b/stratosphere/libstratosphere/source/os/os_system_event.cpp index 2e596a9ca..2ef82542e 100644 --- a/stratosphere/libstratosphere/source/os/os_system_event.cpp +++ b/stratosphere/libstratosphere/source/os/os_system_event.cpp @@ -58,17 +58,22 @@ namespace sts::os { STS_ASSERT(this->state == SystemEventState::Uninitialized); new (GetPointer(this->storage_for_event)) Event(autoclear); this->state = SystemEventState::Event; - return ResultSuccess; + return ResultSuccess(); } Result SystemEvent::InitializeAsInterProcessEvent(bool autoclear) { STS_ASSERT(this->state == SystemEventState::Uninitialized); new (GetPointer(this->storage_for_inter_process_event)) impl::InterProcessEvent(); this->state = SystemEventState::InterProcessEvent; - R_TRY_CLEANUP(this->GetInterProcessEvent().Initialize(autoclear), { - this->Finalize(); - }); - return ResultSuccess; + + /* Ensure we end up in a correct state if initialization fails. */ + { + auto guard = SCOPE_GUARD { this->Finalize(); }; + R_TRY(this->GetInterProcessEvent().Initialize(autoclear)); + guard.Cancel(); + } + + return ResultSuccess(); } void SystemEvent::AttachHandles(Handle read_handle, bool manage_read_handle, Handle write_handle, bool manage_write_handle, bool autoclear) { diff --git a/stratosphere/libstratosphere/source/pm/pm_dmnt_api.cpp b/stratosphere/libstratosphere/source/pm/pm_dmnt_api.cpp index 3687eb003..89ff37495 100644 --- a/stratosphere/libstratosphere/source/pm/pm_dmnt_api.cpp +++ b/stratosphere/libstratosphere/source/pm/pm_dmnt_api.cpp @@ -39,7 +39,7 @@ namespace sts::pm::dmnt { Event evt; R_TRY(pmdmntEnableDebugForApplication(&evt)); *out_handle = evt.revent; - return ResultSuccess; + return ResultSuccess(); } Result AtmosphereGetProcessInfo(Handle *out_handle, ncm::TitleLocation *out_loc, os::ProcessId process_id) { diff --git a/stratosphere/libstratosphere/source/pm/pm_info_api.cpp b/stratosphere/libstratosphere/source/pm/pm_info_api.cpp index 9d8a8c835..88e913c11 100644 --- a/stratosphere/libstratosphere/source/pm/pm_info_api.cpp +++ b/stratosphere/libstratosphere/source/pm/pm_info_api.cpp @@ -48,7 +48,7 @@ namespace sts::pm::info { if (g_cached_launched_titles.find(static_cast(title_id)) != g_cached_launched_titles.end()) { *out = true; - return ResultSuccess; + return ResultSuccess(); } bool has_launched = false; @@ -58,7 +58,7 @@ namespace sts::pm::info { } *out = has_launched; - return ResultSuccess; + return ResultSuccess(); } bool HasLaunchedTitle(ncm::TitleId title_id) { diff --git a/stratosphere/libstratosphere/source/result/result_on_assertion.cpp b/stratosphere/libstratosphere/source/result/result_on_assertion.cpp new file mode 100644 index 000000000..cef621392 --- /dev/null +++ b/stratosphere/libstratosphere/source/result/result_on_assertion.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +namespace sts::result { + + extern bool CallFatalOnResultAssertion; + +} + +namespace sts::result::impl { + + NORETURN WEAK void OnResultAssertion(Result result) { + /* Assert that we should call fatal on result assertion. */ + /* If we shouldn't fatal, this will std::abort(); */ + /* If we should, we'll continue onwards. */ + STS_ASSERT((sts::result::CallFatalOnResultAssertion)); + + /* TODO: sts::fatal:: */ + fatalSimple(result.GetValue()); + while (true) { /* ... */ } + } + +} \ No newline at end of file diff --git a/stratosphere/libstratosphere/source/sf/cmif/sf_cmif_domain_manager.cpp b/stratosphere/libstratosphere/source/sf/cmif/sf_cmif_domain_manager.cpp index 10ebbb5bf..537f451f0 100644 --- a/stratosphere/libstratosphere/source/sf/cmif/sf_cmif_domain_manager.cpp +++ b/stratosphere/libstratosphere/source/sf/cmif/sf_cmif_domain_manager.cpp @@ -34,11 +34,11 @@ namespace sts::sf::cmif { Result ServerDomainManager::Domain::ReserveIds(DomainObjectId *out_ids, size_t count) { for (size_t i = 0; i < count; i++) { Entry *entry = this->manager->entry_manager.AllocateEntry(); - R_UNLESS(entry != nullptr, ResultServiceFrameworkOutOfDomainEntries); + R_UNLESS(entry != nullptr, sf::cmif::ResultOutOfDomainEntries()); STS_ASSERT(entry->owner == nullptr); out_ids[i] = this->manager->entry_manager.GetId(entry); } - return ResultSuccess; + return ResultSuccess(); } void ServerDomainManager::Domain::ReserveSpecificIds(const DomainObjectId *ids, size_t count) { diff --git a/stratosphere/libstratosphere/source/sf/cmif/sf_cmif_domain_service_object.cpp b/stratosphere/libstratosphere/source/sf/cmif/sf_cmif_domain_service_object.cpp index c17bf9a76..8bdaf0831 100644 --- a/stratosphere/libstratosphere/source/sf/cmif/sf_cmif_domain_service_object.cpp +++ b/stratosphere/libstratosphere/source/sf/cmif/sf_cmif_domain_service_object.cpp @@ -28,7 +28,7 @@ namespace sts::sf::cmif { Result DomainServiceObjectDispatchTable::ProcessMessageImpl(ServiceDispatchContext &ctx, ServerDomainBase *domain, const cmif::PointerAndSize &in_raw_data) const { const CmifDomainInHeader *in_header = reinterpret_cast(in_raw_data.GetPointer()); - R_UNLESS(in_raw_data.GetSize() >= sizeof(*in_header), ResultServiceFrameworkInvalidCmifHeaderSize); + R_UNLESS(in_raw_data.GetSize() >= sizeof(*in_header), sf::cmif::ResultInvalidHeaderSize()); const cmif::PointerAndSize in_domain_raw_data = cmif::PointerAndSize(in_raw_data.GetAddress() + sizeof(*in_header), in_raw_data.GetSize() - sizeof(*in_header)); const DomainObjectId target_object_id = DomainObjectId{in_header->object_id}; @@ -36,11 +36,11 @@ namespace sts::sf::cmif { case CmifDomainRequestType_SendMessage: { auto target_object = domain->GetObject(target_object_id); - R_UNLESS(static_cast(target_object), ResultServiceFrameworkTargetNotFound); - R_UNLESS(in_header->data_size + in_header->num_in_objects * sizeof(DomainObjectId) <= in_domain_raw_data.GetSize(), ResultServiceFrameworkInvalidCmifHeaderSize); + R_UNLESS(static_cast(target_object), sf::cmif::ResultTargetNotFound()); + R_UNLESS(in_header->data_size + in_header->num_in_objects * sizeof(DomainObjectId) <= in_domain_raw_data.GetSize(), sf::cmif::ResultInvalidHeaderSize()); const cmif::PointerAndSize in_message_raw_data = cmif::PointerAndSize(in_domain_raw_data.GetAddress(), in_header->data_size); DomainObjectId in_object_ids[8]; - R_UNLESS(in_header->num_in_objects <= util::size(in_object_ids), ResultServiceFrameworkInvalidCmifNumInObjects); + R_UNLESS(in_header->num_in_objects <= util::size(in_object_ids), sf::cmif::ResultInvalidNumInObjects()); std::memcpy(in_object_ids, reinterpret_cast(in_message_raw_data.GetAddress() + in_message_raw_data.GetSize()), sizeof(DomainObjectId) * in_header->num_in_objects); DomainServiceObjectProcessor domain_processor(domain, in_object_ids, in_header->num_in_objects); if (ctx.processor == nullptr) { @@ -54,15 +54,15 @@ namespace sts::sf::cmif { case CmifDomainRequestType_Close: /* TODO: N doesn't error check here. Should we? */ domain->UnregisterObject(target_object_id); - return ResultSuccess; + return ResultSuccess(); default: - return ResultServiceFrameworkInvalidCmifInHeader; + return sf::cmif::ResultInvalidInHeader(); } } Result DomainServiceObjectDispatchTable::ProcessMessageForMitmImpl(ServiceDispatchContext &ctx, ServerDomainBase *domain, const cmif::PointerAndSize &in_raw_data) const { const CmifDomainInHeader *in_header = reinterpret_cast(in_raw_data.GetPointer()); - R_UNLESS(in_raw_data.GetSize() >= sizeof(*in_header), ResultServiceFrameworkInvalidCmifHeaderSize); + R_UNLESS(in_raw_data.GetSize() >= sizeof(*in_header), sf::cmif::ResultInvalidHeaderSize()); const cmif::PointerAndSize in_domain_raw_data = cmif::PointerAndSize(in_raw_data.GetAddress() + sizeof(*in_header), in_raw_data.GetSize() - sizeof(*in_header)); const DomainObjectId target_object_id = DomainObjectId{in_header->object_id}; @@ -76,10 +76,10 @@ namespace sts::sf::cmif { return ctx.session->ForwardRequest(ctx); } - R_UNLESS(in_header->data_size + in_header->num_in_objects * sizeof(DomainObjectId) <= in_domain_raw_data.GetSize(), ResultServiceFrameworkInvalidCmifHeaderSize); + R_UNLESS(in_header->data_size + in_header->num_in_objects * sizeof(DomainObjectId) <= in_domain_raw_data.GetSize(), sf::cmif::ResultInvalidHeaderSize()); const cmif::PointerAndSize in_message_raw_data = cmif::PointerAndSize(in_domain_raw_data.GetAddress(), in_header->data_size); DomainObjectId in_object_ids[8]; - R_UNLESS(in_header->num_in_objects <= util::size(in_object_ids), ResultServiceFrameworkInvalidCmifNumInObjects); + R_UNLESS(in_header->num_in_objects <= util::size(in_object_ids), sf::cmif::ResultInvalidNumInObjects()); std::memcpy(in_object_ids, reinterpret_cast(in_message_raw_data.GetAddress() + in_message_raw_data.GetSize()), sizeof(DomainObjectId) * in_header->num_in_objects); DomainServiceObjectProcessor domain_processor(domain, in_object_ids, in_header->num_in_objects); if (ctx.processor == nullptr) { @@ -101,16 +101,16 @@ namespace sts::sf::cmif { /* If the object is in the domain, close our copy of it. Mitm objects are required to close their associated domain id, so this shouldn't cause desynch. */ domain->UnregisterObject(target_object_id); - return ResultSuccess; + return ResultSuccess(); } default: - return ResultServiceFrameworkInvalidCmifInHeader; + return sf::cmif::ResultInvalidInHeader(); } } Result DomainServiceObjectProcessor::PrepareForProcess(const ServiceDispatchContext &ctx, const ServerMessageRuntimeMetadata runtime_metadata) const { /* Validate in object count. */ - R_UNLESS(this->impl_metadata.GetInObjectCount() == this->GetInObjectCount(), ResultServiceFrameworkInvalidCmifNumInObjects); + R_UNLESS(this->impl_metadata.GetInObjectCount() == this->GetInObjectCount(), sf::cmif::ResultInvalidNumInObjects()); /* Nintendo reserves domain object IDs here. We do this later, to support mitm semantics. */ @@ -122,7 +122,7 @@ namespace sts::sf::cmif { for (size_t i = 0; i < this->GetInObjectCount(); i++) { in_objects[i] = this->domain->GetObject(this->in_object_ids[i]); } - return ResultSuccess; + return ResultSuccess(); } HipcRequest DomainServiceObjectProcessor::PrepareForReply(const cmif::ServiceDispatchContext &ctx, PointerAndSize &out_raw_data, const ServerMessageRuntimeMetadata runtime_metadata) { diff --git a/stratosphere/libstratosphere/source/sf/cmif/sf_cmif_service_dispatch.cpp b/stratosphere/libstratosphere/source/sf/cmif/sf_cmif_service_dispatch.cpp index 673c3d980..4d27bffe2 100644 --- a/stratosphere/libstratosphere/source/sf/cmif/sf_cmif_service_dispatch.cpp +++ b/stratosphere/libstratosphere/source/sf/cmif/sf_cmif_service_dispatch.cpp @@ -24,8 +24,8 @@ namespace sts::sf::cmif { /* Parse the CMIF in header. */ const CmifInHeader *in_header = reinterpret_cast(in_raw_data.GetPointer()); - R_UNLESS(in_raw_data.GetSize() >= sizeof(*in_header), ResultServiceFrameworkInvalidCmifHeaderSize); - R_UNLESS(in_header->magic == CMIF_IN_HEADER_MAGIC && in_header->version <= max_cmif_version, ResultServiceFrameworkInvalidCmifInHeader); + R_UNLESS(in_raw_data.GetSize() >= sizeof(*in_header), sf::cmif::ResultInvalidHeaderSize()); + R_UNLESS(in_header->magic == CMIF_IN_HEADER_MAGIC && in_header->version <= max_cmif_version, sf::cmif::ResultInvalidInHeader()); const cmif::PointerAndSize in_message_raw_data = cmif::PointerAndSize(in_raw_data.GetAddress() + sizeof(*in_header), in_raw_data.GetSize() - sizeof(*in_header)); const u32 cmd_id = in_header->command_id; @@ -37,7 +37,7 @@ namespace sts::sf::cmif { break; } } - R_UNLESS(cmd_handler != nullptr, ResultServiceFrameworkUnknownCmifCommandId); + R_UNLESS(cmd_handler != nullptr, sf::cmif::ResultUnknownCommandId()); /* Invoke handler. */ CmifOutHeader *out_header = nullptr; @@ -45,16 +45,16 @@ namespace sts::sf::cmif { /* Forward forwardable results, otherwise ensure we can send result to user. */ R_TRY_CATCH(command_result) { - R_CATCH(ResultServiceFrameworkRequestDeferredByUser) { return ResultServiceFrameworkRequestDeferredByUser; } + R_CATCH(sf::impl::ResultRequestContextChanged) { return R_CURRENT_RESULT; } R_CATCH_ALL() { STS_ASSERT(out_header != nullptr); } } R_END_TRY_CATCH; /* Write output header to raw data. */ if (out_header != nullptr) { - *out_header = CmifOutHeader{CMIF_OUT_HEADER_MAGIC, 0, command_result, 0}; + *out_header = CmifOutHeader{CMIF_OUT_HEADER_MAGIC, 0, command_result.GetValue(), 0}; } - return ResultSuccess; + return ResultSuccess(); } Result impl::ServiceDispatchTableBase::ProcessMessageForMitmImpl(ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data, const ServiceCommandMeta *entries, const size_t entry_count) const { @@ -64,8 +64,8 @@ namespace sts::sf::cmif { /* Parse the CMIF in header. */ const CmifInHeader *in_header = reinterpret_cast(in_raw_data.GetPointer()); - R_UNLESS(in_raw_data.GetSize() >= sizeof(*in_header), ResultServiceFrameworkInvalidCmifHeaderSize); - R_UNLESS(in_header->magic == CMIF_IN_HEADER_MAGIC && in_header->version <= max_cmif_version, ResultServiceFrameworkInvalidCmifInHeader); + R_UNLESS(in_raw_data.GetSize() >= sizeof(*in_header), sf::cmif::ResultInvalidHeaderSize()); + R_UNLESS(in_header->magic == CMIF_IN_HEADER_MAGIC && in_header->version <= max_cmif_version, sf::cmif::ResultInvalidInHeader()); const cmif::PointerAndSize in_message_raw_data = cmif::PointerAndSize(in_raw_data.GetAddress() + sizeof(*in_header), in_raw_data.GetSize() - sizeof(*in_header)); const u32 cmd_id = in_header->command_id; @@ -89,19 +89,19 @@ namespace sts::sf::cmif { /* Forward forwardable results, otherwise ensure we can send result to user. */ R_TRY_CATCH(command_result) { - R_CATCH(ResultServiceFrameworkRequestDeferredByUser) { return ResultServiceFrameworkRequestDeferredByUser; } - R_CATCH(ResultAtmosphereMitmShouldForwardToSession) { + R_CATCH(ams::mitm::ResultShouldForwardToSession) { return ctx.session->ForwardRequest(ctx); } + R_CATCH(sf::impl::ResultRequestContextChanged) { return R_CURRENT_RESULT; } R_CATCH_ALL() { STS_ASSERT(out_header != nullptr); } } R_END_TRY_CATCH; /* Write output header to raw data. */ if (out_header != nullptr) { - *out_header = CmifOutHeader{CMIF_OUT_HEADER_MAGIC, 0, command_result, 0}; + *out_header = CmifOutHeader{CMIF_OUT_HEADER_MAGIC, 0, command_result.GetValue(), 0}; } - return ResultSuccess; + return ResultSuccess(); } } diff --git a/stratosphere/libstratosphere/source/sf/hipc/sf_hipc_api.cpp b/stratosphere/libstratosphere/source/sf/hipc/sf_hipc_api.cpp index 9a3a5b641..a0994b442 100644 --- a/stratosphere/libstratosphere/source/sf/hipc/sf_hipc_api.cpp +++ b/stratosphere/libstratosphere/source/sf/hipc/sf_hipc_api.cpp @@ -43,34 +43,34 @@ namespace sts::sf::hipc { Result Receive(ReceiveResult *out_recv_result, Handle session_handle, const cmif::PointerAndSize &message_buffer) { R_TRY_CATCH(ReceiveImpl(session_handle, message_buffer.GetPointer(), message_buffer.GetSize())) { - R_CATCH(ResultKernelConnectionClosed) { + R_CATCH(svc::ResultSessionClosed) { *out_recv_result = ReceiveResult::Closed; - return ResultSuccess; + return ResultSuccess(); } - R_CATCH(ResultKernelReceiveListBroken) { + R_CATCH(svc::ResultReceiveListBroken) { *out_recv_result = ReceiveResult::NeedsRetry; - return ResultSuccess; + return ResultSuccess(); } } R_END_TRY_CATCH; *out_recv_result = ReceiveResult::Success; - return ResultSuccess; + return ResultSuccess(); } Result Receive(bool *out_closed, Handle session_handle, const cmif::PointerAndSize &message_buffer) { R_TRY_CATCH(ReceiveImpl(session_handle, message_buffer.GetPointer(), message_buffer.GetSize())) { - R_CATCH(ResultKernelConnectionClosed) { + R_CATCH(svc::ResultSessionClosed) { *out_closed = true; - return ResultSuccess; + return ResultSuccess(); } } R_END_TRY_CATCH; *out_closed = false; - return ResultSuccess; + return ResultSuccess(); } Result Reply(Handle session_handle, const cmif::PointerAndSize &message_buffer) { R_TRY_CATCH(ReplyImpl(session_handle, message_buffer.GetPointer(), message_buffer.GetSize())) { - R_CATCH(ResultKernelTimedOut) { return ResultSuccess; } - R_CATCH(ResultKernelConnectionClosed) { return ResultSuccess; } + R_CONVERT(svc::ResultTimedOut, ResultSuccess()) + R_CONVERT(svc::ResultSessionClosed, ResultSuccess()) } R_END_TRY_CATCH; /* ReplyImpl should *always* return an error. */ STS_ASSERT(false); @@ -78,9 +78,9 @@ namespace sts::sf::hipc { Result CreateSession(Handle *out_server_handle, Handle *out_client_handle) { R_TRY_CATCH(svcCreateSession(out_server_handle, out_client_handle, 0, 0)) { - R_CATCH(ResultKernelResourceExhausted) { return ResultHipcOutOfSessions; } + R_CONVERT(svc::ResultOutOfResource, sf::hipc::ResultOutOfSessions()); } R_END_TRY_CATCH; - return ResultSuccess; + return ResultSuccess(); } } diff --git a/stratosphere/libstratosphere/source/sf/hipc/sf_hipc_server_domain_session_manager.cpp b/stratosphere/libstratosphere/source/sf/hipc/sf_hipc_server_domain_session_manager.cpp index 09fb22878..f096d6942 100644 --- a/stratosphere/libstratosphere/source/sf/hipc/sf_hipc_server_domain_session_manager.cpp +++ b/stratosphere/libstratosphere/source/sf/hipc/sf_hipc_server_domain_session_manager.cpp @@ -36,7 +36,7 @@ namespace sts::sf::hipc { Result CloneCurrentObjectImpl(Handle *out_client_handle, ServerSessionManager *tagged_manager) { /* Clone the object. */ cmif::ServiceObjectHolder &&clone = this->session->srv_obj_holder.Clone(); - R_UNLESS(clone, ResultHipcDomainObjectNotFound); + R_UNLESS(clone, sf::hipc::ResultDomainObjectNotFound()); /* Create new session handles. */ Handle server_handle; @@ -52,7 +52,7 @@ namespace sts::sf::hipc { R_ASSERT(tagged_manager->RegisterMitmSession(server_handle, std::move(clone), std::move(new_forward_service))); } - return ResultSuccess; + return ResultSuccess(); } public: explicit HipcManager(ServerDomainSessionManager *m, ServerSession *s) : manager(m), session(s), is_mitm_session(s->forward_service != nullptr) { @@ -62,7 +62,8 @@ namespace sts::sf::hipc { Result ConvertCurrentObjectToDomain(sf::Out out) { /* Allocate a domain. */ auto domain = this->manager->AllocateDomainServiceObject(); - R_UNLESS(domain, ResultHipcOutOfDomains); + R_UNLESS(domain, sf::hipc::ResultOutOfDomains()); + auto domain_guard = SCOPE_GUARD { this->manager->FreeDomainServiceObject(domain); }; cmif::DomainObjectId object_id = cmif::InvalidDomainObjectId; @@ -71,9 +72,7 @@ namespace sts::sf::hipc { if (this->is_mitm_session) { /* If we're a mitm session, we need to convert the remote session to domain. */ STS_ASSERT(session->forward_service->own_handle); - R_TRY_CLEANUP(serviceConvertToDomain(session->forward_service.get()), { - this->manager->FreeDomainServiceObject(domain); - }); + R_TRY(serviceConvertToDomain(session->forward_service.get())); /* The object ID reservation cannot fail here, as that would cause desynchronization from target domain. */ object_id = cmif::DomainObjectId{session->forward_service->object_id}; @@ -99,22 +98,23 @@ namespace sts::sf::hipc { STS_ASSERT(static_cast(new_holder)); /* We succeeded! */ + domain_guard.Cancel(); domain->RegisterObject(object_id, std::move(session->srv_obj_holder)); session->srv_obj_holder = std::move(new_holder); out.SetValue(object_id); - return ResultSuccess; + return ResultSuccess(); } Result CopyFromCurrentDomain(sf::OutMoveHandle out, cmif::DomainObjectId object_id) { /* Get domain. */ auto domain = this->session->srv_obj_holder.GetServiceObject(); - R_UNLESS(domain != nullptr, ResultHipcTargetNotDomain); + R_UNLESS(domain != nullptr, sf::hipc::ResultTargetNotDomain()); /* Get domain object. */ auto &&object = domain->GetObject(object_id); if (!object) { - R_UNLESS(this->is_mitm_session, ResultHipcDomainObjectNotFound); + R_UNLESS(this->is_mitm_session, sf::hipc::ResultDomainObjectNotFound()); return cmifCopyFromCurrentDomain(this->session->forward_service->session, object_id.value, out.GetHandlePointer()); } @@ -140,7 +140,7 @@ namespace sts::sf::hipc { R_ASSERT(this->manager->RegisterMitmSession(server_handle, std::move(object), std::move(new_forward_service))); } - return ResultSuccess; + return ResultSuccess(); } Result CloneCurrentObject(sf::OutMoveHandle out) { diff --git a/stratosphere/libstratosphere/source/sf/hipc/sf_hipc_server_manager.cpp b/stratosphere/libstratosphere/source/sf/hipc/sf_hipc_server_manager.cpp index d9a23e6ad..51726ae4e 100644 --- a/stratosphere/libstratosphere/source/sf/hipc/sf_hipc_server_manager.cpp +++ b/stratosphere/libstratosphere/source/sf/hipc/sf_hipc_server_manager.cpp @@ -124,7 +124,12 @@ namespace sts::sf::hipc { std::memcpy(tls_message.GetPointer(), saved_message.GetPointer(), tls_message.GetSize()); } - return this->ProcessRequest(session, tls_message); + /* Treat a meta "Context Invalidated" message as a success. */ + R_TRY_CATCH(this->ProcessRequest(session, tls_message)) { + R_CONVERT(sf::impl::ResultRequestInvalidated, ResultSuccess()); + } R_END_TRY_CATCH; + + return ResultSuccess(); } void ServerManagerBase::ProcessDeferredSessions() { @@ -135,12 +140,16 @@ namespace sts::sf::hipc { while (it != this->deferred_session_list.end()) { ServerSession *session = static_cast(&*it); R_TRY_CATCH(this->ProcessForSession(session)) { - R_CATCH(ResultServiceFrameworkRequestDeferredByUser) { + R_CATCH(sf::ResultRequestDeferred) { /* Session is still deferred, so let's continue. */ it++; continue; } - /* TODO: N has a result that undefers without success. */ + R_CATCH(sf::impl::ResultRequestInvalidated) { + /* Session is no longer deferred! */ + it = this->deferred_session_list.erase(it); + continue; + } } R_END_TRY_CATCH_WITH_ASSERT; /* We succeeded! Remove from deferred list. */ @@ -159,17 +168,17 @@ namespace sts::sf::hipc { case UserDataTag::Session: /* Try to process for session. */ R_TRY_CATCH(this->ProcessForSession(holder)) { - R_CATCH(ResultServiceFrameworkRequestDeferredByUser) { + R_CATCH(sf::ResultRequestDeferred) { /* The session was deferred, so push it onto the deferred session list. */ std::scoped_lock lk(this->deferred_session_mutex); this->deferred_session_list.push_back(*static_cast(holder)); - return ResultSuccess; + return ResultSuccess(); } } R_END_TRY_CATCH; /* We successfully invoked a command...so let's see if anything can be undeferred. */ this->ProcessDeferredSessions(); - return ResultSuccess; + return ResultSuccess(); break; STS_UNREACHABLE_DEFAULT_CASE(); } diff --git a/stratosphere/libstratosphere/source/sf/hipc/sf_hipc_server_session_manager.cpp b/stratosphere/libstratosphere/source/sf/hipc/sf_hipc_server_session_manager.cpp index 5290ba67e..9447445f4 100644 --- a/stratosphere/libstratosphere/source/sf/hipc/sf_hipc_server_session_manager.cpp +++ b/stratosphere/libstratosphere/source/sf/hipc/sf_hipc_server_session_manager.cpp @@ -65,7 +65,7 @@ namespace sts::sf::hipc { } } - return ResultSuccess; + return ResultSuccess(); } void ServerSessionManager::DestroySession(ServerSession *session) { @@ -89,7 +89,7 @@ namespace sts::sf::hipc { session_memory->saved_message = this->GetSessionSavedMessageBuffer(session_memory); /* Register to wait list. */ this->RegisterSessionToWaitList(session_memory); - return ResultSuccess; + return ResultSuccess(); } Result ServerSessionManager::AcceptSessionImpl(ServerSession *session_memory, Handle port_handle, cmif::ServiceObjectHolder &&obj) { @@ -105,7 +105,7 @@ namespace sts::sf::hipc { /* Register session. */ R_TRY(this->RegisterSessionImpl(session_memory, session_handle, std::forward(obj))); succeeded = true; - return ResultSuccess; + return ResultSuccess(); } Result ServerSessionManager::RegisterMitmSessionImpl(ServerSession *session_memory, Handle mitm_session_handle, cmif::ServiceObjectHolder &&obj, std::shared_ptr<::Service> &&fsrv) { @@ -119,7 +119,7 @@ namespace sts::sf::hipc { session_memory->pointer_buffer = cmif::PointerAndSize(session_memory->pointer_buffer.GetAddress(), session_memory->forward_service->pointer_buffer_size); /* Register to wait list. */ this->RegisterSessionToWaitList(session_memory); - return ResultSuccess; + return ResultSuccess(); } Result ServerSessionManager::AcceptMitmSessionImpl(ServerSession *session_memory, Handle mitm_port_handle, cmif::ServiceObjectHolder &&obj, std::shared_ptr<::Service> &&fsrv) { @@ -135,7 +135,7 @@ namespace sts::sf::hipc { /* Register session. */ R_TRY(this->RegisterMitmSessionImpl(session_memory, mitm_session_handle, std::forward(obj), std::forward>(fsrv))); succeeded = true; - return ResultSuccess; + return ResultSuccess(); } Result ServerSessionManager::RegisterSession(Handle session_handle, cmif::ServiceObjectHolder &&obj) { @@ -182,10 +182,10 @@ namespace sts::sf::hipc { switch (recv_result) { case hipc::ReceiveResult::Success: session->is_closed = false; - return ResultSuccess; + return ResultSuccess(); case hipc::ReceiveResult::Closed: session->is_closed = true; - return ResultSuccess; + return ResultSuccess(); case hipc::ReceiveResult::NeedsRetry: continue; STS_UNREACHABLE_DEFAULT_CASE(); @@ -206,29 +206,31 @@ namespace sts::sf::hipc { Result ServerSessionManager::ProcessRequest(ServerSession *session, const cmif::PointerAndSize &message) { if (session->is_closed) { this->CloseSessionImpl(session); - return ResultSuccess; + return ResultSuccess(); } switch (GetCmifCommandType(message)) { case CmifCommandType_Close: { this->CloseSessionImpl(session); - return ResultSuccess; + return ResultSuccess(); } default: { R_TRY_CATCH(this->ProcessRequestImpl(session, message, message)) { - R_CATCH(ResultServiceFrameworkRequestDeferredByUser) { /* TODO: Properly include entire range Nintendo does */ - return ResultServiceFrameworkRequestDeferredByUser; + R_CATCH(sf::impl::ResultRequestContextChanged) { + /* A meta message changing the request context has been sent. */ + return R_CURRENT_RESULT; } R_CATCH_ALL() { /* All other results indicate something went very wrong. */ this->CloseSessionImpl(session); - return ResultSuccess; + return ResultSuccess(); } } R_END_TRY_CATCH; + /* We succeeded, so we can process future messages on this session. */ this->RegisterSessionToWaitList(session); - return ResultSuccess; + return ResultSuccess(); } } } @@ -244,13 +246,13 @@ namespace sts::sf::hipc { case CmifCommandType_ControlWithContext: return this->DispatchManagerRequest(session, in_message, out_message); default: - return ResultHipcUnknownCommandType; + return sf::hipc::ResultUnknownCommandType(); } } Result ServerSessionManager::DispatchManagerRequest(ServerSession *session, const cmif::PointerAndSize &in_message, const cmif::PointerAndSize &out_message) { /* This will get overridden by ... WithDomain class. */ - return ResultServiceFrameworkNotSupported; + return sf::ResultNotSupported(); } Result ServerSessionManager::DispatchRequest(cmif::ServiceObjectHolder &&obj_holder, ServerSession *session, const cmif::PointerAndSize &in_message, const cmif::PointerAndSize &out_message) { @@ -273,10 +275,10 @@ namespace sts::sf::hipc { const uintptr_t in_raw_addr = reinterpret_cast(dispatch_ctx.request.data.data_words); const size_t in_raw_size = dispatch_ctx.request.meta.num_data_words * sizeof(u32); /* Note: Nintendo does not validate this size before subtracting 0x10 from it. This is not exploitable. */ - R_UNLESS(in_raw_size >= 0x10, ResultHipcInvalidRequestSize); - R_UNLESS(in_raw_addr + in_raw_size <= in_message_buffer_end, ResultHipcInvalidRequestSize); + R_UNLESS(in_raw_size >= 0x10, sf::hipc::ResultInvalidRequestSize()); + R_UNLESS(in_raw_addr + in_raw_size <= in_message_buffer_end, sf::hipc::ResultInvalidRequestSize()); const uintptr_t recv_list_end = reinterpret_cast(dispatch_ctx.request.data.recv_list + dispatch_ctx.request.meta.num_recv_statics); - R_UNLESS(recv_list_end <= in_message_buffer_end, ResultHipcInvalidRequestSize); + R_UNLESS(recv_list_end <= in_message_buffer_end, sf::hipc::ResultInvalidRequestSize()); /* CMIF has 0x10 of padding in raw data, and requires 0x10 alignment. */ const cmif::PointerAndSize in_raw_data(util::AlignUp(in_raw_addr, 0x10), in_raw_size - 0x10); @@ -294,7 +296,7 @@ namespace sts::sf::hipc { R_TRY(hipc::Reply(session->session_handle, out_message)); } - return ResultSuccess; + return ResultSuccess(); } diff --git a/stratosphere/libstratosphere/source/sm/sm_api.cpp b/stratosphere/libstratosphere/source/sm/sm_api.cpp index c3fb39208..11047c6bd 100644 --- a/stratosphere/libstratosphere/source/sm/sm_api.cpp +++ b/stratosphere/libstratosphere/source/sm/sm_api.cpp @@ -60,7 +60,7 @@ namespace sts::sm { void DoWithSessionImpl(void (*Invoker)(void *), void *Function) { impl::DoWithUserSession([&]() { Invoker(Function); - return ResultSuccess; + return ResultSuccess(); }); } diff --git a/stratosphere/libstratosphere/source/updater/updater_api.cpp b/stratosphere/libstratosphere/source/updater/updater_api.cpp index ab619c107..a573d83d6 100644 --- a/stratosphere/libstratosphere/source/updater/updater_api.cpp +++ b/stratosphere/libstratosphere/source/updater/updater_api.cpp @@ -55,15 +55,15 @@ namespace sts::updater { /* Implementations. */ Result ValidateWorkBuffer(const void *work_buffer, size_t work_buffer_size) { if (work_buffer_size < BctSize + EksSize) { - return ResultUpdaterTooSmallWorkBuffer; + return ResultTooSmallWorkBuffer(); } - if (reinterpret_cast(work_buffer) & 0xFFF) { - return ResultUpdaterMisalignedWorkBuffer; + if (!util::IsAligned(work_buffer, 0x1000)) { + return ResultNotAlignedWorkBuffer(); } - if (reinterpret_cast(work_buffer_size) & 0x1FF) { - return ResultUpdaterMisalignedWorkBuffer; + if (util::IsAligned(work_buffer_size, 0x200)) { + return ResultNotAlignedWorkBuffer(); } - return ResultSuccess; + return ResultSuccess(); } bool HasEks(BootImageUpdateType boot_image_update_type) { @@ -115,7 +115,7 @@ namespace sts::updater { /* Read data from save. */ out->needs_verify_normal = save.GetNeedsVerification(BootModeType::Normal); out->needs_verify_safe = save.GetNeedsVerification(BootModeType::Safe); - return ResultSuccess; + return ResultSuccess(); } Result VerifyBootImagesAndRepairIfNeeded(bool *out_repaired, BootModeType mode, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { @@ -125,7 +125,7 @@ namespace sts::updater { /* Verify the boot images in NAND. */ R_TRY_CATCH(VerifyBootImages(bip_data_id, mode, work_buffer, work_buffer_size, boot_image_update_type)) { - R_CATCH(ResultUpdaterNeedsRepairBootImages) { + R_CATCH(ResultNeedsRepairBootImages) { /* Perform repair. */ *out_repaired = true; R_TRY(UpdateBootImages(bip_data_id, mode, work_buffer, work_buffer_size, boot_image_update_type)); @@ -153,7 +153,7 @@ namespace sts::updater { u32 total_entries; R_TRY(ncmContentMetaDatabaseList(&meta_db, &total_entries, &written_entries, records, MaxContentMetas * sizeof(*records), title_type, 0, 0, UINT64_MAX, NcmContentInstallType_Full)); if (total_entries == 0) { - return ResultUpdaterBootImagePackageNotFound; + return ResultBootImagePackageNotFound(); } STS_ASSERT(total_entries == written_entries); @@ -166,14 +166,14 @@ namespace sts::updater { if (attr & NcmContentMetaAttribute_IncludesExFatDriver) { *out_data_id = records[i].title_id; - return ResultSuccess; + return ResultSuccess(); } } } /* If there's only one entry or no exfat entries, return that entry. */ *out_data_id = records[0].title_id; - return ResultSuccess; + return ResultSuccess(); } Result VerifyBootImages(u64 data_id, BootModeType mode, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { @@ -191,9 +191,7 @@ namespace sts::updater { R_TRY(ValidateWorkBuffer(work_buffer, work_buffer_size)); R_TRY_CATCH(romfsMountFromDataArchive(data_id, FsStorageId_NandSystem, GetBootImagePackageMountPath())) { - R_CATCH(ResultFsTargetNotFound) { - return ResultUpdaterBootImagePackageNotFound; - } + R_CONVERT(fs::ResultTargetNotFound, ResultBootImagePackageNotFound()) } R_END_TRY_CATCH; ON_SCOPE_EXIT { R_ASSERT(romfsUnmount(GetBootImagePackageMountPath())); }; @@ -219,26 +217,26 @@ namespace sts::updater { R_TRY(GetFileHash(&size, file_hash, GetPackage1Path(boot_image_update_type), work_buffer, work_buffer_size)); R_TRY(boot0_accessor.GetHash(nand_hash, size, work_buffer, work_buffer_size, Boot0Partition::Package1NormalMain)); if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) { - return ResultUpdaterNeedsRepairBootImages; + return ResultNeedsRepairBootImages(); } R_TRY(boot0_accessor.GetHash(nand_hash, size, work_buffer, work_buffer_size, Boot0Partition::Package1NormalSub)); if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) { - return ResultUpdaterNeedsRepairBootImages; + return ResultNeedsRepairBootImages(); } /* Compare Package2 Normal/Sub hashes. */ R_TRY(GetFileHash(&size, file_hash, GetPackage2Path(boot_image_update_type), work_buffer, work_buffer_size)); R_TRY(GetPackage2Hash(nand_hash, size, work_buffer, work_buffer_size, Package2Type::NormalMain)); if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) { - return ResultUpdaterNeedsRepairBootImages; + return ResultNeedsRepairBootImages(); } R_TRY(GetPackage2Hash(nand_hash, size, work_buffer, work_buffer_size, Package2Type::NormalSub)); if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) { - return ResultUpdaterNeedsRepairBootImages; + return ResultNeedsRepairBootImages(); } } - return ResultSuccess; + return ResultSuccess(); } Result VerifyBootImagesSafe(u64 data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { @@ -246,9 +244,7 @@ namespace sts::updater { R_TRY(ValidateWorkBuffer(work_buffer, work_buffer_size)); R_TRY_CATCH(romfsMountFromDataArchive(data_id, FsStorageId_NandSystem, GetBootImagePackageMountPath())) { - R_CATCH(ResultFsTargetNotFound) { - return ResultUpdaterBootImagePackageNotFound; - } + R_CONVERT(fs::ResultTargetNotFound, ResultBootImagePackageNotFound()) } R_END_TRY_CATCH; ON_SCOPE_EXIT { R_ASSERT(romfsUnmount(GetBootImagePackageMountPath())); }; @@ -279,26 +275,26 @@ namespace sts::updater { R_TRY(GetFileHash(&size, file_hash, GetPackage1Path(boot_image_update_type), work_buffer, work_buffer_size)); R_TRY(boot1_accessor.GetHash(nand_hash, size, work_buffer, work_buffer_size, Boot1Partition::Package1SafeMain)); if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) { - return ResultUpdaterNeedsRepairBootImages; + return ResultNeedsRepairBootImages(); } R_TRY(boot1_accessor.GetHash(nand_hash, size, work_buffer, work_buffer_size, Boot1Partition::Package1SafeSub)); if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) { - return ResultUpdaterNeedsRepairBootImages; + return ResultNeedsRepairBootImages(); } /* Compare Package2 Normal/Sub hashes. */ R_TRY(GetFileHash(&size, file_hash, GetPackage2Path(boot_image_update_type), work_buffer, work_buffer_size)); R_TRY(GetPackage2Hash(nand_hash, size, work_buffer, work_buffer_size, Package2Type::SafeMain)); if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) { - return ResultUpdaterNeedsRepairBootImages; + return ResultNeedsRepairBootImages(); } R_TRY(GetPackage2Hash(nand_hash, size, work_buffer, work_buffer_size, Package2Type::SafeSub)); if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) { - return ResultUpdaterNeedsRepairBootImages; + return ResultNeedsRepairBootImages(); } } - return ResultSuccess; + return ResultSuccess(); } Result UpdateBootImages(u64 data_id, BootModeType mode, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { @@ -316,9 +312,7 @@ namespace sts::updater { R_TRY(ValidateWorkBuffer(work_buffer, work_buffer_size)); R_TRY_CATCH(romfsMountFromDataArchive(data_id, FsStorageId_NandSystem, GetBootImagePackageMountPath())) { - R_CATCH(ResultFsTargetNotFound) { - return ResultUpdaterBootImagePackageNotFound; - } + R_CONVERT(fs::ResultTargetNotFound, ResultBootImagePackageNotFound()) } R_END_TRY_CATCH; ON_SCOPE_EXIT { R_ASSERT(romfsUnmount(GetBootImagePackageMountPath())); }; @@ -365,7 +359,7 @@ namespace sts::updater { R_TRY(boot0_accessor.Write(GetPackage1Path(boot_image_update_type), work_buffer, work_buffer_size, Boot0Partition::Package1NormalMain)); } - return ResultSuccess; + return ResultSuccess(); } Result UpdateBootImagesSafe(u64 data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { @@ -373,9 +367,7 @@ namespace sts::updater { R_TRY(ValidateWorkBuffer(work_buffer, work_buffer_size)); R_TRY_CATCH(romfsMountFromDataArchive(data_id, FsStorageId_NandSystem, GetBootImagePackageMountPath())) { - R_CATCH(ResultFsTargetNotFound) { - return ResultUpdaterBootImagePackageNotFound; - } + R_CONVERT(fs::ResultTargetNotFound, ResultBootImagePackageNotFound()) } R_END_TRY_CATCH; ON_SCOPE_EXIT { R_ASSERT(romfsUnmount(GetBootImagePackageMountPath())); }; @@ -426,7 +418,7 @@ namespace sts::updater { R_TRY(boot1_accessor.Write(GetPackage1Path(boot_image_update_type), work_buffer, work_buffer_size, Boot1Partition::Package1SafeMain)); } - return ResultSuccess; + return ResultSuccess(); } Result SetVerificationNeeded(BootModeType mode, bool needed, void *work_buffer, size_t work_buffer_size) { @@ -445,7 +437,7 @@ namespace sts::updater { save.SetNeedsVerification(mode, needed); R_TRY(save.Save()); - return ResultSuccess; + return ResultSuccess(); } Result ValidateBctFileHash(Boot0Accessor &accessor, Boot0Partition which, const void *stored_hash, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { @@ -468,10 +460,10 @@ namespace sts::updater { sha256CalculateHash(file_hash, bct, BctSize); if (std::memcmp(file_hash, stored_hash, SHA256_HASH_SIZE) != 0) { - return ResultUpdaterNeedsRepairBootImages; + return ResultNeedsRepairBootImages(); } - return ResultSuccess; + return ResultSuccess(); } Result GetPackage2Hash(void *dst_hash, size_t package2_size, void *work_buffer, size_t work_buffer_size, Package2Type which) { @@ -518,7 +510,7 @@ namespace sts::updater { /* If we don't need to verify anything, we're done. */ if (!verification_state.needs_verify_normal && !verification_state.needs_verify_safe) { - return ResultSuccess; + return ResultSuccess(); } /* Get a session to ncm. */ @@ -528,21 +520,17 @@ namespace sts::updater { /* Verify normal, verify safe as needed. */ if (verification_state.needs_verify_normal) { R_TRY_CATCH(VerifyBootImagesAndRepairIfNeeded(out_repaired_normal, BootModeType::Normal, work_buffer, work_buffer_size, boot_image_update_type)) { - R_CATCH(ResultUpdaterBootImagePackageNotFound) { - /* Nintendo considers failure to locate bip a success. TODO: don't do that? */ - } + R_CATCH(ResultBootImagePackageNotFound) { /* Nintendo considers failure to locate bip a success. TODO: don't do that? */ } } R_END_TRY_CATCH; } if (verification_state.needs_verify_safe) { R_TRY_CATCH(VerifyBootImagesAndRepairIfNeeded(out_repaired_safe, BootModeType::Safe, work_buffer, work_buffer_size, boot_image_update_type)) { - R_CATCH(ResultUpdaterBootImagePackageNotFound) { - /* Nintendo considers failure to locate bip a success. TODO: don't do that? */ - } + R_CATCH(ResultBootImagePackageNotFound) { /* Nintendo considers failure to locate bip a success. TODO: don't do that? */ } } R_END_TRY_CATCH; } - return ResultSuccess; + return ResultSuccess(); } } diff --git a/stratosphere/libstratosphere/source/updater/updater_bis_management.cpp b/stratosphere/libstratosphere/source/updater/updater_bis_management.cpp index 364365fab..d90421f61 100644 --- a/stratosphere/libstratosphere/source/updater/updater_bis_management.cpp +++ b/stratosphere/libstratosphere/source/updater/updater_bis_management.cpp @@ -24,7 +24,7 @@ namespace sts::updater { Result BisAccessor::Initialize() { R_TRY(fsOpenBisStorage(&this->storage, this->partition_id)); this->active = true; - return ResultSuccess; + return ResultSuccess(); } void BisAccessor::Finalize() { @@ -50,7 +50,7 @@ namespace sts::updater { FILE *bip_fp = fopen(bip_path, "rb"); if (bip_fp == NULL) { - return ResultUpdaterInvalidBootImagePackage; + return ResultInvalidBootImagePackage(); } ON_SCOPE_EXIT { fclose(bip_fp); }; @@ -73,7 +73,7 @@ namespace sts::updater { break; } } - return ResultSuccess; + return ResultSuccess(); } Result BisAccessor::Clear(u64 offset, u64 size, void *work_buffer, size_t work_buffer_size) { @@ -88,7 +88,7 @@ namespace sts::updater { R_TRY(this->Write(offset + written, work_buffer, cur_write_size)); written += cur_write_size; } - return ResultSuccess; + return ResultSuccess(); } Result BisAccessor::GetHash(void *dst, u64 offset, u64 size, u64 hash_size, void *work_buffer, size_t work_buffer_size) { @@ -108,7 +108,7 @@ namespace sts::updater { } sha256ContextGetHash(&sha_ctx, dst); - return ResultSuccess; + return ResultSuccess(); } size_t Boot0Accessor::GetBootloaderVersion(void *bct) { @@ -135,7 +135,7 @@ namespace sts::updater { Result Boot0Accessor::UpdateEksManually(void *dst_bct, const void *src_eks) { this->CopyEks(dst_bct, src_eks, GetEksIndex(GetBootloaderVersion(dst_bct))); - return ResultSuccess; + return ResultSuccess(); } Result Boot0Accessor::PreserveAutoRcm(void *dst_bct, void *work_buffer, Boot0Partition which) { @@ -147,7 +147,7 @@ namespace sts::updater { void *dst_pubk = reinterpret_cast(reinterpret_cast(dst_bct) + BctPubkOffset); void *src_pubk = reinterpret_cast(reinterpret_cast(work_buffer) + BctPubkOffset); std::memcpy(dst_pubk, src_pubk, BctPubkSize); - return ResultSuccess; + return ResultSuccess(); } } diff --git a/stratosphere/libstratosphere/source/updater/updater_bis_management.hpp b/stratosphere/libstratosphere/source/updater/updater_bis_management.hpp index 829d465df..597ebd4d2 100644 --- a/stratosphere/libstratosphere/source/updater/updater_bis_management.hpp +++ b/stratosphere/libstratosphere/source/updater/updater_bis_management.hpp @@ -149,7 +149,7 @@ namespace sts::updater { R_TRY(BisAccessor::Read(dst, entry->size, entry->offset)); *out_size = entry->size; - return ResultSuccess; + return ResultSuccess(); } Result Write(const void *src, size_t size, EnumType which) { diff --git a/stratosphere/libstratosphere/source/updater/updater_bis_save.cpp b/stratosphere/libstratosphere/source/updater/updater_bis_save.cpp index 07a5f5689..6ec4fd149 100644 --- a/stratosphere/libstratosphere/source/updater/updater_bis_save.cpp +++ b/stratosphere/libstratosphere/source/updater/updater_bis_save.cpp @@ -39,7 +39,7 @@ namespace sts::updater { R_TRY(this->accessor.Initialize()); this->save_buffer = work_buffer; - return ResultSuccess; + return ResultSuccess(); } void BisSave::Finalize() { diff --git a/stratosphere/libstratosphere/source/updater/updater_files.cpp b/stratosphere/libstratosphere/source/updater/updater_files.cpp index bfb83dc34..feda0b701 100644 --- a/stratosphere/libstratosphere/source/updater/updater_files.cpp +++ b/stratosphere/libstratosphere/source/updater/updater_files.cpp @@ -24,7 +24,7 @@ namespace sts::updater { Result ReadFile(size_t *out_size, void *dst, size_t dst_size, const char *path) { FILE *fp = fopen(path, "rb"); if (fp == NULL) { - return ResultUpdaterInvalidBootImagePackage; + return ResultInvalidBootImagePackage(); } ON_SCOPE_EXIT { fclose(fp); }; @@ -34,13 +34,13 @@ namespace sts::updater { return fsdevGetLastResult(); } *out_size = read_size; - return ResultSuccess; + return ResultSuccess(); } Result GetFileHash(size_t *out_size, void *dst_hash, const char *path, void *work_buffer, size_t work_buffer_size) { FILE *fp = fopen(path, "rb"); if (fp == NULL) { - return ResultUpdaterInvalidBootImagePackage; + return ResultInvalidBootImagePackage(); } ON_SCOPE_EXIT { fclose(fp); }; @@ -66,7 +66,7 @@ namespace sts::updater { sha256ContextGetHash(&sha_ctx, dst_hash); *out_size = total_size; - return ResultSuccess; + return ResultSuccess(); } } diff --git a/stratosphere/loader/Makefile b/stratosphere/loader/Makefile index cd7b81cb1..a33159bd1 100644 --- a/stratosphere/loader/Makefile +++ b/stratosphere/loader/Makefile @@ -31,7 +31,7 @@ DATA := data INCLUDES := include ../../common/include EXEFS_SRC := exefs_src -DEFINES := -DRESULT_ABORT_ON_ASSERT -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\" +DEFINES := -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\" #--------------------------------------------------------------------------------- # options for code generation @@ -45,8 +45,18 @@ CFLAGS += $(INCLUDE) -D__SWITCH__ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17 +CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \ + -Wl,--wrap,__cxa_throw \ + -Wl,--wrap,__cxa_rethrow \ + -Wl,--wrap,__cxa_allocate_exception \ + -Wl,--wrap,__cxa_begin_catch \ + -Wl,--wrap,__cxa_end_catch \ + -Wl,--wrap,__cxa_call_unexpected \ + -Wl,--wrap,__cxa_call_terminate \ + -Wl,--wrap,__gxx_personality_v0 + ASFLAGS := -g $(ARCH) -LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) +LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map) LIBS := -lstratosphere -lnx diff --git a/stratosphere/loader/source/ldr_arguments.cpp b/stratosphere/loader/source/ldr_arguments.cpp index 96e88acf7..fbc934333 100644 --- a/stratosphere/loader/source/ldr_arguments.cpp +++ b/stratosphere/loader/source/ldr_arguments.cpp @@ -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(); } } diff --git a/stratosphere/loader/source/ldr_capabilities.cpp b/stratosphere/loader/source/ldr_capabilities.cpp index 736317b4a..d1075c9d1 100644 --- a/stratosphere/loader/source/ldr_capabilities.cpp +++ b/stratosphere/loader/source/ldr_capabilities.cpp @@ -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) { diff --git a/stratosphere/loader/source/ldr_content_management.cpp b/stratosphere/loader/source/ldr_content_management.cpp index c65eabfe9..380d729b7 100644 --- a/stratosphere/loader/source/ldr_content_management.cpp +++ b/stratosphere/loader/source/ldr_content_management.cpp @@ -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(®.s); }; R_TRY_CATCH(lrRegLrResolveProgramPath(®, static_cast(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(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(loc.title_id), path))) { - return ResultSuccess; - } + R_UNLESS(R_FAILED(lrLrResolveApplicationHtmlDocumentPath(&lr, static_cast(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(loc.title_id), path)); R_TRY(lrLrRedirectApplicationHtmlDocumentPath(&lr, static_cast(loc.title_id), static_cast(loc.title_id), path)); - return ResultSuccess; + return ResultSuccess(); } } diff --git a/stratosphere/loader/source/ldr_ecs.cpp b/stratosphere/loader/source/ldr_ecs.cpp index ee460f112..25435e4ae 100644 --- a/stratosphere/loader/source/ldr_ecs.cpp +++ b/stratosphere/loader/source/ldr_ecs.cpp @@ -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(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(title_id)); - return ResultSuccess; + return ResultSuccess(); } } diff --git a/stratosphere/loader/source/ldr_launch_record.cpp b/stratosphere/loader/source/ldr_launch_record.cpp index e3ff73047..2879d06f3 100644 --- a/stratosphere/loader/source/ldr_launch_record.cpp +++ b/stratosphere/loader/source/ldr_launch_record.cpp @@ -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(); } } diff --git a/stratosphere/loader/source/ldr_loader_service.cpp b/stratosphere/loader/source/ldr_loader_service.cpp index 71ba3bb73..e50306550 100644 --- a/stratosphere/loader/source/ldr_loader_service.cpp +++ b/stratosphere/loader/source/ldr_loader_service.cpp @@ -60,7 +60,7 @@ namespace sts::ldr { } } - return ResultSuccess; + return ResultSuccess(); } Result LoaderService::PinTitle(sf::Out out_id, const ncm::TitleLocation &loc) { @@ -80,10 +80,7 @@ namespace sts::ldr { } Result LoaderService::GetProcessModuleInfo(sf::Out count, const sf::OutPointerArray &out, os::ProcessId process_id) { - if (out.GetSize() > std::numeric_limits::max()) { - return ResultLoaderInvalidSize; - } - + R_UNLESS(out.GetSize() <= std::numeric_limits::max(), ResultInvalidSize()); return ldr::ro::GetProcessModuleInfo(count.GetPointer(), out.GetPointer(), out.GetSize(), process_id); } diff --git a/stratosphere/loader/source/ldr_main.cpp b/stratosphere/loader/source/ldr_main.cpp index ebc612259..0bbd7847f 100644 --- a/stratosphere/loader/source/ldr_main.cpp +++ b/stratosphere/loader/source/ldr_main.cpp @@ -54,6 +54,12 @@ namespace sts::ams { } +namespace sts::result { + + bool CallFatalOnResultAssertion = false; + +} + using namespace sts; void __libnx_exception_handler(ThreadExceptionDump *ctx) { diff --git a/stratosphere/loader/source/ldr_meta.cpp b/stratosphere/loader/source/ldr_meta.cpp index 4725438b2..13d42f1d5 100644 --- a/stratosphere/loader/source/ldr_meta.cpp +++ b/stratosphere/loader/source/ldr_meta.cpp @@ -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(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() { diff --git a/stratosphere/loader/source/ldr_process_creation.cpp b/stratosphere/loader/source/ldr_process_creation.cpp index d5edec87f..ae142c9ee 100644 --- a/stratosphere/loader/source/ldr_process_creation.cpp +++ b/stratosphere/loader/source/ldr_process_creation.cpp @@ -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::max() || segment->size > std::numeric_limits::max()) { - return ResultLoaderInvalidNso; - } + R_UNLESS(file_size <= segment->size, ResultInvalidNso()); + R_UNLESS(segment->size <= std::numeric_limits::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(load_address), file_size, 1, f) != 1) { - return ResultLoaderInvalidNso; - } + R_UNLESS(fread(reinterpret_cast(load_address), file_size, 1, f) == 1, ResultInvalidNso()); /* Uncompress if necessary. */ if (is_compressed) { - if (util::DecompressLZ4(reinterpret_cast(map_base), segment->size, reinterpret_cast(load_address), file_size) != static_cast(segment->size)) { - return ResultLoaderInvalidNso; - } + bool decompressed = (util::DecompressLZ4(reinterpret_cast(map_base), segment->size, reinterpret_cast(load_address), file_size) == static_cast(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(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) { diff --git a/stratosphere/loader/source/ldr_ro_manager.cpp b/stratosphere/loader/source/ldr_ro_manager.cpp index 3bf5a1f48..b53d03272 100644 --- a/stratosphere/loader/source/ldr_ro_manager.cpp +++ b/stratosphere/loader/source/ldr_ro_manager.cpp @@ -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(count); - return ResultSuccess; + return ResultSuccess(); } } diff --git a/stratosphere/pm/Makefile b/stratosphere/pm/Makefile index 09abb4c9a..1fcad970c 100644 --- a/stratosphere/pm/Makefile +++ b/stratosphere/pm/Makefile @@ -31,7 +31,7 @@ DATA := data INCLUDES := include ../../common/include EXEFS_SRC := exefs_src -DEFINES := -DRESULT_ABORT_ON_ASSERT -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\" +DEFINES := -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\" #--------------------------------------------------------------------------------- # options for code generation @@ -45,8 +45,18 @@ CFLAGS += $(INCLUDE) -D__SWITCH__ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17 +CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \ + -Wl,--wrap,__cxa_throw \ + -Wl,--wrap,__cxa_rethrow \ + -Wl,--wrap,__cxa_allocate_exception \ + -Wl,--wrap,__cxa_begin_catch \ + -Wl,--wrap,__cxa_end_catch \ + -Wl,--wrap,__cxa_call_unexpected \ + -Wl,--wrap,__cxa_call_terminate \ + -Wl,--wrap,__gxx_personality_v0 + ASFLAGS := -g $(ARCH) -LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) +LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map) LIBS := -lstratosphere -lnx diff --git a/stratosphere/pm/source/impl/pm_process_manager.cpp b/stratosphere/pm/source/impl/pm_process_manager.cpp index 039776f56..3ac504399 100644 --- a/stratosphere/pm/source/impl/pm_process_manager.cpp +++ b/stratosphere/pm/source/impl/pm_process_manager.cpp @@ -205,7 +205,7 @@ namespace sts::pm::impl { /* Process Launch synchronization globals. */ os::Event g_process_launch_start_event; os::Event g_process_launch_finish_event; - Result g_process_launch_result = ResultSuccess; + Result g_process_launch_result = ResultSuccess(); LaunchProcessArgs g_process_launch_args = {}; /* Hook globals. */ @@ -214,7 +214,7 @@ namespace sts::pm::impl { /* Forward declarations. */ Result LaunchProcess(os::WaitableManager &waitable_manager, const LaunchProcessArgs &args); - Result OnProcessSignaled(ProcessListAccessor &list, ProcessInfo *process_info); + void OnProcessSignaled(ProcessListAccessor &list, ProcessInfo *process_info); /* Helpers. */ void ProcessTrackingMain(void *arg) { @@ -270,7 +270,7 @@ namespace sts::pm::impl { Result StartProcess(ProcessInfo *process_info, const ldr::ProgramInfo *program_info) { R_TRY(svcStartProcess(process_info->GetHandle(), program_info->main_thread_priority, program_info->default_cpu_id, program_info->main_thread_stack_size)); process_info->SetState(ProcessState_Running); - return ResultSuccess; + return ResultSuccess(); } void CleanupProcessInfo(ProcessListAccessor &list, ProcessInfo *process_info) { @@ -289,9 +289,7 @@ namespace sts::pm::impl { const bool allow_debug = (program_info.flags & ldr::ProgramInfoFlag_AllowDebug) || hos::GetVersion() < hos::Version_200; /* Ensure we only try to run one application. */ - if (is_application && HasApplicationProcess()) { - return ResultPmApplicationRunning; - } + R_UNLESS(!is_application || !HasApplicationProcess(), pm::ResultApplicationRunning()); /* Fix the title location to use the right title id. */ const ncm::TitleLocation location = ncm::TitleLocation::Make(program_info.title_id, static_cast(args.location.storage_id)); @@ -300,14 +298,17 @@ namespace sts::pm::impl { ldr::PinId pin_id; R_TRY(ldr::pm::PinTitle(&pin_id, location)); + /* Ensure resources are available. */ resource::WaitResourceAvailable(&program_info); /* Actually create the process. */ Handle process_handle; - R_TRY_CLEANUP(ldr::pm::CreateProcess(&process_handle, pin_id, GetLoaderCreateProcessFlags(args.flags), resource::GetResourceLimitHandle(&program_info)), { - ldr::pm::UnpinTitle(pin_id); - }); + { + auto pin_guard = SCOPE_GUARD { ldr::pm::UnpinTitle(pin_id); }; + R_TRY(ldr::pm::CreateProcess(&process_handle, pin_id, GetLoaderCreateProcessFlags(args.flags), resource::GetResourceLimitHandle(&program_info))); + pin_guard.Cancel(); + } /* Get the process id. */ os::ProcessId process_id = os::GetProcessId(process_handle); @@ -369,11 +370,11 @@ namespace sts::pm::impl { cleanup_guard.Cancel(); *args.out_process_id = process_id; - return ResultSuccess; + return ResultSuccess(); } - Result OnProcessSignaled(ProcessListAccessor &list, ProcessInfo *process_info) { - /* Resest the process's signal. */ + void OnProcessSignaled(ProcessListAccessor &list, ProcessInfo *process_info) { + /* Reset the process's signal. */ svcResetSignal(process_info->GetHandle()); /* Update the process's state. */ @@ -442,8 +443,6 @@ namespace sts::pm::impl { CleanupProcessInfo(list, process_info); } } - /* Return ConnectionClosed to cause libstratosphere to stop waiting on the process. */ - return ResultKernelConnectionClosed; case ProcessState_DebugSuspended: if (process_info->ShouldSignalOnDebugEvent()) { process_info->SetSuspended(); @@ -452,8 +451,6 @@ namespace sts::pm::impl { } break; } - - return ResultSuccess; } } @@ -472,7 +469,7 @@ namespace sts::pm::impl { /* Start thread. */ R_ASSERT(g_process_track_thread.Start()); - return ResultSuccess; + return ResultSuccess(); } /* Process Management. */ @@ -497,13 +494,8 @@ namespace sts::pm::impl { ProcessListAccessor list(g_process_list); auto process_info = list->Find(process_id); - if (process_info == nullptr) { - return ResultPmProcessNotFound; - } - - if (process_info->HasStarted()) { - return ResultPmAlreadyStarted; - } + R_UNLESS(process_info != nullptr, pm::ResultProcessNotFound()); + R_UNLESS(!process_info->HasStarted(), pm::ResultAlreadyStarted()); ldr::ProgramInfo program_info; R_TRY(ldr::pm::GetProgramInfo(&program_info, process_info->GetTitleLocation())); @@ -514,9 +506,7 @@ namespace sts::pm::impl { ProcessListAccessor list(g_process_list); auto process_info = list->Find(process_id); - if (process_info == nullptr) { - return ResultPmProcessNotFound; - } + R_UNLESS(process_info != nullptr, pm::ResultProcessNotFound()); return svcTerminateProcess(process_info->GetHandle()); } @@ -525,16 +515,14 @@ namespace sts::pm::impl { ProcessListAccessor list(g_process_list); auto process_info = list->Find(title_id); - if (process_info == nullptr) { - return ResultPmProcessNotFound; - } + R_UNLESS(process_info != nullptr, pm::ResultProcessNotFound()); return svcTerminateProcess(process_info->GetHandle()); } Result GetProcessEventHandle(Handle *out) { *out = g_process_event.GetReadableHandle(); - return ResultSuccess; + return ResultSuccess(); } Result GetProcessEventInfo(ProcessEventInfo *out) { @@ -548,7 +536,7 @@ namespace sts::pm::impl { process.ClearStartedStateChanged(); out->event = GetProcessEventValue(ProcessEvent::Started); out->process_id = process.GetProcessId(); - return ResultSuccess; + return ResultSuccess(); } if (process.HasSuspendedStateChanged()) { process.ClearSuspendedStateChanged(); @@ -558,18 +546,18 @@ namespace sts::pm::impl { out->event = GetProcessEventValue(ProcessEvent::DebugRunning); } out->process_id = process.GetProcessId(); - return ResultSuccess; + return ResultSuccess(); } if (process.HasExceptionOccurred()) { process.ClearExceptionOccurred(); out->event = GetProcessEventValue(ProcessEvent::Exception); out->process_id = process.GetProcessId(); - return ResultSuccess; + return ResultSuccess(); } if (hos::GetVersion() < hos::Version_500 && process.ShouldSignalOnExit() && process.HasExited()) { out->event = GetProcessEventValue(ProcessEvent::Exited); out->process_id = process.GetProcessId(); - return ResultSuccess; + return ResultSuccess(); } } } @@ -584,48 +572,41 @@ namespace sts::pm::impl { out->process_id = process_info.GetProcessId(); CleanupProcessInfo(dead_list, &process_info); - return ResultSuccess; + return ResultSuccess(); } } out->process_id = os::ProcessId{}; out->event = GetProcessEventValue(ProcessEvent::None); - return ResultSuccess; + return ResultSuccess(); } Result CleanupProcess(os::ProcessId process_id) { ProcessListAccessor list(g_process_list); auto process_info = list->Find(process_id); - if (process_info == nullptr) { - return ResultPmProcessNotFound; - } - - if (!process_info->HasExited()) { - return ResultPmNotExited; - } + R_UNLESS(process_info != nullptr, pm::ResultProcessNotFound()); + R_UNLESS(process_info->HasExited(), pm::ResultNotExited()); CleanupProcessInfo(list, process_info); - return ResultSuccess; + return ResultSuccess(); } Result ClearExceptionOccurred(os::ProcessId process_id) { ProcessListAccessor list(g_process_list); auto process_info = list->Find(process_id); - if (process_info == nullptr) { - return ResultPmProcessNotFound; - } + R_UNLESS(process_info != nullptr, pm::ResultProcessNotFound()); process_info->ClearExceptionOccurred(); - return ResultSuccess; + return ResultSuccess(); } /* Information Getters. */ Result GetModuleIdList(u32 *out_count, u8 *out_buf, size_t max_out_count, u64 unused) { /* This function was always stubbed... */ *out_count = 0; - return ResultSuccess; + return ResultSuccess(); } Result GetExceptionProcessIdList(u32 *out_count, os::ProcessId *out_process_ids, size_t max_out_count) { @@ -638,31 +619,27 @@ namespace sts::pm::impl { } } *out_count = static_cast(count); - return ResultSuccess; + return ResultSuccess(); } Result GetProcessId(os::ProcessId *out, ncm::TitleId title_id) { ProcessListAccessor list(g_process_list); auto process_info = list->Find(title_id); - if (process_info == nullptr) { - return ResultPmProcessNotFound; - } + R_UNLESS(process_info != nullptr, pm::ResultProcessNotFound()); *out = process_info->GetProcessId(); - return ResultSuccess; + return ResultSuccess(); } Result GetTitleId(ncm::TitleId *out, os::ProcessId process_id) { ProcessListAccessor list(g_process_list); auto process_info = list->Find(process_id); - if (process_info == nullptr) { - return ResultPmProcessNotFound; - } + R_UNLESS(process_info != nullptr, pm::ResultProcessNotFound()); *out = process_info->GetTitleLocation().title_id; - return ResultSuccess; + return ResultSuccess(); } Result GetApplicationProcessId(os::ProcessId *out_process_id) { @@ -671,49 +648,47 @@ namespace sts::pm::impl { for (auto &process : *list) { if (process.IsApplication()) { *out_process_id = process.GetProcessId(); - return ResultSuccess; + return ResultSuccess(); } } - return ResultPmProcessNotFound; + return pm::ResultProcessNotFound(); } Result AtmosphereGetProcessInfo(Handle *out_process_handle, ncm::TitleLocation *out_loc, os::ProcessId process_id) { ProcessListAccessor list(g_process_list); auto process_info = list->Find(process_id); - if (process_info == nullptr) { - return ResultPmProcessNotFound; - } + R_UNLESS(process_info != nullptr, pm::ResultProcessNotFound()); *out_process_handle = process_info->GetHandle(); *out_loc = process_info->GetTitleLocation(); - return ResultSuccess; + return ResultSuccess(); } /* Hook API. */ Result HookToCreateProcess(Handle *out_hook, ncm::TitleId title_id) { *out_hook = INVALID_HANDLE; - ncm::TitleId old_value = ncm::TitleId::Invalid; - if (!g_title_id_hook.compare_exchange_strong(old_value, title_id)) { - return ResultPmDebugHookInUse; + { + ncm::TitleId old_value = ncm::TitleId::Invalid; + R_UNLESS(g_title_id_hook.compare_exchange_strong(old_value, title_id), pm::ResultDebugHookInUse()); } *out_hook = g_hook_to_create_process_event.GetReadableHandle(); - return ResultSuccess; + return ResultSuccess(); } Result HookToCreateApplicationProcess(Handle *out_hook) { *out_hook = INVALID_HANDLE; - bool old_value = false; - if (!g_application_hook.compare_exchange_strong(old_value, true)) { - return ResultPmDebugHookInUse; + { + bool old_value = false; + R_UNLESS(g_application_hook.compare_exchange_strong(old_value, true), pm::ResultDebugHookInUse()); } *out_hook = g_hook_to_create_application_process_event.GetReadableHandle(); - return ResultSuccess; + return ResultSuccess(); } Result ClearHook(u32 which) { @@ -723,7 +698,7 @@ namespace sts::pm::impl { if (which & HookType_Application) { g_application_hook = false; } - return ResultSuccess; + return ResultSuccess(); } /* Boot API. */ @@ -734,7 +709,7 @@ namespace sts::pm::impl { g_has_boot_finished = true; g_boot_finished_event.Signal(); } - return ResultSuccess; + return ResultSuccess(); } Result GetBootFinishedEventHandle(Handle *out) { @@ -743,7 +718,7 @@ namespace sts::pm::impl { /* We will signal it always, but only allow this function to succeed on safe mode. */ STS_ASSERT(spl::IsRecoveryBoot()); *out = g_boot_finished_event.GetReadableHandle(); - return ResultSuccess; + return ResultSuccess(); } /* Resource Limit API. */ diff --git a/stratosphere/pm/source/impl/pm_resource_manager.cpp b/stratosphere/pm/source/impl/pm_resource_manager.cpp index 0ddbc6c19..e2bf072f8 100644 --- a/stratosphere/pm/source/impl/pm_resource_manager.cpp +++ b/stratosphere/pm/source/impl/pm_resource_manager.cpp @@ -14,6 +14,7 @@ * along with this program. If not, see . */ +#include #include #include "pm_resource_manager.hpp" @@ -107,11 +108,15 @@ namespace sts::pm::resource { Result SetMemoryResourceLimitLimitValue(ResourceLimitGroup group, u64 new_memory_limit) { const u64 old_memory_limit = g_resource_limits[group][LimitableResource_Memory]; g_resource_limits[group][LimitableResource_Memory] = new_memory_limit; - R_TRY_CLEANUP(svcSetResourceLimitLimitValue(GetResourceLimitHandle(group), LimitableResource_Memory, g_resource_limits[group][LimitableResource_Memory]), { + + { /* If we fail, restore the old memory limit. */ - g_resource_limits[group][LimitableResource_Memory] = old_memory_limit; - }); - return ResultSuccess; + auto limit_guard = SCOPE_GUARD { g_resource_limits[group][LimitableResource_Memory] = old_memory_limit; }; + R_TRY(svcSetResourceLimitLimitValue(GetResourceLimitHandle(group), LimitableResource_Memory, g_resource_limits[group][LimitableResource_Memory])); + limit_guard.Cancel(); + } + + return ResultSuccess(); } Result SetResourceLimitLimitValues(ResourceLimitGroup group, u64 new_memory_limit) { @@ -126,7 +131,7 @@ namespace sts::pm::resource { } R_TRY(svcSetResourceLimitLimitValue(GetResourceLimitHandle(group), resource, g_resource_limits[group][resource])); } - return ResultSuccess; + return ResultSuccess(); } inline ResourceLimitGroup GetResourceLimitGroup(const ldr::ProgramInfo *info) { @@ -269,14 +274,12 @@ namespace sts::pm::resource { } } - return ResultSuccess; + return ResultSuccess(); } Result BoostSystemMemoryResourceLimit(u64 boost_size) { /* Don't allow all application memory to be taken away. */ - if (boost_size > g_memory_resource_limits[g_memory_arrangement][ResourceLimitGroup_Application]) { - return ResultPmInvalidSize; - } + R_UNLESS(boost_size <= g_memory_resource_limits[g_memory_arrangement][ResourceLimitGroup_Application], pm::ResultInvalidSize()); const u64 new_app_size = g_memory_resource_limits[g_memory_arrangement][ResourceLimitGroup_Application] - boost_size; { @@ -305,7 +308,7 @@ namespace sts::pm::resource { g_system_memory_boost_size = boost_size; } - return ResultSuccess; + return ResultSuccess(); } Result BoostApplicationThreadResourceLimit() { @@ -318,7 +321,7 @@ namespace sts::pm::resource { g_resource_limits[ResourceLimitGroup_Application][LimitableResource_Threads] = new_thread_count; g_extra_application_threads_available = 0; - return ResultSuccess; + return ResultSuccess(); } Handle GetResourceLimitHandle(ResourceLimitGroup group) { @@ -347,7 +350,7 @@ namespace sts::pm::resource { R_TRY(svcGetResourceLimitCurrentValue(out_cur, reslimit_hnd, resource)); R_TRY(svcGetResourceLimitLimitValue(out_lim, reslimit_hnd, resource)); - return ResultSuccess; + return ResultSuccess(); } } diff --git a/stratosphere/pm/source/pm_debug_monitor_service.cpp b/stratosphere/pm/source/pm_debug_monitor_service.cpp index 9b26969c1..30df43437 100644 --- a/stratosphere/pm/source/pm_debug_monitor_service.cpp +++ b/stratosphere/pm/source/pm_debug_monitor_service.cpp @@ -22,16 +22,12 @@ namespace sts::pm::dmnt { /* Actual command implementations. */ Result DebugMonitorServiceBase::GetModuleIdList(sf::Out out_count, const sf::OutBuffer &out_buf, u64 unused) { - if (out_buf.GetSize() > std::numeric_limits::max()) { - return ResultPmInvalidSize; - } + R_UNLESS(out_buf.GetSize() <= std::numeric_limits::max(), pm::ResultInvalidSize()); return impl::GetModuleIdList(out_count.GetPointer(), out_buf.GetPointer(), out_buf.GetSize(), unused); } Result DebugMonitorServiceBase::GetExceptionProcessIdList(sf::Out out_count, const sf::OutArray &out_process_ids) { - if (out_process_ids.GetSize() > std::numeric_limits::max()) { - return ResultPmInvalidSize; - } + R_UNLESS(out_process_ids.GetSize() <= std::numeric_limits::max(), pm::ResultInvalidSize()); return impl::GetExceptionProcessIdList(out_count.GetPointer(), out_process_ids.GetPointer(), out_process_ids.GetSize()); } diff --git a/stratosphere/pm/source/pm_main.cpp b/stratosphere/pm/source/pm_main.cpp index a7285c742..04b45a514 100644 --- a/stratosphere/pm/source/pm_main.cpp +++ b/stratosphere/pm/source/pm_main.cpp @@ -56,6 +56,12 @@ namespace sts::ams { } +namespace sts::result { + + bool CallFatalOnResultAssertion = false; + +} + using namespace sts; void __libnx_exception_handler(ThreadExceptionDump *ctx) { diff --git a/stratosphere/ro/Makefile b/stratosphere/ro/Makefile index 17c54ea6f..8d4e634b2 100644 --- a/stratosphere/ro/Makefile +++ b/stratosphere/ro/Makefile @@ -45,8 +45,18 @@ CFLAGS += $(INCLUDE) -D__SWITCH__ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17 +CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \ + -Wl,--wrap,__cxa_throw \ + -Wl,--wrap,__cxa_rethrow \ + -Wl,--wrap,__cxa_allocate_exception \ + -Wl,--wrap,__cxa_begin_catch \ + -Wl,--wrap,__cxa_end_catch \ + -Wl,--wrap,__cxa_call_unexpected \ + -Wl,--wrap,__cxa_call_terminate \ + -Wl,--wrap,__gxx_personality_v0 + ASFLAGS := -g $(ARCH) -LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) +LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map) LIBS := -lstratosphere -lnx diff --git a/stratosphere/ro/source/impl/ro_nro_utils.cpp b/stratosphere/ro/source/impl/ro_nro_utils.cpp index acb4b67bd..68826bfde 100644 --- a/stratosphere/ro/source/impl/ro_nro_utils.cpp +++ b/stratosphere/ro/source/impl/ro_nro_utils.cpp @@ -27,21 +27,21 @@ namespace sts::ro::impl { } Result MapNro(u64 *out_base_address, Handle process_handle, u64 nro_heap_address, u64 nro_heap_size, u64 bss_heap_address, u64 bss_heap_size) { - map::MappedCodeMemory nro_mcm(ResultRoInternalError); - map::MappedCodeMemory bss_mcm(ResultRoInternalError); + map::MappedCodeMemory nro_mcm(ResultInternalError{}); + map::MappedCodeMemory bss_mcm(ResultInternalError{}); u64 base_address; /* Map the NRO, and map the BSS immediately after it. */ size_t i; for (i = 0; i < MaxMapRetries; i++) { - map::MappedCodeMemory tmp_nro_mcm(ResultRoInternalError); + map::MappedCodeMemory tmp_nro_mcm(ResultInternalError{}); R_TRY(map::MapCodeMemoryInProcess(tmp_nro_mcm, process_handle, nro_heap_address, nro_heap_size)); base_address = tmp_nro_mcm.GetDstAddress(); if (bss_heap_size > 0) { map::MappedCodeMemory tmp_bss_mcm(process_handle, base_address + nro_heap_size, bss_heap_address, bss_heap_size); R_TRY_CATCH(tmp_bss_mcm.GetResult()) { - R_CATCH(ResultKernelInvalidMemoryState) { + R_CATCH(svc::ResultInvalidCurrentMemoryState) { continue; } } R_END_TRY_CATCH; @@ -59,16 +59,14 @@ namespace sts::ro::impl { nro_mcm = std::move(tmp_nro_mcm); break; } - if (i == MaxMapRetries) { - return ResultRoInsufficientAddressSpace; - } + R_UNLESS(i < MaxMapRetries, ResultOutOfAddressSpace()); /* Invalidation here actually prevents them from unmapping at scope exit. */ nro_mcm.Invalidate(); bss_mcm.Invalidate(); *out_base_address = base_address; - return ResultSuccess; + return ResultSuccess(); } Result SetNroPerms(Handle process_handle, u64 base_address, u64 rx_size, u64 ro_size, u64 rw_size) { @@ -80,7 +78,7 @@ namespace sts::ro::impl { R_TRY(svcSetProcessMemoryPermission(process_handle, base_address + ro_offset, ro_size, Perm_R )); R_TRY(svcSetProcessMemoryPermission(process_handle, base_address + rw_offset, rw_size, Perm_Rw)); - return ResultSuccess; + return ResultSuccess(); } Result UnmapNro(Handle process_handle, u64 base_address, u64 nro_heap_address, u64 bss_heap_address, u64 bss_heap_size, u64 code_size, u64 rw_size) { @@ -97,7 +95,7 @@ namespace sts::ro::impl { /* Finally, unmap .text + .rodata. */ R_TRY(svcUnmapProcessCodeMemory(process_handle, base_address, nro_heap_address, code_size)); - return ResultSuccess; + return ResultSuccess(); } } diff --git a/stratosphere/ro/source/impl/ro_nrr_utils.cpp b/stratosphere/ro/source/impl/ro_nrr_utils.cpp index d03a74ef9..78cb7fd13 100644 --- a/stratosphere/ro/source/impl/ro_nrr_utils.cpp +++ b/stratosphere/ro/source/impl/ro_nrr_utils.cpp @@ -28,33 +28,23 @@ namespace sts::ro::impl { /* TODO: Implement RSA-2048 PSS..... */ /* TODO: Check PSS fixed-key signature. */ - if (false) { - return ResultRoNotAuthorized; - } + R_UNLESS(true, ResultNotAuthorized()); /* Check TitleID pattern is valid. */ - if (!header->IsTitleIdValid()) { - return ResultRoNotAuthorized; - } + R_UNLESS(header->IsTitleIdValid(), ResultNotAuthorized()); /* TODO: Check PSS signature over hashes. */ - if (false) { - return ResultRoNotAuthorized; - } + R_UNLESS(true, ResultNotAuthorized()); - return ResultSuccess; + return ResultSuccess(); } Result ValidateNrr(const NrrHeader *header, u64 size, ncm::TitleId title_id, ModuleType expected_type, bool enforce_type) { /* Check magic. */ - if (!header->IsMagicValid()) { - return ResultRoInvalidNrr; - } + R_UNLESS(header->IsMagicValid(), ResultInvalidNrr()); /* Check size. */ - if (header->GetSize() != size) { - return ResultRoInvalidSize; - } + R_UNLESS(header->GetSize() == size, ResultInvalidSize()); /* Only perform checks if we must. */ const bool ease_nro_restriction = ShouldEaseNroRestriction(); @@ -63,41 +53,33 @@ namespace sts::ro::impl { R_TRY(ValidateNrrSignature(header)); /* Check title id. */ - if (title_id != header->GetTitleId()) { - return ResultRoInvalidNrr; - } + R_UNLESS(header->GetTitleId() == title_id, ResultInvalidNrr()); /* Check type. */ if (hos::GetVersion() >= hos::Version_700 && enforce_type) { - if (expected_type != header->GetType()) { - return ResultRoInvalidNrrType; - } + R_UNLESS(header->GetType() == expected_type, ResultInvalidNrrType()); } } - return ResultSuccess; + return ResultSuccess(); } } /* Utilities for working with NRRs. */ Result MapAndValidateNrr(NrrHeader **out_header, u64 *out_mapped_code_address, Handle process_handle, ncm::TitleId title_id, u64 nrr_heap_address, u64 nrr_heap_size, ModuleType expected_type, bool enforce_type) { - map::MappedCodeMemory nrr_mcm(ResultRoInternalError); + map::MappedCodeMemory nrr_mcm(ResultInternalError{}); /* First, map the NRR. */ R_TRY(map::MapCodeMemoryInProcess(nrr_mcm, process_handle, nrr_heap_address, nrr_heap_size)); const u64 code_address = nrr_mcm.GetDstAddress(); uintptr_t map_address; - if (R_FAILED(map::LocateMappableSpace(&map_address, nrr_heap_size))) { - return ResultRoInsufficientAddressSpace; - } + R_UNLESS(R_SUCCEEDED(map::LocateMappableSpace(&map_address, nrr_heap_size)), ResultOutOfAddressSpace()); /* Nintendo...does not check the return value of this map. We will check, instead of aborting if it fails. */ map::AutoCloseMap nrr_map(map_address, process_handle, code_address, nrr_heap_size); - if (!nrr_map.IsSuccess()) { - return nrr_map.GetResult(); - } + R_TRY(nrr_map.GetResult()); NrrHeader *nrr_header = reinterpret_cast(map_address); R_TRY(ValidateNrr(nrr_header, nrr_heap_size, title_id, expected_type, enforce_type)); @@ -108,13 +90,13 @@ namespace sts::ro::impl { *out_header = nrr_header; *out_mapped_code_address = code_address; - return ResultSuccess; + return ResultSuccess(); } Result UnmapNrr(Handle process_handle, const NrrHeader *header, u64 nrr_heap_address, u64 nrr_heap_size, u64 mapped_code_address) { R_TRY(svcUnmapProcessMemory(reinterpret_cast(const_cast(header)), process_handle, mapped_code_address, nrr_heap_size)); R_TRY(svcUnmapProcessCodeMemory(process_handle, mapped_code_address, nrr_heap_address, nrr_heap_size)); - return ResultSuccess; + return ResultSuccess(); } } diff --git a/stratosphere/ro/source/impl/ro_service_impl.cpp b/stratosphere/ro/source/impl/ro_service_impl.cpp index 3f3c478e2..6665c5083 100644 --- a/stratosphere/ro/source/impl/ro_service_impl.cpp +++ b/stratosphere/ro/source/impl/ro_service_impl.cpp @@ -105,10 +105,10 @@ namespace sts::ro::impl { if (out != nullptr) { *out = &this->nrr_infos[i]; } - return ResultSuccess; + return ResultSuccess(); } } - return ResultRoNotRegistered; + return ResultNotRegistered(); } Result GetFreeNrrInfo(NrrInfo **out) { @@ -117,10 +117,10 @@ namespace sts::ro::impl { if (out != nullptr) { *out = &this->nrr_infos[i]; } - return ResultSuccess; + return ResultSuccess(); } } - return ResultRoTooManyNrr; + return ResultTooManyNrr(); } Result GetNroInfoByAddress(NroInfo **out, u64 nro_address) { @@ -129,10 +129,10 @@ namespace sts::ro::impl { if (out != nullptr) { *out = &this->nro_infos[i]; } - return ResultSuccess; + return ResultSuccess(); } } - return ResultRoNotLoaded; + return ResultNotLoaded(); } Result GetNroInfoByModuleId(NroInfo **out, const ModuleId *module_id) { @@ -141,10 +141,10 @@ namespace sts::ro::impl { if (out != nullptr) { *out = &this->nro_infos[i]; } - return ResultSuccess; + return ResultSuccess(); } } - return ResultRoNotLoaded; + return ResultNotLoaded(); } Result GetFreeNroInfo(NroInfo **out) { @@ -153,10 +153,10 @@ namespace sts::ro::impl { if (out != nullptr) { *out = &this->nro_infos[i]; } - return ResultSuccess; + return ResultSuccess(); } } - return ResultRoTooManyNro; + return ResultTooManyNro(); } Result ValidateHasNroHash(const NroHeader *nro_header) const { @@ -168,34 +168,27 @@ namespace sts::ro::impl { if (this->nrr_infos[i].in_use) { const NrrHeader *nrr_header = this->nrr_infos[i].header; const Sha256Hash *nro_hashes = reinterpret_cast(nrr_header->GetHashes()); - if (std::binary_search(nro_hashes, nro_hashes + nrr_header->GetNumHashes(), hash)) { - return ResultSuccess; - } + R_UNLESS(!std::binary_search(nro_hashes, nro_hashes + nrr_header->GetNumHashes(), hash), ResultSuccess()); } } - return ResultRoNotAuthorized; + return ResultNotAuthorized(); } Result ValidateNro(ModuleId *out_module_id, u64 *out_rx_size, u64 *out_ro_size, u64 *out_rw_size, u64 base_address, u64 expected_nro_size, u64 expected_bss_size) { /* Find space to map the NRO. */ uintptr_t map_address; - if (R_FAILED(map::LocateMappableSpace(&map_address, expected_nro_size))) { - return ResultRoInsufficientAddressSpace; - } + R_UNLESS(R_SUCCEEDED(map::LocateMappableSpace(&map_address, expected_nro_size)), ResultOutOfAddressSpace()); /* Actually map the NRO. */ map::AutoCloseMap nro_map(map_address, this->process_handle, base_address, expected_nro_size); - if (!nro_map.IsSuccess()) { - return nro_map.GetResult(); - } + R_TRY(nro_map.GetResult()); /* Validate header. */ const NroHeader *header = reinterpret_cast(map_address); - if (!header->IsMagicValid()) { - return ResultRoInvalidNro; - } + R_UNLESS(header->IsMagicValid(), ResultInvalidNro()); + /* Read sizes from header. */ const u64 nro_size = header->GetSize(); const u64 text_ofs = header->GetTextOffset(); const u64 text_size = header->GetTextSize(); @@ -204,27 +197,33 @@ namespace sts::ro::impl { const u64 rw_ofs = header->GetRwOffset(); const u64 rw_size = header->GetRwSize(); const u64 bss_size = header->GetBssSize(); - if (nro_size != expected_nro_size || bss_size != expected_bss_size) { - return ResultRoInvalidNro; - } - if ((text_size & 0xFFF) || (ro_size & 0xFFF) || (rw_size & 0xFFF) || (bss_size & 0xFFF)) { - return ResultRoInvalidNro; - } - if (text_ofs > ro_ofs || ro_ofs > rw_ofs) { - return ResultRoInvalidNro; - } - if (text_ofs != 0 || text_ofs + text_size != ro_ofs || ro_ofs + ro_size != rw_ofs || rw_ofs + rw_size != nro_size) { - return ResultRoInvalidNro; - } + + /* Validate sizes meet expected. */ + R_UNLESS(nro_size == expected_nro_size, ResultInvalidNro()); + R_UNLESS(bss_size == expected_bss_size, ResultInvalidNro()); + + /* Validate all sizes are aligned. */ + R_UNLESS(util::IsAligned(text_size, 0x1000), ResultInvalidNro()); + R_UNLESS(util::IsAligned(ro_size, 0x1000), ResultInvalidNro()); + R_UNLESS(util::IsAligned(rw_size, 0x1000), ResultInvalidNro()); + R_UNLESS(util::IsAligned(bss_size, 0x1000), ResultInvalidNro()); + + /* Validate sections are in order. */ + R_UNLESS(text_ofs <= ro_ofs, ResultInvalidNro()); + R_UNLESS(ro_ofs <= rw_ofs, ResultInvalidNro()); + + /* Validate sections are sequential and contiguous. */ + R_UNLESS(text_ofs == 0, ResultInvalidNro()); + R_UNLESS(text_ofs + text_size == ro_ofs, ResultInvalidNro()); + R_UNLESS(ro_ofs + ro_size == rw_ofs, ResultInvalidNro()); + R_UNLESS(rw_ofs + rw_size == nro_size, ResultInvalidNro()); /* Verify NRO hash. */ R_TRY(this->ValidateHasNroHash(header)); /* Check if NRO has already been loaded. */ const ModuleId *module_id = header->GetModuleId(); - if (R_SUCCEEDED(this->GetNroInfoByModuleId(nullptr, module_id))) { - return ResultRoAlreadyLoaded; - } + R_UNLESS(R_FAILED(this->GetNroInfoByModuleId(nullptr, module_id)), ResultAlreadyLoaded()); /* Apply patches to NRO. */ LocateAndApplyIpsPatchesToModule(module_id, reinterpret_cast(map_address), nro_size); @@ -234,7 +233,7 @@ namespace sts::ro::impl { *out_rx_size = text_size; *out_ro_size = ro_size; *out_rw_size = rw_size; - return ResultSuccess; + return ResultSuccess(); } }; @@ -295,6 +294,14 @@ namespace sts::ro::impl { } } + constexpr inline Result ValidateAddressAndSize(u64 address, u64 size) { + R_UNLESS(util::IsAligned(address, 0x1000), ResultInvalidAddress()); + R_UNLESS(size != 0, ResultInvalidSize()); + R_UNLESS(util::IsAligned(size, 0x1000), ResultInvalidSize()); + R_UNLESS(address < address + size, ResultInvalidSize()); + return ResultSuccess(); + } + } /* Access utilities. */ @@ -334,31 +341,24 @@ namespace sts::ro::impl { os::ProcessId handle_pid = os::InvalidProcessId; /* Validate handle is a valid process handle. */ - if (R_FAILED(os::TryGetProcessId(&handle_pid, process_handle))) { - return ResultRoInvalidProcess; - } + R_UNLESS(R_SUCCEEDED(os::TryGetProcessId(&handle_pid, process_handle)), ResultInvalidProcess()); /* Validate process id. */ - if (handle_pid != process_id) { - return ResultRoInvalidProcess; - } + R_UNLESS(handle_pid == process_id, ResultInvalidProcess()); } /* Check if a process context already exists. */ - if (GetContextByProcessId(process_id) != nullptr) { - return ResultRoInvalidSession; - } + R_UNLESS(GetContextByProcessId(process_id) == nullptr, ResultInvalidSession()); *out_context_id = AllocateContext(process_handle, process_id); - return ResultSuccess; + return ResultSuccess(); } Result ValidateProcess(size_t context_id, os::ProcessId process_id) { const ProcessContext *ctx = GetContextById(context_id); - if (ctx == nullptr || ctx->process_id != process_id) { - return ResultRoInvalidProcess; - } - return ResultSuccess; + R_UNLESS(ctx != nullptr, ResultInvalidProcess()); + R_UNLESS(ctx->process_id == process_id, ResultInvalidProcess()); + return ResultSuccess(); } void UnregisterProcess(size_t context_id) { @@ -375,12 +375,7 @@ namespace sts::ro::impl { const ncm::TitleId title_id = context->GetTitleId(process_h); /* Validate address/size. */ - if (nrr_address & 0xFFF) { - return ResultRoInvalidAddress; - } - if (nrr_size == 0 || (nrr_size & 0xFFF) || !(nrr_address < nrr_address + nrr_size)) { - return ResultRoInvalidSize; - } + R_TRY(ValidateAddressAndSize(nrr_address, nrr_size)); /* Check we have space for a new NRR. */ NrrInfo *nrr_info = nullptr; @@ -398,7 +393,7 @@ namespace sts::ro::impl { nrr_info->nrr_heap_size = nrr_size; nrr_info->mapped_code_address = mapped_code_address; - return ResultSuccess; + return ResultSuccess(); } Result UnloadNrr(size_t context_id, u64 nrr_address) { @@ -407,9 +402,7 @@ namespace sts::ro::impl { STS_ASSERT(context != nullptr); /* Validate address. */ - if (nrr_address & 0xFFF) { - return ResultRoInvalidAddress; - } + R_UNLESS(util::IsAligned(nrr_address, 0x1000), ResultInvalidAddress()); /* Check the NRR is loaded. */ NrrInfo *nrr_info = nullptr; @@ -431,23 +424,12 @@ namespace sts::ro::impl { STS_ASSERT(context != nullptr); /* Validate address/size. */ - if (nro_address & 0xFFF) { - return ResultRoInvalidAddress; - } - if (nro_size == 0 || (nro_size & 0xFFF) || !(nro_address < nro_address + nro_size)) { - return ResultRoInvalidSize; - } - if (bss_address & 0xFFF) { - return ResultRoInvalidAddress; - } - if ((bss_size & 0xFFF) || (bss_size > 0 && !(bss_address < bss_address + bss_size))) { - return ResultRoInvalidSize; - } + R_TRY(ValidateAddressAndSize(nro_address, nro_size)); + R_TRY(ValidateAddressAndSize(bss_address, bss_size)); const u64 total_size = nro_size + bss_size; - if (total_size < nro_size || total_size < bss_size) { - return ResultRoInvalidSize; - } + R_UNLESS(total_size >= nro_size, ResultInvalidSize()); + R_UNLESS(total_size >= bss_size, ResultInvalidSize()); /* Check we have space for a new NRO. */ NroInfo *nro_info = nullptr; @@ -462,20 +444,24 @@ namespace sts::ro::impl { /* Validate the NRO (parsing region extents). */ u64 rx_size = 0, ro_size = 0, rw_size = 0; - R_TRY_CLEANUP(context->ValidateNro(&nro_info->module_id, &rx_size, &ro_size, &rw_size, nro_info->base_address, nro_size, bss_size), { - UnmapNro(context->process_handle, nro_info->base_address, nro_address, bss_address, bss_size, nro_size, 0); - }); + { + auto unmap_guard = SCOPE_GUARD { UnmapNro(context->process_handle, nro_info->base_address, nro_address, bss_address, bss_size, nro_size, 0); }; + R_TRY(context->ValidateNro(&nro_info->module_id, &rx_size, &ro_size, &rw_size, nro_info->base_address, nro_size, bss_size)); + unmap_guard.Cancel(); + } /* Set NRO perms. */ - R_TRY_CLEANUP(SetNroPerms(context->process_handle, nro_info->base_address, rx_size, ro_size, rw_size + bss_size), { - UnmapNro(context->process_handle, nro_info->base_address, nro_address, bss_address, bss_size, rx_size + ro_size, rw_size); - }); + { + auto unmap_guard = SCOPE_GUARD { UnmapNro(context->process_handle, nro_info->base_address, nro_address, bss_address, bss_size, rx_size + ro_size, rw_size); }; + R_TRY(SetNroPerms(context->process_handle, nro_info->base_address, rx_size, ro_size, rw_size + bss_size)); + unmap_guard.Cancel(); + } nro_info->code_size = rx_size + ro_size; nro_info->rw_size = rw_size; nro_info->in_use = true; *out_address = nro_info->base_address; - return ResultSuccess; + return ResultSuccess(); } Result UnloadNro(size_t context_id, u64 nro_address) { @@ -484,9 +470,7 @@ namespace sts::ro::impl { STS_ASSERT(context != nullptr); /* Validate address. */ - if (nro_address & 0xFFF) { - return ResultRoInvalidAddress; - } + R_UNLESS(util::IsAligned(nro_address, 0x1000), ResultInvalidAddress()); /* Check the NRO is loaded. */ NroInfo *nro_info = nullptr; @@ -522,7 +506,7 @@ namespace sts::ro::impl { } *out_count = static_cast(count); - return ResultSuccess; + return ResultSuccess(); } } diff --git a/stratosphere/ro/source/ro_debug_monitor.cpp b/stratosphere/ro/source/ro_debug_monitor.cpp index 89d344ff7..7504c3eb8 100644 --- a/stratosphere/ro/source/ro_debug_monitor.cpp +++ b/stratosphere/ro/source/ro_debug_monitor.cpp @@ -24,9 +24,7 @@ namespace sts::ro { Result DebugMonitorService::GetProcessModuleInfo(sf::Out out_count, const sf::OutArray &out_infos, os::ProcessId process_id) { - if (out_infos.GetSize() > INT_MAX) { - return ResultRoInvalidSize; - } + R_UNLESS(out_infos.GetSize() <= std::numeric_limits::max(), ResultInvalidSize()); return impl::GetProcessModuleInfo(out_count.GetPointer(), out_infos.GetPointer(), out_infos.GetSize(), process_id); } diff --git a/stratosphere/ro/source/ro_main.cpp b/stratosphere/ro/source/ro_main.cpp index 4d33a7d4a..e5f63cf30 100644 --- a/stratosphere/ro/source/ro_main.cpp +++ b/stratosphere/ro/source/ro_main.cpp @@ -50,6 +50,12 @@ namespace sts::ams { } +namespace sts::result { + + bool CallFatalOnResultAssertion = true; + +} + using namespace sts; void __libnx_initheap(void) { diff --git a/stratosphere/sm/Makefile b/stratosphere/sm/Makefile index 001723030..f4ff49057 100644 --- a/stratosphere/sm/Makefile +++ b/stratosphere/sm/Makefile @@ -31,7 +31,7 @@ DATA := data INCLUDES := include ../../common/include EXEFS_SRC := exefs_src -DEFINES := -DRESULT_ABORT_ON_ASSERT -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\" +DEFINES := -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\" #--------------------------------------------------------------------------------- # options for code generation @@ -45,8 +45,19 @@ CFLAGS += $(INCLUDE) -D__SWITCH__ -DSM_MINIMUM_SESSION_LIMIT=8 CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17 +CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \ + -Wl,--wrap,__cxa_throw \ + -Wl,--wrap,__cxa_rethrow \ + -Wl,--wrap,__cxa_allocate_exception \ + -Wl,--wrap,__cxa_begin_catch \ + -Wl,--wrap,__cxa_end_catch \ + -Wl,--wrap,__cxa_call_unexpected \ + -Wl,--wrap,__cxa_call_terminate \ + -Wl,--wrap,__gxx_personality_v0 + ASFLAGS := -g $(ARCH) -LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) + +LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map) LIBS := -lstratosphere -lnx diff --git a/stratosphere/sm/source/impl/sm_service_manager.cpp b/stratosphere/sm/source/impl/sm_service_manager.cpp index db26aad91..218c9b65f 100644 --- a/stratosphere/sm/source/impl/sm_service_manager.cpp +++ b/stratosphere/sm/source/impl/sm_service_manager.cpp @@ -251,10 +251,10 @@ namespace sts::sm::impl { for (size_t i = 0; i < FutureMitmCountMax; i++) { if (g_future_mitm_list[i] == InvalidServiceName) { g_future_mitm_list[i] = service; - return ResultSuccess; + return ResultSuccess(); } } - return ResultSmInsufficientServices; + return sm::ResultOutOfServices(); } bool HasFutureMitmDeclaration(ServiceName service) { @@ -288,23 +288,23 @@ namespace sts::sm::impl { /* Iterate over all entries in the access control, checking to see if we have a match. */ while (access_control.IsValid()) { if (access_control.IsHost() == is_host) { + bool is_valid = true; + if (access_control.IsWildcard() == is_wildcard) { /* Check for exact match. */ - if (access_control.GetServiceName() == service) { - return ResultSuccess; - } + is_valid &= access_control.GetServiceName() == service; } else if (access_control.IsWildcard()) { /* Also allow fuzzy match for wildcard. */ ServiceName ac_service = access_control.GetServiceName(); - if (std::memcmp(&ac_service, &service, access_control.GetServiceNameSize() - 1) == 0) { - return ResultSuccess; - } + is_valid &= std::memcmp(&ac_service, &service, access_control.GetServiceNameSize() - 1) == 0; } + + R_UNLESS(!is_valid, ResultSuccess()); } access_control = access_control.GetNextEntry(); } - return ResultSmNotAllowed; + return sm::ResultNotAllowed(); } Result ValidateAccessControl(AccessControlEntry restriction, AccessControlEntry access) { @@ -314,14 +314,12 @@ namespace sts::sm::impl { access = access.GetNextEntry(); } - return ResultSuccess; + return ResultSuccess(); } Result ValidateServiceName(ServiceName service) { /* Service names must be non-empty. */ - if (service.name[0] == 0) { - return ResultSmInvalidServiceName; - } + R_UNLESS(service.name[0] != 0, sm::ResultInvalidServiceName()); /* Get name length. */ size_t name_len; @@ -333,12 +331,10 @@ namespace sts::sm::impl { /* Names must be all-zero after they end. */ while (name_len < sizeof(service)) { - if (service.name[name_len++] != 0) { - return ResultSmInvalidServiceName; - } + R_UNLESS(service.name[name_len++] == 0, sm::ResultInvalidServiceName()); } - return ResultSuccess; + return ResultSuccess(); } bool ShouldDeferForInit(ServiceName service) { @@ -365,9 +361,7 @@ namespace sts::sm::impl { } /* If we shouldn't mitm, give normal session. */ - if (!should_mitm) { - return svcConnectToPort(out, service_info->port_h.Get()); - } + R_UNLESS(should_mitm, svcConnectToPort(out, service_info->port_h.Get())); /* Create both handles. */ { @@ -381,7 +375,7 @@ namespace sts::sm::impl { service_info->mitm_waiting_ack_pid = process_id; service_info->mitm_waiting_ack = true; - return ResultSuccess; + return ResultSuccess(); } Result GetServiceHandleImpl(Handle *out, ServiceInfo *service_info, os::ProcessId pid) { @@ -395,7 +389,7 @@ namespace sts::sm::impl { if (!IsMitmDisallowed(title_id)) { /* We're mitm'd. Assert, because mitm service host dead is an error state. */ R_ASSERT(GetMitmServiceHandleImpl(out, service_info, pid, title_id)); - return ResultSuccess; + return ResultSuccess(); } } @@ -408,9 +402,7 @@ namespace sts::sm::impl { R_TRY(ValidateServiceName(service)); /* Don't try to register something already registered. */ - if (HasServiceInfo(service)) { - return ResultSmAlreadyRegistered; - } + R_UNLESS(!HasServiceInfo(service), sm::ResultAlreadyRegistered()); /* Adjust session limit, if compile flags tell us to. */ #ifdef SM_MINIMUM_SESSION_LIMIT @@ -421,9 +413,7 @@ namespace sts::sm::impl { /* Get free service. */ ServiceInfo *free_service = GetFreeServiceInfo(); - if (free_service == nullptr) { - return ResultSmInsufficientServices; - } + R_UNLESS(free_service != nullptr, sm::ResultOutOfServices()); /* Create the new service. */ *out = INVALID_HANDLE; @@ -435,27 +425,21 @@ namespace sts::sm::impl { free_service->max_sessions = max_sessions; free_service->is_light = is_light; - return ResultSuccess; + return ResultSuccess(); } } /* Process management. */ Result RegisterProcess(os::ProcessId pid, ncm::TitleId tid, const void *acid_sac, size_t acid_sac_size, const void *aci_sac, size_t aci_sac_size) { /* Check that access control will fit in the ServiceInfo. */ - if (aci_sac_size > AccessControlSizeMax) { - return ResultSmTooLargeAccessControl; - } + R_UNLESS(aci_sac_size <= AccessControlSizeMax, sm::ResultTooLargeAccessControl()); /* Get free process. */ ProcessInfo *proc = GetFreeProcessInfo(); - if (proc == nullptr) { - return ResultSmInsufficientProcesses; - } + R_UNLESS(proc != nullptr, sm::ResultOutOfProcesses()); /* Validate restrictions. */ - if (!aci_sac_size) { - return ResultSmNotAllowed; - } + R_UNLESS(aci_sac_size != 0, sm::ResultNotAllowed()); R_TRY(ValidateAccessControl(AccessControlEntry(acid_sac, acid_sac_size), AccessControlEntry(aci_sac, aci_sac_size))); /* Save info. */ @@ -463,18 +447,16 @@ namespace sts::sm::impl { proc->tid = tid; proc->access_control_size = aci_sac_size; std::memcpy(proc->access_control, aci_sac, proc->access_control_size); - return ResultSuccess; + return ResultSuccess(); } Result UnregisterProcess(os::ProcessId pid) { /* Find the process. */ ProcessInfo *proc = GetProcessInfo(pid); - if (proc == nullptr) { - return ResultSmInvalidClient; - } + R_UNLESS(proc != nullptr, sm::ResultInvalidClient()); proc->Free(); - return ResultSuccess; + return ResultSuccess(); } /* Service management. */ @@ -483,7 +465,7 @@ namespace sts::sm::impl { R_TRY(ValidateServiceName(service)); *out = HasServiceInfo(service); - return ResultSuccess; + return ResultSuccess(); } Result WaitService(ServiceName service) { @@ -491,10 +473,8 @@ namespace sts::sm::impl { R_TRY(impl::HasService(&has_service, service)); /* Wait until we have the service. */ - if (!has_service) { - return ResultServiceFrameworkRequestDeferredByUser; - } - return ResultSuccess; + R_UNLESS(has_service, sf::ResultRequestDeferredByUser()); + return ResultSuccess(); } Result GetServiceHandle(Handle *out, os::ProcessId pid, ServiceName service) { @@ -506,35 +486,29 @@ namespace sts::sm::impl { /* This would return true, and homebrew would *wait forever* trying to get a handle to a service */ /* that will never register. Thus, in the interest of not breaking every single piece of homebrew */ /* we will provide a little first class help. */ - if (hos::GetVersion() >= hos::Version_800 && service == ServiceName::Encode("apm:p")) { - return ResultSmNotAllowed; - } + constexpr ServiceName ApmP = ServiceName::Encode("apm:p"); + R_UNLESS((hos::GetVersion() < hos::Version_800) || (service != ApmP), sm::ResultNotAllowed()); /* Check that the process is registered and allowed to get the service. */ if (!IsInitialProcess(pid)) { ProcessInfo *proc = GetProcessInfo(pid); - if (proc == nullptr) { - return ResultSmInvalidClient; - } - + R_UNLESS(proc != nullptr, sm::ResultInvalidClient()); R_TRY(ValidateAccessControl(AccessControlEntry(proc->access_control, proc->access_control_size), service, false, false)); } /* Get service info. Check to see if we need to defer this until later. */ ServiceInfo *service_info = GetServiceInfo(service); - if (service_info == nullptr || ShouldDeferForInit(service) || HasFutureMitmDeclaration(service) || service_info->mitm_waiting_ack) { - return ResultServiceFrameworkRequestDeferredByUser; - } + R_UNLESS(service_info != nullptr, sf::ResultRequestDeferredByUser()); + R_UNLESS(!ShouldDeferForInit(service), sf::ResultRequestDeferredByUser()); + R_UNLESS(!HasFutureMitmDeclaration(service), sf::ResultRequestDeferredByUser()); + R_UNLESS(!service_info->mitm_waiting_ack, sf::ResultRequestDeferredByUser()); /* Get a handle from the service info. */ R_TRY_CATCH(GetServiceHandleImpl(out, service_info, pid)) { - /* Convert Kernel result to SM result. */ - R_CATCH(ResultKernelOutOfSessions) { - return ResultSmInsufficientSessions; - } + R_CONVERT(svc::ResultOutOfSessions, sm::ResultOutOfSessions()) } R_END_TRY_CATCH; - return ResultSuccess; + return ResultSuccess(); } Result RegisterService(Handle *out, os::ProcessId pid, ServiceName service, size_t max_sessions, bool is_light) { @@ -544,17 +518,12 @@ namespace sts::sm::impl { /* Check that the process is registered and allowed to register the service. */ if (!IsInitialProcess(pid)) { ProcessInfo *proc = GetProcessInfo(pid); - if (proc == nullptr) { - return ResultSmInvalidClient; - } + R_UNLESS(proc != nullptr, sm::ResultInvalidClient()); R_TRY(ValidateAccessControl(AccessControlEntry(proc->access_control, proc->access_control_size), service, true, false)); } - if (HasServiceInfo(service)) { - return ResultSmAlreadyRegistered; - } - + R_UNLESS(!HasServiceInfo(service), sm::ResultAlreadyRegistered()); return RegisterServiceImpl(out, pid, service, max_sessions, is_light); } @@ -568,25 +537,19 @@ namespace sts::sm::impl { /* Check that the process is registered. */ if (!IsInitialProcess(pid)) { - if (!HasProcessInfo(pid)) { - return ResultSmInvalidClient; - } + R_UNLESS(HasProcessInfo(pid), sm::ResultInvalidClient()); } /* Ensure that the service is actually registered. */ ServiceInfo *service_info = GetServiceInfo(service); - if (service_info == nullptr) { - return ResultSmNotRegistered; - } + R_UNLESS(service_info != nullptr, sm::ResultNotRegistered()); /* Check if we have permission to do this. */ - if (service_info->owner_pid != pid) { - return ResultSmNotAllowed; - } + R_UNLESS(service_info->owner_pid == pid, sm::ResultNotAllowed()); /* Unregister the service. */ service_info->Free(); - return ResultSuccess; + return ResultSuccess(); } /* Mitm extensions. */ @@ -596,7 +559,7 @@ namespace sts::sm::impl { const ServiceInfo *service_info = GetServiceInfo(service); *out = service_info != nullptr && IsValidProcessId(service_info->mitm_pid); - return ResultSuccess; + return ResultSuccess(); } Result WaitMitm(ServiceName service) { @@ -604,10 +567,8 @@ namespace sts::sm::impl { R_TRY(impl::HasMitm(&has_mitm, service)); /* Wait until we have the mitm. */ - if (!has_mitm) { - return ResultServiceFrameworkRequestDeferredByUser; - } - return ResultSuccess; + R_UNLESS(has_mitm, sf::ResultRequestDeferredByUser()); + return ResultSuccess(); } Result InstallMitm(Handle *out, Handle *out_query, os::ProcessId pid, ServiceName service) { @@ -617,24 +578,18 @@ namespace sts::sm::impl { /* Check that the process is registered and allowed to register the service. */ if (!IsInitialProcess(pid)) { ProcessInfo *proc = GetProcessInfo(pid); - if (proc == nullptr) { - return ResultSmInvalidClient; - } - + R_UNLESS(proc != nullptr, sm::ResultInvalidClient()); R_TRY(ValidateAccessControl(AccessControlEntry(proc->access_control, proc->access_control_size), service, true, false)); } /* Validate that the service exists. */ ServiceInfo *service_info = GetServiceInfo(service); - if (service_info == nullptr) { - /* If it doesn't exist, defer until it does. */ - return ResultServiceFrameworkRequestDeferredByUser; - } + + /* If it doesn't exist, defer until it does. */ + R_UNLESS(service_info != nullptr, sf::ResultRequestDeferredByUser()); /* Validate that the service isn't already being mitm'd. */ - if (IsValidProcessId(service_info->mitm_pid)) { - return ResultSmAlreadyRegistered; - } + R_UNLESS(!IsValidProcessId(service_info->mitm_pid), sm::ResultAlreadyRegistered()); /* Always clear output. */ *out = INVALID_HANDLE; @@ -658,7 +613,7 @@ namespace sts::sm::impl { /* Clear the future declaration, if one exists. */ ClearFutureMitmDeclaration(service); - return ResultSuccess; + return ResultSuccess(); } Result UninstallMitm(os::ProcessId pid, ServiceName service) { @@ -668,25 +623,19 @@ namespace sts::sm::impl { /* Check that the process is registered. */ if (!IsInitialProcess(pid)) { ProcessInfo *proc = GetProcessInfo(pid); - if (proc == nullptr) { - return ResultSmInvalidClient; - } + R_UNLESS(proc != nullptr, sm::ResultInvalidClient()); } /* Validate that the service exists. */ ServiceInfo *service_info = GetServiceInfo(service); - if (service_info == nullptr) { - return ResultSmNotRegistered; - } + R_UNLESS(service_info != nullptr, sm::ResultNotRegistered()); /* Validate that the client pid is the mitm process. */ - if (service_info->mitm_pid != pid) { - return ResultSmNotAllowed; - } + R_UNLESS(service_info->mitm_pid == pid, sm::ResultNotAllowed()); /* Free Mitm session info. */ service_info->FreeMitm(); - return ResultSuccess; + return ResultSuccess(); } Result DeclareFutureMitm(os::ProcessId pid, ServiceName service) { @@ -696,21 +645,17 @@ namespace sts::sm::impl { /* Check that the process is registered and allowed to register the service. */ if (!IsInitialProcess(pid)) { ProcessInfo *proc = GetProcessInfo(pid); - if (proc == nullptr) { - return ResultSmInvalidClient; - } - + R_UNLESS(proc != nullptr, sm::ResultInvalidClient()); R_TRY(ValidateAccessControl(AccessControlEntry(proc->access_control, proc->access_control_size), service, true, false)); } /* Check that mitm hasn't already been registered or declared. */ - if (HasMitm(service) || HasFutureMitmDeclaration(service)) { - return ResultSmAlreadyRegistered; - } + R_UNLESS(!HasMitm(service), sm::ResultAlreadyRegistered()); + R_UNLESS(!HasFutureMitmDeclaration(service), sm::ResultAlreadyRegistered()); /* Try to forward declare it. */ R_TRY(AddFutureMitmDeclaration(service)); - return ResultSuccess; + return ResultSuccess(); } Result AcknowledgeMitmSession(os::ProcessId *out_pid, ncm::TitleId *out_tid, Handle *out_hnd, os::ProcessId pid, ServiceName service) { @@ -720,25 +665,20 @@ namespace sts::sm::impl { /* Check that the process is registered. */ if (!IsInitialProcess(pid)) { ProcessInfo *proc = GetProcessInfo(pid); - if (proc == nullptr) { - return ResultSmInvalidClient; - } + R_UNLESS(proc != nullptr, sm::ResultInvalidClient()); } /* Validate that the service exists. */ ServiceInfo *service_info = GetServiceInfo(service); - if (service_info == nullptr) { - return ResultSmNotRegistered; - } + R_UNLESS(service_info != nullptr, sm::ResultNotRegistered()); /* Validate that the client pid is the mitm process, and that an acknowledgement is waiting. */ - if (service_info->mitm_pid != pid || !service_info->mitm_waiting_ack) { - return ResultSmNotAllowed; - } + R_UNLESS(service_info->mitm_pid == pid, sm::ResultNotAllowed()); + R_UNLESS(service_info->mitm_waiting_ack, sm::ResultNotAllowed()); /* Acknowledge. */ service_info->AcknowledgeMitmSession(out_pid, out_tid, out_hnd); - return ResultSuccess; + return ResultSuccess(); } /* Dmnt record extensions. */ @@ -748,12 +688,10 @@ namespace sts::sm::impl { /* Validate that the service exists. */ const ServiceInfo *service_info = GetServiceInfo(service); - if (service_info == nullptr) { - return ResultSmNotRegistered; - } + R_UNLESS(service_info != nullptr, sm::ResultNotRegistered()); GetServiceInfoRecord(out, service_info); - return ResultSuccess; + return ResultSuccess(); } Result ListServiceRecords(ServiceRecord *out, u64 *out_count, u64 offset, u64 max_count) { @@ -772,13 +710,13 @@ namespace sts::sm::impl { } *out_count = 0; - return ResultSuccess; + return ResultSuccess(); } /* Deferral extension (works around FS bug). */ Result EndInitialDefers() { g_ended_initial_defers = true; - return ResultSuccess; + return ResultSuccess(); } } diff --git a/stratosphere/sm/source/sm_main.cpp b/stratosphere/sm/source/sm_main.cpp index 239c0c6af..76e1fc661 100644 --- a/stratosphere/sm/source/sm_main.cpp +++ b/stratosphere/sm/source/sm_main.cpp @@ -45,6 +45,7 @@ extern "C" { alignas(16) u8 __nx_exception_stack[0x1000]; u64 __nx_exception_stack_size = sizeof(__nx_exception_stack); void __libnx_exception_handler(ThreadExceptionDump *ctx); + } namespace sts::ams { @@ -53,6 +54,12 @@ namespace sts::ams { } +namespace sts::result { + + bool CallFatalOnResultAssertion = false; + +} + using namespace sts; void __libnx_exception_handler(ThreadExceptionDump *ctx) { diff --git a/stratosphere/sm/source/sm_user_service.cpp b/stratosphere/sm/source/sm_user_service.cpp index 1963c9294..3ae49f62c 100644 --- a/stratosphere/sm/source/sm_user_service.cpp +++ b/stratosphere/sm/source/sm_user_service.cpp @@ -25,14 +25,14 @@ namespace sts::sm { Result UserService::Initialize(const sf::ClientProcessId &client_process_id) { this->process_id = client_process_id.GetValue(); this->has_initialized = true; - return ResultSuccess; + return ResultSuccess(); } Result UserService::EnsureInitialized() { if (!this->has_initialized) { - return ResultSmInvalidClient; + return sm::ResultInvalidClient(); } - return ResultSuccess; + return ResultSuccess(); } Result UserService::GetService(sf::OutMoveHandle out_h, ServiceName service) { diff --git a/stratosphere/spl/Makefile b/stratosphere/spl/Makefile index cd7b81cb1..a33159bd1 100644 --- a/stratosphere/spl/Makefile +++ b/stratosphere/spl/Makefile @@ -31,7 +31,7 @@ DATA := data INCLUDES := include ../../common/include EXEFS_SRC := exefs_src -DEFINES := -DRESULT_ABORT_ON_ASSERT -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\" +DEFINES := -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\" #--------------------------------------------------------------------------------- # options for code generation @@ -45,8 +45,18 @@ CFLAGS += $(INCLUDE) -D__SWITCH__ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17 +CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \ + -Wl,--wrap,__cxa_throw \ + -Wl,--wrap,__cxa_rethrow \ + -Wl,--wrap,__cxa_allocate_exception \ + -Wl,--wrap,__cxa_begin_catch \ + -Wl,--wrap,__cxa_end_catch \ + -Wl,--wrap,__cxa_call_unexpected \ + -Wl,--wrap,__cxa_call_terminate \ + -Wl,--wrap,__gxx_personality_v0 + ASFLAGS := -g $(ARCH) -LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) +LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map) LIBS := -lstratosphere -lnx diff --git a/stratosphere/spl/source/spl_api_impl.cpp b/stratosphere/spl/source/spl_api_impl.cpp index 509652228..aac848bd4 100644 --- a/stratosphere/spl/source/spl_api_impl.cpp +++ b/stratosphere/spl/source/spl_api_impl.cpp @@ -27,8 +27,7 @@ namespace sts::spl::impl { namespace { /* Convenient defines. */ - constexpr size_t DeviceAddressSpaceAlignSize = 0x400000; - constexpr size_t DeviceAddressSpaceAlignMask = DeviceAddressSpaceAlignSize - 1; + constexpr size_t DeviceAddressSpaceAlign = 0x400000; constexpr u32 WorkBufferMapBase = 0x80000000u; constexpr u32 CryptAesInMapBase = 0x90000000u; constexpr u32 CryptAesOutMapBase = 0xC0000000u; @@ -58,7 +57,7 @@ namespace sts::spl::impl { /* ... */ } ~ScopedAesKeyslot() { - if (has_slot) { + if (this->has_slot) { FreeAesKeyslot(slot, this); } } @@ -70,7 +69,7 @@ namespace sts::spl::impl { Result Allocate() { R_TRY(AllocateAesKeyslot(&this->slot, this)); this->has_slot = true; - return ResultSuccess; + return ResultSuccess(); } }; @@ -152,7 +151,7 @@ namespace sts::spl::impl { R_ASSERT(svcAttachDeviceAddressSpace(DeviceName_SE, g_se_das_hnd)); const u64 work_buffer_addr = reinterpret_cast(g_work_buffer); - g_se_mapped_work_buffer_addr = WorkBufferMapBase + (work_buffer_addr & DeviceAddressSpaceAlignMask); + g_se_mapped_work_buffer_addr = WorkBufferMapBase + (work_buffer_addr % DeviceAddressSpaceAlign); /* Map the work buffer for the SE. */ R_ASSERT(svcMapDeviceAddressSpaceAligned(g_se_das_hnd, CUR_PROCESS_HANDLE, work_buffer_addr, sizeof(g_work_buffer), g_se_mapped_work_buffer_addr, 3)); @@ -164,10 +163,7 @@ namespace sts::spl::impl { u32 ctr = 0; while (dst_size > 0) { - size_t cur_size = SHA256_HASH_SIZE; - if (cur_size > dst_size) { - cur_size = dst_size; - } + const size_t cur_size = std::min(size_t(SHA256_HASH_SIZE), dst_size); dst_size -= cur_size; u32 ctr_be = __builtin_bswap32(ctr++); @@ -252,7 +248,7 @@ namespace sts::spl::impl { } } - return ResultSuccess; + return ResultSuccess(); } /* Internal async implementation functionality. */ @@ -286,13 +282,9 @@ namespace sts::spl::impl { /* Internal Keyslot utility. */ Result ValidateAesKeyslot(u32 keyslot, const void *owner) { - if (keyslot >= GetMaxKeyslots()) { - return ResultSplInvalidKeyslot; - } - if (g_keyslot_owners[keyslot] != owner && hos::GetVersion() > hos::Version_100) { - return ResultSplInvalidKeyslot; - } - return ResultSuccess; + R_UNLESS(keyslot < GetMaxKeyslots(), spl::ResultInvalidKeyslot()); + R_UNLESS((g_keyslot_owners[keyslot] == owner || hos::GetVersion() == hos::Version_100), spl::ResultInvalidKeyslot()); + return ResultSuccess(); } /* Helper to do a single AES block decryption. */ @@ -345,10 +337,7 @@ namespace sts::spl::impl { ImportSecureExpModKeyLayout *layout = reinterpret_cast(g_work_buffer); /* Validate size. */ - if (src_size > sizeof(ImportSecureExpModKeyLayout)) { - return ResultSplInvalidSize; - } - + R_UNLESS(src_size <= sizeof(ImportSecureExpModKeyLayout), spl::ResultInvalidSize()); std::memcpy(layout, src, src_size); armDCacheFlush(layout, sizeof(*layout)); @@ -370,15 +359,9 @@ namespace sts::spl::impl { SecureExpModLayout *layout = reinterpret_cast(g_work_buffer); /* Validate sizes. */ - if (base_size > sizeof(layout->base)) { - return ResultSplInvalidSize; - } - if (mod_size > sizeof(layout->mod)) { - return ResultSplInvalidSize; - } - if (out_size > WorkBufferSizeMax) { - return ResultSplInvalidSize; - } + R_UNLESS(base_size <= sizeof(layout->base), spl::ResultInvalidSize()); + R_UNLESS(mod_size <= sizeof(layout->mod), spl::ResultInvalidSize()); + R_UNLESS(out_size <= WorkBufferSizeMax, spl::ResultInvalidSize()); /* Copy data into work buffer. */ const size_t base_ofs = sizeof(layout->base) - base_size; @@ -405,7 +388,7 @@ namespace sts::spl::impl { armDCacheFlush(g_work_buffer, sizeof(out_size)); std::memcpy(out, g_work_buffer, out_size); - return ResultSuccess; + return ResultSuccess(); } Result UnwrapEsRsaOaepWrappedKey(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation, smc::EsKeyType type) { @@ -416,15 +399,9 @@ namespace sts::spl::impl { UnwrapEsKeyLayout *layout = reinterpret_cast(g_work_buffer); /* Validate sizes. */ - if (base_size > sizeof(layout->base)) { - return ResultSplInvalidSize; - } - if (mod_size > sizeof(layout->mod)) { - return ResultSplInvalidSize; - } - if (label_digest_size > LabelDigestSizeMax) { - return ResultSplInvalidSize; - } + R_UNLESS(base_size <= sizeof(layout->base), spl::ResultInvalidSize()); + R_UNLESS(mod_size <= sizeof(layout->mod), spl::ResultInvalidSize()); + R_UNLESS(label_digest_size <= LabelDigestSizeMax, spl::ResultInvalidSize()); /* Copy data into work buffer. */ const size_t base_ofs = sizeof(layout->base) - base_size; @@ -451,7 +428,7 @@ namespace sts::spl::impl { armDCacheFlush(g_work_buffer, sizeof(*out_access_key)); std::memcpy(out_access_key, g_work_buffer, sizeof(*out_access_key)); - return ResultSuccess; + return ResultSuccess(); } @@ -471,9 +448,7 @@ namespace sts::spl::impl { Result GetConfig(u64 *out, SplConfigItem which) { /* Nintendo explicitly blacklists package2 hash here, amusingly. */ /* This is not blacklisted in safemode, but we're never in safe mode... */ - if (which == SplConfigItem_Package2Hash) { - return ResultSplInvalidArgument; - } + R_UNLESS(which != SplConfigItem_Package2Hash, spl::ResultInvalidArgument()); smc::Result res = smc::GetConfig(out, 1, which); @@ -499,18 +474,10 @@ namespace sts::spl::impl { ExpModLayout *layout = reinterpret_cast(g_work_buffer); /* Validate sizes. */ - if (base_size > sizeof(layout->base)) { - return ResultSplInvalidSize; - } - if (exp_size > sizeof(layout->exp)) { - return ResultSplInvalidSize; - } - if (mod_size > sizeof(layout->mod)) { - return ResultSplInvalidSize; - } - if (out_size > WorkBufferSizeMax) { - return ResultSplInvalidSize; - } + R_UNLESS(base_size <= sizeof(layout->base), spl::ResultInvalidSize()); + R_UNLESS(exp_size <= sizeof(layout->exp), spl::ResultInvalidSize()); + R_UNLESS(mod_size <= sizeof(layout->mod), spl::ResultInvalidSize()); + R_UNLESS(out_size <= WorkBufferSizeMax, spl::ResultInvalidSize()); /* Copy data into work buffer. */ const size_t base_ofs = sizeof(layout->base) - base_size; @@ -538,7 +505,7 @@ namespace sts::spl::impl { armDCacheFlush(g_work_buffer, sizeof(out_size)); std::memcpy(out, g_work_buffer, out_size); - return ResultSuccess; + return ResultSuccess(); } Result SetConfig(SplConfigItem which, u64 value) { @@ -555,7 +522,7 @@ namespace sts::spl::impl { cur_dst += cur_size; } - return ResultSuccess; + return ResultSuccess(); } Result IsDevelopment(bool *out) { @@ -563,26 +530,22 @@ namespace sts::spl::impl { R_TRY(GetConfig(&is_retail, SplConfigItem_IsRetail)); *out = (is_retail == 0); - return ResultSuccess; + return ResultSuccess(); } Result SetBootReason(BootReasonValue boot_reason) { - if (IsBootReasonSet()) { - return ResultSplBootReasonAlreadySet; - } + R_UNLESS(!IsBootReasonSet(), spl::ResultBootReasonAlreadySet()); g_boot_reason = boot_reason; g_boot_reason_set = true; - return ResultSuccess; + return ResultSuccess(); } Result GetBootReason(BootReasonValue *out) { - if (!IsBootReasonSet()) { - return ResultSplBootReasonNotSet; - } + R_UNLESS(IsBootReasonSet(), spl::ResultBootReasonNotSet()); *out = GetBootReason(); - return ResultSuccess; + return ResultSuccess(); } /* Crypto. */ @@ -629,30 +592,28 @@ namespace sts::spl::impl { /* Succeed immediately if there's nothing to crypt. */ if (src_size == 0) { - return ResultSuccess; + return ResultSuccess(); } /* Validate sizes. */ - if (src_size > dst_size || src_size % AES_BLOCK_SIZE != 0) { - return ResultSplInvalidSize; - } + R_UNLESS(src_size <= dst_size, spl::ResultInvalidSize()); + R_UNLESS(util::IsAligned(src_size, AES_BLOCK_SIZE), spl::ResultInvalidSize()); /* We can only map 0x400000 aligned buffers for the SE. With that in mind, we have some math to do. */ const uintptr_t src_addr = reinterpret_cast(src); const uintptr_t dst_addr = reinterpret_cast(dst); - const uintptr_t src_addr_page_aligned = src_addr & ~0xFFFul; - const uintptr_t dst_addr_page_aligned = dst_addr & ~0xFFFul; - const size_t src_size_page_aligned = ((src_addr + src_size + 0xFFFul) & ~0xFFFul) - src_addr_page_aligned; - const size_t dst_size_page_aligned = ((dst_addr + dst_size + 0xFFFul) & ~0xFFFul) - dst_addr_page_aligned; - const u32 src_se_map_addr = CryptAesInMapBase + (src_addr_page_aligned & DeviceAddressSpaceAlignMask); - const u32 dst_se_map_addr = CryptAesOutMapBase + (dst_addr_page_aligned & DeviceAddressSpaceAlignMask); - const u32 src_se_addr = CryptAesInMapBase + (src_addr & DeviceAddressSpaceAlignMask); - const u32 dst_se_addr = CryptAesOutMapBase + (dst_addr & DeviceAddressSpaceAlignMask); + const uintptr_t src_addr_page_aligned = util::AlignDown(src_addr, 0x1000); + const uintptr_t dst_addr_page_aligned = util::AlignDown(dst_addr, 0x1000); + const size_t src_size_page_aligned = util::AlignUp(src_addr + src_size, 0x1000) - src_addr_page_aligned; + const size_t dst_size_page_aligned = util::AlignUp(dst_addr + dst_size, 0x1000) - dst_addr_page_aligned; + const u32 src_se_map_addr = CryptAesInMapBase + (src_addr_page_aligned % DeviceAddressSpaceAlign); + const u32 dst_se_map_addr = CryptAesOutMapBase + (dst_addr_page_aligned % DeviceAddressSpaceAlign); + const u32 src_se_addr = CryptAesInMapBase + (src_addr % DeviceAddressSpaceAlign); + const u32 dst_se_addr = CryptAesOutMapBase + (dst_addr % DeviceAddressSpaceAlign); /* Validate aligned sizes. */ - if (src_size_page_aligned > CryptAesSizeMax || dst_size_page_aligned > CryptAesSizeMax) { - return ResultSplInvalidSize; - } + R_UNLESS(src_size_page_aligned <= CryptAesSizeMax, spl::ResultInvalidSize()); + R_UNLESS(dst_size_page_aligned <= CryptAesSizeMax, spl::ResultInvalidSize()); /* Helpers for mapping/unmapping. */ DeviceAddressSpaceMapHelper in_mapper(g_se_das_hnd, src_se_map_addr, src_addr_page_aligned, src_size_page_aligned, 1); @@ -688,15 +649,13 @@ namespace sts::spl::impl { } armDCacheFlush(dst, dst_size); - return ResultSuccess; + return ResultSuccess(); } Result ComputeCmac(Cmac *out_cmac, u32 keyslot, const void *owner, const void *data, size_t size) { R_TRY(ValidateAesKeyslot(keyslot, owner)); - if (size > WorkBufferSizeMax) { - return ResultSplInvalidSize; - } + R_UNLESS(size <= WorkBufferSizeMax, spl::ResultInvalidSize()); std::memcpy(g_work_buffer, data, size); return smc::ConvertResult(smc::ComputeCmac(out_cmac, keyslot, g_work_buffer, size)); @@ -706,25 +665,25 @@ namespace sts::spl::impl { if (hos::GetVersion() <= hos::Version_100) { /* On 1.0.0, keyslots were kind of a wild west. */ *out_keyslot = 0; - return ResultSuccess; + return ResultSuccess(); } for (size_t i = 0; i < GetMaxKeyslots(); i++) { if (g_keyslot_owners[i] == 0) { g_keyslot_owners[i] = owner; *out_keyslot = static_cast(i); - return ResultSuccess; + return ResultSuccess(); } } g_se_keyslot_available_event.Reset(); - return ResultSplOutOfKeyslots; + return spl::ResultOutOfKeyslots(); } Result FreeAesKeyslot(u32 keyslot, const void *owner) { if (hos::GetVersion() <= hos::Version_100) { /* On 1.0.0, keyslots were kind of a wild west. */ - return ResultSuccess; + return ResultSuccess(); } R_TRY(ValidateAesKeyslot(keyslot, owner)); @@ -738,7 +697,7 @@ namespace sts::spl::impl { } g_keyslot_owners[keyslot] = nullptr; g_se_keyslot_available_event.Signal(); - return ResultSuccess; + return ResultSuccess(); } /* RSA. */ @@ -749,9 +708,8 @@ namespace sts::spl::impl { DecryptRsaPrivateKeyLayout *layout = reinterpret_cast(g_work_buffer); /* Validate size. */ - if (src_size < RsaPrivateKeyMetaSize || src_size > sizeof(DecryptRsaPrivateKeyLayout)) { - return ResultSplInvalidSize; - } + R_UNLESS(src_size >= RsaPrivateKeyMetaSize, spl::ResultInvalidSize()); + R_UNLESS(src_size <= sizeof(DecryptRsaPrivateKeyLayout), spl::ResultInvalidSize()); std::memcpy(layout->data, src, src_size); armDCacheFlush(layout, sizeof(*layout)); @@ -794,9 +752,7 @@ namespace sts::spl::impl { ImportEsKeyLayout *layout = reinterpret_cast(g_work_buffer); /* Validate size. */ - if (src_size > sizeof(ImportEsKeyLayout)) { - return ResultSplInvalidSize; - } + R_UNLESS(src_size <= sizeof(ImportEsKeyLayout), spl::ResultInvalidSize()); std::memcpy(layout, src, src_size); @@ -837,20 +793,17 @@ namespace sts::spl::impl { Result DecryptLotusMessage(u32 *out_size, void *dst, size_t dst_size, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size) { /* Validate sizes. */ - if (dst_size > WorkBufferSizeMax || label_digest_size != LabelDigestSizeMax) { - return ResultSplInvalidSize; - } + R_UNLESS(dst_size <= WorkBufferSizeMax, spl::ResultInvalidSize()); + R_UNLESS(label_digest_size == LabelDigestSizeMax, spl::ResultInvalidSize()); /* Nintendo doesn't check this result code, but we will. */ R_TRY(SecureExpMod(g_work_buffer, 0x100, base, base_size, mod, mod_size, smc::SecureExpModMode::Lotus)); size_t data_size = DecodeRsaOaep(dst, dst_size, label_digest, label_digest_size, g_work_buffer, 0x100); - if (data_size == 0) { - return ResultSplDecryptionFailed; - } + R_UNLESS(data_size > 0, spl::ResultDecryptionFailed()); *out_size = static_cast(data_size); - return ResultSuccess; + return ResultSuccess(); } Result GenerateSpecificAesKey(AesKey *out_key, const KeySource &key_source, u32 generation, u32 which) { @@ -864,10 +817,7 @@ namespace sts::spl::impl { Result GetPackage2Hash(void *dst, const size_t size) { u64 hash[4]; - - if (size < sizeof(hash)) { - return ResultSplInvalidSize; - } + R_UNLESS(size >= sizeof(hash), spl::ResultInvalidSize()); smc::Result smc_res; if ((smc_res = smc::GetConfig(hash, 4, SplConfigItem_Package2Hash)) != smc::Result::Success) { @@ -875,7 +825,7 @@ namespace sts::spl::impl { } std::memcpy(dst, hash, sizeof(hash)); - return ResultSuccess; + return ResultSuccess(); } /* Manu. */ @@ -890,9 +840,8 @@ namespace sts::spl::impl { ReEncryptRsaPrivateKeyLayout *layout = reinterpret_cast(g_work_buffer); /* Validate size. */ - if (src_size < RsaPrivateKeyMetaSize || src_size > sizeof(ReEncryptRsaPrivateKeyLayout)) { - return ResultSplInvalidSize; - } + R_UNLESS(src_size >= RsaPrivateKeyMetaSize, spl::ResultInvalidSize()); + R_UNLESS(src_size <= sizeof(ReEncryptRsaPrivateKeyLayout), spl::ResultInvalidSize()); std::memcpy(layout, src, src_size); layout->access_key_dec = access_key_dec; @@ -919,7 +868,7 @@ namespace sts::spl::impl { FreeAesKeyslot(i, owner); } } - return ResultSuccess; + return ResultSuccess(); } Handle GetAesKeyslotAvailableEventHandle() { diff --git a/stratosphere/spl/source/spl_main.cpp b/stratosphere/spl/source/spl_main.cpp index b3ea6a7ec..febf25182 100644 --- a/stratosphere/spl/source/spl_main.cpp +++ b/stratosphere/spl/source/spl_main.cpp @@ -59,6 +59,12 @@ namespace sts::ams { } +namespace sts::result { + + bool CallFatalOnResultAssertion = false; + +} + using namespace sts; void __libnx_exception_handler(ThreadExceptionDump *ctx) {