diff options
| author | 2014-03-31 22:23:55 -0400 | |
|---|---|---|
| committer | 2014-03-31 22:23:55 -0400 | |
| commit | 85e8da6fc8579c313649d12494f58b654b439326 (patch) | |
| tree | c0df9bef50676c484964a9e3efda4114e1b87046 /src/core | |
| parent | commented out bswap stuff... ARM ELF files are little endian anyway (diff) | |
| download | yuzu-85e8da6fc8579c313649d12494f58b654b439326.tar.gz yuzu-85e8da6fc8579c313649d12494f58b654b439326.tar.xz yuzu-85e8da6fc8579c313649d12494f58b654b439326.zip | |
added ELF loading support to loader.cpp
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/src/loader.cpp | 182 |
1 files changed, 113 insertions, 69 deletions
diff --git a/src/core/src/loader.cpp b/src/core/src/loader.cpp index 994ce85e9..7e7eb9161 100644 --- a/src/core/src/loader.cpp +++ b/src/core/src/loader.cpp | |||
| @@ -26,35 +26,67 @@ | |||
| 26 | #include "loader.h" | 26 | #include "loader.h" |
| 27 | #include "system.h" | 27 | #include "system.h" |
| 28 | #include "file_sys/directory_file_system.h" | 28 | #include "file_sys/directory_file_system.h" |
| 29 | #include "elf/elf_reader.h" | ||
| 29 | 30 | ||
| 30 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 31 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 31 | 32 | ||
| 32 | /// Loads an extracted CXI from a directory | 33 | /// Loads an extracted CXI from a directory |
| 33 | bool LoadDirectory_CXI(std::string &filename) { | 34 | bool LoadDirectory_CXI(std::string &filename) { |
| 34 | std::string full_path = filename; | 35 | std::string full_path = filename; |
| 35 | std::string path, file, extension; | 36 | std::string path, file, extension; |
| 36 | SplitPath(ReplaceAll(full_path, "\\", "/"), &path, &file, &extension); | 37 | SplitPath(ReplaceAll(full_path, "\\", "/"), &path, &file, &extension); |
| 37 | #if EMU_PLATFORM == PLATFORM_WINDOWS | 38 | #if EMU_PLATFORM == PLATFORM_WINDOWS |
| 38 | path = ReplaceAll(path, "/", "\\"); | 39 | path = ReplaceAll(path, "/", "\\"); |
| 39 | #endif | 40 | #endif |
| 40 | DirectoryFileSystem *fs = new DirectoryFileSystem(&System::g_ctr_file_system, path); | 41 | DirectoryFileSystem *fs = new DirectoryFileSystem(&System::g_ctr_file_system, path); |
| 41 | System::g_ctr_file_system.Mount("fs:", fs); | 42 | System::g_ctr_file_system.Mount("fs:", fs); |
| 42 | 43 | ||
| 43 | std::string final_name = "fs:/" + file + extension; | 44 | std::string final_name = "fs:/" + file + extension; |
| 44 | File::IOFile f(filename, "rb"); | 45 | File::IOFile f(filename, "rb"); |
| 45 | 46 | ||
| 46 | if (f.IsOpen()) { | 47 | if (f.IsOpen()) { |
| 47 | // TODO(ShizZy): read here to memory.... | 48 | // TODO(ShizZy): read here to memory.... |
| 48 | } | 49 | } |
| 49 | ERROR_LOG(TIME, "Unimplemented function!"); | 50 | ERROR_LOG(TIME, "Unimplemented function!"); |
| 50 | return true; | 51 | return true; |
| 52 | } | ||
| 53 | |||
| 54 | /// Loads a CTR ELF file | ||
| 55 | bool Load_ELF(std::string &filename) { | ||
| 56 | std::string full_path = filename; | ||
| 57 | std::string path, file, extension; | ||
| 58 | SplitPath(ReplaceAll(full_path, "\\", "/"), &path, &file, &extension); | ||
| 59 | #if EMU_PLATFORM == PLATFORM_WINDOWS | ||
| 60 | path = ReplaceAll(path, "/", "\\"); | ||
| 61 | #endif | ||
| 62 | File::IOFile f(filename, "rb"); | ||
| 63 | |||
| 64 | if (f.IsOpen()) { | ||
| 65 | u64 size = f.GetSize(); | ||
| 66 | u8* buffer = new u8[size]; | ||
| 67 | ElfReader* elf_reader = NULL; | ||
| 68 | |||
| 69 | f.ReadBytes(buffer, size); | ||
| 70 | |||
| 71 | elf_reader = new ElfReader(buffer); | ||
| 72 | elf_reader->LoadInto(0x00100000); | ||
| 73 | |||
| 74 | delete[] buffer; | ||
| 75 | delete elf_reader; | ||
| 76 | } | ||
| 77 | else { | ||
| 78 | return false; | ||
| 79 | } | ||
| 80 | f.Close(); | ||
| 81 | |||
| 82 | return true; | ||
| 51 | } | 83 | } |
| 52 | 84 | ||
| 53 | namespace Loader { | 85 | namespace Loader { |
| 54 | 86 | ||
| 55 | bool IsBootableDirectory() { | 87 | bool IsBootableDirectory() { |
| 56 | ERROR_LOG(TIME, "Unimplemented function!"); | 88 | ERROR_LOG(TIME, "Unimplemented function!"); |
| 57 | return true; | 89 | return true; |
| 58 | } | 90 | } |
| 59 | 91 | ||
| 60 | /** | 92 | /** |
| @@ -64,28 +96,36 @@ bool IsBootableDirectory() { | |||
| 64 | * @return FileType of file | 96 | * @return FileType of file |
| 65 | */ | 97 | */ |
| 66 | FileType IdentifyFile(std::string &filename) { | 98 | FileType IdentifyFile(std::string &filename) { |
| 67 | if (filename.size() == 0) { | 99 | if (filename.size() == 0) { |
| 68 | ERROR_LOG(LOADER, "invalid filename %s", filename.c_str()); | 100 | ERROR_LOG(LOADER, "invalid filename %s", filename.c_str()); |
| 69 | return FILETYPE_ERROR; | 101 | return FILETYPE_ERROR; |
| 70 | } | 102 | } |
| 71 | std::string extension = filename.size() >= 5 ? filename.substr(filename.size() - 4) : ""; | 103 | std::string extension = filename.size() >= 5 ? filename.substr(filename.size() - 4) : ""; |
| 72 | 104 | ||
| 73 | if (File::IsDirectory(filename)) { | 105 | if (File::IsDirectory(filename)) { |
| 74 | if (IsBootableDirectory()) { | 106 | if (IsBootableDirectory()) { |
| 75 | return FILETYPE_DIRECTORY_CXI; | 107 | return FILETYPE_DIRECTORY_CXI; |
| 76 | } else { | 108 | } |
| 77 | return FILETYPE_NORMAL_DIRECTORY; | 109 | else { |
| 78 | } | 110 | return FILETYPE_NORMAL_DIRECTORY; |
| 79 | } else if (!strcasecmp(extension.c_str(),".zip")) { | 111 | } |
| 80 | return FILETYPE_ARCHIVE_ZIP; | 112 | } |
| 81 | } else if (!strcasecmp(extension.c_str(),".rar")) { | 113 | else if (!strcasecmp(extension.c_str(), ".elf")) { |
| 82 | return FILETYPE_ARCHIVE_RAR; | 114 | return FILETYPE_CTR_ELF; // TODO(bunnei): Do some filetype checking :p |
| 83 | } else if (!strcasecmp(extension.c_str(),".r00")) { | 115 | } |
| 84 | return FILETYPE_ARCHIVE_RAR; | 116 | else if (!strcasecmp(extension.c_str(), ".zip")) { |
| 85 | } else if (!strcasecmp(extension.c_str(),".r01")) { | 117 | return FILETYPE_ARCHIVE_ZIP; |
| 86 | return FILETYPE_ARCHIVE_RAR; | 118 | } |
| 87 | } | 119 | else if (!strcasecmp(extension.c_str(), ".rar")) { |
| 88 | return FILETYPE_UNKNOWN; | 120 | return FILETYPE_ARCHIVE_RAR; |
| 121 | } | ||
| 122 | else if (!strcasecmp(extension.c_str(), ".r00")) { | ||
| 123 | return FILETYPE_ARCHIVE_RAR; | ||
| 124 | } | ||
| 125 | else if (!strcasecmp(extension.c_str(), ".r01")) { | ||
| 126 | return FILETYPE_ARCHIVE_RAR; | ||
| 127 | } | ||
| 128 | return FILETYPE_UNKNOWN; | ||
| 89 | } | 129 | } |
| 90 | 130 | ||
| 91 | /** | 131 | /** |
| @@ -95,48 +135,52 @@ FileType IdentifyFile(std::string &filename) { | |||
| 95 | * @return True on success, otherwise false | 135 | * @return True on success, otherwise false |
| 96 | */ | 136 | */ |
| 97 | bool LoadFile(std::string &filename, std::string *error_string) { | 137 | bool LoadFile(std::string &filename, std::string *error_string) { |
| 98 | INFO_LOG(LOADER,"Identifying file..."); | 138 | INFO_LOG(LOADER, "Identifying file..."); |
| 99 | // Note that this can modify filename! | 139 | |
| 100 | switch (IdentifyFile(filename)) { | 140 | // Note that this can modify filename! |
| 141 | switch (IdentifyFile(filename)) { | ||
| 142 | |||
| 143 | case FILETYPE_CTR_ELF: | ||
| 144 | return Load_ELF(filename); | ||
| 101 | 145 | ||
| 102 | case FILETYPE_DIRECTORY_CXI: | 146 | case FILETYPE_DIRECTORY_CXI: |
| 103 | return LoadDirectory_CXI(filename); | 147 | return LoadDirectory_CXI(filename); |
| 104 | 148 | ||
| 105 | case FILETYPE_ERROR: | 149 | case FILETYPE_ERROR: |
| 106 | ERROR_LOG(LOADER, "Could not read file"); | 150 | ERROR_LOG(LOADER, "Could not read file"); |
| 107 | *error_string = "Error reading file"; | 151 | *error_string = "Error reading file"; |
| 108 | break; | 152 | break; |
| 109 | 153 | ||
| 110 | case FILETYPE_ARCHIVE_RAR: | 154 | case FILETYPE_ARCHIVE_RAR: |
| 111 | #ifdef WIN32 | 155 | #ifdef WIN32 |
| 112 | *error_string = "RAR file detected (Require WINRAR)"; | 156 | *error_string = "RAR file detected (Require WINRAR)"; |
| 113 | #else | 157 | #else |
| 114 | *error_string = "RAR file detected (Require UnRAR)"; | 158 | *error_string = "RAR file detected (Require UnRAR)"; |
| 115 | #endif | 159 | #endif |
| 116 | break; | 160 | break; |
| 117 | 161 | ||
| 118 | case FILETYPE_ARCHIVE_ZIP: | 162 | case FILETYPE_ARCHIVE_ZIP: |
| 119 | #ifdef WIN32 | 163 | #ifdef WIN32 |
| 120 | *error_string = "ZIP file detected (Require WINRAR)"; | 164 | *error_string = "ZIP file detected (Require WINRAR)"; |
| 121 | #else | 165 | #else |
| 122 | *error_string = "ZIP file detected (Require UnRAR)"; | 166 | *error_string = "ZIP file detected (Require UnRAR)"; |
| 123 | #endif | 167 | #endif |
| 124 | break; | 168 | break; |
| 125 | 169 | ||
| 126 | case FILETYPE_NORMAL_DIRECTORY: | 170 | case FILETYPE_NORMAL_DIRECTORY: |
| 127 | ERROR_LOG(LOADER, "Just a directory."); | 171 | ERROR_LOG(LOADER, "Just a directory."); |
| 128 | *error_string = "Just a directory."; | 172 | *error_string = "Just a directory."; |
| 129 | break; | 173 | break; |
| 130 | 174 | ||
| 131 | case FILETYPE_UNKNOWN_BIN: | 175 | case FILETYPE_UNKNOWN_BIN: |
| 132 | case FILETYPE_UNKNOWN_ELF: | 176 | case FILETYPE_UNKNOWN_ELF: |
| 133 | case FILETYPE_UNKNOWN: | 177 | case FILETYPE_UNKNOWN: |
| 134 | default: | 178 | default: |
| 135 | ERROR_LOG(LOADER, "Failed to identify file"); | 179 | ERROR_LOG(LOADER, "Failed to identify file"); |
| 136 | *error_string = "Failed to identify file"; | 180 | *error_string = "Failed to identify file"; |
| 137 | break; | 181 | break; |
| 138 | } | 182 | } |
| 139 | return false; | 183 | return false; |
| 140 | } | 184 | } |
| 141 | 185 | ||
| 142 | } // namespace \ No newline at end of file | 186 | } // namespace \ No newline at end of file |