summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/CMakeLists.txt4
-rw-r--r--src/core/crypto/partition_data_manager.cpp4
-rw-r--r--src/core/file_sys/bis_factory.cpp12
-rw-r--r--src/core/file_sys/bis_factory.h8
-rw-r--r--src/core/file_sys/control_metadata.cpp13
-rw-r--r--src/core/file_sys/control_metadata.h1
-rw-r--r--src/core/file_sys/patch_manager.cpp2
-rw-r--r--src/core/file_sys/registered_cache.cpp14
-rw-r--r--src/core/file_sys/registered_cache.h12
-rw-r--r--src/core/file_sys/sdmc_factory.cpp8
-rw-r--r--src/core/file_sys/sdmc_factory.h4
-rw-r--r--src/core/hle/service/aoc/aoc_u.cpp18
-rw-r--r--src/core/hle/service/filesystem/filesystem.cpp13
-rw-r--r--src/core/hle/service/filesystem/filesystem.h8
-rw-r--r--src/core/hle/service/ns/pl_u.cpp2
-rw-r--r--src/core/loader/deconstructed_rom_directory.cpp22
-rw-r--r--src/core/loader/loader.cpp3
-rw-r--r--src/core/loader/loader.h1
-rw-r--r--src/core/loader/nro.cpp10
-rw-r--r--src/core/loader/nro.h2
-rw-r--r--src/core/loader/nso.cpp23
-rw-r--r--src/core/loader/nso.h6
22 files changed, 110 insertions, 80 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 4fddaafd1..78986deb5 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -400,8 +400,8 @@ create_target_directory_groups(core)
target_link_libraries(core PUBLIC common PRIVATE audio_core video_core)
target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt lz4_static mbedtls opus unicorn open_source_archives)
if (ENABLE_WEB_SERVICE)
- add_definitions(-DENABLE_WEB_SERVICE)
- target_link_libraries(core PUBLIC json-headers web_service)
+ target_compile_definitions(core PRIVATE -DENABLE_WEB_SERVICE)
+ target_link_libraries(core PRIVATE web_service)
endif()
if (ARCHITECTURE_x86_64)
diff --git a/src/core/crypto/partition_data_manager.cpp b/src/core/crypto/partition_data_manager.cpp
index ed5e2b145..25cee1f3a 100644
--- a/src/core/crypto/partition_data_manager.cpp
+++ b/src/core/crypto/partition_data_manager.cpp
@@ -303,8 +303,8 @@ FileSys::VirtualFile FindFileInDirWithNames(const FileSys::VirtualDir& dir,
PartitionDataManager::PartitionDataManager(const FileSys::VirtualDir& sysdata_dir)
: boot0(FindFileInDirWithNames(sysdata_dir, "BOOT0")),
- fuses(FindFileInDirWithNames(sysdata_dir, "fuse")),
- kfuses(FindFileInDirWithNames(sysdata_dir, "kfuse")),
+ fuses(FindFileInDirWithNames(sysdata_dir, "fuses")),
+ kfuses(FindFileInDirWithNames(sysdata_dir, "kfuses")),
package2({
FindFileInDirWithNames(sysdata_dir, "BCPKG2-1-Normal-Main"),
FindFileInDirWithNames(sysdata_dir, "BCPKG2-2-Normal-Sub"),
diff --git a/src/core/file_sys/bis_factory.cpp b/src/core/file_sys/bis_factory.cpp
index 6102ef476..76a2b7e86 100644
--- a/src/core/file_sys/bis_factory.cpp
+++ b/src/core/file_sys/bis_factory.cpp
@@ -10,19 +10,19 @@ namespace FileSys {
BISFactory::BISFactory(VirtualDir nand_root_, VirtualDir load_root_)
: nand_root(std::move(nand_root_)), load_root(std::move(load_root_)),
- sysnand_cache(std::make_shared<RegisteredCache>(
+ sysnand_cache(std::make_unique<RegisteredCache>(
GetOrCreateDirectoryRelative(nand_root, "/system/Contents/registered"))),
- usrnand_cache(std::make_shared<RegisteredCache>(
+ usrnand_cache(std::make_unique<RegisteredCache>(
GetOrCreateDirectoryRelative(nand_root, "/user/Contents/registered"))) {}
BISFactory::~BISFactory() = default;
-std::shared_ptr<RegisteredCache> BISFactory::GetSystemNANDContents() const {
- return sysnand_cache;
+RegisteredCache* BISFactory::GetSystemNANDContents() const {
+ return sysnand_cache.get();
}
-std::shared_ptr<RegisteredCache> BISFactory::GetUserNANDContents() const {
- return usrnand_cache;
+RegisteredCache* BISFactory::GetUserNANDContents() const {
+ return usrnand_cache.get();
}
VirtualDir BISFactory::GetModificationLoadRoot(u64 title_id) const {
diff --git a/src/core/file_sys/bis_factory.h b/src/core/file_sys/bis_factory.h
index c352e0925..364d309bd 100644
--- a/src/core/file_sys/bis_factory.h
+++ b/src/core/file_sys/bis_factory.h
@@ -20,8 +20,8 @@ public:
explicit BISFactory(VirtualDir nand_root, VirtualDir load_root);
~BISFactory();
- std::shared_ptr<RegisteredCache> GetSystemNANDContents() const;
- std::shared_ptr<RegisteredCache> GetUserNANDContents() const;
+ RegisteredCache* GetSystemNANDContents() const;
+ RegisteredCache* GetUserNANDContents() const;
VirtualDir GetModificationLoadRoot(u64 title_id) const;
@@ -29,8 +29,8 @@ private:
VirtualDir nand_root;
VirtualDir load_root;
- std::shared_ptr<RegisteredCache> sysnand_cache;
- std::shared_ptr<RegisteredCache> usrnand_cache;
+ std::unique_ptr<RegisteredCache> sysnand_cache;
+ std::unique_ptr<RegisteredCache> usrnand_cache;
};
} // namespace FileSys
diff --git a/src/core/file_sys/control_metadata.cpp b/src/core/file_sys/control_metadata.cpp
index 5b1177a03..a012c2be9 100644
--- a/src/core/file_sys/control_metadata.cpp
+++ b/src/core/file_sys/control_metadata.cpp
@@ -17,11 +17,13 @@ const std::array<const char*, 15> LANGUAGE_NAMES = {
};
std::string LanguageEntry::GetApplicationName() const {
- return Common::StringFromFixedZeroTerminatedBuffer(application_name.data(), 0x200);
+ return Common::StringFromFixedZeroTerminatedBuffer(application_name.data(),
+ application_name.size());
}
std::string LanguageEntry::GetDeveloperName() const {
- return Common::StringFromFixedZeroTerminatedBuffer(developer_name.data(), 0x100);
+ return Common::StringFromFixedZeroTerminatedBuffer(developer_name.data(),
+ developer_name.size());
}
NACP::NACP(VirtualFile file) : raw(std::make_unique<RawNACP>()) {
@@ -56,7 +58,12 @@ u64 NACP::GetTitleId() const {
return raw->title_id;
}
+u64 NACP::GetDLCBaseTitleId() const {
+ return raw->dlc_base_title_id;
+}
+
std::string NACP::GetVersionString() const {
- return Common::StringFromFixedZeroTerminatedBuffer(raw->version_string.data(), 0x10);
+ return Common::StringFromFixedZeroTerminatedBuffer(raw->version_string.data(),
+ raw->version_string.size());
}
} // namespace FileSys
diff --git a/src/core/file_sys/control_metadata.h b/src/core/file_sys/control_metadata.h
index 43d6f0719..141f7e056 100644
--- a/src/core/file_sys/control_metadata.h
+++ b/src/core/file_sys/control_metadata.h
@@ -79,6 +79,7 @@ public:
std::string GetApplicationName(Language language = Language::Default) const;
std::string GetDeveloperName(Language language = Language::Default) const;
u64 GetTitleId() const;
+ u64 GetDLCBaseTitleId() const;
std::string GetVersionString() const;
private:
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp
index 019caebe9..c15ac8e19 100644
--- a/src/core/file_sys/patch_manager.cpp
+++ b/src/core/file_sys/patch_manager.cpp
@@ -346,7 +346,7 @@ std::map<std::string, std::string, std::less<>> PatchManager::GetPatchVersionNam
}
std::pair<std::unique_ptr<NACP>, VirtualFile> PatchManager::GetControlMetadata() const {
- const auto& installed{Service::FileSystem::GetUnionContents()};
+ const auto installed{Service::FileSystem::GetUnionContents()};
const auto base_control_nca = installed->GetEntry(title_id, ContentRecordType::Control);
if (base_control_nca == nullptr)
diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp
index e9b040689..1febb398e 100644
--- a/src/core/file_sys/registered_cache.cpp
+++ b/src/core/file_sys/registered_cache.cpp
@@ -308,14 +308,14 @@ VirtualFile RegisteredCache::GetEntryRaw(RegisteredCacheEntry entry) const {
return GetEntryRaw(entry.title_id, entry.type);
}
-std::shared_ptr<NCA> RegisteredCache::GetEntry(u64 title_id, ContentRecordType type) const {
+std::unique_ptr<NCA> RegisteredCache::GetEntry(u64 title_id, ContentRecordType type) const {
const auto raw = GetEntryRaw(title_id, type);
if (raw == nullptr)
return nullptr;
- return std::make_shared<NCA>(raw);
+ return std::make_unique<NCA>(raw);
}
-std::shared_ptr<NCA> RegisteredCache::GetEntry(RegisteredCacheEntry entry) const {
+std::unique_ptr<NCA> RegisteredCache::GetEntry(RegisteredCacheEntry entry) const {
return GetEntry(entry.title_id, entry.type);
}
@@ -516,7 +516,7 @@ bool RegisteredCache::RawInstallYuzuMeta(const CNMT& cnmt) {
}) != yuzu_meta.end();
}
-RegisteredCacheUnion::RegisteredCacheUnion(std::vector<std::shared_ptr<RegisteredCache>> caches)
+RegisteredCacheUnion::RegisteredCacheUnion(std::vector<RegisteredCache*> caches)
: caches(std::move(caches)) {}
void RegisteredCacheUnion::Refresh() {
@@ -572,14 +572,14 @@ VirtualFile RegisteredCacheUnion::GetEntryRaw(RegisteredCacheEntry entry) const
return GetEntryRaw(entry.title_id, entry.type);
}
-std::shared_ptr<NCA> RegisteredCacheUnion::GetEntry(u64 title_id, ContentRecordType type) const {
+std::unique_ptr<NCA> RegisteredCacheUnion::GetEntry(u64 title_id, ContentRecordType type) const {
const auto raw = GetEntryRaw(title_id, type);
if (raw == nullptr)
return nullptr;
- return std::make_shared<NCA>(raw);
+ return std::make_unique<NCA>(raw);
}
-std::shared_ptr<NCA> RegisteredCacheUnion::GetEntry(RegisteredCacheEntry entry) const {
+std::unique_ptr<NCA> RegisteredCacheUnion::GetEntry(RegisteredCacheEntry entry) const {
return GetEntry(entry.title_id, entry.type);
}
diff --git a/src/core/file_sys/registered_cache.h b/src/core/file_sys/registered_cache.h
index c0cd59fc5..5ddacba47 100644
--- a/src/core/file_sys/registered_cache.h
+++ b/src/core/file_sys/registered_cache.h
@@ -88,8 +88,8 @@ public:
VirtualFile GetEntryRaw(u64 title_id, ContentRecordType type) const;
VirtualFile GetEntryRaw(RegisteredCacheEntry entry) const;
- std::shared_ptr<NCA> GetEntry(u64 title_id, ContentRecordType type) const;
- std::shared_ptr<NCA> GetEntry(RegisteredCacheEntry entry) const;
+ std::unique_ptr<NCA> GetEntry(u64 title_id, ContentRecordType type) const;
+ std::unique_ptr<NCA> GetEntry(RegisteredCacheEntry entry) const;
std::vector<RegisteredCacheEntry> ListEntries() const;
// If a parameter is not boost::none, it will be filtered for from all entries.
@@ -142,7 +142,7 @@ private:
// Combines multiple RegisteredCaches (i.e. SysNAND, UserNAND, SDMC) into one interface.
class RegisteredCacheUnion {
public:
- explicit RegisteredCacheUnion(std::vector<std::shared_ptr<RegisteredCache>> caches);
+ explicit RegisteredCacheUnion(std::vector<RegisteredCache*> caches);
void Refresh();
@@ -157,8 +157,8 @@ public:
VirtualFile GetEntryRaw(u64 title_id, ContentRecordType type) const;
VirtualFile GetEntryRaw(RegisteredCacheEntry entry) const;
- std::shared_ptr<NCA> GetEntry(u64 title_id, ContentRecordType type) const;
- std::shared_ptr<NCA> GetEntry(RegisteredCacheEntry entry) const;
+ std::unique_ptr<NCA> GetEntry(u64 title_id, ContentRecordType type) const;
+ std::unique_ptr<NCA> GetEntry(RegisteredCacheEntry entry) const;
std::vector<RegisteredCacheEntry> ListEntries() const;
// If a parameter is not boost::none, it will be filtered for from all entries.
@@ -168,7 +168,7 @@ public:
boost::optional<u64> title_id = boost::none) const;
private:
- std::vector<std::shared_ptr<RegisteredCache>> caches;
+ std::vector<RegisteredCache*> caches;
};
} // namespace FileSys
diff --git a/src/core/file_sys/sdmc_factory.cpp b/src/core/file_sys/sdmc_factory.cpp
index d66a9c9a4..bd3a57058 100644
--- a/src/core/file_sys/sdmc_factory.cpp
+++ b/src/core/file_sys/sdmc_factory.cpp
@@ -10,10 +10,10 @@
namespace FileSys {
SDMCFactory::SDMCFactory(VirtualDir dir_)
- : dir(std::move(dir_)), contents(std::make_shared<RegisteredCache>(
+ : dir(std::move(dir_)), contents(std::make_unique<RegisteredCache>(
GetOrCreateDirectoryRelative(dir, "/Nintendo/Contents/registered"),
[](const VirtualFile& file, const NcaID& id) {
- return std::make_shared<NAX>(file, id)->GetDecrypted();
+ return NAX{file, id}.GetDecrypted();
})) {}
SDMCFactory::~SDMCFactory() = default;
@@ -22,8 +22,8 @@ ResultVal<VirtualDir> SDMCFactory::Open() {
return MakeResult<VirtualDir>(dir);
}
-std::shared_ptr<RegisteredCache> SDMCFactory::GetSDMCContents() const {
- return contents;
+RegisteredCache* SDMCFactory::GetSDMCContents() const {
+ return contents.get();
}
} // namespace FileSys
diff --git a/src/core/file_sys/sdmc_factory.h b/src/core/file_sys/sdmc_factory.h
index ea12149de..42794ba5b 100644
--- a/src/core/file_sys/sdmc_factory.h
+++ b/src/core/file_sys/sdmc_factory.h
@@ -19,12 +19,12 @@ public:
~SDMCFactory();
ResultVal<VirtualDir> Open();
- std::shared_ptr<RegisteredCache> GetSDMCContents() const;
+ RegisteredCache* GetSDMCContents() const;
private:
VirtualDir dir;
- std::shared_ptr<RegisteredCache> contents;
+ std::unique_ptr<RegisteredCache> contents;
};
} // namespace FileSys
diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp
index 0ecfb5af1..518161bf7 100644
--- a/src/core/hle/service/aoc/aoc_u.cpp
+++ b/src/core/hle/service/aoc/aoc_u.cpp
@@ -7,8 +7,10 @@
#include <vector>
#include "common/logging/log.h"
#include "core/file_sys/content_archive.h"
+#include "core/file_sys/control_metadata.h"
#include "core/file_sys/nca_metadata.h"
#include "core/file_sys/partition_filesystem.h"
+#include "core/file_sys/patch_manager.h"
#include "core/file_sys/registered_cache.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/process.h"
@@ -19,7 +21,7 @@
namespace Service::AOC {
constexpr u64 DLC_BASE_TITLE_ID_MASK = 0xFFFFFFFFFFFFE000;
-constexpr u64 DLC_BASE_TO_AOC_ID_MASK = 0x1000;
+constexpr u64 DLC_BASE_TO_AOC_ID = 0x1000;
static bool CheckAOCTitleIDMatchesBase(u64 base, u64 aoc) {
return (aoc & DLC_BASE_TITLE_ID_MASK) == base;
@@ -97,14 +99,24 @@ void AOC_U::ListAddOnContent(Kernel::HLERequestContext& ctx) {
ctx.WriteBuffer(out);
- IPC::ResponseBuilder rb{ctx, 2};
+ IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
+ rb.Push(count);
}
void AOC_U::GetAddOnContentBaseId(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
- rb.Push(Core::System::GetInstance().CurrentProcess()->GetTitleID() | DLC_BASE_TO_AOC_ID_MASK);
+ const auto title_id = Core::System::GetInstance().CurrentProcess()->GetTitleID();
+ FileSys::PatchManager pm{title_id};
+
+ const auto res = pm.GetControlMetadata();
+ if (res.first == nullptr) {
+ rb.Push(title_id + DLC_BASE_TO_AOC_ID);
+ return;
+ }
+
+ rb.Push(res.first->GetDLCBaseTitleId());
}
void AOC_U::PrepareAddOnContent(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp
index e06712603..e32a7c48e 100644
--- a/src/core/hle/service/filesystem/filesystem.cpp
+++ b/src/core/hle/service/filesystem/filesystem.cpp
@@ -319,13 +319,12 @@ ResultVal<FileSys::VirtualDir> OpenSDMC() {
return sdmc_factory->Open();
}
-std::shared_ptr<FileSys::RegisteredCacheUnion> GetUnionContents() {
- return std::make_shared<FileSys::RegisteredCacheUnion>(
- std::vector<std::shared_ptr<FileSys::RegisteredCache>>{
- GetSystemNANDContents(), GetUserNANDContents(), GetSDMCContents()});
+std::unique_ptr<FileSys::RegisteredCacheUnion> GetUnionContents() {
+ return std::make_unique<FileSys::RegisteredCacheUnion>(std::vector<FileSys::RegisteredCache*>{
+ GetSystemNANDContents(), GetUserNANDContents(), GetSDMCContents()});
}
-std::shared_ptr<FileSys::RegisteredCache> GetSystemNANDContents() {
+FileSys::RegisteredCache* GetSystemNANDContents() {
LOG_TRACE(Service_FS, "Opening System NAND Contents");
if (bis_factory == nullptr)
@@ -334,7 +333,7 @@ std::shared_ptr<FileSys::RegisteredCache> GetSystemNANDContents() {
return bis_factory->GetSystemNANDContents();
}
-std::shared_ptr<FileSys::RegisteredCache> GetUserNANDContents() {
+FileSys::RegisteredCache* GetUserNANDContents() {
LOG_TRACE(Service_FS, "Opening User NAND Contents");
if (bis_factory == nullptr)
@@ -343,7 +342,7 @@ std::shared_ptr<FileSys::RegisteredCache> GetUserNANDContents() {
return bis_factory->GetUserNANDContents();
}
-std::shared_ptr<FileSys::RegisteredCache> GetSDMCContents() {
+FileSys::RegisteredCache* GetSDMCContents() {
LOG_TRACE(Service_FS, "Opening SDMC Contents");
if (sdmc_factory == nullptr)
diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h
index 2df1faeb0..6ca5c5636 100644
--- a/src/core/hle/service/filesystem/filesystem.h
+++ b/src/core/hle/service/filesystem/filesystem.h
@@ -47,11 +47,11 @@ ResultVal<FileSys::VirtualDir> OpenSaveData(FileSys::SaveDataSpaceId space,
FileSys::SaveDataDescriptor save_struct);
ResultVal<FileSys::VirtualDir> OpenSDMC();
-std::shared_ptr<FileSys::RegisteredCacheUnion> GetUnionContents();
+std::unique_ptr<FileSys::RegisteredCacheUnion> GetUnionContents();
-std::shared_ptr<FileSys::RegisteredCache> GetSystemNANDContents();
-std::shared_ptr<FileSys::RegisteredCache> GetUserNANDContents();
-std::shared_ptr<FileSys::RegisteredCache> GetSDMCContents();
+FileSys::RegisteredCache* GetSystemNANDContents();
+FileSys::RegisteredCache* GetUserNANDContents();
+FileSys::RegisteredCache* GetSDMCContents();
FileSys::VirtualDir GetModificationLoadRoot(u64 title_id);
diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp
index 4b2f758a8..44accecb7 100644
--- a/src/core/hle/service/ns/pl_u.cpp
+++ b/src/core/hle/service/ns/pl_u.cpp
@@ -161,7 +161,7 @@ PL_U::PL_U() : ServiceFramework("pl:u"), impl{std::make_unique<Impl>()} {
};
RegisterHandlers(functions);
// Attempt to load shared font data from disk
- const auto nand = FileSystem::GetSystemNANDContents();
+ const auto* nand = FileSystem::GetSystemNANDContents();
std::size_t offset = 0;
// Rebuild shared fonts from data ncas
if (nand->HasEntry(static_cast<u64>(FontArchives::Standard),
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp
index 951fd8257..8518dddcb 100644
--- a/src/core/loader/deconstructed_rom_directory.cpp
+++ b/src/core/loader/deconstructed_rom_directory.cpp
@@ -139,14 +139,22 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(Kernel::Process& process)
for (const auto& module : {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3",
"subsdk4", "subsdk5", "subsdk6", "subsdk7", "sdk"}) {
const FileSys::VirtualFile module_file = dir->GetFile(module);
- if (module_file != nullptr) {
- const VAddr load_addr = next_load_addr;
- next_load_addr = AppLoader_NSO::LoadModule(module_file, load_addr,
- std::strcmp(module, "rtld") == 0, pm);
- LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr);
- // Register module with GDBStub
- GDBStub::RegisterModule(module, load_addr, next_load_addr - 1, false);
+ if (module_file == nullptr) {
+ continue;
}
+
+ const VAddr load_addr = next_load_addr;
+ const bool should_pass_arguments = std::strcmp(module, "rtld") == 0;
+ const auto tentative_next_load_addr =
+ AppLoader_NSO::LoadModule(*module_file, load_addr, should_pass_arguments, pm);
+ if (!tentative_next_load_addr) {
+ return ResultStatus::ErrorLoadingNSO;
+ }
+
+ next_load_addr = *tentative_next_load_addr;
+ LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr);
+ // Register module with GDBStub
+ GDBStub::RegisterModule(module, load_addr, next_load_addr - 1, false);
}
process.Run(base_address, metadata.GetMainThreadPriority(), metadata.GetMainThreadStackSize());
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp
index 91659ec17..9cd0b0ccd 100644
--- a/src/core/loader/loader.cpp
+++ b/src/core/loader/loader.cpp
@@ -93,7 +93,7 @@ std::string GetFileTypeString(FileType type) {
return "unknown";
}
-constexpr std::array<const char*, 59> RESULT_MESSAGES{
+constexpr std::array<const char*, 60> RESULT_MESSAGES{
"The operation completed successfully.",
"The loader requested to load is already loaded.",
"The operation is not implemented.",
@@ -128,6 +128,7 @@ constexpr std::array<const char*, 59> RESULT_MESSAGES{
"The RomFS could not be found.",
"The ELF file has incorrect size as determined by the header.",
"There was a general error loading the NRO into emulated memory.",
+ "There was a general error loading the NSO into emulated memory.",
"There is no icon available.",
"There is no control data available.",
"The NAX file has a bad header.",
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h
index 0e0333db5..e562b3a04 100644
--- a/src/core/loader/loader.h
+++ b/src/core/loader/loader.h
@@ -90,6 +90,7 @@ enum class ResultStatus : u16 {
ErrorNoRomFS,
ErrorIncorrectELFFileSize,
ErrorLoadingNRO,
+ ErrorLoadingNSO,
ErrorNoIcon,
ErrorNoControl,
ErrorBadNAXHeader,
diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp
index 576fe692a..243b499f2 100644
--- a/src/core/loader/nro.cpp
+++ b/src/core/loader/nro.cpp
@@ -127,10 +127,10 @@ static constexpr u32 PageAlignSize(u32 size) {
return (size + Memory::PAGE_MASK) & ~Memory::PAGE_MASK;
}
-bool AppLoader_NRO::LoadNro(FileSys::VirtualFile file, VAddr load_base) {
+bool AppLoader_NRO::LoadNro(const FileSys::VfsFile& file, VAddr load_base) {
// Read NSO header
NroHeader nro_header{};
- if (sizeof(NroHeader) != file->ReadObject(&nro_header)) {
+ if (sizeof(NroHeader) != file.ReadObject(&nro_header)) {
return {};
}
if (nro_header.magic != Common::MakeMagic('N', 'R', 'O', '0')) {
@@ -138,7 +138,7 @@ bool AppLoader_NRO::LoadNro(FileSys::VirtualFile file, VAddr load_base) {
}
// Build program image
- std::vector<u8> program_image = file->ReadBytes(PageAlignSize(nro_header.file_size));
+ std::vector<u8> program_image = file.ReadBytes(PageAlignSize(nro_header.file_size));
if (program_image.size() != PageAlignSize(nro_header.file_size)) {
return {};
}
@@ -182,7 +182,7 @@ bool AppLoader_NRO::LoadNro(FileSys::VirtualFile file, VAddr load_base) {
Core::CurrentProcess()->LoadModule(std::move(codeset), load_base);
// Register module with GDBStub
- GDBStub::RegisterModule(file->GetName(), load_base, load_base);
+ GDBStub::RegisterModule(file.GetName(), load_base, load_base);
return true;
}
@@ -195,7 +195,7 @@ ResultStatus AppLoader_NRO::Load(Kernel::Process& process) {
// Load NRO
const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress();
- if (!LoadNro(file, base_address)) {
+ if (!LoadNro(*file, base_address)) {
return ResultStatus::ErrorLoadingNRO;
}
diff --git a/src/core/loader/nro.h b/src/core/loader/nro.h
index 04b46119a..50ee5a78a 100644
--- a/src/core/loader/nro.h
+++ b/src/core/loader/nro.h
@@ -41,7 +41,7 @@ public:
bool IsRomFSUpdatable() const override;
private:
- bool LoadNro(FileSys::VirtualFile file, VAddr load_base);
+ bool LoadNro(const FileSys::VfsFile& file, VAddr load_base);
std::vector<u8> icon_data;
std::unique_ptr<FileSys::NACP> nacp;
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp
index ba57db9bf..68efca5c0 100644
--- a/src/core/loader/nso.cpp
+++ b/src/core/loader/nso.cpp
@@ -93,17 +93,14 @@ static constexpr u32 PageAlignSize(u32 size) {
return (size + Memory::PAGE_MASK) & ~Memory::PAGE_MASK;
}
-VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base,
- bool should_pass_arguments,
- boost::optional<FileSys::PatchManager> pm) {
- if (file == nullptr)
- return {};
-
- if (file->GetSize() < sizeof(NsoHeader))
+std::optional<VAddr> AppLoader_NSO::LoadModule(const FileSys::VfsFile& file, VAddr load_base,
+ bool should_pass_arguments,
+ std::optional<FileSys::PatchManager> pm) {
+ if (file.GetSize() < sizeof(NsoHeader))
return {};
NsoHeader nso_header{};
- if (sizeof(NsoHeader) != file->ReadObject(&nso_header))
+ if (sizeof(NsoHeader) != file.ReadObject(&nso_header))
return {};
if (nso_header.magic != Common::MakeMagic('N', 'S', 'O', '0'))
@@ -114,7 +111,7 @@ VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base,
std::vector<u8> program_image;
for (std::size_t i = 0; i < nso_header.segments.size(); ++i) {
std::vector<u8> data =
- file->ReadBytes(nso_header.segments_compressed_size[i], nso_header.segments[i].offset);
+ file.ReadBytes(nso_header.segments_compressed_size[i], nso_header.segments[i].offset);
if (nso_header.IsSegmentCompressed(i)) {
data = DecompressSegment(data, nso_header.segments[i]);
}
@@ -157,7 +154,7 @@ VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base,
program_image.resize(image_size);
// Apply patches if necessary
- if (pm != boost::none && pm->HasNSOPatch(nso_header.build_id)) {
+ if (pm && pm->HasNSOPatch(nso_header.build_id)) {
std::vector<u8> pi_header(program_image.size() + 0x100);
std::memcpy(pi_header.data(), &nso_header, sizeof(NsoHeader));
std::memcpy(pi_header.data() + 0x100, program_image.data(), program_image.size());
@@ -172,7 +169,7 @@ VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base,
Core::CurrentProcess()->LoadModule(std::move(codeset), load_base);
// Register module with GDBStub
- GDBStub::RegisterModule(file->GetName(), load_base, load_base);
+ GDBStub::RegisterModule(file.GetName(), load_base, load_base);
return load_base + image_size;
}
@@ -184,7 +181,9 @@ ResultStatus AppLoader_NSO::Load(Kernel::Process& process) {
// Load module
const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress();
- LoadModule(file, base_address, true);
+ if (!LoadModule(*file, base_address, true)) {
+ 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);
diff --git a/src/core/loader/nso.h b/src/core/loader/nso.h
index 70ab3b718..433306139 100644
--- a/src/core/loader/nso.h
+++ b/src/core/loader/nso.h
@@ -4,6 +4,7 @@
#pragma once
+#include <optional>
#include "common/common_types.h"
#include "core/file_sys/patch_manager.h"
#include "core/loader/linker.h"
@@ -36,8 +37,9 @@ public:
return IdentifyType(file);
}
- static VAddr LoadModule(FileSys::VirtualFile file, VAddr load_base, bool should_pass_arguments,
- boost::optional<FileSys::PatchManager> pm = boost::none);
+ static std::optional<VAddr> LoadModule(const FileSys::VfsFile& file, VAddr load_base,
+ bool should_pass_arguments,
+ std::optional<FileSys::PatchManager> pm = {});
ResultStatus Load(Kernel::Process& process) override;
};