summaryrefslogtreecommitdiff
path: root/src/core/loader
diff options
context:
space:
mode:
authorGravatar bunnei2018-01-20 14:59:17 -0500
committerGravatar bunnei2018-01-20 15:54:15 -0500
commite75aba3ed0eb0933c023f955d4c2e53e58ef6a5f (patch)
tree4ef2b528a335d3da15a678afb4a60df490bc5037 /src/core/loader
parentloader: Refactor to also pass filepath into IdentifyType. (diff)
downloadyuzu-e75aba3ed0eb0933c023f955d4c2e53e58ef6a5f.tar.gz
yuzu-e75aba3ed0eb0933c023f955d4c2e53e58ef6a5f.tar.xz
yuzu-e75aba3ed0eb0933c023f955d4c2e53e58ef6a5f.zip
loader: Add DeconstructedRomDirectory for game dumps.
Diffstat (limited to 'src/core/loader')
-rw-r--r--src/core/loader/deconstructed_rom_directory.cpp101
-rw-r--r--src/core/loader/deconstructed_rom_directory.h44
-rw-r--r--src/core/loader/loader.cpp8
-rw-r--r--src/core/loader/loader.h1
4 files changed, 154 insertions, 0 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..daedeaab0
--- /dev/null
+++ b/src/core/loader/deconstructed_rom_directory.cpp
@@ -0,0 +1,101 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/common_funcs.h"
6#include "common/common_paths.h"
7#include "common/logging/log.h"
8#include "common/string_util.h"
9#include "core/hle/kernel/process.h"
10#include "core/hle/kernel/resource_limit.h"
11#include "core/loader/deconstructed_rom_directory.h"
12#include "core/loader/nso.h"
13#include "core/memory.h"
14
15namespace Loader {
16
17FileType AppLoader_DeconstructedRomDirectory::IdentifyType(FileUtil::IOFile& file,
18 const std::string& filepath) {
19 bool is_main_found{};
20 bool is_rtld_found{};
21 bool is_sdk_found{};
22
23 const auto callback = [&](unsigned* num_entries_out, const std::string& directory,
24 const std::string& virtual_name) -> bool {
25
26 // Skip directories
27 std::string physical_name = directory + virtual_name;
28 if (FileUtil::IsDirectory(physical_name)) {
29 return true;
30 }
31
32 // Verify filename
33 if (Common::ToLower(virtual_name) == "main") {
34 is_main_found = true;
35 } else if (Common::ToLower(virtual_name) == "rtld") {
36 is_rtld_found = true;
37 } else if (Common::ToLower(virtual_name) == "sdk") {
38 is_sdk_found = true;
39 } else {
40 // Contrinue searching
41 return true;
42 }
43
44 // Verify file is an NSO
45 FileUtil::IOFile file(physical_name, "rb");
46 if (AppLoader_NSO::IdentifyType(file, physical_name) != FileType::NSO) {
47 return false;
48 }
49
50 // We are done if we've found and verified all required NSOs
51 return !(is_main_found && is_rtld_found && is_sdk_found);
52 };
53
54 // Search the directory recursively, looking for the required modules
55 const std::string directory = filepath.substr(0, filepath.find_last_of("/\\")) + DIR_SEP;
56 FileUtil::ForeachDirectoryEntry(nullptr, directory, callback);
57
58 if (is_main_found && is_rtld_found && is_sdk_found) {
59 return FileType::DeconstructedRomDirectory;
60 }
61
62 return FileType::Error;
63}
64
65ResultStatus AppLoader_DeconstructedRomDirectory::Load(
66 Kernel::SharedPtr<Kernel::Process>& process) {
67 if (is_loaded) {
68 return ResultStatus::ErrorAlreadyLoaded;
69 }
70 if (!file.IsOpen()) {
71 return ResultStatus::Error;
72 }
73
74 process = Kernel::Process::Create("main");
75
76 // Load NSO modules
77 VAddr next_load_addr{Memory::PROCESS_IMAGE_VADDR};
78 for (const auto& module : {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3",
79 "subsdk4", "subsdk5", "subsdk6", "subsdk7", "sdk"}) {
80 const std::string path =
81 filepath.substr(0, filepath.find_last_of("/\\")) + DIR_SEP + module;
82 const VAddr load_addr = next_load_addr;
83 next_load_addr = AppLoader_NSO::LoadModule(path, load_addr);
84 if (next_load_addr) {
85 LOG_DEBUG(Loader, "loaded module %s @ 0x%llx", module, load_addr);
86 } else {
87 next_load_addr = load_addr;
88 }
89 }
90
91 process->svc_access_mask.set();
92 process->address_mappings = default_address_mappings;
93 process->resource_limit =
94 Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
95 process->Run(Memory::PROCESS_IMAGE_VADDR, 48, Kernel::DEFAULT_STACK_SIZE);
96
97 is_loaded = true;
98 return ResultStatus::Success;
99}
100
101} // 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..d0391aac5
--- /dev/null
+++ b/src/core/loader/deconstructed_rom_directory.h
@@ -0,0 +1,44 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <string>
8#include "common/common_types.h"
9#include "common/file_util.h"
10#include "core/hle/kernel/kernel.h"
11#include "core/loader/loader.h"
12
13namespace Loader {
14
15/**
16 * This class loads a "deconstructed ROM directory", which are the typical format we see for Switch
17 * game dumps. The path should be a "main" NSO, which must be in a directory that contains the other
18 * standard ExeFS NSOs (e.g. rtld, sdk, etc.). It will automatically find and load these.
19 * Furthermore, it will look for the first .istorage file (optionally) and use this for the RomFS.
20 */
21class AppLoader_DeconstructedRomDirectory final : public AppLoader {
22public:
23 AppLoader_DeconstructedRomDirectory(FileUtil::IOFile&& file, std::string filepath)
24 : AppLoader(std::move(file)), filepath(std::move(filepath)) {}
25
26 /**
27 * Returns the type of the file
28 * @param file FileUtil::IOFile open file
29 * @param filepath Path of the file that we are opening.
30 * @return FileType found, or FileType::Error if this loader doesn't know it
31 */
32 static FileType IdentifyType(FileUtil::IOFile& file, const std::string& filepath);
33
34 FileType GetFileType() override {
35 return IdentifyType(file, filepath);
36 }
37
38 ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override;
39
40private:
41 std::string filepath;
42};
43
44} // namespace Loader
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp
index 2ecccdd4f..9d87b07d7 100644
--- a/src/core/loader/loader.cpp
+++ b/src/core/loader/loader.cpp
@@ -7,6 +7,7 @@
7#include "common/logging/log.h" 7#include "common/logging/log.h"
8#include "common/string_util.h" 8#include "common/string_util.h"
9#include "core/hle/kernel/process.h" 9#include "core/hle/kernel/process.h"
10#include "core/loader/deconstructed_rom_directory.h"
10#include "core/loader/elf.h" 11#include "core/loader/elf.h"
11#include "core/loader/nro.h" 12#include "core/loader/nro.h"
12#include "core/loader/nso.h" 13#include "core/loader/nso.h"
@@ -29,6 +30,7 @@ FileType IdentifyFile(FileUtil::IOFile& file, const std::string& filepath) {
29 if (FileType::Error != type) \ 30 if (FileType::Error != type) \
30 return type; 31 return type;
31 32
33 CHECK_TYPE(DeconstructedRomDirectory)
32 CHECK_TYPE(ELF) 34 CHECK_TYPE(ELF)
33 CHECK_TYPE(NSO) 35 CHECK_TYPE(NSO)
34 CHECK_TYPE(NRO) 36 CHECK_TYPE(NRO)
@@ -69,6 +71,8 @@ const char* GetFileTypeString(FileType type) {
69 return "NRO"; 71 return "NRO";
70 case FileType::NSO: 72 case FileType::NSO:
71 return "NSO"; 73 return "NSO";
74 case FileType::DeconstructedRomDirectory:
75 return "Directory";
72 case FileType::Error: 76 case FileType::Error:
73 case FileType::Unknown: 77 case FileType::Unknown:
74 break; 78 break;
@@ -102,6 +106,10 @@ static std::unique_ptr<AppLoader> GetFileLoader(FileUtil::IOFile&& file, FileTyp
102 case FileType::NRO: 106 case FileType::NRO:
103 return std::make_unique<AppLoader_NRO>(std::move(file), filepath); 107 return std::make_unique<AppLoader_NRO>(std::move(file), filepath);
104 108
109 // NX deconstructed ROM directory.
110 case FileType::DeconstructedRomDirectory:
111 return std::make_unique<AppLoader_DeconstructedRomDirectory>(std::move(file), filepath);
112
105 default: 113 default:
106 return nullptr; 114 return nullptr;
107 } 115 }
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h
index f7828b7ad..6075853b4 100644
--- a/src/core/loader/loader.h
+++ b/src/core/loader/loader.h
@@ -32,6 +32,7 @@ enum class FileType {
32 ELF, 32 ELF,
33 NSO, 33 NSO,
34 NRO, 34 NRO,
35 DeconstructedRomDirectory,
35}; 36};
36 37
37/** 38/**