mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 10:42:36 +01:00
Added ELF32 little endian support for PSP ELF files.
This commit is contained in:
parent
f1b420eb3b
commit
198d0a2fc0
@ -1,6 +1,8 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "ELF32.h"
|
#include "ELF32.h"
|
||||||
|
|
||||||
|
bool isLittleEndian;
|
||||||
|
|
||||||
ELF32Loader::ELF32Loader(vfsStream& f)
|
ELF32Loader::ELF32Loader(vfsStream& f)
|
||||||
: elf32_f(f)
|
: elf32_f(f)
|
||||||
, LoaderBase()
|
, LoaderBase()
|
||||||
@ -36,13 +38,21 @@ bool ELF32Loader::Close()
|
|||||||
|
|
||||||
bool ELF32Loader::LoadEhdrInfo()
|
bool ELF32Loader::LoadEhdrInfo()
|
||||||
{
|
{
|
||||||
|
u8 endian;
|
||||||
|
elf32_f.Seek(5);
|
||||||
|
elf32_f.Read(&endian, 1);
|
||||||
|
isLittleEndian = (endian == 0x1);
|
||||||
|
|
||||||
|
elf32_f.Reset();
|
||||||
elf32_f.Seek(0);
|
elf32_f.Seek(0);
|
||||||
ehdr.Load(elf32_f);
|
if (isLittleEndian) ehdr.LoadLE(elf32_f);
|
||||||
|
else ehdr.Load(elf32_f);
|
||||||
|
|
||||||
if(!ehdr.CheckMagic()) return false;
|
if(!ehdr.CheckMagic()) return false;
|
||||||
|
|
||||||
switch(ehdr.e_machine)
|
switch(ehdr.e_machine)
|
||||||
{
|
{
|
||||||
|
case MACHINE_MIPS:
|
||||||
case MACHINE_PPC64:
|
case MACHINE_PPC64:
|
||||||
case MACHINE_SPU:
|
case MACHINE_SPU:
|
||||||
machine = (Elf_Machine)ehdr.e_machine;
|
machine = (Elf_Machine)ehdr.e_machine;
|
||||||
@ -76,7 +86,8 @@ bool ELF32Loader::LoadPhdrInfo()
|
|||||||
for(uint i=0; i<ehdr.e_phnum; ++i)
|
for(uint i=0; i<ehdr.e_phnum; ++i)
|
||||||
{
|
{
|
||||||
Elf32_Phdr* phdr = new Elf32_Phdr();
|
Elf32_Phdr* phdr = new Elf32_Phdr();
|
||||||
phdr->Load(elf32_f);
|
if(isLittleEndian) phdr->LoadLE(elf32_f);
|
||||||
|
else phdr->Load(elf32_f);
|
||||||
phdr_arr.Move(phdr);
|
phdr_arr.Move(phdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,13 +100,14 @@ bool ELF32Loader::LoadShdrInfo()
|
|||||||
for(u32 i=0; i<ehdr.e_shnum; ++i)
|
for(u32 i=0; i<ehdr.e_shnum; ++i)
|
||||||
{
|
{
|
||||||
Elf32_Shdr* shdr = new Elf32_Shdr();
|
Elf32_Shdr* shdr = new Elf32_Shdr();
|
||||||
shdr->Load(elf32_f);
|
if(isLittleEndian) shdr->LoadLE(elf32_f);
|
||||||
|
else shdr->Load(elf32_f);
|
||||||
shdr_arr.Move(shdr);
|
shdr_arr.Move(shdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ehdr.e_shstrndx >= shdr_arr.GetCount())
|
if(ehdr.e_shstrndx >= shdr_arr.GetCount())
|
||||||
{
|
{
|
||||||
ConLog.Error("LoadShdr64 error: shstrndx too big!");
|
ConLog.Error("LoadShdr32 error: shstrndx too big!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,8 +122,7 @@ bool ELF32Loader::LoadShdrInfo()
|
|||||||
if(c == 0) break;
|
if(c == 0) break;
|
||||||
name += c;
|
name += c;
|
||||||
}
|
}
|
||||||
|
shdr_name_arr.Add(name);
|
||||||
shdr_name_arr.Add(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -162,7 +173,8 @@ bool ELF32Loader::LoadPhdrData(u64 offset)
|
|||||||
{
|
{
|
||||||
elf32_f.Seek(phdr_arr[i].p_offset);
|
elf32_f.Seek(phdr_arr[i].p_offset);
|
||||||
Elf32_Note note;
|
Elf32_Note note;
|
||||||
note.Load(elf32_f);
|
if(isLittleEndian) note.LoadLE(elf32_f);
|
||||||
|
else note.Load(elf32_f);
|
||||||
|
|
||||||
if(note.type != 1)
|
if(note.type != 1)
|
||||||
{
|
{
|
||||||
|
@ -71,6 +71,29 @@ struct Elf32_Ehdr
|
|||||||
e_shstrndx = Read16(f);
|
e_shstrndx = Read16(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LoadLE(vfsStream& f)
|
||||||
|
{
|
||||||
|
e_magic = Read32(f);
|
||||||
|
e_class = Read8(f);
|
||||||
|
e_data = Read8(f);
|
||||||
|
e_curver = Read8(f);
|
||||||
|
e_os_abi = Read8(f);
|
||||||
|
e_abi_ver = Read64LE(f);
|
||||||
|
e_type = Read16LE(f);
|
||||||
|
e_machine = Read16LE(f);
|
||||||
|
e_version = Read32LE(f);
|
||||||
|
e_entry = Read32LE(f);
|
||||||
|
e_phoff = Read32LE(f);
|
||||||
|
e_shoff = Read32LE(f);
|
||||||
|
e_flags = Read32LE(f);
|
||||||
|
e_ehsize = Read16LE(f);
|
||||||
|
e_phentsize = Read16LE(f);
|
||||||
|
e_phnum = Read16LE(f);
|
||||||
|
e_shentsize = Read16LE(f);
|
||||||
|
e_shnum = Read16LE(f);
|
||||||
|
e_shstrndx = Read16LE(f);
|
||||||
|
}
|
||||||
|
|
||||||
bool CheckMagic() const { return e_magic == 0x7F454C46; }
|
bool CheckMagic() const { return e_magic == 0x7F454C46; }
|
||||||
u32 GetEntry() const { return e_entry; }
|
u32 GetEntry() const { return e_entry; }
|
||||||
};
|
};
|
||||||
@ -89,6 +112,14 @@ struct Elf32_Desc
|
|||||||
stack_size = Read32(f);
|
stack_size = Read32(f);
|
||||||
flags = Read32(f);
|
flags = Read32(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LoadLE(vfsStream& f)
|
||||||
|
{
|
||||||
|
revision = Read32LE(f);
|
||||||
|
ls_size = Read32LE(f);
|
||||||
|
stack_size = Read32LE(f);
|
||||||
|
flags = Read32LE(f);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Elf32_Note
|
struct Elf32_Note
|
||||||
@ -119,6 +150,23 @@ struct Elf32_Note
|
|||||||
desc.Load(f);
|
desc.Load(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LoadLE(vfsStream& f)
|
||||||
|
{
|
||||||
|
namesz = Read32LE(f);
|
||||||
|
descsz = Read32LE(f);
|
||||||
|
type = Read32LE(f);
|
||||||
|
f.Read(name, 8);
|
||||||
|
|
||||||
|
if(descsz == 32)
|
||||||
|
{
|
||||||
|
f.Read(desc_text, descsz);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
desc.Load(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Elf32_Shdr
|
struct Elf32_Shdr
|
||||||
@ -148,6 +196,20 @@ struct Elf32_Shdr
|
|||||||
sh_entsize = Read32(f);
|
sh_entsize = Read32(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LoadLE(vfsStream& f)
|
||||||
|
{
|
||||||
|
sh_name = Read32LE(f);
|
||||||
|
sh_type = Read32LE(f);
|
||||||
|
sh_flags = Read32LE(f);
|
||||||
|
sh_addr = Read32LE(f);
|
||||||
|
sh_offset = Read32LE(f);
|
||||||
|
sh_size = Read32LE(f);
|
||||||
|
sh_link = Read32LE(f);
|
||||||
|
sh_info = Read32LE(f);
|
||||||
|
sh_addralign = Read32LE(f);
|
||||||
|
sh_entsize = Read32LE(f);
|
||||||
|
}
|
||||||
|
|
||||||
void Show()
|
void Show()
|
||||||
{
|
{
|
||||||
#ifdef LOADER_DEBUG
|
#ifdef LOADER_DEBUG
|
||||||
@ -188,6 +250,18 @@ struct Elf32_Phdr
|
|||||||
p_align = Read32(f);
|
p_align = Read32(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LoadLE(vfsStream& f)
|
||||||
|
{
|
||||||
|
p_type = Read32LE(f);
|
||||||
|
p_offset = Read32LE(f);
|
||||||
|
p_vaddr = Read32LE(f);
|
||||||
|
p_paddr = Read32LE(f);
|
||||||
|
p_filesz = Read32LE(f);
|
||||||
|
p_memsz = Read32LE(f);
|
||||||
|
p_flags = Read32LE(f);
|
||||||
|
p_align = Read32LE(f);
|
||||||
|
}
|
||||||
|
|
||||||
void Show()
|
void Show()
|
||||||
{
|
{
|
||||||
#ifdef LOADER_DEBUG
|
#ifdef LOADER_DEBUG
|
||||||
|
@ -39,6 +39,7 @@ const wxString Ehdr_MachineToString(const u16 machine)
|
|||||||
{
|
{
|
||||||
switch(machine)
|
switch(machine)
|
||||||
{
|
{
|
||||||
|
case MACHINE_MIPS: return "MIPS";
|
||||||
case MACHINE_PPC64: return "PowerPC64";
|
case MACHINE_PPC64: return "PowerPC64";
|
||||||
case MACHINE_SPU: return "SPU";
|
case MACHINE_SPU: return "SPU";
|
||||||
};
|
};
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
enum Elf_Machine
|
enum Elf_Machine
|
||||||
{
|
{
|
||||||
MACHINE_Unknown,
|
MACHINE_Unknown,
|
||||||
|
MACHINE_MIPS = 0x08,
|
||||||
MACHINE_PPC64 = 0x15,
|
MACHINE_PPC64 = 0x15,
|
||||||
MACHINE_SPU = 0x17,
|
MACHINE_SPU = 0x17,
|
||||||
};
|
};
|
||||||
@ -58,6 +59,21 @@ __forceinline static u64 Read64(vfsStream& f)
|
|||||||
return ((u64)Read32(f) << 32) | (u64)Read32(f);
|
return ((u64)Read32(f) << 32) | (u64)Read32(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__forceinline static u16 Read16LE(vfsStream& f)
|
||||||
|
{
|
||||||
|
return ((u16)Read8(f) | ((u16)Read8(f) << 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
__forceinline static u32 Read32LE(vfsStream& f)
|
||||||
|
{
|
||||||
|
return Read16LE(f) | (Read16LE(f) << 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
__forceinline static u64 Read64LE(vfsStream& f)
|
||||||
|
{
|
||||||
|
return ((u64)Read32LE(f) | (u64)Read32LE(f) << 32);
|
||||||
|
}
|
||||||
|
|
||||||
__forceinline static void Write8(wxFile& f, const u8 data)
|
__forceinline static void Write8(wxFile& f, const u8 data)
|
||||||
{
|
{
|
||||||
f.Write(&data, 1);
|
f.Write(&data, 1);
|
||||||
@ -81,6 +97,24 @@ __forceinline static void Write64(wxFile& f, const u64 data)
|
|||||||
Write32(f, data);
|
Write32(f, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__forceinline static void Write16LE(wxFile& f, const u16 data)
|
||||||
|
{
|
||||||
|
Write8(f, data);
|
||||||
|
Write8(f, data >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
__forceinline static void Write32LE(wxFile& f, const u32 data)
|
||||||
|
{
|
||||||
|
Write16(f, data);
|
||||||
|
Write16(f, data >> 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
__forceinline static void Write64LE(wxFile& f, const u64 data)
|
||||||
|
{
|
||||||
|
Write32(f, data);
|
||||||
|
Write32(f, data >> 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const wxString Ehdr_DataToString(const u8 data);
|
const wxString Ehdr_DataToString(const u8 data);
|
||||||
const wxString Ehdr_TypeToString(const u16 type);
|
const wxString Ehdr_TypeToString(const u16 type);
|
||||||
|
Loading…
Reference in New Issue
Block a user