mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +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 <string> | ||||||
| 
 | 
 | ||||||
| #include "common/common.h" | #include "common/common.h" | ||||||
| 
 | #include "common/file_util.h" | ||||||
| #include "common/symbols.h" | #include "common/symbols.h" | ||||||
|  | 
 | ||||||
| #include "core/mem_map.h" | #include "core/mem_map.h" | ||||||
| #include "core/loader/elf.h" | #include "core/loader/elf.h" | ||||||
|  | #include "core/hle/kernel/kernel.h" | ||||||
| 
 | 
 | ||||||
| //void bswap(Elf32_Word &w) {w = Common::swap32(w);}
 | ElfReader::ElfReader(void *ptr) { | ||||||
| //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) |  | ||||||
| { |  | ||||||
|     base = (char*)ptr; |     base = (char*)ptr; | ||||||
|     base32 = (u32 *)ptr; |     base32 = (u32 *)ptr; | ||||||
|     header = (Elf32_Ehdr*)ptr; |     header = (Elf32_Ehdr*)ptr; | ||||||
|     byteswapHeader(*header); |  | ||||||
| 
 | 
 | ||||||
|     segments = (Elf32_Phdr *)(base + header->e_phoff); |     segments = (Elf32_Phdr *)(base + header->e_phoff); | ||||||
|     sections = (Elf32_Shdr *)(base + header->e_shoff); |     sections = (Elf32_Shdr *)(base + header->e_shoff); | ||||||
|  | @ -73,8 +25,7 @@ ElfReader::ElfReader(void *ptr) | ||||||
|     LoadSymbols(); |     LoadSymbols(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const char *ElfReader::GetSectionName(int section) const | const char *ElfReader::GetSectionName(int section) const { | ||||||
| { |  | ||||||
|     if (sections[section].sh_type == SHT_NULL) |     if (sections[section].sh_type == SHT_NULL) | ||||||
|         return nullptr; |         return nullptr; | ||||||
| 
 | 
 | ||||||
|  | @ -87,8 +38,7 @@ const char *ElfReader::GetSectionName(int section) const | ||||||
|         return nullptr; |         return nullptr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool ElfReader::LoadInto(u32 vaddr) | bool ElfReader::LoadInto(u32 vaddr) { | ||||||
| { |  | ||||||
|     DEBUG_LOG(MASTER_LOG, "String section: %i", header->e_shstrndx); |     DEBUG_LOG(MASTER_LOG, "String section: %i", header->e_shstrndx); | ||||||
| 
 | 
 | ||||||
|     // Should we relocate?
 |     // Should we relocate?
 | ||||||
|  | @ -188,3 +138,48 @@ bool ElfReader::LoadSymbols() | ||||||
| 
 | 
 | ||||||
|     return hasSymbols; |     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; |         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
 | // Licensed under GPLv2
 | ||||||
| // Refer to the license.txt file included.
 | // 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/loader.h" | ||||||
| #include "core/loader/elf.h" | #include "core/loader/elf.h" | ||||||
| #include "core/loader/ncch.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 { | namespace Loader { | ||||||
| 
 | 
 | ||||||
| bool IsBootableDirectory() { |  | ||||||
|     ERROR_LOG(TIME, "Unimplemented function!"); |  | ||||||
|     return true; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /**
 | /**
 | ||||||
|  * Identifies the type of a bootable file |  * Identifies the type of a bootable file | ||||||
|  * @param filename String filename of 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) : ""; |     std::string extension = filename.size() >= 5 ? filename.substr(filename.size() - 4) : ""; | ||||||
| 
 | 
 | ||||||
|     if (File::IsDirectory(filename)) { |     if (!strcasecmp(extension.c_str(), ".elf")) { | ||||||
|         if (IsBootableDirectory()) { |  | ||||||
|             return FILETYPE_DIRECTORY_CXI; |  | ||||||
|         } |  | ||||||
|         else { |  | ||||||
|             return FILETYPE_NORMAL_DIRECTORY; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     else if (!strcasecmp(extension.c_str(), ".elf")) { |  | ||||||
|         return FILETYPE_CTR_ELF; // TODO(bunnei): Do some filetype checking :p
 |         return FILETYPE_CTR_ELF; // TODO(bunnei): Do some filetype checking :p
 | ||||||
|     } |     } | ||||||
|     else if (!strcasecmp(extension.c_str(), ".axf")) { |     else if (!strcasecmp(extension.c_str(), ".axf")) { | ||||||
|  | @ -127,24 +35,6 @@ FileType IdentifyFile(std::string &filename) { | ||||||
|     else if (!strcasecmp(extension.c_str(), ".cci")) { |     else if (!strcasecmp(extension.c_str(), ".cci")) { | ||||||
|         return FILETYPE_CTR_CCI; // TODO(bunnei): Do some filetype checking :p
 |         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; |     return FILETYPE_UNKNOWN; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -161,10 +51,7 @@ bool LoadFile(std::string &filename, std::string *error_string) { | ||||||
|     switch (IdentifyFile(filename)) { |     switch (IdentifyFile(filename)) { | ||||||
| 
 | 
 | ||||||
|     case FILETYPE_CTR_ELF: |     case FILETYPE_CTR_ELF: | ||||||
|         return Load_ELF(filename); |         return Loader::Load_ELF(filename, error_string); | ||||||
| 
 |  | ||||||
|     case FILETYPE_CTR_BIN: |  | ||||||
|         return Load_BIN(filename); |  | ||||||
| 
 | 
 | ||||||
|     case FILETYPE_CTR_CXI: |     case FILETYPE_CTR_CXI: | ||||||
|     case FILETYPE_CTR_CCI: |     case FILETYPE_CTR_CCI: | ||||||
|  | @ -175,29 +62,6 @@ bool LoadFile(std::string &filename, std::string *error_string) { | ||||||
|         *error_string = "Error reading file"; |         *error_string = "Error reading file"; | ||||||
|         break; |         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: |     case FILETYPE_UNKNOWN: | ||||||
|     default: |     default: | ||||||
|         ERROR_LOG(LOADER, "Failed to identify file"); |         ERROR_LOG(LOADER, "Failed to identify file"); | ||||||
|  | @ -207,4 +71,4 @@ bool LoadFile(std::string &filename, std::string *error_string) { | ||||||
|     return false; |     return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } // namespace
 | } // namespace Loader
 | ||||||
|  |  | ||||||
|  | @ -7,6 +7,7 @@ | ||||||
| #include "common/common.h" | #include "common/common.h" | ||||||
| 
 | 
 | ||||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||||
|  | // Loader namespace
 | ||||||
| 
 | 
 | ||||||
| namespace Loader { | namespace Loader { | ||||||
| 
 | 
 | ||||||
|  | @ -19,23 +20,9 @@ enum FileType { | ||||||
|     FILETYPE_CTR_ELF, |     FILETYPE_CTR_ELF, | ||||||
|     FILETYPE_CTR_BIN, |     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 |     FILETYPE_UNKNOWN | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 |  | ||||||
| 
 |  | ||||||
| /**
 | /**
 | ||||||
|  * Identifies the type of a bootable file |  * Identifies the type of a bootable file | ||||||
|  * @param filename String filename of bootable file |  * @param filename String filename of bootable file | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue