From 1da361c7ab55e1dbe6709a738e228bfab5a5bb78 Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 16 Jun 2014 23:05:10 -0400 Subject: Elf: Renamed modules to be consistent with new loader naming, fixed tabs -> spaces. --- src/core/loader/elf.cpp | 190 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 src/core/loader/elf.cpp (limited to 'src/core/loader/elf.cpp') diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp new file mode 100644 index 000000000..153c30f51 --- /dev/null +++ b/src/core/loader/elf.cpp @@ -0,0 +1,190 @@ +// Copyright 2013 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#include + +#include "common/common.h" + +#include "common/symbols.h" +#include "core/mem_map.h" +#include "core/loader/elf.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) +{ + 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); + + entryPoint = header->e_entry; + + LoadSymbols(); +} + +const char *ElfReader::GetSectionName(int section) const +{ + if (sections[section].sh_type == SHT_NULL) + return nullptr; + + int nameOffset = sections[section].sh_name; + char *ptr = (char*)GetSectionDataPtr(header->e_shstrndx); + + if (ptr) + return ptr + nameOffset; + else + return nullptr; +} + +bool ElfReader::LoadInto(u32 vaddr) +{ + DEBUG_LOG(MASTER_LOG, "String section: %i", header->e_shstrndx); + + // Should we relocate? + bRelocate = (header->e_type != ET_EXEC); + + if (bRelocate) + { + DEBUG_LOG(MASTER_LOG, "Relocatable module"); + entryPoint += vaddr; + } + else + { + DEBUG_LOG(MASTER_LOG, "Prerelocated executable"); + } + + INFO_LOG(MASTER_LOG, "%i segments:", header->e_phnum); + + // First pass : Get the bits into RAM + u32 segmentVAddr[32]; + + u32 baseAddress = bRelocate ? vaddr : 0; + + for (int i = 0; i < header->e_phnum; i++) + { + Elf32_Phdr *p = segments + i; + + INFO_LOG(MASTER_LOG, "Type: %i Vaddr: %08x Filesz: %i Memsz: %i ", p->p_type, p->p_vaddr, p->p_filesz, p->p_memsz); + + if (p->p_type == PT_LOAD) + { + segmentVAddr[i] = baseAddress + p->p_vaddr; + u32 writeAddr = segmentVAddr[i]; + + const u8 *src = GetSegmentPtr(i); + u8 *dst = Memory::GetPointer(writeAddr); + u32 srcSize = p->p_filesz; + u32 dstSize = p->p_memsz; + u32 *s = (u32*)src; + u32 *d = (u32*)dst; + for (int j = 0; j < (int)(srcSize + 3) / 4; j++) + { + *d++ = /*_byteswap_ulong*/(*s++); + } + if (srcSize < dstSize) + { + //memset(dst + srcSize, 0, dstSize-srcSize); //zero out bss + } + INFO_LOG(MASTER_LOG, "Loadable Segment Copied to %08x, size %08x", writeAddr, p->p_memsz); + } + } + + + INFO_LOG(MASTER_LOG, "Done loading."); + return true; +} + +SectionID ElfReader::GetSectionByName(const char *name, int firstSection) const +{ + for (int i = firstSection; i < header->e_shnum; i++) + { + const char *secname = GetSectionName(i); + + if (secname != nullptr && strcmp(name, secname) == 0) + return i; + } + return -1; +} + +bool ElfReader::LoadSymbols() +{ + bool hasSymbols = false; + SectionID sec = GetSectionByName(".symtab"); + if (sec != -1) + { + int stringSection = sections[sec].sh_link; + const char *stringBase = (const char *)GetSectionDataPtr(stringSection); + + //We have a symbol table! + Elf32_Sym *symtab = (Elf32_Sym *)(GetSectionDataPtr(sec)); + int numSymbols = sections[sec].sh_size / sizeof(Elf32_Sym); + for (int sym = 0; sym < numSymbols; sym++) + { + int size = symtab[sym].st_size; + if (size == 0) + continue; + + // int bind = symtab[sym].st_info >> 4; + int type = symtab[sym].st_info & 0xF; + + const char *name = stringBase + symtab[sym].st_name; + + Symbols::Add(symtab[sym].st_value, name, size, type); + + hasSymbols = true; + } + } + + return hasSymbols; +} -- cgit v1.2.3 From 13bdaa6c609a8718d4ce6ca3ce5f1e16f4d7c600 Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 16 Jun 2014 23:18:10 -0400 Subject: Loader: Cleaned up and removed unused code, refactored ELF namespace. --- src/core/loader/elf.cpp | 107 +++++++++++++++++++++++------------------------- 1 file changed, 51 insertions(+), 56 deletions(-) (limited to 'src/core/loader/elf.cpp') 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 #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 -- cgit v1.2.3 From 7889cafc76ac99b8509fa3cd1558a09f8a7e5f91 Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 18 Jun 2014 18:58:09 -0400 Subject: Loader: Implemented AppLoader interface for abstracting application loading. - Various cleanups/refactorings to Loader, ELF, and NCCH modules. - Added AppLoader interface to ELF and NCCH. - Updated Qt/GLFW frontends to check AppLoader ResultStatus. NCCH: Removed extra qualification typos. Loader: Removed unnecessary #include's. NCCH: Improved readability of memcmp statements. NCCH: Added missing space. Elf: Removed unnecessary usage of unique_ptr. Loader: Removed unnecessary usage of unique_ptr. --- src/core/loader/elf.cpp | 318 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 257 insertions(+), 61 deletions(-) (limited to 'src/core/loader/elf.cpp') diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index f93354817..065601546 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include #include "common/common.h" #include "common/file_util.h" @@ -12,6 +13,220 @@ #include "core/loader/elf.h" #include "core/hle/kernel/kernel.h" +//////////////////////////////////////////////////////////////////////////////////////////////////// +// ELF Header Constants + +// File type +enum ElfType { + 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_SPARC = 2, + EM_386 = 3, + EM_68K = 4, + EM_88K = 5, + EM_860 = 7, + EM_MIPS = 8 +}; + +// File version +#define EV_NONE 0 +#define EV_CURRENT 1 + +// Identification index +#define EI_MAG0 0 +#define EI_MAG1 1 +#define EI_MAG2 2 +#define EI_MAG3 3 +#define EI_CLASS 4 +#define EI_DATA 5 +#define EI_VERSION 6 +#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 +#define SHT_NULL 0 +#define SHT_PROGBITS 1 +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 +#define SHT_RELA 4 +#define SHT_HASH 5 +#define SHT_DYNAMIC 6 +#define SHT_NOTE 7 +#define SHT_NOBITS 8 +#define SHT_REL 9 +#define SHT_SHLIB 10 +#define SHT_DYNSYM 11 +#define SHT_LOPROC 0x70000000 +#define SHT_HIPROC 0x7FFFFFFF +#define SHT_LOUSER 0x80000000 +#define SHT_HIUSER 0xFFFFFFFF + +// Section flags +enum ElfSectionFlags +{ + SHF_WRITE = 0x1, + SHF_ALLOC = 0x2, + SHF_EXECINSTR = 0x4, + SHF_MASKPROC = 0xF0000000, +}; + +// Segment types +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 +#define PT_LOPROC 0x70000000 +#define PT_HIPROC 0x7FFFFFFF + +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; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// ELF file header + +struct Elf32_Ehdr { + unsigned char e_ident[EI_NIDENT]; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; +}; + +// Section header +struct Elf32_Shdr { + Elf32_Word sh_name; + Elf32_Word sh_type; + Elf32_Word sh_flags; + Elf32_Addr sh_addr; + Elf32_Off sh_offset; + Elf32_Word sh_size; + Elf32_Word sh_link; + Elf32_Word sh_info; + Elf32_Word sh_addralign; + Elf32_Word sh_entsize; +}; + +// Segment header +struct Elf32_Phdr { + Elf32_Word p_type; + Elf32_Off p_offset; + Elf32_Addr p_vaddr; + Elf32_Addr p_paddr; + Elf32_Word p_filesz; + Elf32_Word p_memsz; + Elf32_Word p_flags; + Elf32_Word p_align; +}; + +// Symbol table entry +struct Elf32_Sym { + Elf32_Word st_name; + Elf32_Addr st_value; + Elf32_Word st_size; + unsigned char st_info; + unsigned char st_other; + Elf32_Half st_shndx; +}; + +// Relocation entries +struct Elf32_Rel { + Elf32_Addr r_offset; + Elf32_Word r_info; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// ElfReader class + +typedef int SectionID; + +class ElfReader { +private: + char *base; + u32 *base32; + + Elf32_Ehdr *header; + Elf32_Phdr *segments; + Elf32_Shdr *sections; + + u32 *sectionAddrs; + bool relocate; + u32 entryPoint; + +public: + ElfReader(void *ptr); + ~ElfReader() { } + + u32 Read32(int off) const { return base32[off >> 2]; } + + // Quick accessors + ElfType GetType() const { return (ElfType)(header->e_type); } + 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); + bool LoadSymbols(); + + int GetNumSegments() const { return (int)(header->e_phnum); } + int GetNumSections() const { return (int)(header->e_shnum); } + const u8 *GetPtr(int offset) const { return (u8*)base + offset; } + const char *GetSectionName(int section) const; + const u8 *GetSectionDataPtr(int section) const { + if (section < 0 || section >= header->e_shnum) + return nullptr; + if (sections[section].sh_type != SHT_NOBITS) + return GetPtr(sections[section].sh_offset); + else + return nullptr; + } + bool IsCodeSection(int section) const { + return sections[section].sh_type == SHT_PROGBITS; + } + const u8 *GetSegmentPtr(int segment) { + return GetPtr(segments[segment].p_offset); + } + u32 GetSectionAddr(SectionID section) const { return sectionAddrs[section]; } + int GetSectionSize(SectionID section) const { return sections[section].sh_size; } + SectionID GetSectionByName(const char *name, int firstSection = 0) const; //-1 for not found + + bool DidRelocate() { + return relocate; + } +}; + ElfReader::ElfReader(void *ptr) { base = (char*)ptr; base32 = (u32 *)ptr; @@ -29,28 +244,25 @@ const char *ElfReader::GetSectionName(int section) const { if (sections[section].sh_type == SHT_NULL) return nullptr; - int nameOffset = sections[section].sh_name; + int name_offset = sections[section].sh_name; char *ptr = (char*)GetSectionDataPtr(header->e_shstrndx); if (ptr) - return ptr + nameOffset; - else - return nullptr; + return ptr + name_offset; + + return nullptr; } bool ElfReader::LoadInto(u32 vaddr) { DEBUG_LOG(MASTER_LOG, "String section: %i", header->e_shstrndx); // Should we relocate? - bRelocate = (header->e_type != ET_EXEC); + relocate = (header->e_type != ET_EXEC); - if (bRelocate) - { + if (relocate) { DEBUG_LOG(MASTER_LOG, "Relocatable module"); entryPoint += vaddr; - } - else - { + } else { DEBUG_LOG(MASTER_LOG, "Prerelocated executable"); } @@ -58,17 +270,14 @@ bool ElfReader::LoadInto(u32 vaddr) { // First pass : Get the bits into RAM u32 segmentVAddr[32]; + u32 baseAddress = relocate ? vaddr : 0; - u32 baseAddress = bRelocate ? vaddr : 0; - - for (int i = 0; i < header->e_phnum; i++) - { + for (int i = 0; i < header->e_phnum; i++) { Elf32_Phdr *p = segments + i; INFO_LOG(MASTER_LOG, "Type: %i Vaddr: %08x Filesz: %i Memsz: %i ", p->p_type, p->p_vaddr, p->p_filesz, p->p_memsz); - if (p->p_type == PT_LOAD) - { + if (p->p_type == PT_LOAD) { segmentVAddr[i] = baseAddress + p->p_vaddr; u32 writeAddr = segmentVAddr[i]; @@ -78,27 +287,19 @@ bool ElfReader::LoadInto(u32 vaddr) { u32 dstSize = p->p_memsz; u32 *s = (u32*)src; u32 *d = (u32*)dst; - for (int j = 0; j < (int)(srcSize + 3) / 4; j++) - { - *d++ = /*_byteswap_ulong*/(*s++); - } - if (srcSize < dstSize) - { - //memset(dst + srcSize, 0, dstSize-srcSize); //zero out bss + for (int j = 0; j < (int)(srcSize + 3) / 4; j++) { + *d++ = (*s++); } INFO_LOG(MASTER_LOG, "Loadable Segment Copied to %08x, size %08x", writeAddr, p->p_memsz); } } - INFO_LOG(MASTER_LOG, "Done loading."); return true; } -SectionID ElfReader::GetSectionByName(const char *name, int firstSection) const -{ - for (int i = firstSection; i < header->e_shnum; i++) - { +SectionID ElfReader::GetSectionByName(const char *name, int firstSection) const { + for (int i = firstSection; i < header->e_shnum; i++) { const char *secname = GetSectionName(i); if (secname != nullptr && strcmp(name, secname) == 0) @@ -107,25 +308,21 @@ SectionID ElfReader::GetSectionByName(const char *name, int firstSection) const return -1; } -bool ElfReader::LoadSymbols() -{ +bool ElfReader::LoadSymbols() { bool hasSymbols = false; SectionID sec = GetSectionByName(".symtab"); - if (sec != -1) - { + if (sec != -1) { int stringSection = sections[sec].sh_link; const char *stringBase = (const char *)GetSectionDataPtr(stringSection); //We have a symbol table! Elf32_Sym *symtab = (Elf32_Sym *)(GetSectionDataPtr(sec)); int numSymbols = sections[sec].sh_size / sizeof(Elf32_Sym); - for (int sym = 0; sym < numSymbols; sym++) - { + for (int sym = 0; sym < numSymbols; sym++) { int size = symtab[sym].st_size; if (size == 0) continue; - // int bind = symtab[sym].st_info >> 4; int type = symtab[sym].st_info & 0xF; const char *name = stringBase + symtab[sym].st_name; @@ -144,42 +341,41 @@ bool ElfReader::LoadSymbols() namespace Loader { +/// AppLoader_ELF constructor +AppLoader_ELF::AppLoader_ELF(std::string& filename) : is_loaded(false) { + this->filename = filename; +} + +/// AppLoader_NCCH destructor +AppLoader_ELF::~AppLoader_ELF() { +} + /** - * Loads an ELF file - * @param filename String filename of ELF file + * 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 */ -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"); +const ResultStatus AppLoader_ELF::Load() { + INFO_LOG(LOADER, "Loading ELF file %s...", filename.c_str()); - if (f.IsOpen()) { - u32 size = (u32)f.GetSize(); - u8* buffer = new u8[size]; - ElfReader* elf_reader = NULL; + if (is_loaded) + return ResultStatus::ErrorAlreadyLoaded; - f.ReadBytes(buffer, size); + File::IOFile file(filename, "rb"); - elf_reader = new ElfReader(buffer); - elf_reader->LoadInto(0x00100000); + if (file.IsOpen()) { + u32 size = (u32)file.GetSize(); + std::unique_ptr buffer(new u8[size]); + file.ReadBytes(&buffer[0], size); - Kernel::LoadExec(elf_reader->GetEntryPoint()); - - delete[] buffer; - delete elf_reader; + ElfReader elf_reader(&buffer[0]); + elf_reader.LoadInto(0x00100000); + Kernel::LoadExec(elf_reader.GetEntryPoint()); } else { - *error_string = "Unable to open ELF file!"; - return false; + return ResultStatus::Error; } - f.Close(); - - return true; + return ResultStatus::Success; } } // namespace Loader -- cgit v1.2.3 From 62b444cd17c17e6f8009d87609b620bcb51b43bd Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 19 Jun 2014 17:46:05 -0400 Subject: Loader: Refactored use of const. --- src/core/loader/elf.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/core/loader/elf.cpp') diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index 065601546..d9e5e130f 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -342,7 +342,7 @@ bool ElfReader::LoadSymbols() { namespace Loader { /// AppLoader_ELF constructor -AppLoader_ELF::AppLoader_ELF(std::string& filename) : is_loaded(false) { +AppLoader_ELF::AppLoader_ELF(const std::string& filename) : is_loaded(false) { this->filename = filename; } @@ -356,7 +356,7 @@ AppLoader_ELF::~AppLoader_ELF() { * @todo Move NCSD parsing out of here and create a separate function for loading these * @return True on success, otherwise false */ -const ResultStatus AppLoader_ELF::Load() { +ResultStatus AppLoader_ELF::Load() { INFO_LOG(LOADER, "Loading ELF file %s...", filename.c_str()); if (is_loaded) -- cgit v1.2.3 From cedc28dcc654961c419ad916cf56f18b0f94e7f5 Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 19 Jun 2014 17:52:15 -0400 Subject: ELF: Refactored LoadInto(..) to use memcpy, removed unnecessary code. --- src/core/loader/elf.cpp | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) (limited to 'src/core/loader/elf.cpp') diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index d9e5e130f..76c9d6d54 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -265,35 +265,24 @@ bool ElfReader::LoadInto(u32 vaddr) { } else { DEBUG_LOG(MASTER_LOG, "Prerelocated executable"); } - INFO_LOG(MASTER_LOG, "%i segments:", header->e_phnum); // First pass : Get the bits into RAM - u32 segmentVAddr[32]; - u32 baseAddress = relocate ? vaddr : 0; + u32 segment_addr[32]; + u32 base_addr = relocate ? vaddr : 0; for (int i = 0; i < header->e_phnum; i++) { Elf32_Phdr *p = segments + i; - - INFO_LOG(MASTER_LOG, "Type: %i Vaddr: %08x Filesz: %i Memsz: %i ", p->p_type, p->p_vaddr, p->p_filesz, p->p_memsz); + INFO_LOG(MASTER_LOG, "Type: %i Vaddr: %08x Filesz: %i Memsz: %i ", p->p_type, p->p_vaddr, + p->p_filesz, p->p_memsz); if (p->p_type == PT_LOAD) { - segmentVAddr[i] = baseAddress + p->p_vaddr; - u32 writeAddr = segmentVAddr[i]; - - const u8 *src = GetSegmentPtr(i); - u8 *dst = Memory::GetPointer(writeAddr); - u32 srcSize = p->p_filesz; - u32 dstSize = p->p_memsz; - u32 *s = (u32*)src; - u32 *d = (u32*)dst; - for (int j = 0; j < (int)(srcSize + 3) / 4; j++) { - *d++ = (*s++); - } - INFO_LOG(MASTER_LOG, "Loadable Segment Copied to %08x, size %08x", writeAddr, p->p_memsz); + segment_addr[i] = base_addr + p->p_vaddr; + memcpy(Memory::GetPointer(segment_addr[i]), GetSegmentPtr(i), p->p_filesz); + INFO_LOG(MASTER_LOG, "Loadable Segment Copied to %08x, size %08x", segment_addr[i], + p->p_memsz); } } - INFO_LOG(MASTER_LOG, "Done loading."); return true; } -- cgit v1.2.3