diff options
Diffstat (limited to '')
-rw-r--r-- | src/core/loader/elf.cpp | 107 | ||||
-rw-r--r-- | src/core/loader/elf.h | 15 | ||||
-rw-r--r-- | src/core/loader/loader.cpp | 142 | ||||
-rw-r--r-- | src/core/loader/loader.h | 15 |
4 files changed, 70 insertions, 209 deletions
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index 153c30f51..f93354817 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -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 diff --git a/src/core/loader/elf.h b/src/core/loader/elf.h index 2e6b80982..708281478 100644 --- a/src/core/loader/elf.h +++ b/src/core/loader/elf.h @@ -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 diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index d8060c0e6..1a647d8a5 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -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
\ No newline at end of file +} // namespace Loader diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index 9d4aaa874..979003553 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h @@ -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 |