mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-11 09:18:40 +12:00
- Improved sc function binder.
- Improved GLGSRender.
This commit is contained in:
parent
3bb7a299ca
commit
5753edf6ef
133 changed files with 13624 additions and 3898 deletions
|
@ -1,18 +1,14 @@
|
|||
#include "stdafx.h"
|
||||
#include "ELF64.h"
|
||||
#include "Gui/CompilerELF.h"
|
||||
using namespace PPU_opcodes;
|
||||
|
||||
ELF64Loader::ELF64Loader(wxFile& f)
|
||||
ELF64Loader::ELF64Loader(vfsStream& 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;
|
||||
|
@ -24,13 +20,13 @@ bool ELF64Loader::LoadInfo()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ELF64Loader::LoadData()
|
||||
bool ELF64Loader::LoadData(u64 offset)
|
||||
{
|
||||
if(!elf64_f.IsOpened()) return false;
|
||||
|
||||
if(!LoadEhdrData()) return false;
|
||||
if(!LoadPhdrData()) return false;
|
||||
if(!LoadShdrData()) return false;
|
||||
if(!LoadEhdrData(offset)) return false;
|
||||
if(!LoadPhdrData(offset)) return false;
|
||||
if(!LoadShdrData(offset)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -40,9 +36,9 @@ bool ELF64Loader::Close()
|
|||
return elf64_f.Close();
|
||||
}
|
||||
|
||||
bool ELF64Loader::LoadEhdrInfo()
|
||||
bool ELF64Loader::LoadEhdrInfo(s64 offset)
|
||||
{
|
||||
elf64_f.Seek(0);
|
||||
elf64_f.Seek(offset < 0 ? 0 : offset);
|
||||
ehdr.Load(elf64_f);
|
||||
|
||||
if(!ehdr.CheckMagic()) return false;
|
||||
|
@ -82,7 +78,7 @@ bool ELF64Loader::LoadEhdrInfo()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ELF64Loader::LoadPhdrInfo()
|
||||
bool ELF64Loader::LoadPhdrInfo(s64 offset)
|
||||
{
|
||||
phdr_arr.Clear();
|
||||
|
||||
|
@ -92,18 +88,19 @@ bool ELF64Loader::LoadPhdrInfo()
|
|||
return false;
|
||||
}
|
||||
|
||||
elf64_f.Seek(ehdr.e_phoff);
|
||||
elf64_f.Seek(offset < 0 ? ehdr.e_phoff : offset);
|
||||
|
||||
for(u32 i=0; i<ehdr.e_phnum; ++i)
|
||||
{
|
||||
Elf64_Phdr phdr;
|
||||
phdr.Load(elf64_f);
|
||||
phdr_arr.AddCpy(phdr);
|
||||
Elf64_Phdr* phdr = new Elf64_Phdr();
|
||||
phdr->Load(elf64_f);
|
||||
phdr_arr.Move(phdr);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ELF64Loader::LoadShdrInfo()
|
||||
bool ELF64Loader::LoadShdrInfo(s64 offset)
|
||||
{
|
||||
shdr_arr.Clear();
|
||||
shdr_name_arr.Clear();
|
||||
|
@ -113,12 +110,12 @@ bool ELF64Loader::LoadShdrInfo()
|
|||
return false;
|
||||
}
|
||||
|
||||
elf64_f.Seek(ehdr.e_shoff);
|
||||
elf64_f.Seek(offset < 0 ? ehdr.e_shoff : offset);
|
||||
for(u32 i=0; i<ehdr.e_shnum; ++i)
|
||||
{
|
||||
Elf64_Shdr shdr;
|
||||
shdr.Load(elf64_f);
|
||||
shdr_arr.AddCpy(shdr);
|
||||
Elf64_Shdr* shdr = new Elf64_Shdr();
|
||||
shdr->Load(elf64_f);
|
||||
shdr_arr.Move(shdr);
|
||||
}
|
||||
|
||||
if(ehdr.e_shstrndx >= shdr_arr.GetCount())
|
||||
|
@ -129,7 +126,7 @@ bool ELF64Loader::LoadShdrInfo()
|
|||
|
||||
for(u32 i=0; i<shdr_arr.GetCount(); ++i)
|
||||
{
|
||||
elf64_f.Seek(shdr_arr[ehdr.e_shstrndx].sh_offset + shdr_arr[i].sh_name);
|
||||
elf64_f.Seek((offset < 0 ? shdr_arr[ehdr.e_shstrndx].sh_offset : shdr_arr[ehdr.e_shstrndx].sh_offset - ehdr.e_shoff + offset) + shdr_arr[i].sh_name);
|
||||
wxString name = wxEmptyString;
|
||||
while(!elf64_f.Eof())
|
||||
{
|
||||
|
@ -145,7 +142,7 @@ bool ELF64Loader::LoadShdrInfo()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ELF64Loader::LoadEhdrData()
|
||||
bool ELF64Loader::LoadEhdrData(u64 offset)
|
||||
{
|
||||
#ifdef LOADER_DEBUG
|
||||
ConLog.SkipLn();
|
||||
|
@ -155,10 +152,8 @@ bool ELF64Loader::LoadEhdrData()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ELF64Loader::LoadPhdrData()
|
||||
bool ELF64Loader::LoadPhdrData(u64 offset)
|
||||
{
|
||||
Memory.MemFlags.Clear();
|
||||
|
||||
for(u32 i=0; i<phdr_arr.GetCount(); ++i)
|
||||
{
|
||||
phdr_arr[i].Show();
|
||||
|
@ -172,10 +167,10 @@ bool ELF64Loader::LoadPhdrData()
|
|||
);
|
||||
}
|
||||
|
||||
if(!Memory.MainMem.IsInMyRange(phdr_arr[i].p_vaddr, phdr_arr[i].p_memsz))
|
||||
if(!Memory.MainMem.IsInMyRange(offset + phdr_arr[i].p_vaddr, phdr_arr[i].p_memsz))
|
||||
{
|
||||
ConLog.Warning("Skipping...");
|
||||
#ifdef LOADER_DEBUG
|
||||
ConLog.Warning("Skipping...");
|
||||
ConLog.SkipLn();
|
||||
#endif
|
||||
continue;
|
||||
|
@ -184,20 +179,27 @@ bool ELF64Loader::LoadPhdrData()
|
|||
switch(phdr_arr[i].p_type)
|
||||
{
|
||||
case 0x00000001: //LOAD
|
||||
Memory.MainMem.Alloc(phdr_arr[i].p_vaddr, phdr_arr[i].p_memsz);
|
||||
elf64_f.Seek(phdr_arr[i].p_offset);
|
||||
elf64_f.Read(&Memory[phdr_arr[i].p_vaddr], phdr_arr[i].p_filesz);
|
||||
if(phdr_arr[i].p_memsz)
|
||||
{
|
||||
Memory.MainMem.Alloc(offset + phdr_arr[i].p_vaddr, phdr_arr[i].p_memsz);
|
||||
|
||||
if(phdr_arr[i].p_filesz)
|
||||
{
|
||||
elf64_f.Seek(phdr_arr[i].p_offset);
|
||||
elf64_f.Read(&Memory[offset + phdr_arr[i].p_vaddr], phdr_arr[i].p_filesz);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x00000007: //TLS
|
||||
Emu.SetTLSData(phdr_arr[i].p_vaddr, phdr_arr[i].p_filesz, phdr_arr[i].p_memsz);
|
||||
Emu.SetTLSData(offset + phdr_arr[i].p_vaddr, phdr_arr[i].p_filesz, phdr_arr[i].p_memsz);
|
||||
break;
|
||||
|
||||
case 0x60000001: //LOOS+1
|
||||
{
|
||||
if(!phdr_arr[i].p_filesz) break;
|
||||
|
||||
const sys_process_param& proc_param = *(sys_process_param*)&Memory[phdr_arr[i].p_vaddr];
|
||||
const sys_process_param& proc_param = *(sys_process_param*)&Memory[offset + phdr_arr[i].p_vaddr];
|
||||
|
||||
if(re(proc_param.size) < sizeof(sys_process_param))
|
||||
{
|
||||
|
@ -233,7 +235,7 @@ bool ELF64Loader::LoadPhdrData()
|
|||
{
|
||||
if(!phdr_arr[i].p_filesz) break;
|
||||
|
||||
sys_proc_prx_param proc_prx_param = *(sys_proc_prx_param*)&Memory[phdr_arr[i].p_vaddr];
|
||||
sys_proc_prx_param proc_prx_param = *(sys_proc_prx_param*)&Memory[offset + phdr_arr[i].p_vaddr];
|
||||
|
||||
proc_prx_param.size = re(proc_prx_param.size);
|
||||
proc_prx_param.magic = re(proc_prx_param.magic);
|
||||
|
@ -257,13 +259,13 @@ bool ELF64Loader::LoadPhdrData()
|
|||
|
||||
if(proc_prx_param.magic != 0x1b434cec)
|
||||
{
|
||||
ConLog.Error("Bad magic!");
|
||||
ConLog.Error("Bad magic! (0x%x)", proc_prx_param.magic);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(u32 s=proc_prx_param.libstubstart; s<proc_prx_param.libstubend; s+=sizeof(Elf64_StubHeader))
|
||||
{
|
||||
Elf64_StubHeader stub = *(Elf64_StubHeader*)Memory.GetMemFromAddr(s);
|
||||
Elf64_StubHeader stub = *(Elf64_StubHeader*)Memory.GetMemFromAddr(offset + s);
|
||||
|
||||
stub.s_size = re(stub.s_size);
|
||||
stub.s_version = re(stub.s_version);
|
||||
|
@ -274,6 +276,17 @@ bool ELF64Loader::LoadPhdrData()
|
|||
stub.s_nid = re(stub.s_nid);
|
||||
stub.s_text = re(stub.s_text);
|
||||
|
||||
const wxString& module_name = Memory.ReadString(stub.s_modulename);
|
||||
Module* module = GetModuleByName(module_name);
|
||||
if(module)
|
||||
{
|
||||
module->SetLoaded();
|
||||
}
|
||||
else
|
||||
{
|
||||
ConLog.Warning("Unknown module '%s'", module_name);
|
||||
}
|
||||
|
||||
#ifdef LOADER_DEBUG
|
||||
ConLog.SkipLn();
|
||||
ConLog.Write("*** size: 0x%x", stub.s_size);
|
||||
|
@ -281,21 +294,41 @@ bool ELF64Loader::LoadPhdrData()
|
|||
ConLog.Write("*** unk0: 0x%x", stub.s_unk0);
|
||||
ConLog.Write("*** unk1: 0x%x", stub.s_unk1);
|
||||
ConLog.Write("*** imports: %d", stub.s_imports);
|
||||
ConLog.Write("*** module name: %s [0x%x]", Memory.ReadString(stub.s_modulename), stub.s_modulename);
|
||||
ConLog.Write("*** module name: %s [0x%x]", module_name, stub.s_modulename);
|
||||
ConLog.Write("*** nid: 0x%x", stub.s_nid);
|
||||
ConLog.Write("*** text: 0x%x", stub.s_text);
|
||||
#endif
|
||||
static const u32 section = 4 * 3;
|
||||
u64 tbl = Memory.MainMem.Alloc(stub.s_imports * 4 * 2);
|
||||
u64 dst = Memory.MainMem.Alloc(stub.s_imports * section);
|
||||
|
||||
for(u32 i=0; i<stub.s_imports; ++i)
|
||||
{
|
||||
const u32 nid = Memory.Read32(stub.s_nid + i*4);
|
||||
const u32 text = Memory.Read32(stub.s_text + i*4);
|
||||
|
||||
if(module)
|
||||
{
|
||||
if(!module->Load(nid))
|
||||
{
|
||||
ConLog.Warning("Unknown function 0x%08x in '%s' module", nid, module_name);
|
||||
}
|
||||
}
|
||||
#ifdef LOADER_DEBUG
|
||||
ConLog.Write("import %d:", i+1);
|
||||
ConLog.Write("*** nid: 0x%x", nid);
|
||||
ConLog.Write("*** text: 0x%x", text);
|
||||
ConLog.Write("*** nid: 0x%x (0x%x)", nid, stub.s_nid + i*4);
|
||||
ConLog.Write("*** text: 0x%x (0x%x)", text, stub.s_text + i*4);
|
||||
#endif
|
||||
Memory.MemFlags.Add(text, stub.s_text + i*4, nid);
|
||||
Memory.Write32(stub.s_text + i*4, tbl + i*8);
|
||||
|
||||
mem32_t out_tbl(tbl + i*8);
|
||||
out_tbl += dst + i*section;
|
||||
out_tbl += nid;
|
||||
|
||||
mem32_t out_dst(dst + i*section);
|
||||
out_dst += ToOpcode(G_1f) | SetField(OR, 21, 30) | ToRA(11) | ToRS(2) | ToRB(2) | ToRC(0);
|
||||
out_dst += ToOpcode(SC) | ToSYS(2);
|
||||
out_dst += ToOpcode(G_13) | SetField(BCLR, 21, 30) | ToBO(0x10 | 0x04) | ToBI(0) | ToLK(0);
|
||||
}
|
||||
}
|
||||
#ifdef LOADER_DEBUG
|
||||
|
@ -313,7 +346,7 @@ bool ELF64Loader::LoadPhdrData()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ELF64Loader::LoadShdrData()
|
||||
bool ELF64Loader::LoadShdrData(u64 offset)
|
||||
{
|
||||
u64 max_addr = 0;
|
||||
|
||||
|
@ -341,12 +374,12 @@ bool ELF64Loader::LoadShdrData()
|
|||
const u64 addr = shdr.sh_addr;
|
||||
const u64 size = shdr.sh_size;
|
||||
|
||||
if(size == 0 || !Memory.IsGoodAddr(addr, size)) continue;
|
||||
if(size == 0 || !Memory.IsGoodAddr(offset + addr, size)) continue;
|
||||
|
||||
switch(shdr.sh_type)
|
||||
{
|
||||
case SHT_NOBITS:
|
||||
memset(&Memory[addr], 0, size);
|
||||
memset(&Memory[offset + addr], 0, size);
|
||||
break;
|
||||
|
||||
case SHT_PROGBITS:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue