diff options
Diffstat (limited to 'src/core/loader')
| -rw-r--r-- | src/core/loader/deconstructed_rom_directory.cpp | 183 | ||||
| -rw-r--r-- | src/core/loader/deconstructed_rom_directory.h | 48 | ||||
| -rw-r--r-- | src/core/loader/elf.cpp | 15 | ||||
| -rw-r--r-- | src/core/loader/elf.h | 8 | ||||
| -rw-r--r-- | src/core/loader/linker.cpp | 2 | ||||
| -rw-r--r-- | src/core/loader/loader.cpp | 22 | ||||
| -rw-r--r-- | src/core/loader/loader.h | 9 | ||||
| -rw-r--r-- | src/core/loader/nro.cpp | 17 | ||||
| -rw-r--r-- | src/core/loader/nro.h | 10 | ||||
| -rw-r--r-- | src/core/loader/nso.cpp | 40 | ||||
| -rw-r--r-- | src/core/loader/nso.h | 14 |
11 files changed, 299 insertions, 69 deletions
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp new file mode 100644 index 000000000..aa09ed323 --- /dev/null +++ b/src/core/loader/deconstructed_rom_directory.cpp @@ -0,0 +1,183 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <cinttypes> +#include "common/common_funcs.h" +#include "common/common_paths.h" +#include "common/file_util.h" +#include "common/logging/log.h" +#include "common/string_util.h" +#include "core/file_sys/romfs_factory.h" +#include "core/hle/kernel/process.h" +#include "core/hle/kernel/resource_limit.h" +#include "core/hle/service/filesystem/filesystem.h" +#include "core/loader/deconstructed_rom_directory.h" +#include "core/loader/nso.h" +#include "core/memory.h" + +namespace Loader { + +static std::string FindRomFS(const std::string& directory) { + std::string filepath_romfs; + const auto callback = [&filepath_romfs](unsigned*, const std::string& directory, + const std::string& virtual_name) -> bool { + const std::string physical_name = directory + virtual_name; + if (FileUtil::IsDirectory(physical_name)) { + // Skip directories + return true; + } + + // Verify extension + const std::string extension = physical_name.substr(physical_name.find_last_of(".") + 1); + if (Common::ToLower(extension) != "romfs") { + return true; + } + + // Found it - we are done + filepath_romfs = std::move(physical_name); + return false; + }; + + // Search the specified directory recursively, looking for the first .romfs file, which will + // be used for the RomFS + FileUtil::ForeachDirectoryEntry(nullptr, directory, callback); + + return filepath_romfs; +} + +AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileUtil::IOFile&& file, + std::string filepath) + : AppLoader(std::move(file)), filepath(std::move(filepath)) {} + +FileType AppLoader_DeconstructedRomDirectory::IdentifyType(FileUtil::IOFile& file, + const std::string& filepath) { + bool is_main_found{}; + bool is_npdm_found{}; + bool is_rtld_found{}; + bool is_sdk_found{}; + + const auto callback = [&](unsigned* num_entries_out, const std::string& directory, + const std::string& virtual_name) -> bool { + // Skip directories + std::string physical_name = directory + virtual_name; + if (FileUtil::IsDirectory(physical_name)) { + return true; + } + + // Verify filename + if (Common::ToLower(virtual_name) == "main") { + is_main_found = true; + } else if (Common::ToLower(virtual_name) == "main.npdm") { + is_npdm_found = true; + return true; + } else if (Common::ToLower(virtual_name) == "rtld") { + is_rtld_found = true; + } else if (Common::ToLower(virtual_name) == "sdk") { + is_sdk_found = true; + } else { + // Contrinue searching + return true; + } + + // Verify file is an NSO + FileUtil::IOFile file(physical_name, "rb"); + if (AppLoader_NSO::IdentifyType(file, physical_name) != FileType::NSO) { + return false; + } + + // We are done if we've found and verified all required NSOs + return !(is_main_found && is_npdm_found && is_rtld_found && is_sdk_found); + }; + + // Search the directory recursively, looking for the required modules + const std::string directory = filepath.substr(0, filepath.find_last_of("/\\")) + DIR_SEP; + FileUtil::ForeachDirectoryEntry(nullptr, directory, callback); + + if (is_main_found && is_npdm_found && is_rtld_found && is_sdk_found) { + return FileType::DeconstructedRomDirectory; + } + + return FileType::Error; +} + +ResultStatus AppLoader_DeconstructedRomDirectory::Load( + Kernel::SharedPtr<Kernel::Process>& process) { + if (is_loaded) { + return ResultStatus::ErrorAlreadyLoaded; + } + if (!file.IsOpen()) { + return ResultStatus::Error; + } + + const std::string directory = filepath.substr(0, filepath.find_last_of("/\\")) + DIR_SEP; + const std::string npdm_path = directory + DIR_SEP + "main.npdm"; + + ResultStatus result = metadata.Load(npdm_path); + if (result != ResultStatus::Success) { + return result; + } + metadata.Print(); + + // Load NSO modules + VAddr next_load_addr{Memory::PROCESS_IMAGE_VADDR}; + for (const auto& module : {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3", + "subsdk4", "subsdk5", "subsdk6", "subsdk7", "sdk"}) { + const std::string path = directory + DIR_SEP + module; + const VAddr load_addr = next_load_addr; + next_load_addr = AppLoader_NSO::LoadModule(path, load_addr); + if (next_load_addr) { + LOG_DEBUG(Loader, "loaded module %s @ 0x%" PRIx64, module, load_addr); + } else { + next_load_addr = load_addr; + } + } + + process->program_id = metadata.GetTitleID(); + process->svc_access_mask.set(); + process->address_mappings = default_address_mappings; + process->resource_limit = + Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); + process->Run(Memory::PROCESS_IMAGE_VADDR, metadata.GetMainThreadPriority(), + metadata.GetMainThreadStackSize()); + + // Find the RomFS by searching for a ".romfs" file in this directory + filepath_romfs = FindRomFS(directory); + + // Register the RomFS if a ".romfs" file was found + if (!filepath_romfs.empty()) { + Service::FileSystem::RegisterFileSystem(std::make_unique<FileSys::RomFS_Factory>(*this), + Service::FileSystem::Type::RomFS); + } + + is_loaded = true; + return ResultStatus::Success; +} + +ResultStatus AppLoader_DeconstructedRomDirectory::ReadRomFS( + std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) { + + if (filepath_romfs.empty()) { + LOG_DEBUG(Loader, "No RomFS available"); + return ResultStatus::ErrorNotUsed; + } + + // We reopen the file, to allow its position to be independent + romfs_file = std::make_shared<FileUtil::IOFile>(filepath_romfs, "rb"); + if (!romfs_file->IsOpen()) { + return ResultStatus::Error; + } + + offset = 0; + size = romfs_file->GetSize(); + + LOG_DEBUG(Loader, "RomFS offset: 0x%016" PRIX64, offset); + LOG_DEBUG(Loader, "RomFS size: 0x%016" PRIX64, size); + + // Reset read pointer + file.Seek(0, SEEK_SET); + + return ResultStatus::Success; +} + +} // namespace Loader diff --git a/src/core/loader/deconstructed_rom_directory.h b/src/core/loader/deconstructed_rom_directory.h new file mode 100644 index 000000000..23295d911 --- /dev/null +++ b/src/core/loader/deconstructed_rom_directory.h @@ -0,0 +1,48 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <string> +#include "common/common_types.h" +#include "core/file_sys/program_metadata.h" +#include "core/hle/kernel/kernel.h" +#include "core/loader/loader.h" + +namespace Loader { + +/** + * This class loads a "deconstructed ROM directory", which are the typical format we see for Switch + * game dumps. The path should be a "main" NSO, which must be in a directory that contains the other + * standard ExeFS NSOs (e.g. rtld, sdk, etc.). It will automatically find and load these. + * Furthermore, it will look for the first .romfs file (optionally) and use this for the RomFS. + */ +class AppLoader_DeconstructedRomDirectory final : public AppLoader { +public: + AppLoader_DeconstructedRomDirectory(FileUtil::IOFile&& file, std::string filepath); + + /** + * Returns the type of the file + * @param file FileUtil::IOFile open file + * @param filepath Path of the file that we are opening. + * @return FileType found, or FileType::Error if this loader doesn't know it + */ + static FileType IdentifyType(FileUtil::IOFile& file, const std::string& filepath); + + FileType GetFileType() override { + return IdentifyType(file, filepath); + } + + ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override; + + ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, + u64& size) override; + +private: + std::string filepath_romfs; + std::string filepath; + FileSys::ProgramMetadata metadata; +}; + +} // namespace Loader diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index 9ba913dbe..0ba8c6fd2 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -300,7 +300,7 @@ SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) { std::vector<u8> program_image(total_image_size); size_t current_image_position = 0; - SharedPtr<CodeSet> codeset = CodeSet::Create("", 0); + SharedPtr<CodeSet> codeset = CodeSet::Create(""); for (unsigned int i = 0; i < header->e_phnum; ++i) { Elf32_Phdr* p = &segments[i]; @@ -323,8 +323,9 @@ SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) { } if (codeset_segment->size != 0) { - LOG_ERROR(Loader, "ELF has more than one segment of the same type. Skipping extra " - "segment (id %i)", + LOG_ERROR(Loader, + "ELF has more than one segment of the same type. Skipping extra " + "segment (id %i)", i); continue; } @@ -364,7 +365,10 @@ SectionID ElfReader::GetSectionByName(const char* name, int firstSection) const namespace Loader { -FileType AppLoader_ELF::IdentifyType(FileUtil::IOFile& file) { +AppLoader_ELF::AppLoader_ELF(FileUtil::IOFile&& file, std::string filename) + : AppLoader(std::move(file)), filename(std::move(filename)) {} + +FileType AppLoader_ELF::IdentifyType(FileUtil::IOFile& file, const std::string&) { static constexpr u16 ELF_MACHINE_ARM{0x28}; u32 magic = 0; @@ -402,7 +406,6 @@ ResultStatus AppLoader_ELF::Load(Kernel::SharedPtr<Kernel::Process>& process) { SharedPtr<CodeSet> codeset = elf_reader.LoadInto(Memory::PROCESS_IMAGE_VADDR); codeset->name = filename; - process = Kernel::Process::Create("main"); process->LoadModule(codeset, codeset->entrypoint); process->svc_access_mask.set(); process->address_mappings = default_address_mappings; @@ -411,7 +414,7 @@ ResultStatus AppLoader_ELF::Load(Kernel::SharedPtr<Kernel::Process>& process) { process->resource_limit = Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); - process->Run(codeset->entrypoint, 48, Kernel::DEFAULT_STACK_SIZE); + process->Run(codeset->entrypoint, 48, Memory::STACK_SIZE); is_loaded = true; return ResultStatus::Success; diff --git a/src/core/loader/elf.h b/src/core/loader/elf.h index 113da5917..ee741a789 100644 --- a/src/core/loader/elf.h +++ b/src/core/loader/elf.h @@ -16,18 +16,18 @@ namespace Loader { /// Loads an ELF/AXF file class AppLoader_ELF final : public AppLoader { public: - AppLoader_ELF(FileUtil::IOFile&& file, std::string filename) - : AppLoader(std::move(file)), filename(std::move(filename)) {} + AppLoader_ELF(FileUtil::IOFile&& file, std::string filename); /** * Returns the type of the file * @param file FileUtil::IOFile open file + * @param filepath Path of the file that we are opening. * @return FileType found, or FileType::Error if this loader doesn't know it */ - static FileType IdentifyType(FileUtil::IOFile& file); + static FileType IdentifyType(FileUtil::IOFile& file, const std::string& filepath); FileType GetFileType() override { - return IdentifyType(file); + return IdentifyType(file, filename); } ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override; diff --git a/src/core/loader/linker.cpp b/src/core/loader/linker.cpp index 87cc65e91..69198e3e3 100644 --- a/src/core/loader/linker.cpp +++ b/src/core/loader/linker.cpp @@ -84,7 +84,7 @@ void Linker::WriteRelocations(std::vector<u8>& program_image, const std::vector< } break; default: - LOG_CRITICAL(Loader, "Unknown relocation type: %d", rela.type); + LOG_CRITICAL(Loader, "Unknown relocation type: %d", static_cast<int>(rela.type)); break; } } diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 92defd381..2ec08506d 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -1,4 +1,4 @@ -// Copyright 2014 Citra Emulator Project +// Copyright 2018 yuzu emulator team // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -7,12 +7,11 @@ #include "common/logging/log.h" #include "common/string_util.h" #include "core/hle/kernel/process.h" +#include "core/loader/deconstructed_rom_directory.h" #include "core/loader/elf.h" #include "core/loader/nro.h" #include "core/loader/nso.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// - namespace Loader { const std::initializer_list<Kernel::AddressMapping> default_address_mappings = { @@ -21,14 +20,15 @@ const std::initializer_list<Kernel::AddressMapping> default_address_mappings = { {0x1F000000, 0x600000, false}, // entire VRAM }; -FileType IdentifyFile(FileUtil::IOFile& file) { +FileType IdentifyFile(FileUtil::IOFile& file, const std::string& filepath) { FileType type; #define CHECK_TYPE(loader) \ - type = AppLoader_##loader::IdentifyType(file); \ + type = AppLoader_##loader::IdentifyType(file, filepath); \ if (FileType::Error != type) \ return type; + CHECK_TYPE(DeconstructedRomDirectory) CHECK_TYPE(ELF) CHECK_TYPE(NSO) CHECK_TYPE(NRO) @@ -45,13 +45,13 @@ FileType IdentifyFile(const std::string& file_name) { return FileType::Unknown; } - return IdentifyFile(file); + return IdentifyFile(file, file_name); } FileType GuessFromExtension(const std::string& extension_) { std::string extension = Common::ToLower(extension_); - if (extension == ".elf" || extension == ".axf") + if (extension == ".elf") return FileType::ELF; else if (extension == ".nro") return FileType::NRO; @@ -69,6 +69,8 @@ const char* GetFileTypeString(FileType type) { return "NRO"; case FileType::NSO: return "NSO"; + case FileType::DeconstructedRomDirectory: + return "Directory"; case FileType::Error: case FileType::Unknown: break; @@ -102,6 +104,10 @@ static std::unique_ptr<AppLoader> GetFileLoader(FileUtil::IOFile&& file, FileTyp case FileType::NRO: return std::make_unique<AppLoader_NRO>(std::move(file), filepath); + // NX deconstructed ROM directory. + case FileType::DeconstructedRomDirectory: + return std::make_unique<AppLoader_DeconstructedRomDirectory>(std::move(file), filepath); + default: return nullptr; } @@ -117,7 +123,7 @@ std::unique_ptr<AppLoader> GetLoader(const std::string& filename) { std::string filename_filename, filename_extension; Common::SplitPath(filename, nullptr, &filename_filename, &filename_extension); - FileType type = IdentifyFile(file); + FileType type = IdentifyFile(file, filename); FileType filename_type = GuessFromExtension(filename_extension); if (type != filename_type) { diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index dd6bb4e64..dd44ee9a6 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h @@ -1,4 +1,4 @@ -// Copyright 2014 Citra Emulator Project +// Copyright 2018 yuzu emulator team // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -20,9 +20,6 @@ struct AddressMapping; class Process; } // namespace Kernel -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Loader namespace - namespace Loader { /// File types supported by CTR @@ -32,14 +29,16 @@ enum class FileType { ELF, NSO, NRO, + DeconstructedRomDirectory, }; /** * Identifies the type of a bootable file based on the magic value in its header. * @param file open file + * @param filepath Path of the file that we are opening. * @return FileType of file */ -FileType IdentifyFile(FileUtil::IOFile& file); +FileType IdentifyFile(FileUtil::IOFile& file, const std::string& filepath); /** * Identifies the type of a bootable file based on the magic value in its header. diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp index 6864a1926..6dcd1ce48 100644 --- a/src/core/loader/nro.cpp +++ b/src/core/loader/nro.cpp @@ -5,8 +5,10 @@ #include <vector> #include "common/common_funcs.h" +#include "common/file_util.h" #include "common/logging/log.h" #include "common/swap.h" +#include "core/core.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/resource_limit.h" #include "core/loader/nro.h" @@ -45,7 +47,10 @@ struct ModHeader { }; static_assert(sizeof(ModHeader) == 0x1c, "ModHeader has incorrect size."); -FileType AppLoader_NRO::IdentifyType(FileUtil::IOFile& file) { +AppLoader_NRO::AppLoader_NRO(FileUtil::IOFile&& file, std::string filepath) + : AppLoader(std::move(file)), filepath(std::move(filepath)) {} + +FileType AppLoader_NRO::IdentifyType(FileUtil::IOFile& file, const std::string&) { // Read NSO header NroHeader nro_header{}; file.Seek(0, SEEK_SET); @@ -79,7 +84,7 @@ bool AppLoader_NRO::LoadNro(const std::string& path, VAddr load_base) { } // Build program image - Kernel::SharedPtr<Kernel::CodeSet> codeset = Kernel::CodeSet::Create("", 0); + Kernel::SharedPtr<Kernel::CodeSet> codeset = Kernel::CodeSet::Create(""); std::vector<u8> program_image; program_image.resize(PageAlignSize(nro_header.file_size)); file.Seek(0, SEEK_SET); @@ -103,12 +108,12 @@ bool AppLoader_NRO::LoadNro(const std::string& path, VAddr load_base) { bss_size = PageAlignSize(mod_header.bss_end_offset - mod_header.bss_start_offset); } codeset->data.size += bss_size; - program_image.resize(PageAlignSize(static_cast<u32>(program_image.size()) + bss_size)); + program_image.resize(static_cast<u32>(program_image.size()) + bss_size); // Load codeset for current process codeset->name = path; codeset->memory = std::make_shared<std::vector<u8>>(std::move(program_image)); - Kernel::g_current_process->LoadModule(codeset, load_base); + Core::CurrentProcess()->LoadModule(codeset, load_base); return true; } @@ -121,8 +126,6 @@ ResultStatus AppLoader_NRO::Load(Kernel::SharedPtr<Kernel::Process>& process) { return ResultStatus::Error; } - process = Kernel::Process::Create("main"); - // Load NRO static constexpr VAddr base_addr{Memory::PROCESS_IMAGE_VADDR}; @@ -134,7 +137,7 @@ ResultStatus AppLoader_NRO::Load(Kernel::SharedPtr<Kernel::Process>& process) { process->address_mappings = default_address_mappings; process->resource_limit = Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); - process->Run(base_addr + sizeof(NroHeader), 48, Kernel::DEFAULT_STACK_SIZE); + process->Run(base_addr, 48, Memory::STACK_SIZE); is_loaded = true; return ResultStatus::Success; diff --git a/src/core/loader/nro.h b/src/core/loader/nro.h index e20fa1555..599adb253 100644 --- a/src/core/loader/nro.h +++ b/src/core/loader/nro.h @@ -4,10 +4,8 @@ #pragma once -#include <map> #include <string> #include "common/common_types.h" -#include "common/file_util.h" #include "core/hle/kernel/kernel.h" #include "core/loader/linker.h" #include "core/loader/loader.h" @@ -17,18 +15,18 @@ namespace Loader { /// Loads an NRO file class AppLoader_NRO final : public AppLoader, Linker { public: - AppLoader_NRO(FileUtil::IOFile&& file, std::string filepath) - : AppLoader(std::move(file)), filepath(std::move(filepath)) {} + AppLoader_NRO(FileUtil::IOFile&& file, std::string filepath); /** * Returns the type of the file * @param file FileUtil::IOFile open file + * @param filepath Path of the file that we are opening. * @return FileType found, or FileType::Error if this loader doesn't know it */ - static FileType IdentifyType(FileUtil::IOFile& file); + static FileType IdentifyType(FileUtil::IOFile& file, const std::string& filepath); FileType GetFileType() override { - return IdentifyType(file); + return IdentifyType(file, filepath); } ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override; diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index ef769dd91..100aa022e 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp @@ -2,12 +2,14 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <cinttypes> #include <vector> #include <lz4.h> - #include "common/common_funcs.h" +#include "common/file_util.h" #include "common/logging/log.h" #include "common/swap.h" +#include "core/core.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/resource_limit.h" #include "core/loader/nso.h" @@ -47,7 +49,10 @@ struct ModHeader { }; static_assert(sizeof(ModHeader) == 0x1c, "ModHeader has incorrect size."); -FileType AppLoader_NSO::IdentifyType(FileUtil::IOFile& file) { +AppLoader_NSO::AppLoader_NSO(FileUtil::IOFile&& file, std::string filepath) + : AppLoader(std::move(file)), filepath(std::move(filepath)) {} + +FileType AppLoader_NSO::IdentifyType(FileUtil::IOFile& file, const std::string&) { u32 magic = 0; file.Seek(0, SEEK_SET); if (1 != file.ReadArray<u32>(&magic, 1)) { @@ -79,7 +84,7 @@ static std::vector<u8> ReadSegment(FileUtil::IOFile& file, const NsoSegmentHeade reinterpret_cast<char*>(uncompressed_data.data()), compressed_size, header.size); ASSERT_MSG(bytes_uncompressed == header.size && bytes_uncompressed == uncompressed_data.size(), - "%d != %d != %d", bytes_uncompressed, header.size, uncompressed_data.size()); + "%d != %u != %zu", bytes_uncompressed, header.size, uncompressed_data.size()); return uncompressed_data; } @@ -88,7 +93,7 @@ static constexpr u32 PageAlignSize(u32 size) { return (size + Memory::PAGE_MASK) & ~Memory::PAGE_MASK; } -VAddr AppLoader_NSO::LoadNso(const std::string& path, VAddr load_base) { +VAddr AppLoader_NSO::LoadModule(const std::string& path, VAddr load_base) { FileUtil::IOFile file(path, "rb"); if (!file.IsOpen()) { return {}; @@ -105,7 +110,7 @@ VAddr AppLoader_NSO::LoadNso(const std::string& path, VAddr load_base) { } // Build program image - Kernel::SharedPtr<Kernel::CodeSet> codeset = Kernel::CodeSet::Create("", 0); + Kernel::SharedPtr<Kernel::CodeSet> codeset = Kernel::CodeSet::Create(""); std::vector<u8> program_image; for (int i = 0; i < nso_header.segments.size(); ++i) { std::vector<u8> data = @@ -138,7 +143,7 @@ VAddr AppLoader_NSO::LoadNso(const std::string& path, VAddr load_base) { // Load codeset for current process codeset->name = path; codeset->memory = std::make_shared<std::vector<u8>>(std::move(program_image)); - Kernel::g_current_process->LoadModule(codeset, load_base); + Core::CurrentProcess()->LoadModule(codeset, load_base); return load_base + image_size; } @@ -151,29 +156,16 @@ ResultStatus AppLoader_NSO::Load(Kernel::SharedPtr<Kernel::Process>& process) { return ResultStatus::Error; } - process = Kernel::Process::Create("main"); - - // Load NSO modules - VAddr next_load_addr{Memory::PROCESS_IMAGE_VADDR}; - for (const auto& module : - {"rtld", "sdk", "subsdk0", "subsdk1", "subsdk2", "subsdk3", "subsdk4"}) { - const std::string path = filepath.substr(0, filepath.find_last_of("/\\")) + "/" + module; - const VAddr load_addr = next_load_addr; - next_load_addr = LoadNso(path, load_addr); - if (next_load_addr) { - LOG_DEBUG(Loader, "loaded module %s @ 0x%llx", module, load_addr); - } else { - next_load_addr = load_addr; - } - } - // Load "main" module - LoadNso(filepath, next_load_addr); + // Load module + LoadModule(filepath, Memory::PROCESS_IMAGE_VADDR); + LOG_DEBUG(Loader, "loaded module %s @ 0x%" PRIx64, filepath.c_str(), + Memory::PROCESS_IMAGE_VADDR); process->svc_access_mask.set(); process->address_mappings = default_address_mappings; process->resource_limit = Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); - process->Run(Memory::PROCESS_IMAGE_VADDR, 48, Kernel::DEFAULT_STACK_SIZE); + process->Run(Memory::PROCESS_IMAGE_VADDR, 48, Memory::STACK_SIZE); is_loaded = true; return ResultStatus::Success; diff --git a/src/core/loader/nso.h b/src/core/loader/nso.h index a24bcdc24..1ae30a824 100644 --- a/src/core/loader/nso.h +++ b/src/core/loader/nso.h @@ -4,10 +4,8 @@ #pragma once -#include <map> #include <string> #include "common/common_types.h" -#include "common/file_util.h" #include "core/hle/kernel/kernel.h" #include "core/loader/linker.h" #include "core/loader/loader.h" @@ -17,25 +15,25 @@ namespace Loader { /// Loads an NSO file class AppLoader_NSO final : public AppLoader, Linker { public: - AppLoader_NSO(FileUtil::IOFile&& file, std::string filepath) - : AppLoader(std::move(file)), filepath(std::move(filepath)) {} + AppLoader_NSO(FileUtil::IOFile&& file, std::string filepath); /** * Returns the type of the file * @param file FileUtil::IOFile open file + * @param filepath Path of the file that we are opening. * @return FileType found, or FileType::Error if this loader doesn't know it */ - static FileType IdentifyType(FileUtil::IOFile& file); + static FileType IdentifyType(FileUtil::IOFile& file, const std::string& filepath); FileType GetFileType() override { - return IdentifyType(file); + return IdentifyType(file, filepath); } + static VAddr LoadModule(const std::string& path, VAddr load_base); + ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override; private: - VAddr LoadNso(const std::string& path, VAddr load_base); - std::string filepath; }; |
