mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 22:00:05 +00:00 
			
		
		
		
	Loader: Keep a reference to the file and pass it to the correct AppLoader, instead of loading it multiple times.
This commit is contained in:
		
							parent
							
								
									2d63df90a9
								
							
						
					
					
						commit
						b5237e885d
					
				
					 8 changed files with 130 additions and 190 deletions
				
			
		|  | @ -199,28 +199,15 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr) | |||
|     return ERROR_NONE; | ||||
| } | ||||
| 
 | ||||
| /// AppLoader_DSX constructor
 | ||||
| AppLoader_THREEDSX::AppLoader_THREEDSX(const std::string& filename) : filename(filename) { | ||||
| } | ||||
| 
 | ||||
| /// AppLoader_DSX destructor
 | ||||
| AppLoader_THREEDSX::~AppLoader_THREEDSX() { | ||||
| } | ||||
| 
 | ||||
| ResultStatus AppLoader_THREEDSX::Load() { | ||||
|     LOG_INFO(Loader, "Loading 3DSX file %s...", filename.c_str()); | ||||
| 
 | ||||
|     if (is_loaded) | ||||
|         return ResultStatus::ErrorAlreadyLoaded; | ||||
| 
 | ||||
|     FileUtil::IOFile file(filename, "rb"); | ||||
| 
 | ||||
|     if (file.IsOpen()) { | ||||
|         Load3DSXFile(file, 0x00100000); | ||||
|         Kernel::LoadExec(0x00100000); | ||||
|     } else { | ||||
|     if (!file->IsOpen()) | ||||
|         return ResultStatus::Error; | ||||
|     } | ||||
| 
 | ||||
|     Load3DSXFile(*file, 0x00100000); | ||||
|     Kernel::LoadExec(0x00100000); | ||||
| 
 | ||||
|     is_loaded = true; | ||||
|     return ResultStatus::Success; | ||||
|  |  | |||
|  | @ -15,18 +15,13 @@ namespace Loader { | |||
| /// Loads an 3DSX file
 | ||||
| class AppLoader_THREEDSX final : public AppLoader { | ||||
| public: | ||||
|     AppLoader_THREEDSX(const std::string& filename); | ||||
|     ~AppLoader_THREEDSX() override; | ||||
|     AppLoader_THREEDSX(std::unique_ptr<FileUtil::IOFile>&& file) : AppLoader(std::move(file)) { } | ||||
| 
 | ||||
|     /**
 | ||||
|      * Load the bootable file | ||||
|      * @return ResultStatus result of function | ||||
|      */ | ||||
|     ResultStatus Load() override; | ||||
| 
 | ||||
| private: | ||||
|     std::string filename; | ||||
|     bool        is_loaded = false; | ||||
| }; | ||||
| 
 | ||||
| } // namespace Loader
 | ||||
|  |  | |||
|  | @ -330,34 +330,20 @@ bool ElfReader::LoadSymbols() { | |||
| 
 | ||||
| namespace Loader { | ||||
| 
 | ||||
| /// AppLoader_ELF constructor
 | ||||
| AppLoader_ELF::AppLoader_ELF(const std::string& filename) { | ||||
|     this->filename = filename; | ||||
| } | ||||
| 
 | ||||
| /// AppLoader_NCCH destructor
 | ||||
| AppLoader_ELF::~AppLoader_ELF() { | ||||
| } | ||||
| 
 | ||||
| ResultStatus AppLoader_ELF::Load() { | ||||
|     LOG_INFO(Loader, "Loading ELF file %s...", filename.c_str()); | ||||
| 
 | ||||
|     if (is_loaded) | ||||
|         return ResultStatus::ErrorAlreadyLoaded; | ||||
| 
 | ||||
|     FileUtil::IOFile file(filename, "rb"); | ||||
| 
 | ||||
|     if (file.IsOpen()) { | ||||
|         u32 size = (u32)file.GetSize(); | ||||
|         std::unique_ptr<u8[]> buffer(new u8[size]); | ||||
|         file.ReadBytes(&buffer[0], size); | ||||
| 
 | ||||
|         ElfReader elf_reader(&buffer[0]); | ||||
|         elf_reader.LoadInto(0x00100000); | ||||
|         Kernel::LoadExec(elf_reader.GetEntryPoint()); | ||||
|     } else { | ||||
|     if (!file->IsOpen()) | ||||
|         return ResultStatus::Error; | ||||
|     } | ||||
| 
 | ||||
|     u32 size = static_cast<u32>(file->GetSize()); | ||||
|     std::unique_ptr<u8[]> buffer(new u8[size]); | ||||
|     file->ReadBytes(&buffer[0], size); | ||||
| 
 | ||||
|     ElfReader elf_reader(&buffer[0]); | ||||
|     elf_reader.LoadInto(0x00100000); | ||||
|     Kernel::LoadExec(elf_reader.GetEntryPoint()); | ||||
| 
 | ||||
|     is_loaded = true; | ||||
|     return ResultStatus::Success; | ||||
|  |  | |||
|  | @ -15,18 +15,13 @@ namespace Loader { | |||
| /// Loads an ELF/AXF file
 | ||||
| class AppLoader_ELF final : public AppLoader { | ||||
| public: | ||||
|     AppLoader_ELF(const std::string& filename); | ||||
|     ~AppLoader_ELF() override; | ||||
|     AppLoader_ELF(std::unique_ptr<FileUtil::IOFile>&& file) : AppLoader(std::move(file)) { } | ||||
| 
 | ||||
|     /**
 | ||||
|      * Load the bootable file | ||||
|      * @return ResultStatus result of function | ||||
|      */ | ||||
|     ResultStatus Load() override; | ||||
| 
 | ||||
| private: | ||||
|     std::string filename; | ||||
|     bool        is_loaded = false; | ||||
| }; | ||||
| 
 | ||||
| } // namespace Loader
 | ||||
|  |  | |||
|  | @ -56,20 +56,24 @@ FileType IdentifyFile(const std::string &filename) { | |||
| ResultStatus LoadFile(const std::string& filename) { | ||||
|     LOG_INFO(Loader, "Loading file %s...", filename.c_str()); | ||||
| 
 | ||||
|     std::unique_ptr<FileUtil::IOFile> file(new FileUtil::IOFile(filename, "rb")); | ||||
|     if (!file->IsOpen()) | ||||
|         return ResultStatus::Error; | ||||
| 
 | ||||
|     switch (IdentifyFile(filename)) { | ||||
| 
 | ||||
|     //3DSX file format...
 | ||||
|     case FileType::THREEDSX: | ||||
|         return AppLoader_THREEDSX(filename).Load(); | ||||
|         return AppLoader_THREEDSX(std::move(file)).Load(); | ||||
| 
 | ||||
|     // Standard ELF file format...
 | ||||
|     case FileType::ELF: | ||||
|         return AppLoader_ELF(filename).Load(); | ||||
|         return AppLoader_ELF(std::move(file)).Load(); | ||||
| 
 | ||||
|     // NCCH/NCSD container formats...
 | ||||
|     case FileType::CXI: | ||||
|     case FileType::CCI: { | ||||
|         AppLoader_NCCH app_loader(filename); | ||||
|         AppLoader_NCCH app_loader(std::move(file)); | ||||
| 
 | ||||
|         // Load application and RomFS
 | ||||
|         if (ResultStatus::Success == app_loader.Load()) { | ||||
|  | @ -83,16 +87,11 @@ ResultStatus LoadFile(const std::string& filename) { | |||
|     // Raw BIN file format...
 | ||||
|     case FileType::BIN: | ||||
|     { | ||||
|         LOG_INFO(Loader, "Loading BIN file %s...", filename.c_str()); | ||||
| 
 | ||||
|         FileUtil::IOFile file(filename, "rb"); | ||||
| 
 | ||||
|         if (file.IsOpen()) { | ||||
|             file.ReadBytes(Memory::GetPointer(Memory::EXEFS_CODE_VADDR), (size_t)file.GetSize()); | ||||
|             Kernel::LoadExec(Memory::EXEFS_CODE_VADDR); | ||||
|         } else { | ||||
|         size_t size = (size_t)file->GetSize(); | ||||
|         if (file->ReadBytes(Memory::GetPointer(Memory::EXEFS_CODE_VADDR), size) != size) | ||||
|             return ResultStatus::Error; | ||||
|         } | ||||
| 
 | ||||
|         Kernel::LoadExec(Memory::EXEFS_CODE_VADDR); | ||||
|         return ResultStatus::Success; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -7,6 +7,7 @@ | |||
| #include <vector> | ||||
| 
 | ||||
| #include "common/common.h" | ||||
| #include "common/file_util.h" | ||||
| 
 | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| // Loader namespace
 | ||||
|  | @ -40,7 +41,7 @@ enum class ResultStatus { | |||
| /// Interface for loading an application
 | ||||
| class AppLoader : NonCopyable { | ||||
| public: | ||||
|     AppLoader() { } | ||||
|     AppLoader(std::unique_ptr<FileUtil::IOFile>&& file) : file(std::move(file)) { } | ||||
|     virtual ~AppLoader() { } | ||||
| 
 | ||||
|     /**
 | ||||
|  | @ -93,6 +94,10 @@ public: | |||
|     virtual ResultStatus ReadRomFS(std::vector<u8>& buffer) const { | ||||
|         return ResultStatus::ErrorNotImplemented; | ||||
|     } | ||||
| 
 | ||||
| protected: | ||||
|     std::unique_ptr<FileUtil::IOFile> file; | ||||
|     bool                              is_loaded = false; | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  |  | |||
|  | @ -4,8 +4,6 @@ | |||
| 
 | ||||
| #include <memory> | ||||
| 
 | ||||
| #include "common/file_util.h" | ||||
| 
 | ||||
| #include "core/loader/ncch.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/mem_map.h" | ||||
|  | @ -99,15 +97,6 @@ static bool LZSS_Decompress(u8* compressed, u32 compressed_size, u8* decompresse | |||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| // AppLoader_NCCH class
 | ||||
| 
 | ||||
| /// AppLoader_NCCH constructor
 | ||||
| AppLoader_NCCH::AppLoader_NCCH(const std::string& filename) { | ||||
|     this->filename = filename; | ||||
| } | ||||
| 
 | ||||
| /// AppLoader_NCCH destructor
 | ||||
| AppLoader_NCCH::~AppLoader_NCCH() { | ||||
| } | ||||
| 
 | ||||
| ResultStatus AppLoader_NCCH::LoadExec() const { | ||||
|     if (!is_loaded) | ||||
|         return ResultStatus::ErrorNotLoaded; | ||||
|  | @ -123,108 +112,100 @@ ResultStatus AppLoader_NCCH::LoadExec() const { | |||
| 
 | ||||
| ResultStatus AppLoader_NCCH::LoadSectionExeFS(const char* name, std::vector<u8>& buffer) const { | ||||
|     // Iterate through the ExeFs archive until we find the .code file...
 | ||||
|     FileUtil::IOFile file(filename, "rb"); | ||||
|     if (file.IsOpen()) { | ||||
|         LOG_DEBUG(Loader, "%d sections:", kMaxSections); | ||||
|         for (int i = 0; i < kMaxSections; i++) { | ||||
|             // Load the specified section...
 | ||||
|             if (strcmp((const char*)exefs_header.section[i].name, name) == 0) { | ||||
|                 LOG_DEBUG(Loader, "%d - offset: 0x%08X, size: 0x%08X, name: %s", i, | ||||
|                         exefs_header.section[i].offset, exefs_header.section[i].size, | ||||
|                         exefs_header.section[i].name); | ||||
| 
 | ||||
|                 s64 section_offset = (exefs_header.section[i].offset + exefs_offset + | ||||
|                                      sizeof(ExeFs_Header)+ncch_offset); | ||||
|                 file.Seek(section_offset, 0); | ||||
| 
 | ||||
|                 // Section is compressed...
 | ||||
|                 if (i == 0 && is_compressed) { | ||||
|                     // Read compressed .code section...
 | ||||
|                     std::unique_ptr<u8[]> temp_buffer; | ||||
|                     try { | ||||
|                         temp_buffer.reset(new u8[exefs_header.section[i].size]); | ||||
|                     } catch (std::bad_alloc&) { | ||||
|                         return ResultStatus::ErrorMemoryAllocationFailed; | ||||
|                     } | ||||
|                     file.ReadBytes(&temp_buffer[0], exefs_header.section[i].size); | ||||
| 
 | ||||
|                     // Decompress .code section...
 | ||||
|                     u32 decompressed_size = LZSS_GetDecompressedSize(&temp_buffer[0], | ||||
|                         exefs_header.section[i].size); | ||||
|                     buffer.resize(decompressed_size); | ||||
|                     if (!LZSS_Decompress(&temp_buffer[0], exefs_header.section[i].size, &buffer[0], | ||||
|                         decompressed_size)) { | ||||
|                         return ResultStatus::ErrorInvalidFormat; | ||||
|                     } | ||||
|                     // Section is uncompressed...
 | ||||
|                 } | ||||
|                 else { | ||||
|                     buffer.resize(exefs_header.section[i].size); | ||||
|                     file.ReadBytes(&buffer[0], exefs_header.section[i].size); | ||||
|                 } | ||||
|                 return ResultStatus::Success; | ||||
|             } | ||||
|         } | ||||
|     } else { | ||||
|         LOG_ERROR(Loader, "Unable to read file %s!", filename.c_str()); | ||||
|     if (!file->IsOpen()) | ||||
|         return ResultStatus::Error; | ||||
| 
 | ||||
|     LOG_DEBUG(Loader, "%d sections:", kMaxSections); | ||||
|     for (int i = 0; i < kMaxSections; i++) { | ||||
|         // Load the specified section...
 | ||||
|         if (strcmp((const char*)exefs_header.section[i].name, name) == 0) { | ||||
|             LOG_DEBUG(Loader, "%d - offset: 0x%08X, size: 0x%08X, name: %s", i, | ||||
|                     exefs_header.section[i].offset, exefs_header.section[i].size, | ||||
|                     exefs_header.section[i].name); | ||||
| 
 | ||||
|             s64 section_offset = (exefs_header.section[i].offset + exefs_offset + | ||||
|                                  sizeof(ExeFs_Header)+ncch_offset); | ||||
|             file->Seek(section_offset, 0); | ||||
| 
 | ||||
|             // Section is compressed...
 | ||||
|             if (i == 0 && is_compressed) { | ||||
|                 // Read compressed .code section...
 | ||||
|                 std::unique_ptr<u8[]> temp_buffer; | ||||
|                 try { | ||||
|                     temp_buffer.reset(new u8[exefs_header.section[i].size]); | ||||
|                 } catch (std::bad_alloc&) { | ||||
|                     return ResultStatus::ErrorMemoryAllocationFailed; | ||||
|                 } | ||||
|                 file->ReadBytes(&temp_buffer[0], exefs_header.section[i].size); | ||||
| 
 | ||||
|                 // Decompress .code section...
 | ||||
|                 u32 decompressed_size = LZSS_GetDecompressedSize(&temp_buffer[0], | ||||
|                     exefs_header.section[i].size); | ||||
|                 buffer.resize(decompressed_size); | ||||
|                 if (!LZSS_Decompress(&temp_buffer[0], exefs_header.section[i].size, &buffer[0], | ||||
|                     decompressed_size)) { | ||||
|                     return ResultStatus::ErrorInvalidFormat; | ||||
|                 } | ||||
|                 // Section is uncompressed...
 | ||||
|             } | ||||
|             else { | ||||
|                 buffer.resize(exefs_header.section[i].size); | ||||
|                 file->ReadBytes(&buffer[0], exefs_header.section[i].size); | ||||
|             } | ||||
|             return ResultStatus::Success; | ||||
|         } | ||||
|     } | ||||
|     return ResultStatus::ErrorNotUsed; | ||||
| } | ||||
| 
 | ||||
| ResultStatus AppLoader_NCCH::Load() { | ||||
|     LOG_INFO(Loader, "Loading NCCH file %s...", filename.c_str()); | ||||
| 
 | ||||
|     if (is_loaded) | ||||
|         return ResultStatus::ErrorAlreadyLoaded; | ||||
| 
 | ||||
|     FileUtil::IOFile file(filename, "rb"); | ||||
|     if (file.IsOpen()) { | ||||
|         file.ReadBytes(&ncch_header, sizeof(NCCH_Header)); | ||||
|     if (!file->IsOpen()) | ||||
|         return ResultStatus::Error; | ||||
| 
 | ||||
|         // Skip NCSD header and load first NCCH (NCSD is just a container of NCCH files)...
 | ||||
|         if (0 == memcmp(&ncch_header.magic, "NCSD", 4)) { | ||||
|             LOG_WARNING(Loader, "Only loading the first (bootable) NCCH within the NCSD file!"); | ||||
|             ncch_offset = 0x4000; | ||||
|             file.Seek(ncch_offset, 0); | ||||
|             file.ReadBytes(&ncch_header, sizeof(NCCH_Header)); | ||||
|         } | ||||
|     file->ReadBytes(&ncch_header, sizeof(NCCH_Header)); | ||||
| 
 | ||||
|         // Verify we are loading the correct file type...
 | ||||
|         if (0 != memcmp(&ncch_header.magic, "NCCH", 4)) | ||||
|             return ResultStatus::ErrorInvalidFormat; | ||||
| 
 | ||||
|         // Read ExHeader...
 | ||||
| 
 | ||||
|         file.ReadBytes(&exheader_header, sizeof(ExHeader_Header)); | ||||
| 
 | ||||
|         is_compressed = (exheader_header.codeset_info.flags.flag & 1) == 1; | ||||
|         entry_point = exheader_header.codeset_info.text.address; | ||||
| 
 | ||||
|         LOG_INFO(Loader, "Name:            %s", exheader_header.codeset_info.name); | ||||
|         LOG_DEBUG(Loader, "Code compressed: %s", is_compressed ? "yes" : "no"); | ||||
|         LOG_DEBUG(Loader, "Entry point:     0x%08X", entry_point); | ||||
| 
 | ||||
|         // Read ExeFS...
 | ||||
| 
 | ||||
|         exefs_offset = ncch_header.exefs_offset * kBlockSize; | ||||
|         u32 exefs_size = ncch_header.exefs_size * kBlockSize; | ||||
| 
 | ||||
|         LOG_DEBUG(Loader, "ExeFS offset:    0x%08X", exefs_offset); | ||||
|         LOG_DEBUG(Loader, "ExeFS size:      0x%08X", exefs_size); | ||||
| 
 | ||||
|         file.Seek(exefs_offset + ncch_offset, 0); | ||||
|         file.ReadBytes(&exefs_header, sizeof(ExeFs_Header)); | ||||
| 
 | ||||
|         LoadExec(); // Load the executable into memory for booting
 | ||||
| 
 | ||||
|         is_loaded = true; // Set state to loaded
 | ||||
| 
 | ||||
|         return ResultStatus::Success; | ||||
|     } else { | ||||
|         LOG_ERROR(Loader, "Unable to read file %s!", filename.c_str()); | ||||
|     // Skip NCSD header and load first NCCH (NCSD is just a container of NCCH files)...
 | ||||
|     if (0 == memcmp(&ncch_header.magic, "NCSD", 4)) { | ||||
|         LOG_WARNING(Loader, "Only loading the first (bootable) NCCH within the NCSD file!"); | ||||
|         ncch_offset = 0x4000; | ||||
|         file->Seek(ncch_offset, 0); | ||||
|         file->ReadBytes(&ncch_header, sizeof(NCCH_Header)); | ||||
|     } | ||||
|     return ResultStatus::Error; | ||||
| 
 | ||||
|     // Verify we are loading the correct file type...
 | ||||
|     if (0 != memcmp(&ncch_header.magic, "NCCH", 4)) | ||||
|         return ResultStatus::ErrorInvalidFormat; | ||||
| 
 | ||||
|     // Read ExHeader...
 | ||||
| 
 | ||||
|     file->ReadBytes(&exheader_header, sizeof(ExHeader_Header)); | ||||
| 
 | ||||
|     is_compressed = (exheader_header.codeset_info.flags.flag & 1) == 1; | ||||
|     entry_point = exheader_header.codeset_info.text.address; | ||||
| 
 | ||||
|     LOG_INFO(Loader, "Name:            %s", exheader_header.codeset_info.name); | ||||
|     LOG_DEBUG(Loader, "Code compressed: %s", is_compressed ? "yes" : "no"); | ||||
|     LOG_DEBUG(Loader, "Entry point:     0x%08X", entry_point); | ||||
| 
 | ||||
|     // Read ExeFS...
 | ||||
| 
 | ||||
|     exefs_offset = ncch_header.exefs_offset * kBlockSize; | ||||
|     u32 exefs_size = ncch_header.exefs_size * kBlockSize; | ||||
| 
 | ||||
|     LOG_DEBUG(Loader, "ExeFS offset:    0x%08X", exefs_offset); | ||||
|     LOG_DEBUG(Loader, "ExeFS size:      0x%08X", exefs_size); | ||||
| 
 | ||||
|     file->Seek(exefs_offset + ncch_offset, 0); | ||||
|     file->ReadBytes(&exefs_header, sizeof(ExeFs_Header)); | ||||
| 
 | ||||
|     LoadExec(); // Load the executable into memory for booting
 | ||||
| 
 | ||||
|     is_loaded = true; // Set state to loaded
 | ||||
| 
 | ||||
|     return ResultStatus::Success; | ||||
| } | ||||
| 
 | ||||
| ResultStatus AppLoader_NCCH::ReadCode(std::vector<u8>& buffer) const { | ||||
|  | @ -244,29 +225,26 @@ ResultStatus AppLoader_NCCH::ReadLogo(std::vector<u8>& buffer) const { | |||
| } | ||||
| 
 | ||||
| ResultStatus AppLoader_NCCH::ReadRomFS(std::vector<u8>& buffer) const { | ||||
|     FileUtil::IOFile file(filename, "rb"); | ||||
|     if (file.IsOpen()) { | ||||
|         // Check if the NCCH has a RomFS...
 | ||||
|         if (ncch_header.romfs_offset != 0 && ncch_header.romfs_size != 0) { | ||||
|             u32 romfs_offset = ncch_offset + (ncch_header.romfs_offset * kBlockSize) + 0x1000; | ||||
|             u32 romfs_size = (ncch_header.romfs_size * kBlockSize) - 0x1000; | ||||
|     if (!file->IsOpen()) | ||||
|         return ResultStatus::Error; | ||||
| 
 | ||||
|             LOG_DEBUG(Loader, "RomFS offset:    0x%08X", romfs_offset); | ||||
|             LOG_DEBUG(Loader, "RomFS size:      0x%08X", romfs_size); | ||||
|     // Check if the NCCH has a RomFS...
 | ||||
|     if (ncch_header.romfs_offset != 0 && ncch_header.romfs_size != 0) { | ||||
|         u32 romfs_offset = ncch_offset + (ncch_header.romfs_offset * kBlockSize) + 0x1000; | ||||
|         u32 romfs_size = (ncch_header.romfs_size * kBlockSize) - 0x1000; | ||||
| 
 | ||||
|             buffer.resize(romfs_size); | ||||
|         LOG_DEBUG(Loader, "RomFS offset:    0x%08X", romfs_offset); | ||||
|         LOG_DEBUG(Loader, "RomFS size:      0x%08X", romfs_size); | ||||
| 
 | ||||
|             file.Seek(romfs_offset, 0); | ||||
|             file.ReadBytes(&buffer[0], romfs_size); | ||||
|         buffer.resize(romfs_size); | ||||
| 
 | ||||
|             return ResultStatus::Success; | ||||
|         } | ||||
|         LOG_DEBUG(Loader, "NCCH has no RomFS"); | ||||
|         return ResultStatus::ErrorNotUsed; | ||||
|     } else { | ||||
|         LOG_ERROR(Loader, "Unable to read file %s!", filename.c_str()); | ||||
|         file->Seek(romfs_offset, 0); | ||||
|         file->ReadBytes(&buffer[0], romfs_size); | ||||
| 
 | ||||
|         return ResultStatus::Success; | ||||
|     } | ||||
|     return ResultStatus::Error; | ||||
|     LOG_DEBUG(Loader, "NCCH has no RomFS"); | ||||
|     return ResultStatus::ErrorNotUsed; | ||||
| } | ||||
| 
 | ||||
| u64 AppLoader_NCCH::GetProgramId() const { | ||||
|  |  | |||
|  | @ -5,7 +5,6 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include "common/common.h" | ||||
| #include "common/file_util.h" | ||||
| 
 | ||||
| #include "core/loader/loader.h" | ||||
| 
 | ||||
|  | @ -147,8 +146,7 @@ namespace Loader { | |||
| /// Loads an NCCH file (e.g. from a CCI, or the first NCCH in a CXI)
 | ||||
| class AppLoader_NCCH final : public AppLoader { | ||||
| public: | ||||
|     AppLoader_NCCH(const std::string& filename); | ||||
|     ~AppLoader_NCCH() override; | ||||
|     AppLoader_NCCH(std::unique_ptr<FileUtil::IOFile>&& file) : AppLoader(std::move(file)) { } | ||||
| 
 | ||||
|     /**
 | ||||
|      * Load the application | ||||
|  | @ -213,9 +211,6 @@ private: | |||
|      */ | ||||
|     ResultStatus LoadExec() const; | ||||
| 
 | ||||
|     std::string     filename; | ||||
| 
 | ||||
|     bool            is_loaded = false; | ||||
|     bool            is_compressed = false; | ||||
| 
 | ||||
|     u32             entry_point = 0; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue