Loader: Clean up the ELF AppLoader.

This commit is contained in:
Emmanuel Gil Peyrot 2015-01-07 01:30:32 +00:00
parent 84e52a944d
commit df0d66c7cf
2 changed files with 35 additions and 42 deletions

View file

@ -130,7 +130,7 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr)
// Read the relocation headers // Read the relocation headers
u32* relocs = (u32*)(loadinfo.seg_ptrs[2] + hdr.data_seg_size); u32* relocs = (u32*)(loadinfo.seg_ptrs[2] + hdr.data_seg_size);
for (unsigned current_segment = 0; current_segment < 3; current_segment++) { for (unsigned current_segment : {0, 1, 2}) {
size_t size = n_reloc_tables * 4; size_t size = n_reloc_tables * 4;
if (file.ReadBytes(&relocs[current_segment * n_reloc_tables], size) != size) if (file.ReadBytes(&relocs[current_segment * n_reloc_tables], size) != size)
return ERROR_READ; return ERROR_READ;
@ -148,7 +148,7 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr)
memset((char*)loadinfo.seg_ptrs[2] + hdr.data_seg_size - hdr.bss_size, 0, hdr.bss_size); memset((char*)loadinfo.seg_ptrs[2] + hdr.data_seg_size - hdr.bss_size, 0, hdr.bss_size);
// Relocate the segments // Relocate the segments
for (unsigned current_segment = 0; current_segment < 3; current_segment++) { for (unsigned current_segment : {0, 1, 2}) {
for (unsigned current_segment_reloc_table = 0; current_segment_reloc_table < n_reloc_tables; current_segment_reloc_table++) { for (unsigned current_segment_reloc_table = 0; current_segment_reloc_table < n_reloc_tables; current_segment_reloc_table++) {
u32 n_relocs = relocs[current_segment * n_reloc_tables + current_segment_reloc_table]; u32 n_relocs = relocs[current_segment * n_reloc_tables + current_segment_reloc_table];
if (current_segment_reloc_table >= 2) { if (current_segment_reloc_table >= 2) {

View file

@ -18,25 +18,25 @@
// File type // File type
enum ElfType { enum ElfType {
ET_NONE = 0, ET_NONE = 0,
ET_REL = 1, ET_REL = 1,
ET_EXEC = 2, ET_EXEC = 2,
ET_DYN = 3, ET_DYN = 3,
ET_CORE = 4, ET_CORE = 4,
ET_LOPROC = 0xFF00, ET_LOPROC = 0xFF00,
ET_HIPROC = 0xFFFF, ET_HIPROC = 0xFFFF,
}; };
// Machine/Architecture // Machine/Architecture
enum ElfMachine { enum ElfMachine {
EM_NONE = 0, EM_NONE = 0,
EM_M32 = 1, EM_M32 = 1,
EM_SPARC = 2, EM_SPARC = 2,
EM_386 = 3, EM_386 = 3,
EM_68K = 4, EM_68K = 4,
EM_88K = 5, EM_88K = 5,
EM_860 = 7, EM_860 = 7,
EM_MIPS = 8 EM_MIPS = 8
}; };
// File version // File version
@ -54,12 +54,6 @@ enum ElfMachine {
#define EI_PAD 7 #define EI_PAD 7
#define EI_NIDENT 16 #define EI_NIDENT 16
// Magic number
#define ELFMAG0 0x7F
#define ELFMAG1 'E'
#define ELFMAG2 'L'
#define ELFMAG3 'F'
// Sections constants // Sections constants
// Section types // Section types
@ -83,10 +77,10 @@ enum ElfMachine {
// Section flags // Section flags
enum ElfSectionFlags enum ElfSectionFlags
{ {
SHF_WRITE = 0x1, SHF_WRITE = 0x1,
SHF_ALLOC = 0x2, SHF_ALLOC = 0x2,
SHF_EXECINSTR = 0x4, SHF_EXECINSTR = 0x4,
SHF_MASKPROC = 0xF0000000, SHF_MASKPROC = 0xF0000000,
}; };
// Segment types // Segment types
@ -100,11 +94,11 @@ enum ElfSectionFlags
#define PT_LOPROC 0x70000000 #define PT_LOPROC 0x70000000
#define PT_HIPROC 0x7FFFFFFF #define PT_HIPROC 0x7FFFFFFF
typedef unsigned int Elf32_Addr; typedef unsigned int Elf32_Addr;
typedef unsigned short Elf32_Half; typedef unsigned short Elf32_Half;
typedef unsigned int Elf32_Off; typedef unsigned int Elf32_Off;
typedef signed int Elf32_Sword; typedef signed int Elf32_Sword;
typedef unsigned int Elf32_Word; typedef unsigned int Elf32_Word;
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
// ELF file header // ELF file header
@ -188,7 +182,6 @@ private:
public: public:
ElfReader(void *ptr); ElfReader(void *ptr);
~ElfReader() { }
u32 Read32(int off) const { return base32[off >> 2]; } u32 Read32(int off) const { return base32[off >> 2]; }
@ -197,7 +190,7 @@ public:
ElfMachine GetMachine() const { return (ElfMachine)(header->e_machine); } ElfMachine GetMachine() const { return (ElfMachine)(header->e_machine); }
u32 GetEntryPoint() const { return entryPoint; } u32 GetEntryPoint() const { return entryPoint; }
u32 GetFlags() const { return (u32)(header->e_flags); } u32 GetFlags() const { return (u32)(header->e_flags); }
bool LoadInto(u32 vaddr); void LoadInto(u32 vaddr);
bool LoadSymbols(); bool LoadSymbols();
int GetNumSegments() const { return (int)(header->e_phnum); } int GetNumSegments() const { return (int)(header->e_phnum); }
@ -229,11 +222,11 @@ public:
ElfReader::ElfReader(void *ptr) { ElfReader::ElfReader(void *ptr) {
base = (char*)ptr; base = (char*)ptr;
base32 = (u32 *)ptr; base32 = (u32*)ptr;
header = (Elf32_Ehdr*)ptr; header = (Elf32_Ehdr*)ptr;
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);
entryPoint = header->e_entry; entryPoint = header->e_entry;
@ -245,7 +238,7 @@ const char *ElfReader::GetSectionName(int section) const {
return nullptr; return nullptr;
int name_offset = sections[section].sh_name; int name_offset = sections[section].sh_name;
char *ptr = (char*)GetSectionDataPtr(header->e_shstrndx); const char* ptr = (char*)GetSectionDataPtr(header->e_shstrndx);
if (ptr) if (ptr)
return ptr + name_offset; return ptr + name_offset;
@ -253,7 +246,7 @@ const char *ElfReader::GetSectionName(int section) const {
return nullptr; return nullptr;
} }
bool ElfReader::LoadInto(u32 vaddr) { void ElfReader::LoadInto(u32 vaddr) {
LOG_DEBUG(Loader, "String section: %i", header->e_shstrndx); LOG_DEBUG(Loader, "String section: %i", header->e_shstrndx);
// Should we relocate? // Should we relocate?
@ -271,20 +264,19 @@ bool ElfReader::LoadInto(u32 vaddr) {
u32 segment_addr[32]; u32 segment_addr[32];
u32 base_addr = relocate ? vaddr : 0; u32 base_addr = relocate ? vaddr : 0;
for (int i = 0; i < header->e_phnum; i++) { for (unsigned i = 0; i < header->e_phnum; i++) {
Elf32_Phdr *p = segments + i; Elf32_Phdr* p = segments + i;
LOG_DEBUG(Loader, "Type: %i Vaddr: %08x Filesz: %i Memsz: %i ", p->p_type, p->p_vaddr, 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) { if (p->p_type == PT_LOAD) {
segment_addr[i] = base_addr + p->p_vaddr; segment_addr[i] = base_addr + p->p_vaddr;
memcpy(Memory::GetPointer(segment_addr[i]), GetSegmentPtr(i), p->p_filesz); memcpy(Memory::GetPointer(segment_addr[i]), GetSegmentPtr(i), p->p_filesz);
LOG_DEBUG(Loader, "Loadable Segment Copied to %08x, size %08x", segment_addr[i], LOG_DEBUG(Loader, "Loadable Segment Copied to %08x, size %08x", segment_addr[i],
p->p_memsz); p->p_memsz);
} }
} }
LOG_DEBUG(Loader, "Done loading."); LOG_DEBUG(Loader, "Done loading.");
return true;
} }
SectionID ElfReader::GetSectionByName(const char *name, int firstSection) const { SectionID ElfReader::GetSectionByName(const char *name, int firstSection) const {
@ -305,9 +297,9 @@ bool ElfReader::LoadSymbols() {
const char *stringBase = (const char *)GetSectionDataPtr(stringSection); const char *stringBase = (const char *)GetSectionDataPtr(stringSection);
//We have a symbol table! //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); 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; int size = symtab[sym].st_size;
if (size == 0) if (size == 0)
continue; continue;
@ -354,7 +346,8 @@ ResultStatus AppLoader_ELF::Load() {
u32 size = static_cast<u32>(file->GetSize()); u32 size = static_cast<u32>(file->GetSize());
std::unique_ptr<u8[]> buffer(new u8[size]); std::unique_ptr<u8[]> buffer(new u8[size]);
file->ReadBytes(&buffer[0], size); if (file->ReadBytes(&buffer[0], size) != size)
return ResultStatus::Error;
ElfReader elf_reader(&buffer[0]); ElfReader elf_reader(&buffer[0]);
elf_reader.LoadInto(0x00100000); elf_reader.LoadInto(0x00100000);