#include "stdafx.h" #include "ELF64.h" ELF64Loader::ELF64Loader(wxFile& f) : elf64_f(f) , LoaderBase() { } ELF64Loader::ELF64Loader(const wxString& path) : elf64_f(*new wxFile(path)) , LoaderBase() { } bool ELF64Loader::LoadInfo() { if(!elf64_f.IsOpened()) return false; if(!LoadEhdrInfo()) return false; if(!LoadPhdrInfo()) return false; if(!LoadShdrInfo()) return false; return true; } bool ELF64Loader::LoadData() { if(!elf64_f.IsOpened()) return false; if(!LoadEhdrData()) return false; if(!LoadPhdrData()) return false; if(!LoadShdrData()) return false; return true; } bool ELF64Loader::Close() { return elf64_f.Close(); } bool ELF64Loader::LoadEhdrInfo() { elf64_f.Seek(0); ehdr.Load(elf64_f); if(!ehdr.CheckMagic()) return false; if(ehdr.e_phentsize != sizeof(Elf64_Phdr)) { ConLog.Error("elf64 error: e_phentsize[0x%x] != sizeof(Elf64_Phdr)[0x%x]", ehdr.e_phentsize, sizeof(Elf64_Phdr)); return false; } if(ehdr.e_shentsize != sizeof(Elf64_Shdr)) { ConLog.Error("elf64 error: e_shentsize[0x%x] != sizeof(Elf64_Shdr)[0x%x]", ehdr.e_shentsize, sizeof(Elf64_Shdr)); return false; } switch(ehdr.e_machine) { case MACHINE_PPC64: case MACHINE_SPU: machine = (Elf_Machine)ehdr.e_machine; break; default: machine = MACHINE_Unknown; ConLog.Error("Unknown elf64 type: 0x%x", ehdr.e_machine); return false; } entry = ehdr.GetEntry(); if(entry == 0) { ConLog.Error("elf64 error: entry is null!"); return false; } return true; } bool ELF64Loader::LoadPhdrInfo() { phdr_arr.Clear(); if(ehdr.e_phoff == 0 && ehdr.e_phnum) { ConLog.Error("LoadPhdr64 error: Program header offset is null!"); return false; } elf64_f.Seek(ehdr.e_phoff); for(u32 i=0; i= shdr_arr.GetCount()) { ConLog.Error("LoadShdr64 error: shstrndx too big!"); return false; } for(u32 i=0; i max_addr) max_addr = shdr.sh_addr + shdr.sh_size; if((shdr.sh_flags & SHF_ALLOC) != SHF_ALLOC) continue; const u64 addr = shdr.sh_addr; const u64 size = shdr.sh_size; if(size == 0 || !Memory.IsGoodAddr(addr, size)) continue; switch(shdr.sh_type) { case SHT_NOBITS: memset(&Memory[addr], 0, size); break; case SHT_PROGBITS: /* elf64_f.Seek(shdr.sh_offset); elf64_f.Read(&Memory[addr], shdr.sh_size); */ break; } } return true; }