summaryrefslogtreecommitdiff
path: root/src/core/loader/loader.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2014-06-16 18:03:13 -0400
committerGravatar bunnei2014-06-16 18:03:13 -0400
commit0aca202ae936d3fccbab34f36d9246e0598849a5 (patch)
treefff4a16ed505ebddcc3048cf734db0237839d338 /src/core/loader/loader.cpp
parentLoader: Added stubbed detection of CXI and CCI files. (diff)
downloadyuzu-0aca202ae936d3fccbab34f36d9246e0598849a5.tar.gz
yuzu-0aca202ae936d3fccbab34f36d9246e0598849a5.tar.xz
yuzu-0aca202ae936d3fccbab34f36d9246e0598849a5.zip
Loader: Moved elf and loader modules to a "loader" subdirectory.
Diffstat (limited to 'src/core/loader/loader.cpp')
-rw-r--r--src/core/loader/loader.cpp205
1 files changed, 205 insertions, 0 deletions
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp
new file mode 100644
index 000000000..7e6922e0c
--- /dev/null
+++ b/src/core/loader/loader.cpp
@@ -0,0 +1,205 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#include "common/common_types.h"
6#include "common/file_util.h"
7
8#include "core/loader/loader.h"
9#include "core/loader/elf_reader.h"
10#include "core/system.h"
11#include "core/core.h"
12#include "core/hle/kernel/kernel.h"
13#include "core/mem_map.h"
14
15////////////////////////////////////////////////////////////////////////////////////////////////////
16
17/// Loads a CTR ELF file
18bool Load_ELF(std::string &filename) {
19 std::string full_path = filename;
20 std::string path, file, extension;
21 SplitPath(ReplaceAll(full_path, "\\", "/"), &path, &file, &extension);
22#if EMU_PLATFORM == PLATFORM_WINDOWS
23 path = ReplaceAll(path, "/", "\\");
24#endif
25 File::IOFile f(filename, "rb");
26
27 if (f.IsOpen()) {
28 u64 size = f.GetSize();
29 u8* buffer = new u8[size];
30 ElfReader* elf_reader = NULL;
31
32 f.ReadBytes(buffer, size);
33
34 elf_reader = new ElfReader(buffer);
35 elf_reader->LoadInto(0x00100000);
36
37 Kernel::LoadExec(elf_reader->GetEntryPoint());
38
39 delete[] buffer;
40 delete elf_reader;
41 } else {
42 return false;
43 }
44 f.Close();
45
46 return true;
47}
48
49/// Loads a CTR BIN file extracted from an ExeFS
50bool Load_BIN(std::string &filename) {
51 std::string full_path = filename;
52 std::string path, file, extension;
53 SplitPath(ReplaceAll(full_path, "\\", "/"), &path, &file, &extension);
54#if EMU_PLATFORM == PLATFORM_WINDOWS
55 path = ReplaceAll(path, "/", "\\");
56#endif
57 File::IOFile f(filename, "rb");
58
59 if (f.IsOpen()) {
60 u64 size = f.GetSize();
61 u8* buffer = new u8[size];
62
63 f.ReadBytes(buffer, size);
64
65 u32 entry_point = 0x00100000; // Hardcoded, read from exheader
66
67 const u8 *src = buffer;
68 u8 *dst = Memory::GetPointer(entry_point);
69 u32 srcSize = size;
70 u32 *s = (u32*)src;
71 u32 *d = (u32*)dst;
72 for (int j = 0; j < (int)(srcSize + 3) / 4; j++)
73 {
74 *d++ = (*s++);
75 }
76
77 Kernel::LoadExec(entry_point);
78
79 delete[] buffer;
80 }
81 else {
82 return false;
83 }
84 f.Close();
85
86 return true;
87}
88
89namespace Loader {
90
91bool IsBootableDirectory() {
92 ERROR_LOG(TIME, "Unimplemented function!");
93 return true;
94}
95
96/**
97 * Identifies the type of a bootable file
98 * @param filename String filename of bootable file
99 * @todo (ShizZy) this function sucks... make it actually check file contents etc.
100 * @return FileType of file
101 */
102FileType IdentifyFile(std::string &filename) {
103 if (filename.size() == 0) {
104 ERROR_LOG(LOADER, "invalid filename %s", filename.c_str());
105 return FILETYPE_ERROR;
106 }
107 std::string extension = filename.size() >= 5 ? filename.substr(filename.size() - 4) : "";
108
109 if (File::IsDirectory(filename)) {
110 if (IsBootableDirectory()) {
111 return FILETYPE_DIRECTORY_CXI;
112 }
113 else {
114 return FILETYPE_NORMAL_DIRECTORY;
115 }
116 }
117 else if (!strcasecmp(extension.c_str(), ".elf")) {
118 return FILETYPE_CTR_ELF; // TODO(bunnei): Do some filetype checking :p
119 }
120 else if (!strcasecmp(extension.c_str(), ".axf")) {
121 return FILETYPE_CTR_ELF; // TODO(bunnei): Do some filetype checking :p
122 }
123 else if (!strcasecmp(extension.c_str(), ".cxi")) {
124 return FILETYPE_CTR_CXI; // TODO(bunnei): Do some filetype checking :p
125 }
126 else if (!strcasecmp(extension.c_str(), ".cci")) {
127 return FILETYPE_CTR_CCI; // TODO(bunnei): Do some filetype checking :p
128 }
129 else if (!strcasecmp(extension.c_str(), ".bin")) {
130 return FILETYPE_CTR_BIN;
131 }
132 else if (!strcasecmp(extension.c_str(), ".dat")) {
133 return FILETYPE_LAUNCHER_DAT;
134 }
135 else if (!strcasecmp(extension.c_str(), ".zip")) {
136 return FILETYPE_ARCHIVE_ZIP;
137 }
138 else if (!strcasecmp(extension.c_str(), ".rar")) {
139 return FILETYPE_ARCHIVE_RAR;
140 }
141 else if (!strcasecmp(extension.c_str(), ".r00")) {
142 return FILETYPE_ARCHIVE_RAR;
143 }
144 else if (!strcasecmp(extension.c_str(), ".r01")) {
145 return FILETYPE_ARCHIVE_RAR;
146 }
147 return FILETYPE_UNKNOWN;
148}
149
150/**
151 * Identifies and loads a bootable file
152 * @param filename String filename of bootable file
153 * @param error_string Point to string to put error message if an error has occurred
154 * @return True on success, otherwise false
155 */
156bool LoadFile(std::string &filename, std::string *error_string) {
157 INFO_LOG(LOADER, "Identifying file...");
158
159 // Note that this can modify filename!
160 switch (IdentifyFile(filename)) {
161
162 case FILETYPE_CTR_ELF:
163 return Load_ELF(filename);
164
165 case FILETYPE_CTR_BIN:
166 return Load_BIN(filename);
167
168 case FILETYPE_ERROR:
169 ERROR_LOG(LOADER, "Could not read file");
170 *error_string = "Error reading file";
171 break;
172
173 case FILETYPE_ARCHIVE_RAR:
174#ifdef WIN32
175 *error_string = "RAR file detected (Require WINRAR)";
176#else
177 *error_string = "RAR file detected (Require UnRAR)";
178#endif
179 break;
180
181 case FILETYPE_ARCHIVE_ZIP:
182#ifdef WIN32
183 *error_string = "ZIP file detected (Require WINRAR)";
184#else
185 *error_string = "ZIP file detected (Require UnRAR)";
186#endif
187 break;
188
189 case FILETYPE_NORMAL_DIRECTORY:
190 ERROR_LOG(LOADER, "Just a directory.");
191 *error_string = "Just a directory.";
192 break;
193
194 case FILETYPE_UNKNOWN_BIN:
195 case FILETYPE_UNKNOWN_ELF:
196 case FILETYPE_UNKNOWN:
197 default:
198 ERROR_LOG(LOADER, "Failed to identify file");
199 *error_string = " Failed to identify file";
200 break;
201 }
202 return false;
203}
204
205} // namespace \ No newline at end of file