From 43e699d849ac5dd7a29ff0eeb5821e2a824c091e Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Tue, 6 Jan 2015 23:36:48 +0000 Subject: =?UTF-8?q?Loader:=20Don=E2=80=99t=20duplicate=20the=20docstring?= =?UTF-8?q?=20into=20the=20cpp=20file.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/loader/elf.cpp | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src/core/loader/elf.cpp') diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index 3ca60c072..89664229a 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -339,12 +339,6 @@ AppLoader_ELF::AppLoader_ELF(const std::string& filename) : is_loaded(false) { AppLoader_ELF::~AppLoader_ELF() { } -/** - * Loads an NCCH file (e.g. from a CCI, or the first NCCH in a CXI) - * @param error_string Pointer to string to put error message if an error has occurred - * @todo Move NCSD parsing out of here and create a separate function for loading these - * @return True on success, otherwise false - */ ResultStatus AppLoader_ELF::Load() { LOG_INFO(Loader, "Loading ELF file %s...", filename.c_str()); -- cgit v1.2.3 From 85030c6e6bfe83b6671de45b25535fe3ef713319 Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Tue, 6 Jan 2015 19:49:25 +0000 Subject: Loader: Never forget to change is_loaded. --- src/core/loader/elf.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/core/loader/elf.cpp') diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index 89664229a..ee711d8b2 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -331,7 +331,7 @@ bool ElfReader::LoadSymbols() { namespace Loader { /// AppLoader_ELF constructor -AppLoader_ELF::AppLoader_ELF(const std::string& filename) : is_loaded(false) { +AppLoader_ELF::AppLoader_ELF(const std::string& filename) { this->filename = filename; } @@ -358,6 +358,8 @@ ResultStatus AppLoader_ELF::Load() { } else { return ResultStatus::Error; } + + is_loaded = true; return ResultStatus::Success; } -- cgit v1.2.3 From b5237e885df72f6c37532fc8af9573966e7b07e5 Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Tue, 6 Jan 2015 21:30:40 +0000 Subject: Loader: Keep a reference to the file and pass it to the correct AppLoader, instead of loading it multiple times. --- src/core/loader/elf.cpp | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-) (limited to 'src/core/loader/elf.cpp') diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index ee711d8b2..d1a1ef595 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -330,34 +330,20 @@ bool ElfReader::LoadSymbols() { namespace Loader { -/// AppLoader_ELF constructor -AppLoader_ELF::AppLoader_ELF(const std::string& filename) { - this->filename = filename; -} - -/// AppLoader_NCCH destructor -AppLoader_ELF::~AppLoader_ELF() { -} - ResultStatus AppLoader_ELF::Load() { - LOG_INFO(Loader, "Loading ELF file %s...", filename.c_str()); - if (is_loaded) return ResultStatus::ErrorAlreadyLoaded; - FileUtil::IOFile file(filename, "rb"); + if (!file->IsOpen()) + return ResultStatus::Error; - if (file.IsOpen()) { - u32 size = (u32)file.GetSize(); - std::unique_ptr buffer(new u8[size]); - file.ReadBytes(&buffer[0], size); + u32 size = static_cast(file->GetSize()); + std::unique_ptr buffer(new u8[size]); + file->ReadBytes(&buffer[0], size); - ElfReader elf_reader(&buffer[0]); - elf_reader.LoadInto(0x00100000); - Kernel::LoadExec(elf_reader.GetEntryPoint()); - } else { - return ResultStatus::Error; - } + ElfReader elf_reader(&buffer[0]); + elf_reader.LoadInto(0x00100000); + Kernel::LoadExec(elf_reader.GetEntryPoint()); is_loaded = true; return ResultStatus::Success; -- cgit v1.2.3 From 04622a859cc748745cbbeb0b332f930085438077 Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Tue, 6 Jan 2015 22:47:43 +0000 Subject: =?UTF-8?q?Loader:=20Don=E2=80=99t=20assume=20the=20file=20hasn?= =?UTF-8?q?=E2=80=99t=20been=20read=20before.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/loader/elf.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/core/loader/elf.cpp') diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index d1a1ef595..712d564d1 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -337,6 +337,9 @@ ResultStatus AppLoader_ELF::Load() { if (!file->IsOpen()) return ResultStatus::Error; + // Reset read pointer in case this file has been read before. + file->Seek(0, SEEK_SET); + u32 size = static_cast(file->GetSize()); std::unique_ptr buffer(new u8[size]); file->ReadBytes(&buffer[0], size); -- cgit v1.2.3 From 82ec17db7df53ed1c376d1cdaa9a6587719a546d Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Tue, 6 Jan 2015 23:10:13 +0000 Subject: Loader: Guess filetype from the magic, or fallback to the extension. --- src/core/loader/elf.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/core/loader/elf.cpp') diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index 712d564d1..d1c3aea72 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -330,6 +330,18 @@ bool ElfReader::LoadSymbols() { namespace Loader { +FileType AppLoader_ELF::IdentifyType(FileUtil::IOFile& file) { + u32 magic; + file.Seek(0, SEEK_SET); + if (1 != file.ReadArray(&magic, 1)) + return FileType::Error; + + if (MakeMagic('\x7f', 'E', 'L', 'F') == magic) + return FileType::ELF; + + return FileType::Error; +} + ResultStatus AppLoader_ELF::Load() { if (is_loaded) return ResultStatus::ErrorAlreadyLoaded; -- cgit v1.2.3 From df0d66c7cf518638112843b0bf0a8d7950b9041c Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Wed, 7 Jan 2015 01:30:32 +0000 Subject: Loader: Clean up the ELF AppLoader. --- src/core/loader/elf.cpp | 73 ++++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 40 deletions(-) (limited to 'src/core/loader/elf.cpp') diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index d1c3aea72..e7e5df408 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -18,25 +18,25 @@ // File type enum ElfType { - ET_NONE = 0, - ET_REL = 1, - ET_EXEC = 2, - ET_DYN = 3, - ET_CORE = 4, + ET_NONE = 0, + ET_REL = 1, + ET_EXEC = 2, + ET_DYN = 3, + ET_CORE = 4, ET_LOPROC = 0xFF00, ET_HIPROC = 0xFFFF, }; // Machine/Architecture enum ElfMachine { - EM_NONE = 0, - EM_M32 = 1, + EM_NONE = 0, + EM_M32 = 1, EM_SPARC = 2, - EM_386 = 3, - EM_68K = 4, - EM_88K = 5, - EM_860 = 7, - EM_MIPS = 8 + EM_386 = 3, + EM_68K = 4, + EM_88K = 5, + EM_860 = 7, + EM_MIPS = 8 }; // File version @@ -54,12 +54,6 @@ enum ElfMachine { #define EI_PAD 7 #define EI_NIDENT 16 -// Magic number -#define ELFMAG0 0x7F -#define ELFMAG1 'E' -#define ELFMAG2 'L' -#define ELFMAG3 'F' - // Sections constants // Section types @@ -83,10 +77,10 @@ enum ElfMachine { // Section flags enum ElfSectionFlags { - SHF_WRITE = 0x1, - SHF_ALLOC = 0x2, + SHF_WRITE = 0x1, + SHF_ALLOC = 0x2, SHF_EXECINSTR = 0x4, - SHF_MASKPROC = 0xF0000000, + SHF_MASKPROC = 0xF0000000, }; // Segment types @@ -100,11 +94,11 @@ enum ElfSectionFlags #define PT_LOPROC 0x70000000 #define PT_HIPROC 0x7FFFFFFF -typedef unsigned int Elf32_Addr; +typedef unsigned int Elf32_Addr; typedef unsigned short Elf32_Half; -typedef unsigned int Elf32_Off; -typedef signed int Elf32_Sword; -typedef unsigned int Elf32_Word; +typedef unsigned int Elf32_Off; +typedef signed int Elf32_Sword; +typedef unsigned int Elf32_Word; //////////////////////////////////////////////////////////////////////////////////////////////////// // ELF file header @@ -188,7 +182,6 @@ private: public: ElfReader(void *ptr); - ~ElfReader() { } u32 Read32(int off) const { return base32[off >> 2]; } @@ -197,7 +190,7 @@ public: ElfMachine GetMachine() const { return (ElfMachine)(header->e_machine); } u32 GetEntryPoint() const { return entryPoint; } u32 GetFlags() const { return (u32)(header->e_flags); } - bool LoadInto(u32 vaddr); + void LoadInto(u32 vaddr); bool LoadSymbols(); int GetNumSegments() const { return (int)(header->e_phnum); } @@ -229,11 +222,11 @@ public: ElfReader::ElfReader(void *ptr) { base = (char*)ptr; - base32 = (u32 *)ptr; + base32 = (u32*)ptr; header = (Elf32_Ehdr*)ptr; - segments = (Elf32_Phdr *)(base + header->e_phoff); - sections = (Elf32_Shdr *)(base + header->e_shoff); + segments = (Elf32_Phdr*)(base + header->e_phoff); + sections = (Elf32_Shdr*)(base + header->e_shoff); entryPoint = header->e_entry; @@ -245,7 +238,7 @@ const char *ElfReader::GetSectionName(int section) const { return nullptr; int name_offset = sections[section].sh_name; - char *ptr = (char*)GetSectionDataPtr(header->e_shstrndx); + const char* ptr = (char*)GetSectionDataPtr(header->e_shstrndx); if (ptr) return ptr + name_offset; @@ -253,7 +246,7 @@ const char *ElfReader::GetSectionName(int section) const { return nullptr; } -bool ElfReader::LoadInto(u32 vaddr) { +void ElfReader::LoadInto(u32 vaddr) { LOG_DEBUG(Loader, "String section: %i", header->e_shstrndx); // Should we relocate? @@ -271,20 +264,19 @@ bool ElfReader::LoadInto(u32 vaddr) { u32 segment_addr[32]; u32 base_addr = relocate ? vaddr : 0; - for (int i = 0; i < header->e_phnum; i++) { - Elf32_Phdr *p = segments + i; + for (unsigned i = 0; i < header->e_phnum; i++) { + Elf32_Phdr* p = segments + i; LOG_DEBUG(Loader, "Type: %i Vaddr: %08x Filesz: %i Memsz: %i ", p->p_type, p->p_vaddr, - p->p_filesz, p->p_memsz); + p->p_filesz, p->p_memsz); if (p->p_type == PT_LOAD) { segment_addr[i] = base_addr + p->p_vaddr; memcpy(Memory::GetPointer(segment_addr[i]), GetSegmentPtr(i), p->p_filesz); LOG_DEBUG(Loader, "Loadable Segment Copied to %08x, size %08x", segment_addr[i], - p->p_memsz); + p->p_memsz); } } LOG_DEBUG(Loader, "Done loading."); - return true; } SectionID ElfReader::GetSectionByName(const char *name, int firstSection) const { @@ -305,9 +297,9 @@ bool ElfReader::LoadSymbols() { const char *stringBase = (const char *)GetSectionDataPtr(stringSection); //We have a symbol table! - Elf32_Sym *symtab = (Elf32_Sym *)(GetSectionDataPtr(sec)); + Elf32_Sym* symtab = (Elf32_Sym *)(GetSectionDataPtr(sec)); int numSymbols = sections[sec].sh_size / sizeof(Elf32_Sym); - for (int sym = 0; sym < numSymbols; sym++) { + for (unsigned sym = 0; sym < numSymbols; sym++) { int size = symtab[sym].st_size; if (size == 0) continue; @@ -354,7 +346,8 @@ ResultStatus AppLoader_ELF::Load() { u32 size = static_cast(file->GetSize()); std::unique_ptr buffer(new u8[size]); - file->ReadBytes(&buffer[0], size); + if (file->ReadBytes(&buffer[0], size) != size) + return ResultStatus::Error; ElfReader elf_reader(&buffer[0]); elf_reader.LoadInto(0x00100000); -- cgit v1.2.3