diff options
Diffstat (limited to 'src/core/loader')
| -rw-r--r-- | src/core/loader/3dsx.cpp | 21 | ||||
| -rw-r--r-- | src/core/loader/3dsx.h | 7 | ||||
| -rw-r--r-- | src/core/loader/elf.cpp | 30 | ||||
| -rw-r--r-- | src/core/loader/elf.h | 7 | ||||
| -rw-r--r-- | src/core/loader/loader.cpp | 23 | ||||
| -rw-r--r-- | src/core/loader/loader.h | 7 | ||||
| -rw-r--r-- | src/core/loader/ncch.cpp | 190 | ||||
| -rw-r--r-- | src/core/loader/ncch.h | 7 |
8 files changed, 116 insertions, 176 deletions
diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp index 54ee992fc..873ee8b25 100644 --- a/src/core/loader/3dsx.cpp +++ b/src/core/loader/3dsx.cpp | |||
| @@ -199,28 +199,15 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr) | |||
| 199 | return ERROR_NONE; | 199 | return ERROR_NONE; |
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | /// AppLoader_DSX constructor | ||
| 203 | AppLoader_THREEDSX::AppLoader_THREEDSX(const std::string& filename) : filename(filename) { | ||
| 204 | } | ||
| 205 | |||
| 206 | /// AppLoader_DSX destructor | ||
| 207 | AppLoader_THREEDSX::~AppLoader_THREEDSX() { | ||
| 208 | } | ||
| 209 | |||
| 210 | ResultStatus AppLoader_THREEDSX::Load() { | 202 | ResultStatus AppLoader_THREEDSX::Load() { |
| 211 | LOG_INFO(Loader, "Loading 3DSX file %s...", filename.c_str()); | ||
| 212 | |||
| 213 | if (is_loaded) | 203 | if (is_loaded) |
| 214 | return ResultStatus::ErrorAlreadyLoaded; | 204 | return ResultStatus::ErrorAlreadyLoaded; |
| 215 | 205 | ||
| 216 | FileUtil::IOFile file(filename, "rb"); | 206 | if (!file->IsOpen()) |
| 217 | |||
| 218 | if (file.IsOpen()) { | ||
| 219 | Load3DSXFile(file, 0x00100000); | ||
| 220 | Kernel::LoadExec(0x00100000); | ||
| 221 | } else { | ||
| 222 | return ResultStatus::Error; | 207 | return ResultStatus::Error; |
| 223 | } | 208 | |
| 209 | Load3DSXFile(*file, 0x00100000); | ||
| 210 | Kernel::LoadExec(0x00100000); | ||
| 224 | 211 | ||
| 225 | is_loaded = true; | 212 | is_loaded = true; |
| 226 | return ResultStatus::Success; | 213 | return ResultStatus::Success; |
diff --git a/src/core/loader/3dsx.h b/src/core/loader/3dsx.h index f28224628..2f2e8bec0 100644 --- a/src/core/loader/3dsx.h +++ b/src/core/loader/3dsx.h | |||
| @@ -15,18 +15,13 @@ namespace Loader { | |||
| 15 | /// Loads an 3DSX file | 15 | /// Loads an 3DSX file |
| 16 | class AppLoader_THREEDSX final : public AppLoader { | 16 | class AppLoader_THREEDSX final : public AppLoader { |
| 17 | public: | 17 | public: |
| 18 | AppLoader_THREEDSX(const std::string& filename); | 18 | AppLoader_THREEDSX(std::unique_ptr<FileUtil::IOFile>&& file) : AppLoader(std::move(file)) { } |
| 19 | ~AppLoader_THREEDSX() override; | ||
| 20 | 19 | ||
| 21 | /** | 20 | /** |
| 22 | * Load the bootable file | 21 | * Load the bootable file |
| 23 | * @return ResultStatus result of function | 22 | * @return ResultStatus result of function |
| 24 | */ | 23 | */ |
| 25 | ResultStatus Load() override; | 24 | ResultStatus Load() override; |
| 26 | |||
| 27 | private: | ||
| 28 | std::string filename; | ||
| 29 | bool is_loaded = false; | ||
| 30 | }; | 25 | }; |
| 31 | 26 | ||
| 32 | } // namespace Loader | 27 | } // namespace Loader |
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index ee711d8b2..d1a1ef595 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp | |||
| @@ -330,34 +330,20 @@ bool ElfReader::LoadSymbols() { | |||
| 330 | 330 | ||
| 331 | namespace Loader { | 331 | namespace Loader { |
| 332 | 332 | ||
| 333 | /// AppLoader_ELF constructor | ||
| 334 | AppLoader_ELF::AppLoader_ELF(const std::string& filename) { | ||
| 335 | this->filename = filename; | ||
| 336 | } | ||
| 337 | |||
| 338 | /// AppLoader_NCCH destructor | ||
| 339 | AppLoader_ELF::~AppLoader_ELF() { | ||
| 340 | } | ||
| 341 | |||
| 342 | ResultStatus AppLoader_ELF::Load() { | 333 | ResultStatus AppLoader_ELF::Load() { |
| 343 | LOG_INFO(Loader, "Loading ELF file %s...", filename.c_str()); | ||
| 344 | |||
| 345 | if (is_loaded) | 334 | if (is_loaded) |
| 346 | return ResultStatus::ErrorAlreadyLoaded; | 335 | return ResultStatus::ErrorAlreadyLoaded; |
| 347 | 336 | ||
| 348 | FileUtil::IOFile file(filename, "rb"); | 337 | if (!file->IsOpen()) |
| 338 | return ResultStatus::Error; | ||
| 349 | 339 | ||
| 350 | if (file.IsOpen()) { | 340 | u32 size = static_cast<u32>(file->GetSize()); |
| 351 | u32 size = (u32)file.GetSize(); | 341 | std::unique_ptr<u8[]> buffer(new u8[size]); |
| 352 | std::unique_ptr<u8[]> buffer(new u8[size]); | 342 | file->ReadBytes(&buffer[0], size); |
| 353 | file.ReadBytes(&buffer[0], size); | ||
| 354 | 343 | ||
| 355 | ElfReader elf_reader(&buffer[0]); | 344 | ElfReader elf_reader(&buffer[0]); |
| 356 | elf_reader.LoadInto(0x00100000); | 345 | elf_reader.LoadInto(0x00100000); |
| 357 | Kernel::LoadExec(elf_reader.GetEntryPoint()); | 346 | Kernel::LoadExec(elf_reader.GetEntryPoint()); |
| 358 | } else { | ||
| 359 | return ResultStatus::Error; | ||
| 360 | } | ||
| 361 | 347 | ||
| 362 | is_loaded = true; | 348 | is_loaded = true; |
| 363 | return ResultStatus::Success; | 349 | return ResultStatus::Success; |
diff --git a/src/core/loader/elf.h b/src/core/loader/elf.h index 856722f1e..1c476c86b 100644 --- a/src/core/loader/elf.h +++ b/src/core/loader/elf.h | |||
| @@ -15,18 +15,13 @@ namespace Loader { | |||
| 15 | /// Loads an ELF/AXF file | 15 | /// Loads an ELF/AXF file |
| 16 | class AppLoader_ELF final : public AppLoader { | 16 | class AppLoader_ELF final : public AppLoader { |
| 17 | public: | 17 | public: |
| 18 | AppLoader_ELF(const std::string& filename); | 18 | AppLoader_ELF(std::unique_ptr<FileUtil::IOFile>&& file) : AppLoader(std::move(file)) { } |
| 19 | ~AppLoader_ELF() override; | ||
| 20 | 19 | ||
| 21 | /** | 20 | /** |
| 22 | * Load the bootable file | 21 | * Load the bootable file |
| 23 | * @return ResultStatus result of function | 22 | * @return ResultStatus result of function |
| 24 | */ | 23 | */ |
| 25 | ResultStatus Load() override; | 24 | ResultStatus Load() override; |
| 26 | |||
| 27 | private: | ||
| 28 | std::string filename; | ||
| 29 | bool is_loaded = false; | ||
| 30 | }; | 25 | }; |
| 31 | 26 | ||
| 32 | } // namespace Loader | 27 | } // namespace Loader |
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 32196a1dc..fd32b7b20 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp | |||
| @@ -56,20 +56,24 @@ FileType IdentifyFile(const std::string &filename) { | |||
| 56 | ResultStatus LoadFile(const std::string& filename) { | 56 | ResultStatus LoadFile(const std::string& filename) { |
| 57 | LOG_INFO(Loader, "Loading file %s...", filename.c_str()); | 57 | LOG_INFO(Loader, "Loading file %s...", filename.c_str()); |
| 58 | 58 | ||
| 59 | std::unique_ptr<FileUtil::IOFile> file(new FileUtil::IOFile(filename, "rb")); | ||
| 60 | if (!file->IsOpen()) | ||
| 61 | return ResultStatus::Error; | ||
| 62 | |||
| 59 | switch (IdentifyFile(filename)) { | 63 | switch (IdentifyFile(filename)) { |
| 60 | 64 | ||
| 61 | //3DSX file format... | 65 | //3DSX file format... |
| 62 | case FileType::THREEDSX: | 66 | case FileType::THREEDSX: |
| 63 | return AppLoader_THREEDSX(filename).Load(); | 67 | return AppLoader_THREEDSX(std::move(file)).Load(); |
| 64 | 68 | ||
| 65 | // Standard ELF file format... | 69 | // Standard ELF file format... |
| 66 | case FileType::ELF: | 70 | case FileType::ELF: |
| 67 | return AppLoader_ELF(filename).Load(); | 71 | return AppLoader_ELF(std::move(file)).Load(); |
| 68 | 72 | ||
| 69 | // NCCH/NCSD container formats... | 73 | // NCCH/NCSD container formats... |
| 70 | case FileType::CXI: | 74 | case FileType::CXI: |
| 71 | case FileType::CCI: { | 75 | case FileType::CCI: { |
| 72 | AppLoader_NCCH app_loader(filename); | 76 | AppLoader_NCCH app_loader(std::move(file)); |
| 73 | 77 | ||
| 74 | // Load application and RomFS | 78 | // Load application and RomFS |
| 75 | if (ResultStatus::Success == app_loader.Load()) { | 79 | if (ResultStatus::Success == app_loader.Load()) { |
| @@ -83,16 +87,11 @@ ResultStatus LoadFile(const std::string& filename) { | |||
| 83 | // Raw BIN file format... | 87 | // Raw BIN file format... |
| 84 | case FileType::BIN: | 88 | case FileType::BIN: |
| 85 | { | 89 | { |
| 86 | LOG_INFO(Loader, "Loading BIN file %s...", filename.c_str()); | 90 | size_t size = (size_t)file->GetSize(); |
| 87 | 91 | if (file->ReadBytes(Memory::GetPointer(Memory::EXEFS_CODE_VADDR), size) != size) | |
| 88 | FileUtil::IOFile file(filename, "rb"); | ||
| 89 | |||
| 90 | if (file.IsOpen()) { | ||
| 91 | file.ReadBytes(Memory::GetPointer(Memory::EXEFS_CODE_VADDR), (size_t)file.GetSize()); | ||
| 92 | Kernel::LoadExec(Memory::EXEFS_CODE_VADDR); | ||
| 93 | } else { | ||
| 94 | return ResultStatus::Error; | 92 | return ResultStatus::Error; |
| 95 | } | 93 | |
| 94 | Kernel::LoadExec(Memory::EXEFS_CODE_VADDR); | ||
| 96 | return ResultStatus::Success; | 95 | return ResultStatus::Success; |
| 97 | } | 96 | } |
| 98 | 97 | ||
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index ec5534d41..b4fc8636d 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <vector> | 7 | #include <vector> |
| 8 | 8 | ||
| 9 | #include "common/common.h" | 9 | #include "common/common.h" |
| 10 | #include "common/file_util.h" | ||
| 10 | 11 | ||
| 11 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 12 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 12 | // Loader namespace | 13 | // Loader namespace |
| @@ -40,7 +41,7 @@ enum class ResultStatus { | |||
| 40 | /// Interface for loading an application | 41 | /// Interface for loading an application |
| 41 | class AppLoader : NonCopyable { | 42 | class AppLoader : NonCopyable { |
| 42 | public: | 43 | public: |
| 43 | AppLoader() { } | 44 | AppLoader(std::unique_ptr<FileUtil::IOFile>&& file) : file(std::move(file)) { } |
| 44 | virtual ~AppLoader() { } | 45 | virtual ~AppLoader() { } |
| 45 | 46 | ||
| 46 | /** | 47 | /** |
| @@ -93,6 +94,10 @@ public: | |||
| 93 | virtual ResultStatus ReadRomFS(std::vector<u8>& buffer) const { | 94 | virtual ResultStatus ReadRomFS(std::vector<u8>& buffer) const { |
| 94 | return ResultStatus::ErrorNotImplemented; | 95 | return ResultStatus::ErrorNotImplemented; |
| 95 | } | 96 | } |
| 97 | |||
| 98 | protected: | ||
| 99 | std::unique_ptr<FileUtil::IOFile> file; | ||
| 100 | bool is_loaded = false; | ||
| 96 | }; | 101 | }; |
| 97 | 102 | ||
| 98 | /** | 103 | /** |
diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp index 883a0f753..eca57d14b 100644 --- a/src/core/loader/ncch.cpp +++ b/src/core/loader/ncch.cpp | |||
| @@ -4,8 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | #include <memory> | 5 | #include <memory> |
| 6 | 6 | ||
| 7 | #include "common/file_util.h" | ||
| 8 | |||
| 9 | #include "core/loader/ncch.h" | 7 | #include "core/loader/ncch.h" |
| 10 | #include "core/hle/kernel/kernel.h" | 8 | #include "core/hle/kernel/kernel.h" |
| 11 | #include "core/mem_map.h" | 9 | #include "core/mem_map.h" |
| @@ -99,15 +97,6 @@ static bool LZSS_Decompress(u8* compressed, u32 compressed_size, u8* decompresse | |||
| 99 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 97 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 100 | // AppLoader_NCCH class | 98 | // AppLoader_NCCH class |
| 101 | 99 | ||
| 102 | /// AppLoader_NCCH constructor | ||
| 103 | AppLoader_NCCH::AppLoader_NCCH(const std::string& filename) { | ||
| 104 | this->filename = filename; | ||
| 105 | } | ||
| 106 | |||
| 107 | /// AppLoader_NCCH destructor | ||
| 108 | AppLoader_NCCH::~AppLoader_NCCH() { | ||
| 109 | } | ||
| 110 | |||
| 111 | ResultStatus AppLoader_NCCH::LoadExec() const { | 100 | ResultStatus AppLoader_NCCH::LoadExec() const { |
| 112 | if (!is_loaded) | 101 | if (!is_loaded) |
| 113 | return ResultStatus::ErrorNotLoaded; | 102 | return ResultStatus::ErrorNotLoaded; |
| @@ -123,108 +112,100 @@ ResultStatus AppLoader_NCCH::LoadExec() const { | |||
| 123 | 112 | ||
| 124 | ResultStatus AppLoader_NCCH::LoadSectionExeFS(const char* name, std::vector<u8>& buffer) const { | 113 | ResultStatus AppLoader_NCCH::LoadSectionExeFS(const char* name, std::vector<u8>& buffer) const { |
| 125 | // Iterate through the ExeFs archive until we find the .code file... | 114 | // Iterate through the ExeFs archive until we find the .code file... |
| 126 | FileUtil::IOFile file(filename, "rb"); | 115 | if (!file->IsOpen()) |
| 127 | if (file.IsOpen()) { | 116 | return ResultStatus::Error; |
| 128 | LOG_DEBUG(Loader, "%d sections:", kMaxSections); | 117 | |
| 129 | for (int i = 0; i < kMaxSections; i++) { | 118 | LOG_DEBUG(Loader, "%d sections:", kMaxSections); |
| 130 | // Load the specified section... | 119 | for (int i = 0; i < kMaxSections; i++) { |
| 131 | if (strcmp((const char*)exefs_header.section[i].name, name) == 0) { | 120 | // Load the specified section... |
| 132 | LOG_DEBUG(Loader, "%d - offset: 0x%08X, size: 0x%08X, name: %s", i, | 121 | if (strcmp((const char*)exefs_header.section[i].name, name) == 0) { |
| 133 | exefs_header.section[i].offset, exefs_header.section[i].size, | 122 | LOG_DEBUG(Loader, "%d - offset: 0x%08X, size: 0x%08X, name: %s", i, |
| 134 | exefs_header.section[i].name); | 123 | exefs_header.section[i].offset, exefs_header.section[i].size, |
| 135 | 124 | exefs_header.section[i].name); | |
| 136 | s64 section_offset = (exefs_header.section[i].offset + exefs_offset + | 125 | |
| 137 | sizeof(ExeFs_Header)+ncch_offset); | 126 | s64 section_offset = (exefs_header.section[i].offset + exefs_offset + |
| 138 | file.Seek(section_offset, 0); | 127 | sizeof(ExeFs_Header)+ncch_offset); |
| 139 | 128 | file->Seek(section_offset, 0); | |
| 140 | // Section is compressed... | 129 | |
| 141 | if (i == 0 && is_compressed) { | 130 | // Section is compressed... |
| 142 | // Read compressed .code section... | 131 | if (i == 0 && is_compressed) { |
| 143 | std::unique_ptr<u8[]> temp_buffer; | 132 | // Read compressed .code section... |
| 144 | try { | 133 | std::unique_ptr<u8[]> temp_buffer; |
| 145 | temp_buffer.reset(new u8[exefs_header.section[i].size]); | 134 | try { |
| 146 | } catch (std::bad_alloc&) { | 135 | temp_buffer.reset(new u8[exefs_header.section[i].size]); |
| 147 | return ResultStatus::ErrorMemoryAllocationFailed; | 136 | } catch (std::bad_alloc&) { |
| 148 | } | 137 | return ResultStatus::ErrorMemoryAllocationFailed; |
| 149 | file.ReadBytes(&temp_buffer[0], exefs_header.section[i].size); | ||
| 150 | |||
| 151 | // Decompress .code section... | ||
| 152 | u32 decompressed_size = LZSS_GetDecompressedSize(&temp_buffer[0], | ||
| 153 | exefs_header.section[i].size); | ||
| 154 | buffer.resize(decompressed_size); | ||
| 155 | if (!LZSS_Decompress(&temp_buffer[0], exefs_header.section[i].size, &buffer[0], | ||
| 156 | decompressed_size)) { | ||
| 157 | return ResultStatus::ErrorInvalidFormat; | ||
| 158 | } | ||
| 159 | // Section is uncompressed... | ||
| 160 | } | 138 | } |
| 161 | else { | 139 | file->ReadBytes(&temp_buffer[0], exefs_header.section[i].size); |
| 162 | buffer.resize(exefs_header.section[i].size); | 140 | |
| 163 | file.ReadBytes(&buffer[0], exefs_header.section[i].size); | 141 | // Decompress .code section... |
| 142 | u32 decompressed_size = LZSS_GetDecompressedSize(&temp_buffer[0], | ||
| 143 | exefs_header.section[i].size); | ||
| 144 | buffer.resize(decompressed_size); | ||
| 145 | if (!LZSS_Decompress(&temp_buffer[0], exefs_header.section[i].size, &buffer[0], | ||
| 146 | decompressed_size)) { | ||
| 147 | return ResultStatus::ErrorInvalidFormat; | ||
| 164 | } | 148 | } |
| 165 | return ResultStatus::Success; | 149 | // Section is uncompressed... |
| 166 | } | 150 | } |
| 151 | else { | ||
| 152 | buffer.resize(exefs_header.section[i].size); | ||
| 153 | file->ReadBytes(&buffer[0], exefs_header.section[i].size); | ||
| 154 | } | ||
| 155 | return ResultStatus::Success; | ||
| 167 | } | 156 | } |
| 168 | } else { | ||
| 169 | LOG_ERROR(Loader, "Unable to read file %s!", filename.c_str()); | ||
| 170 | return ResultStatus::Error; | ||
| 171 | } | 157 | } |
| 172 | return ResultStatus::ErrorNotUsed; | 158 | return ResultStatus::ErrorNotUsed; |
| 173 | } | 159 | } |
| 174 | 160 | ||
| 175 | ResultStatus AppLoader_NCCH::Load() { | 161 | ResultStatus AppLoader_NCCH::Load() { |
| 176 | LOG_INFO(Loader, "Loading NCCH file %s...", filename.c_str()); | ||
| 177 | |||
| 178 | if (is_loaded) | 162 | if (is_loaded) |
| 179 | return ResultStatus::ErrorAlreadyLoaded; | 163 | return ResultStatus::ErrorAlreadyLoaded; |
| 180 | 164 | ||
| 181 | FileUtil::IOFile file(filename, "rb"); | 165 | if (!file->IsOpen()) |
| 182 | if (file.IsOpen()) { | 166 | return ResultStatus::Error; |
| 183 | file.ReadBytes(&ncch_header, sizeof(NCCH_Header)); | ||
| 184 | 167 | ||
| 185 | // Skip NCSD header and load first NCCH (NCSD is just a container of NCCH files)... | 168 | file->ReadBytes(&ncch_header, sizeof(NCCH_Header)); |
| 186 | if (0 == memcmp(&ncch_header.magic, "NCSD", 4)) { | ||
| 187 | LOG_WARNING(Loader, "Only loading the first (bootable) NCCH within the NCSD file!"); | ||
| 188 | ncch_offset = 0x4000; | ||
| 189 | file.Seek(ncch_offset, 0); | ||
| 190 | file.ReadBytes(&ncch_header, sizeof(NCCH_Header)); | ||
| 191 | } | ||
| 192 | 169 | ||
| 193 | // Verify we are loading the correct file type... | 170 | // Skip NCSD header and load first NCCH (NCSD is just a container of NCCH files)... |
| 194 | if (0 != memcmp(&ncch_header.magic, "NCCH", 4)) | 171 | if (0 == memcmp(&ncch_header.magic, "NCSD", 4)) { |
| 195 | return ResultStatus::ErrorInvalidFormat; | 172 | LOG_WARNING(Loader, "Only loading the first (bootable) NCCH within the NCSD file!"); |
| 173 | ncch_offset = 0x4000; | ||
| 174 | file->Seek(ncch_offset, 0); | ||
| 175 | file->ReadBytes(&ncch_header, sizeof(NCCH_Header)); | ||
| 176 | } | ||
| 196 | 177 | ||
| 197 | // Read ExHeader... | 178 | // Verify we are loading the correct file type... |
| 179 | if (0 != memcmp(&ncch_header.magic, "NCCH", 4)) | ||
| 180 | return ResultStatus::ErrorInvalidFormat; | ||
| 198 | 181 | ||
| 199 | file.ReadBytes(&exheader_header, sizeof(ExHeader_Header)); | 182 | // Read ExHeader... |
| 200 | 183 | ||
| 201 | is_compressed = (exheader_header.codeset_info.flags.flag & 1) == 1; | 184 | file->ReadBytes(&exheader_header, sizeof(ExHeader_Header)); |
| 202 | entry_point = exheader_header.codeset_info.text.address; | ||
| 203 | 185 | ||
| 204 | LOG_INFO(Loader, "Name: %s", exheader_header.codeset_info.name); | 186 | is_compressed = (exheader_header.codeset_info.flags.flag & 1) == 1; |
| 205 | LOG_DEBUG(Loader, "Code compressed: %s", is_compressed ? "yes" : "no"); | 187 | entry_point = exheader_header.codeset_info.text.address; |
| 206 | LOG_DEBUG(Loader, "Entry point: 0x%08X", entry_point); | ||
| 207 | 188 | ||
| 208 | // Read ExeFS... | 189 | LOG_INFO(Loader, "Name: %s", exheader_header.codeset_info.name); |
| 190 | LOG_DEBUG(Loader, "Code compressed: %s", is_compressed ? "yes" : "no"); | ||
| 191 | LOG_DEBUG(Loader, "Entry point: 0x%08X", entry_point); | ||
| 209 | 192 | ||
| 210 | exefs_offset = ncch_header.exefs_offset * kBlockSize; | 193 | // Read ExeFS... |
| 211 | u32 exefs_size = ncch_header.exefs_size * kBlockSize; | ||
| 212 | 194 | ||
| 213 | LOG_DEBUG(Loader, "ExeFS offset: 0x%08X", exefs_offset); | 195 | exefs_offset = ncch_header.exefs_offset * kBlockSize; |
| 214 | LOG_DEBUG(Loader, "ExeFS size: 0x%08X", exefs_size); | 196 | u32 exefs_size = ncch_header.exefs_size * kBlockSize; |
| 215 | 197 | ||
| 216 | file.Seek(exefs_offset + ncch_offset, 0); | 198 | LOG_DEBUG(Loader, "ExeFS offset: 0x%08X", exefs_offset); |
| 217 | file.ReadBytes(&exefs_header, sizeof(ExeFs_Header)); | 199 | LOG_DEBUG(Loader, "ExeFS size: 0x%08X", exefs_size); |
| 218 | 200 | ||
| 219 | LoadExec(); // Load the executable into memory for booting | 201 | file->Seek(exefs_offset + ncch_offset, 0); |
| 202 | file->ReadBytes(&exefs_header, sizeof(ExeFs_Header)); | ||
| 220 | 203 | ||
| 221 | is_loaded = true; // Set state to loaded | 204 | LoadExec(); // Load the executable into memory for booting |
| 222 | 205 | ||
| 223 | return ResultStatus::Success; | 206 | is_loaded = true; // Set state to loaded |
| 224 | } else { | 207 | |
| 225 | LOG_ERROR(Loader, "Unable to read file %s!", filename.c_str()); | 208 | return ResultStatus::Success; |
| 226 | } | ||
| 227 | return ResultStatus::Error; | ||
| 228 | } | 209 | } |
| 229 | 210 | ||
| 230 | ResultStatus AppLoader_NCCH::ReadCode(std::vector<u8>& buffer) const { | 211 | ResultStatus AppLoader_NCCH::ReadCode(std::vector<u8>& buffer) const { |
| @@ -244,29 +225,26 @@ ResultStatus AppLoader_NCCH::ReadLogo(std::vector<u8>& buffer) const { | |||
| 244 | } | 225 | } |
| 245 | 226 | ||
| 246 | ResultStatus AppLoader_NCCH::ReadRomFS(std::vector<u8>& buffer) const { | 227 | ResultStatus AppLoader_NCCH::ReadRomFS(std::vector<u8>& buffer) const { |
| 247 | FileUtil::IOFile file(filename, "rb"); | 228 | if (!file->IsOpen()) |
| 248 | if (file.IsOpen()) { | 229 | return ResultStatus::Error; |
| 249 | // Check if the NCCH has a RomFS... | ||
| 250 | if (ncch_header.romfs_offset != 0 && ncch_header.romfs_size != 0) { | ||
| 251 | u32 romfs_offset = ncch_offset + (ncch_header.romfs_offset * kBlockSize) + 0x1000; | ||
| 252 | u32 romfs_size = (ncch_header.romfs_size * kBlockSize) - 0x1000; | ||
| 253 | 230 | ||
| 254 | LOG_DEBUG(Loader, "RomFS offset: 0x%08X", romfs_offset); | 231 | // Check if the NCCH has a RomFS... |
| 255 | LOG_DEBUG(Loader, "RomFS size: 0x%08X", romfs_size); | 232 | if (ncch_header.romfs_offset != 0 && ncch_header.romfs_size != 0) { |
| 233 | u32 romfs_offset = ncch_offset + (ncch_header.romfs_offset * kBlockSize) + 0x1000; | ||
| 234 | u32 romfs_size = (ncch_header.romfs_size * kBlockSize) - 0x1000; | ||
| 256 | 235 | ||
| 257 | buffer.resize(romfs_size); | 236 | LOG_DEBUG(Loader, "RomFS offset: 0x%08X", romfs_offset); |
| 237 | LOG_DEBUG(Loader, "RomFS size: 0x%08X", romfs_size); | ||
| 258 | 238 | ||
| 259 | file.Seek(romfs_offset, 0); | 239 | buffer.resize(romfs_size); |
| 260 | file.ReadBytes(&buffer[0], romfs_size); | ||
| 261 | 240 | ||
| 262 | return ResultStatus::Success; | 241 | file->Seek(romfs_offset, 0); |
| 263 | } | 242 | file->ReadBytes(&buffer[0], romfs_size); |
| 264 | LOG_DEBUG(Loader, "NCCH has no RomFS"); | 243 | |
| 265 | return ResultStatus::ErrorNotUsed; | 244 | return ResultStatus::Success; |
| 266 | } else { | ||
| 267 | LOG_ERROR(Loader, "Unable to read file %s!", filename.c_str()); | ||
| 268 | } | 245 | } |
| 269 | return ResultStatus::Error; | 246 | LOG_DEBUG(Loader, "NCCH has no RomFS"); |
| 247 | return ResultStatus::ErrorNotUsed; | ||
| 270 | } | 248 | } |
| 271 | 249 | ||
| 272 | u64 AppLoader_NCCH::GetProgramId() const { | 250 | u64 AppLoader_NCCH::GetProgramId() const { |
diff --git a/src/core/loader/ncch.h b/src/core/loader/ncch.h index 578513f77..d9d68f154 100644 --- a/src/core/loader/ncch.h +++ b/src/core/loader/ncch.h | |||
| @@ -5,7 +5,6 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include "common/common.h" | 7 | #include "common/common.h" |
| 8 | #include "common/file_util.h" | ||
| 9 | 8 | ||
| 10 | #include "core/loader/loader.h" | 9 | #include "core/loader/loader.h" |
| 11 | 10 | ||
| @@ -147,8 +146,7 @@ namespace Loader { | |||
| 147 | /// Loads an NCCH file (e.g. from a CCI, or the first NCCH in a CXI) | 146 | /// Loads an NCCH file (e.g. from a CCI, or the first NCCH in a CXI) |
| 148 | class AppLoader_NCCH final : public AppLoader { | 147 | class AppLoader_NCCH final : public AppLoader { |
| 149 | public: | 148 | public: |
| 150 | AppLoader_NCCH(const std::string& filename); | 149 | AppLoader_NCCH(std::unique_ptr<FileUtil::IOFile>&& file) : AppLoader(std::move(file)) { } |
| 151 | ~AppLoader_NCCH() override; | ||
| 152 | 150 | ||
| 153 | /** | 151 | /** |
| 154 | * Load the application | 152 | * Load the application |
| @@ -213,9 +211,6 @@ private: | |||
| 213 | */ | 211 | */ |
| 214 | ResultStatus LoadExec() const; | 212 | ResultStatus LoadExec() const; |
| 215 | 213 | ||
| 216 | std::string filename; | ||
| 217 | |||
| 218 | bool is_loaded = false; | ||
| 219 | bool is_compressed = false; | 214 | bool is_compressed = false; |
| 220 | 215 | ||
| 221 | u32 entry_point = 0; | 216 | u32 entry_point = 0; |