From 612e1388df3bed64081488f2a99cce522c80c76d Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 9 Apr 2019 17:03:04 -0400 Subject: core/core: Move process execution start to System's Load() This gives us significantly more control over where in the initialization process we start execution of the main process. Previously we were running the main process before the CPU or GPU threads were initialized (not good). This amends execution to start after all of our threads are properly set up. --- src/core/core.cpp | 6 +++- src/core/hle/kernel/process.cpp | 12 ++++---- src/core/hle/kernel/process.h | 7 +++-- src/core/loader/deconstructed_rom_directory.cpp | 40 ++++++++++++++----------- src/core/loader/deconstructed_rom_directory.h | 2 +- src/core/loader/elf.cpp | 15 +++++----- src/core/loader/elf.h | 2 +- src/core/loader/loader.h | 8 ++++- src/core/loader/nax.cpp | 30 +++++++++++-------- src/core/loader/nax.h | 2 +- src/core/loader/nca.cpp | 26 ++++++++-------- src/core/loader/nca.h | 2 +- src/core/loader/nro.cpp | 14 ++++----- src/core/loader/nro.h | 2 +- src/core/loader/nso.cpp | 11 ++++--- src/core/loader/nso.h | 2 +- src/core/loader/nsp.cpp | 38 +++++++++++++---------- src/core/loader/nsp.h | 2 +- src/core/loader/xci.cpp | 28 +++++++++-------- src/core/loader/xci.h | 2 +- 20 files changed, 144 insertions(+), 107 deletions(-) (limited to 'src') diff --git a/src/core/core.cpp b/src/core/core.cpp index 265ac2835..175a5f2ea 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -168,7 +168,7 @@ struct System::Impl { } auto main_process = Kernel::Process::Create(system, "main"); - const Loader::ResultStatus load_result{app_loader->Load(*main_process)}; + const auto [load_result, load_parameters] = app_loader->Load(*main_process); if (load_result != Loader::ResultStatus::Success) { LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", static_cast(load_result)); Shutdown(); @@ -183,6 +183,10 @@ struct System::Impl { gpu_core->Start(); cpu_core_manager.StartThreads(); + // All threads are started, begin main process execution, now that we're in the clear. + main_process->Run(load_parameters->main_thread_priority, + load_parameters->main_thread_stack_size); + status = ResultStatus::Success; return status; } diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index bf0d479af..9825274b4 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -28,12 +28,12 @@ namespace { * * @param owner_process The parent process for the main thread * @param kernel The kernel instance to create the main thread under. - * @param entry_point The address at which the thread should start execution * @param priority The priority to give the main thread */ -void SetupMainThread(Process& owner_process, KernelCore& kernel, VAddr entry_point, u32 priority) { - // Initialize new "main" thread - const VAddr stack_top = owner_process.VMManager().GetTLSIORegionEndAddress(); +void SetupMainThread(Process& owner_process, KernelCore& kernel, u32 priority) { + const auto& vm_manager = owner_process.VMManager(); + const VAddr entry_point = vm_manager.GetCodeRegionBaseAddress(); + const VAddr stack_top = vm_manager.GetTLSIORegionEndAddress(); auto thread_res = Thread::Create(kernel, "main", entry_point, priority, 0, owner_process.GetIdealCore(), stack_top, owner_process); @@ -117,7 +117,7 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) { return handle_table.SetSize(capabilities.GetHandleTableSize()); } -void Process::Run(VAddr entry_point, s32 main_thread_priority, u64 stack_size) { +void Process::Run(s32 main_thread_priority, u64 stack_size) { // The kernel always ensures that the given stack size is page aligned. main_thread_stack_size = Common::AlignUp(stack_size, Memory::PAGE_SIZE); @@ -133,7 +133,7 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u64 stack_size) { vm_manager.LogLayout(); ChangeStatus(ProcessStatus::Running); - SetupMainThread(*this, kernel, entry_point, main_thread_priority); + SetupMainThread(*this, kernel, main_thread_priority); } void Process::PrepareForTermination() { diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index dda52f4c0..bf3b7eef3 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -225,9 +225,12 @@ public: ResultCode LoadFromMetadata(const FileSys::ProgramMetadata& metadata); /** - * Applies address space changes and launches the process main thread. + * Starts the main application thread for this process. + * + * @param main_thread_priority The priority for the main thread. + * @param stack_size The stack size for the main thread in bytes. */ - void Run(VAddr entry_point, s32 main_thread_priority, u64 stack_size); + void Run(s32 main_thread_priority, u64 stack_size); /** * Prepares a process for termination by stopping all of its threads diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index 07aa7a1cd..10b13fb1d 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp @@ -86,25 +86,29 @@ FileType AppLoader_DeconstructedRomDirectory::IdentifyType(const FileSys::Virtua return FileType::Error; } -ResultStatus AppLoader_DeconstructedRomDirectory::Load(Kernel::Process& process) { +AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirectory::Load( + Kernel::Process& process) { if (is_loaded) { - return ResultStatus::ErrorAlreadyLoaded; + return {ResultStatus::ErrorAlreadyLoaded, {}}; } if (dir == nullptr) { - if (file == nullptr) - return ResultStatus::ErrorNullFile; + if (file == nullptr) { + return {ResultStatus::ErrorNullFile, {}}; + } + dir = file->GetContainingDirectory(); } // Read meta to determine title ID FileSys::VirtualFile npdm = dir->GetFile("main.npdm"); - if (npdm == nullptr) - return ResultStatus::ErrorMissingNPDM; + if (npdm == nullptr) { + return {ResultStatus::ErrorMissingNPDM, {}}; + } - ResultStatus result = metadata.Load(npdm); + const ResultStatus result = metadata.Load(npdm); if (result != ResultStatus::Success) { - return result; + return {result, {}}; } if (override_update) { @@ -114,23 +118,24 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(Kernel::Process& process) // Reread in case PatchExeFS affected the main.npdm npdm = dir->GetFile("main.npdm"); - if (npdm == nullptr) - return ResultStatus::ErrorMissingNPDM; + if (npdm == nullptr) { + return {ResultStatus::ErrorMissingNPDM, {}}; + } - ResultStatus result2 = metadata.Load(npdm); + const ResultStatus result2 = metadata.Load(npdm); if (result2 != ResultStatus::Success) { - return result2; + return {result2, {}}; } metadata.Print(); const FileSys::ProgramAddressSpaceType arch_bits{metadata.GetAddressSpaceType()}; if (arch_bits == FileSys::ProgramAddressSpaceType::Is32Bit || arch_bits == FileSys::ProgramAddressSpaceType::Is32BitNoMap) { - return ResultStatus::Error32BitISA; + return {ResultStatus::Error32BitISA, {}}; } if (process.LoadFromMetadata(metadata).IsError()) { - return ResultStatus::ErrorUnableToParseKernelMetadata; + return {ResultStatus::ErrorUnableToParseKernelMetadata, {}}; } const FileSys::PatchManager pm(metadata.GetTitleID()); @@ -150,7 +155,7 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(Kernel::Process& process) const auto tentative_next_load_addr = AppLoader_NSO::LoadModule(process, *module_file, load_addr, should_pass_arguments, pm); if (!tentative_next_load_addr) { - return ResultStatus::ErrorLoadingNSO; + return {ResultStatus::ErrorLoadingNSO, {}}; } next_load_addr = *tentative_next_load_addr; @@ -159,8 +164,6 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(Kernel::Process& process) GDBStub::RegisterModule(module, load_addr, next_load_addr - 1, false); } - process.Run(base_address, metadata.GetMainThreadPriority(), metadata.GetMainThreadStackSize()); - // Find the RomFS by searching for a ".romfs" file in this directory const auto& files = dir->GetFiles(); const auto romfs_iter = @@ -175,7 +178,8 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(Kernel::Process& process) } is_loaded = true; - return ResultStatus::Success; + return {ResultStatus::Success, + LoadParameters{metadata.GetMainThreadPriority(), metadata.GetMainThreadStackSize()}}; } ResultStatus AppLoader_DeconstructedRomDirectory::ReadRomFS(FileSys::VirtualFile& dir) { diff --git a/src/core/loader/deconstructed_rom_directory.h b/src/core/loader/deconstructed_rom_directory.h index 1615cb5a8..1a65c16a4 100644 --- a/src/core/loader/deconstructed_rom_directory.h +++ b/src/core/loader/deconstructed_rom_directory.h @@ -37,7 +37,7 @@ public: return IdentifyType(file); } - ResultStatus Load(Kernel::Process& process) override; + LoadResult Load(Kernel::Process& process) override; ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; ResultStatus ReadIcon(std::vector& buffer) override; diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index 46ac372f6..6d4b02375 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -382,13 +382,15 @@ FileType AppLoader_ELF::IdentifyType(const FileSys::VirtualFile& file) { return FileType::Error; } -ResultStatus AppLoader_ELF::Load(Kernel::Process& process) { - if (is_loaded) - return ResultStatus::ErrorAlreadyLoaded; +AppLoader_ELF::LoadResult AppLoader_ELF::Load(Kernel::Process& process) { + if (is_loaded) { + return {ResultStatus::ErrorAlreadyLoaded, {}}; + } std::vector buffer = file->ReadAllBytes(); - if (buffer.size() != file->GetSize()) - return ResultStatus::ErrorIncorrectELFFileSize; + if (buffer.size() != file->GetSize()) { + return {ResultStatus::ErrorIncorrectELFFileSize, {}}; + } const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress(); ElfReader elf_reader(&buffer[0]); @@ -396,10 +398,9 @@ ResultStatus AppLoader_ELF::Load(Kernel::Process& process) { const VAddr entry_point = codeset.entrypoint; process.LoadModule(std::move(codeset), entry_point); - process.Run(entry_point, 48, Memory::DEFAULT_STACK_SIZE); is_loaded = true; - return ResultStatus::Success; + return {ResultStatus::Success, LoadParameters{48, Memory::DEFAULT_STACK_SIZE}}; } } // namespace Loader diff --git a/src/core/loader/elf.h b/src/core/loader/elf.h index a2d33021c..7ef7770a6 100644 --- a/src/core/loader/elf.h +++ b/src/core/loader/elf.h @@ -26,7 +26,7 @@ public: return IdentifyType(file); } - ResultStatus Load(Kernel::Process& process) override; + LoadResult Load(Kernel::Process& process) override; }; } // namespace Loader diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index bb925f4a6..f7846db52 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h @@ -131,6 +131,12 @@ std::ostream& operator<<(std::ostream& os, ResultStatus status); /// Interface for loading an application class AppLoader : NonCopyable { public: + struct LoadParameters { + s32 main_thread_priority; + u64 main_thread_stack_size; + }; + using LoadResult = std::pair>; + explicit AppLoader(FileSys::VirtualFile file); virtual ~AppLoader(); @@ -145,7 +151,7 @@ public: * @param process The newly created process. * @return The status result of the operation. */ - virtual ResultStatus Load(Kernel::Process& process) = 0; + virtual LoadResult Load(Kernel::Process& process) = 0; /** * Loads the system mode that this application needs. diff --git a/src/core/loader/nax.cpp b/src/core/loader/nax.cpp index 93a970d10..34efef09a 100644 --- a/src/core/loader/nax.cpp +++ b/src/core/loader/nax.cpp @@ -41,31 +41,37 @@ FileType AppLoader_NAX::GetFileType() const { return IdentifyTypeImpl(*nax); } -ResultStatus AppLoader_NAX::Load(Kernel::Process& process) { +AppLoader_NAX::LoadResult AppLoader_NAX::Load(Kernel::Process& process) { if (is_loaded) { - return ResultStatus::ErrorAlreadyLoaded; + return {ResultStatus::ErrorAlreadyLoaded, {}}; } - if (nax->GetStatus() != ResultStatus::Success) - return nax->GetStatus(); + const auto nax_status = nax->GetStatus(); + if (nax_status != ResultStatus::Success) { + return {nax_status, {}}; + } const auto nca = nax->AsNCA(); if (nca == nullptr) { - if (!Core::Crypto::KeyManager::KeyFileExists(false)) - return ResultStatus::ErrorMissingProductionKeyFile; - return ResultStatus::ErrorNAXInconvertibleToNCA; + if (!Core::Crypto::KeyManager::KeyFileExists(false)) { + return {ResultStatus::ErrorMissingProductionKeyFile, {}}; + } + + return {ResultStatus::ErrorNAXInconvertibleToNCA, {}}; } - if (nca->GetStatus() != ResultStatus::Success) - return nca->GetStatus(); + const auto nca_status = nca->GetStatus(); + if (nca_status != ResultStatus::Success) { + return {nca_status, {}}; + } const auto result = nca_loader->Load(process); - if (result != ResultStatus::Success) + if (result.first != ResultStatus::Success) { return result; + } is_loaded = true; - - return ResultStatus::Success; + return result; } ResultStatus AppLoader_NAX::ReadRomFS(FileSys::VirtualFile& dir) { diff --git a/src/core/loader/nax.h b/src/core/loader/nax.h index f40079574..00f1659c1 100644 --- a/src/core/loader/nax.h +++ b/src/core/loader/nax.h @@ -33,7 +33,7 @@ public: FileType GetFileType() const override; - ResultStatus Load(Kernel::Process& process) override; + LoadResult Load(Kernel::Process& process) override; ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; u64 ReadRomFSIVFCOffset() const override; diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp index ce8196fcf..b3f8f1083 100644 --- a/src/core/loader/nca.cpp +++ b/src/core/loader/nca.cpp @@ -30,36 +30,38 @@ FileType AppLoader_NCA::IdentifyType(const FileSys::VirtualFile& file) { return FileType::Error; } -ResultStatus AppLoader_NCA::Load(Kernel::Process& process) { +AppLoader_NCA::LoadResult AppLoader_NCA::Load(Kernel::Process& process) { if (is_loaded) { - return ResultStatus::ErrorAlreadyLoaded; + return {ResultStatus::ErrorAlreadyLoaded, {}}; } const auto result = nca->GetStatus(); if (result != ResultStatus::Success) { - return result; + return {result, {}}; } - if (nca->GetType() != FileSys::NCAContentType::Program) - return ResultStatus::ErrorNCANotProgram; + if (nca->GetType() != FileSys::NCAContentType::Program) { + return {ResultStatus::ErrorNCANotProgram, {}}; + } const auto exefs = nca->GetExeFS(); - - if (exefs == nullptr) - return ResultStatus::ErrorNoExeFS; + if (exefs == nullptr) { + return {ResultStatus::ErrorNoExeFS, {}}; + } directory_loader = std::make_unique(exefs, true); const auto load_result = directory_loader->Load(process); - if (load_result != ResultStatus::Success) + if (load_result.first != ResultStatus::Success) { return load_result; + } - if (nca->GetRomFS() != nullptr && nca->GetRomFS()->GetSize() > 0) + if (nca->GetRomFS() != nullptr && nca->GetRomFS()->GetSize() > 0) { Service::FileSystem::RegisterRomFS(std::make_unique(*this)); + } is_loaded = true; - - return ResultStatus::Success; + return load_result; } ResultStatus AppLoader_NCA::ReadRomFS(FileSys::VirtualFile& dir) { diff --git a/src/core/loader/nca.h b/src/core/loader/nca.h index b9f077468..94f0ed677 100644 --- a/src/core/loader/nca.h +++ b/src/core/loader/nca.h @@ -33,7 +33,7 @@ public: return IdentifyType(file); } - ResultStatus Load(Kernel::Process& process) override; + LoadResult Load(Kernel::Process& process) override; ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; u64 ReadRomFSIVFCOffset() const override; diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp index 31e4a0c84..6a0ca389b 100644 --- a/src/core/loader/nro.cpp +++ b/src/core/loader/nro.cpp @@ -201,25 +201,25 @@ bool AppLoader_NRO::LoadNro(Kernel::Process& process, const FileSys::VfsFile& fi return LoadNroImpl(process, file.ReadAllBytes(), file.GetName(), load_base); } -ResultStatus AppLoader_NRO::Load(Kernel::Process& process) { +AppLoader_NRO::LoadResult AppLoader_NRO::Load(Kernel::Process& process) { if (is_loaded) { - return ResultStatus::ErrorAlreadyLoaded; + return {ResultStatus::ErrorAlreadyLoaded, {}}; } // Load NRO const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress(); if (!LoadNro(process, *file, base_address)) { - return ResultStatus::ErrorLoadingNRO; + return {ResultStatus::ErrorLoadingNRO, {}}; } - if (romfs != nullptr) + if (romfs != nullptr) { Service::FileSystem::RegisterRomFS(std::make_unique(*this)); - - process.Run(base_address, Kernel::THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE); + } is_loaded = true; - return ResultStatus::Success; + return {ResultStatus::Success, + LoadParameters{Kernel::THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE}}; } ResultStatus AppLoader_NRO::ReadIcon(std::vector& buffer) { diff --git a/src/core/loader/nro.h b/src/core/loader/nro.h index 85b0ed644..1ffdae805 100644 --- a/src/core/loader/nro.h +++ b/src/core/loader/nro.h @@ -37,7 +37,7 @@ public: return IdentifyType(file); } - ResultStatus Load(Kernel::Process& process) override; + LoadResult Load(Kernel::Process& process) override; ResultStatus ReadIcon(std::vector& buffer) override; ResultStatus ReadProgramId(u64& out_program_id) override; diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index d7c47c197..a86653204 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp @@ -169,22 +169,21 @@ std::optional AppLoader_NSO::LoadModule(Kernel::Process& process, return load_base + image_size; } -ResultStatus AppLoader_NSO::Load(Kernel::Process& process) { +AppLoader_NSO::LoadResult AppLoader_NSO::Load(Kernel::Process& process) { if (is_loaded) { - return ResultStatus::ErrorAlreadyLoaded; + return {ResultStatus::ErrorAlreadyLoaded, {}}; } // Load module const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress(); if (!LoadModule(process, *file, base_address, true)) { - return ResultStatus::ErrorLoadingNSO; + return {ResultStatus::ErrorLoadingNSO, {}}; } LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", file->GetName(), base_address); - process.Run(base_address, Kernel::THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE); - is_loaded = true; - return ResultStatus::Success; + return {ResultStatus::Success, + LoadParameters{Kernel::THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE}}; } } // namespace Loader diff --git a/src/core/loader/nso.h b/src/core/loader/nso.h index 4674c3724..fdce9191c 100644 --- a/src/core/loader/nso.h +++ b/src/core/loader/nso.h @@ -84,7 +84,7 @@ public: VAddr load_base, bool should_pass_arguments, std::optional pm = {}); - ResultStatus Load(Kernel::Process& process) override; + LoadResult Load(Kernel::Process& process) override; }; } // namespace Loader diff --git a/src/core/loader/nsp.cpp b/src/core/loader/nsp.cpp index 7da1f8960..ad56bbb38 100644 --- a/src/core/loader/nsp.cpp +++ b/src/core/loader/nsp.cpp @@ -72,37 +72,45 @@ FileType AppLoader_NSP::IdentifyType(const FileSys::VirtualFile& file) { return FileType::Error; } -ResultStatus AppLoader_NSP::Load(Kernel::Process& process) { +AppLoader_NSP::LoadResult AppLoader_NSP::Load(Kernel::Process& process) { if (is_loaded) { - return ResultStatus::ErrorAlreadyLoaded; + return {ResultStatus::ErrorAlreadyLoaded, {}}; } - if (title_id == 0) - return ResultStatus::ErrorNSPMissingProgramNCA; + if (title_id == 0) { + return {ResultStatus::ErrorNSPMissingProgramNCA, {}}; + } - if (nsp->GetStatus() != ResultStatus::Success) - return nsp->GetStatus(); + const auto nsp_status = nsp->GetStatus(); + if (nsp_status != ResultStatus::Success) { + return {nsp_status, {}}; + } - if (nsp->GetProgramStatus(title_id) != ResultStatus::Success) - return nsp->GetProgramStatus(title_id); + const auto nsp_program_status = nsp->GetProgramStatus(title_id); + if (nsp_program_status != ResultStatus::Success) { + return {nsp_program_status, {}}; + } if (nsp->GetNCA(title_id, FileSys::ContentRecordType::Program) == nullptr) { - if (!Core::Crypto::KeyManager::KeyFileExists(false)) - return ResultStatus::ErrorMissingProductionKeyFile; - return ResultStatus::ErrorNSPMissingProgramNCA; + if (!Core::Crypto::KeyManager::KeyFileExists(false)) { + return {ResultStatus::ErrorMissingProductionKeyFile, {}}; + } + + return {ResultStatus::ErrorNSPMissingProgramNCA, {}}; } const auto result = secondary_loader->Load(process); - if (result != ResultStatus::Success) + if (result.first != ResultStatus::Success) { return result; + } FileSys::VirtualFile update_raw; - if (ReadUpdateRaw(update_raw) == ResultStatus::Success && update_raw != nullptr) + if (ReadUpdateRaw(update_raw) == ResultStatus::Success && update_raw != nullptr) { Service::FileSystem::SetPackedUpdate(std::move(update_raw)); + } is_loaded = true; - - return ResultStatus::Success; + return result; } ResultStatus AppLoader_NSP::ReadRomFS(FileSys::VirtualFile& file) { diff --git a/src/core/loader/nsp.h b/src/core/loader/nsp.h index 953a1b508..85e870bdf 100644 --- a/src/core/loader/nsp.h +++ b/src/core/loader/nsp.h @@ -35,7 +35,7 @@ public: return IdentifyType(file); } - ResultStatus Load(Kernel::Process& process) override; + LoadResult Load(Kernel::Process& process) override; ResultStatus ReadRomFS(FileSys::VirtualFile& file) override; u64 ReadRomFSIVFCOffset() const override; diff --git a/src/core/loader/xci.cpp b/src/core/loader/xci.cpp index 89f7bbf77..1e285a053 100644 --- a/src/core/loader/xci.cpp +++ b/src/core/loader/xci.cpp @@ -48,31 +48,35 @@ FileType AppLoader_XCI::IdentifyType(const FileSys::VirtualFile& file) { return FileType::Error; } -ResultStatus AppLoader_XCI::Load(Kernel::Process& process) { +AppLoader_XCI::LoadResult AppLoader_XCI::Load(Kernel::Process& process) { if (is_loaded) { - return ResultStatus::ErrorAlreadyLoaded; + return {ResultStatus::ErrorAlreadyLoaded, {}}; } - if (xci->GetStatus() != ResultStatus::Success) - return xci->GetStatus(); + if (xci->GetStatus() != ResultStatus::Success) { + return {xci->GetStatus(), {}}; + } - if (xci->GetProgramNCAStatus() != ResultStatus::Success) - return xci->GetProgramNCAStatus(); + if (xci->GetProgramNCAStatus() != ResultStatus::Success) { + return {xci->GetProgramNCAStatus(), {}}; + } - if (!xci->HasProgramNCA() && !Core::Crypto::KeyManager::KeyFileExists(false)) - return ResultStatus::ErrorMissingProductionKeyFile; + if (!xci->HasProgramNCA() && !Core::Crypto::KeyManager::KeyFileExists(false)) { + return {ResultStatus::ErrorMissingProductionKeyFile, {}}; + } const auto result = nca_loader->Load(process); - if (result != ResultStatus::Success) + if (result.first != ResultStatus::Success) { return result; + } FileSys::VirtualFile update_raw; - if (ReadUpdateRaw(update_raw) == ResultStatus::Success && update_raw != nullptr) + if (ReadUpdateRaw(update_raw) == ResultStatus::Success && update_raw != nullptr) { Service::FileSystem::SetPackedUpdate(std::move(update_raw)); + } is_loaded = true; - - return ResultStatus::Success; + return result; } ResultStatus AppLoader_XCI::ReadRomFS(FileSys::VirtualFile& file) { diff --git a/src/core/loader/xci.h b/src/core/loader/xci.h index 436f7387c..ae7145b14 100644 --- a/src/core/loader/xci.h +++ b/src/core/loader/xci.h @@ -35,7 +35,7 @@ public: return IdentifyType(file); } - ResultStatus Load(Kernel::Process& process) override; + LoadResult Load(Kernel::Process& process) override; ResultStatus ReadRomFS(FileSys::VirtualFile& file) override; u64 ReadRomFSIVFCOffset() const override; -- cgit v1.2.3