mirror of
https://github.com/yuzu-emu/yuzu.git
synced 2024-08-23 17:07:19 +02:00
Loader: Clean up the ELF AppLoader.
This commit is contained in:
parent
84e52a944d
commit
df0d66c7cf
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user