mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	Loader: Cleaned up and removed unused code, refactored ELF namespace.
This commit is contained in:
		
							parent
							
								
									1da361c7ab
								
							
						
					
					
						commit
						13bdaa6c60
					
				
					 4 changed files with 70 additions and 209 deletions
				
			
		|  | @ -5,65 +5,17 @@ | |||
| #include <string> | ||||
| 
 | ||||
| #include "common/common.h" | ||||
| 
 | ||||
| #include "common/file_util.h" | ||||
| #include "common/symbols.h" | ||||
| 
 | ||||
| #include "core/mem_map.h" | ||||
| #include "core/loader/elf.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| 
 | ||||
| //void bswap(Elf32_Word &w) {w = Common::swap32(w);}
 | ||||
| //void bswap(Elf32_Half &w) {w = Common::swap16(w);}
 | ||||
| 
 | ||||
| #define bswap(w) w // Dirty bswap disable for now... 3DS is little endian, anyway
 | ||||
| 
 | ||||
| static void byteswapHeader(Elf32_Ehdr &ELF_H) | ||||
| { | ||||
|     bswap(ELF_H.e_type); | ||||
|     bswap(ELF_H.e_machine); | ||||
|     bswap(ELF_H.e_ehsize); | ||||
|     bswap(ELF_H.e_phentsize); | ||||
|     bswap(ELF_H.e_phnum); | ||||
|     bswap(ELF_H.e_shentsize); | ||||
|     bswap(ELF_H.e_shnum); | ||||
|     bswap(ELF_H.e_shstrndx); | ||||
|     bswap(ELF_H.e_version); | ||||
|     bswap(ELF_H.e_entry); | ||||
|     bswap(ELF_H.e_phoff); | ||||
|     bswap(ELF_H.e_shoff); | ||||
|     bswap(ELF_H.e_flags); | ||||
| } | ||||
| 
 | ||||
| static void byteswapSegment(Elf32_Phdr &sec) | ||||
| { | ||||
|     bswap(sec.p_align); | ||||
|     bswap(sec.p_filesz); | ||||
|     bswap(sec.p_flags); | ||||
|     bswap(sec.p_memsz); | ||||
|     bswap(sec.p_offset); | ||||
|     bswap(sec.p_paddr); | ||||
|     bswap(sec.p_vaddr); | ||||
|     bswap(sec.p_type); | ||||
| } | ||||
| 
 | ||||
| static void byteswapSection(Elf32_Shdr &sec) | ||||
| { | ||||
|     bswap(sec.sh_addr); | ||||
|     bswap(sec.sh_addralign); | ||||
|     bswap(sec.sh_entsize); | ||||
|     bswap(sec.sh_flags); | ||||
|     bswap(sec.sh_info); | ||||
|     bswap(sec.sh_link); | ||||
|     bswap(sec.sh_name); | ||||
|     bswap(sec.sh_offset); | ||||
|     bswap(sec.sh_size); | ||||
|     bswap(sec.sh_type); | ||||
| } | ||||
| 
 | ||||
| ElfReader::ElfReader(void *ptr) | ||||
| { | ||||
| ElfReader::ElfReader(void *ptr) { | ||||
|     base = (char*)ptr; | ||||
|     base32 = (u32 *)ptr; | ||||
|     header = (Elf32_Ehdr*)ptr; | ||||
|     byteswapHeader(*header); | ||||
| 
 | ||||
|     segments = (Elf32_Phdr *)(base + header->e_phoff); | ||||
|     sections = (Elf32_Shdr *)(base + header->e_shoff); | ||||
|  | @ -73,8 +25,7 @@ ElfReader::ElfReader(void *ptr) | |||
|     LoadSymbols(); | ||||
| } | ||||
| 
 | ||||
| const char *ElfReader::GetSectionName(int section) const | ||||
| { | ||||
| const char *ElfReader::GetSectionName(int section) const { | ||||
|     if (sections[section].sh_type == SHT_NULL) | ||||
|         return nullptr; | ||||
| 
 | ||||
|  | @ -87,8 +38,7 @@ const char *ElfReader::GetSectionName(int section) const | |||
|         return nullptr; | ||||
| } | ||||
| 
 | ||||
| bool ElfReader::LoadInto(u32 vaddr) | ||||
| { | ||||
| bool ElfReader::LoadInto(u32 vaddr) { | ||||
|     DEBUG_LOG(MASTER_LOG, "String section: %i", header->e_shstrndx); | ||||
| 
 | ||||
|     // Should we relocate?
 | ||||
|  | @ -188,3 +138,48 @@ bool ElfReader::LoadSymbols() | |||
| 
 | ||||
|     return hasSymbols; | ||||
| } | ||||
| 
 | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| // Loader namespace
 | ||||
| 
 | ||||
| namespace Loader { | ||||
| 
 | ||||
| /**
 | ||||
|  * Loads an ELF file | ||||
|  * @param filename String filename of ELF file | ||||
|  * @param error_string Pointer to string to put error message if an error has occurred | ||||
|  * @return True on success, otherwise false | ||||
|  */ | ||||
| bool Load_ELF(std::string& filename, std::string* error_string) { | ||||
|     std::string full_path = filename; | ||||
|     std::string path, file, extension; | ||||
|     SplitPath(ReplaceAll(full_path, "\\", "/"), &path, &file, &extension); | ||||
| #if EMU_PLATFORM == PLATFORM_WINDOWS | ||||
|     path = ReplaceAll(path, "/", "\\"); | ||||
| #endif | ||||
|     File::IOFile f(filename, "rb"); | ||||
| 
 | ||||
|     if (f.IsOpen()) { | ||||
|         u32 size = (u32)f.GetSize(); | ||||
|         u8* buffer = new u8[size]; | ||||
|         ElfReader* elf_reader = NULL; | ||||
| 
 | ||||
|         f.ReadBytes(buffer, size); | ||||
| 
 | ||||
|         elf_reader = new ElfReader(buffer); | ||||
|         elf_reader->LoadInto(0x00100000); | ||||
| 
 | ||||
|         Kernel::LoadExec(elf_reader->GetEntryPoint()); | ||||
| 
 | ||||
|         delete[] buffer; | ||||
|         delete elf_reader; | ||||
|     } else { | ||||
|         *error_string = "Unable to open ELF file!"; | ||||
|         return false; | ||||
|     } | ||||
|     f.Close(); | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| } // namespace Loader
 | ||||
|  |  | |||
|  | @ -329,3 +329,18 @@ public: | |||
|         return bRelocate; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| // Loader namespace
 | ||||
| 
 | ||||
| namespace Loader { | ||||
| 
 | ||||
| /**
 | ||||
|  * Loads an ELF file | ||||
|  * @param filename String filename of ELF file | ||||
|  * @param error_string Pointer to string to put error message if an error has occurred | ||||
|  * @return True on success, otherwise false | ||||
|  */ | ||||
| bool Load_ELF(std::string& filename, std::string* error_string); | ||||
| 
 | ||||
| } // namespace Loader
 | ||||
|  |  | |||
|  | @ -2,98 +2,14 @@ | |||
| // Licensed under GPLv2
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include "common/common_types.h" | ||||
| #include "common/file_util.h" | ||||
| 
 | ||||
| #include "core/loader/loader.h" | ||||
| #include "core/loader/elf.h" | ||||
| #include "core/loader/ncch.h" | ||||
| #include "core/system.h" | ||||
| #include "core/core.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/mem_map.h" | ||||
| 
 | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| /// Loads a CTR ELF file
 | ||||
| bool Load_ELF(std::string &filename) { | ||||
|     std::string full_path = filename; | ||||
|     std::string path, file, extension; | ||||
|     SplitPath(ReplaceAll(full_path, "\\", "/"), &path, &file, &extension); | ||||
| #if EMU_PLATFORM == PLATFORM_WINDOWS | ||||
|     path = ReplaceAll(path, "/", "\\"); | ||||
| #endif | ||||
|     File::IOFile f(filename, "rb"); | ||||
| 
 | ||||
|     if (f.IsOpen()) { | ||||
|         u64 size = f.GetSize(); | ||||
|         u8* buffer = new u8[size]; | ||||
|         ElfReader* elf_reader = NULL; | ||||
| 
 | ||||
|         f.ReadBytes(buffer, size); | ||||
| 
 | ||||
|         elf_reader = new ElfReader(buffer); | ||||
|         elf_reader->LoadInto(0x00100000); | ||||
| 
 | ||||
|         Kernel::LoadExec(elf_reader->GetEntryPoint()); | ||||
| 
 | ||||
|         delete[] buffer; | ||||
|         delete elf_reader; | ||||
|     } else { | ||||
|         return false; | ||||
|     } | ||||
|     f.Close(); | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| /// Loads a CTR BIN file extracted from an ExeFS
 | ||||
| bool Load_BIN(std::string &filename) { | ||||
|     std::string full_path = filename; | ||||
|     std::string path, file, extension; | ||||
|     SplitPath(ReplaceAll(full_path, "\\", "/"), &path, &file, &extension); | ||||
| #if EMU_PLATFORM == PLATFORM_WINDOWS | ||||
|     path = ReplaceAll(path, "/", "\\"); | ||||
| #endif | ||||
|     File::IOFile f(filename, "rb"); | ||||
| 
 | ||||
|     if (f.IsOpen()) { | ||||
|         u64 size = f.GetSize(); | ||||
|         u8* buffer = new u8[size]; | ||||
| 
 | ||||
|         f.ReadBytes(buffer, size); | ||||
| 
 | ||||
|         u32 entry_point = 0x00100000; // Hardcoded, read from exheader
 | ||||
|          | ||||
|         const u8 *src = buffer; | ||||
|         u8 *dst = Memory::GetPointer(entry_point); | ||||
|         u32 srcSize = size; | ||||
|         u32 *s = (u32*)src; | ||||
|         u32 *d = (u32*)dst; | ||||
|         for (int j = 0; j < (int)(srcSize + 3) / 4; j++) | ||||
|         { | ||||
|             *d++ = (*s++); | ||||
|         } | ||||
|          | ||||
|         Kernel::LoadExec(entry_point); | ||||
| 
 | ||||
|         delete[] buffer; | ||||
|     } | ||||
|     else { | ||||
|         return false; | ||||
|     } | ||||
|     f.Close(); | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| namespace Loader { | ||||
| 
 | ||||
| bool IsBootableDirectory() { | ||||
|     ERROR_LOG(TIME, "Unimplemented function!"); | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Identifies the type of a bootable file | ||||
|  * @param filename String filename of bootable file | ||||
|  | @ -107,15 +23,7 @@ FileType IdentifyFile(std::string &filename) { | |||
|     } | ||||
|     std::string extension = filename.size() >= 5 ? filename.substr(filename.size() - 4) : ""; | ||||
| 
 | ||||
|     if (File::IsDirectory(filename)) { | ||||
|         if (IsBootableDirectory()) { | ||||
|             return FILETYPE_DIRECTORY_CXI; | ||||
|         } | ||||
|         else { | ||||
|             return FILETYPE_NORMAL_DIRECTORY; | ||||
|         } | ||||
|     } | ||||
|     else if (!strcasecmp(extension.c_str(), ".elf")) { | ||||
|     if (!strcasecmp(extension.c_str(), ".elf")) { | ||||
|         return FILETYPE_CTR_ELF; // TODO(bunnei): Do some filetype checking :p
 | ||||
|     } | ||||
|     else if (!strcasecmp(extension.c_str(), ".axf")) { | ||||
|  | @ -127,24 +35,6 @@ FileType IdentifyFile(std::string &filename) { | |||
|     else if (!strcasecmp(extension.c_str(), ".cci")) { | ||||
|         return FILETYPE_CTR_CCI; // TODO(bunnei): Do some filetype checking :p
 | ||||
|     } | ||||
|     else if (!strcasecmp(extension.c_str(), ".bin")) { | ||||
|         return FILETYPE_CTR_BIN; | ||||
|     } | ||||
|     else if (!strcasecmp(extension.c_str(), ".dat")) { | ||||
|         return FILETYPE_LAUNCHER_DAT; | ||||
|     } | ||||
|     else if (!strcasecmp(extension.c_str(), ".zip")) { | ||||
|         return FILETYPE_ARCHIVE_ZIP; | ||||
|     } | ||||
|     else if (!strcasecmp(extension.c_str(), ".rar")) { | ||||
|         return FILETYPE_ARCHIVE_RAR; | ||||
|     } | ||||
|     else if (!strcasecmp(extension.c_str(), ".r00")) { | ||||
|         return FILETYPE_ARCHIVE_RAR; | ||||
|     } | ||||
|     else if (!strcasecmp(extension.c_str(), ".r01")) { | ||||
|         return FILETYPE_ARCHIVE_RAR; | ||||
|     } | ||||
|     return FILETYPE_UNKNOWN; | ||||
| } | ||||
| 
 | ||||
|  | @ -161,10 +51,7 @@ bool LoadFile(std::string &filename, std::string *error_string) { | |||
|     switch (IdentifyFile(filename)) { | ||||
| 
 | ||||
|     case FILETYPE_CTR_ELF: | ||||
|         return Load_ELF(filename); | ||||
| 
 | ||||
|     case FILETYPE_CTR_BIN: | ||||
|         return Load_BIN(filename); | ||||
|         return Loader::Load_ELF(filename, error_string); | ||||
| 
 | ||||
|     case FILETYPE_CTR_CXI: | ||||
|     case FILETYPE_CTR_CCI: | ||||
|  | @ -175,29 +62,6 @@ bool LoadFile(std::string &filename, std::string *error_string) { | |||
|         *error_string = "Error reading file"; | ||||
|         break; | ||||
| 
 | ||||
|     case FILETYPE_ARCHIVE_RAR: | ||||
| #ifdef WIN32 | ||||
|         *error_string = "RAR file detected (Require WINRAR)"; | ||||
| #else | ||||
|         *error_string = "RAR file detected (Require UnRAR)"; | ||||
| #endif | ||||
|         break; | ||||
| 
 | ||||
|     case FILETYPE_ARCHIVE_ZIP: | ||||
| #ifdef WIN32 | ||||
|         *error_string = "ZIP file detected (Require WINRAR)"; | ||||
| #else | ||||
|         *error_string = "ZIP file detected (Require UnRAR)"; | ||||
| #endif | ||||
|         break; | ||||
| 
 | ||||
|     case FILETYPE_NORMAL_DIRECTORY: | ||||
|         ERROR_LOG(LOADER, "Just a directory."); | ||||
|         *error_string = "Just a directory."; | ||||
|         break; | ||||
| 
 | ||||
|     case FILETYPE_UNKNOWN_BIN: | ||||
|     case FILETYPE_UNKNOWN_ELF: | ||||
|     case FILETYPE_UNKNOWN: | ||||
|     default: | ||||
|         ERROR_LOG(LOADER, "Failed to identify file"); | ||||
|  | @ -207,4 +71,4 @@ bool LoadFile(std::string &filename, std::string *error_string) { | |||
|     return false; | ||||
| } | ||||
| 
 | ||||
| } // namespace
 | ||||
| } // namespace Loader
 | ||||
|  |  | |||
|  | @ -7,6 +7,7 @@ | |||
| #include "common/common.h" | ||||
| 
 | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| // Loader namespace
 | ||||
| 
 | ||||
| namespace Loader { | ||||
| 
 | ||||
|  | @ -19,23 +20,9 @@ enum FileType { | |||
|     FILETYPE_CTR_ELF, | ||||
|     FILETYPE_CTR_BIN, | ||||
| 
 | ||||
|     FILETYPE_LAUNCHER_DAT, | ||||
| 
 | ||||
|     FILETYPE_DIRECTORY_CXI, | ||||
|      | ||||
|     FILETYPE_UNKNOWN_BIN, | ||||
|     FILETYPE_UNKNOWN_ELF, | ||||
|      | ||||
|     FILETYPE_ARCHIVE_RAR, | ||||
|     FILETYPE_ARCHIVE_ZIP, | ||||
|      | ||||
|     FILETYPE_NORMAL_DIRECTORY, | ||||
|      | ||||
|     FILETYPE_UNKNOWN | ||||
| }; | ||||
| 
 | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| /**
 | ||||
|  * Identifies the type of a bootable file | ||||
|  * @param filename String filename of bootable file | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue