mirror of
https://github.com/libretro/Play-.git
synced 2024-11-28 03:00:49 +00:00
Added support for LOADCORE's "LoadElf" function which allows loading an executable into EE memory.
Fixed a bug with module parameter passing in the LoadModule function. git-svn-id: http://svn.purei.org/purei/trunk@1023 b36208d7-6611-0410-8bec-b1987f11c4a2
This commit is contained in:
parent
b801b3d7f8
commit
91030fbbdd
@ -506,6 +506,47 @@ void CPS2OS::UnloadExecutable()
|
||||
DELETEPTR(m_pELF);
|
||||
}
|
||||
|
||||
uint32 CPS2OS::LoadExecutable(const char* path, const char* section)
|
||||
{
|
||||
auto ioman = m_iopBios.GetIoman();
|
||||
|
||||
uint32 handle = ioman->Open(Iop::Ioman::CDevice::OPEN_FLAG_RDONLY, path);
|
||||
if(static_cast<int32>(handle) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32 result = 0;
|
||||
|
||||
//We don't support loading anything else than all sections
|
||||
assert(strcmp(section, "all") == 0);
|
||||
|
||||
auto fileStream(ioman->GetFileStream(handle));
|
||||
|
||||
//Load all program sections
|
||||
{
|
||||
CElfFile executable(*fileStream);
|
||||
const auto& header = executable.GetHeader();
|
||||
for(unsigned int i = 0; i < header.nProgHeaderCount; i++)
|
||||
{
|
||||
auto p = executable.GetProgram(i);
|
||||
if(p)
|
||||
{
|
||||
memcpy(m_ram + p->nVAddress, executable.GetContent() + p->nOffset, p->nFileSize);
|
||||
}
|
||||
}
|
||||
|
||||
result = executable.GetHeader().nEntryPoint;
|
||||
}
|
||||
|
||||
//Flush all instruction cache
|
||||
OnRequestInstructionCacheFlush();
|
||||
|
||||
ioman->Close(handle);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void CPS2OS::ApplyPatches()
|
||||
{
|
||||
auto patchesPath = Framework::PathUtils::GetAppResourcesPath() / PATCHESFILENAME;
|
||||
|
@ -37,6 +37,8 @@ public:
|
||||
BiosDebugModuleInfoArray GetModuleInfos() const;
|
||||
BiosDebugThreadInfoArray GetThreadInfos() const;
|
||||
|
||||
uint32 LoadExecutable(const char*, const char*);
|
||||
|
||||
void ExceptionHandler();
|
||||
void SysCallHandler();
|
||||
static uint32 TranslateAddress(CMIPS*, uint32);
|
||||
|
@ -515,6 +515,8 @@ void CPS2VM::ResetVM()
|
||||
m_iopOs->GetIoman()->RegisterDevice("mc1", Iop::CIoman::DevicePtr(new Iop::Ioman::CDirectoryDevice(PREF_PS2_MC1_DIRECTORY)));
|
||||
m_iopOs->GetIoman()->RegisterDevice("cdrom0", Iop::CIoman::DevicePtr(new Iop::Ioman::CIsoDevice(m_pCDROM0)));
|
||||
|
||||
m_iopOs->GetLoadcore()->SetLoadExecutableHandler(std::bind(&CPS2OS::LoadExecutable, m_os, std::placeholders::_1, std::placeholders::_2));
|
||||
|
||||
m_frameSkip = CAppConfig::GetInstance().GetPreferenceInteger(PREF_PS2_FRAMESKIP);
|
||||
|
||||
m_vblankTicks = ONSCREEN_TICKS;
|
||||
|
@ -77,6 +77,7 @@ CIopBios::CIopBios(CMIPS& cpu, uint8* ram, uint32 ramSize)
|
||||
, m_ioman(nullptr)
|
||||
, m_modload(nullptr)
|
||||
, m_cdvdman(nullptr)
|
||||
, m_loadcore(nullptr)
|
||||
#ifdef _IOP_EMULATE_MODULES
|
||||
, m_padman(nullptr)
|
||||
, m_cdvdfsv(nullptr)
|
||||
@ -159,7 +160,8 @@ void CIopBios::Reset(Iop::CSifMan* sifMan)
|
||||
RegisterModule(new Iop::CSysclib(m_ram, *m_stdio));
|
||||
}
|
||||
{
|
||||
RegisterModule(new Iop::CLoadcore(*this, m_ram, *m_sifMan));
|
||||
m_loadcore = new Iop::CLoadcore(*this, m_ram, *m_sifMan);
|
||||
RegisterModule(m_loadcore);
|
||||
}
|
||||
{
|
||||
RegisterModule(new Iop::CThbase(*this, m_ram));
|
||||
@ -1425,6 +1427,11 @@ Iop::CCdvdman* CIopBios::GetCdvdman()
|
||||
return m_cdvdman;
|
||||
}
|
||||
|
||||
Iop::CLoadcore* CIopBios::GetLoadcore()
|
||||
{
|
||||
return m_loadcore;
|
||||
}
|
||||
|
||||
#ifdef _IOP_EMULATE_MODULES
|
||||
|
||||
Iop::CPadMan* CIopBios::GetPadman()
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "Iop_Stdio.h"
|
||||
#include "Iop_Sysmem.h"
|
||||
#include "Iop_Modload.h"
|
||||
#include "Iop_Loadcore.h"
|
||||
#include "Iop_Dynamic.h"
|
||||
#ifdef _IOP_EMULATE_MODULES
|
||||
#include "Iop_PadMan.h"
|
||||
@ -121,6 +122,7 @@ public:
|
||||
|
||||
Iop::CIoman* GetIoman();
|
||||
Iop::CCdvdman* GetCdvdman();
|
||||
Iop::CLoadcore* GetLoadcore();
|
||||
#ifdef _IOP_EMULATE_MODULES
|
||||
Iop::CPadMan* GetPadman();
|
||||
Iop::CCdvdfsv* GetCdvdfsv();
|
||||
@ -349,6 +351,7 @@ private:
|
||||
Iop::CCdvdman* m_cdvdman;
|
||||
Iop::CSysmem* m_sysmem;
|
||||
Iop::CModload* m_modload;
|
||||
Iop::CLoadcore* m_loadcore;
|
||||
#ifdef _IOP_EMULATE_MODULES
|
||||
Iop::CPadMan* m_padman;
|
||||
Iop::CCdvdfsv* m_cdvdfsv;
|
||||
|
@ -72,6 +72,9 @@ bool CLoadcore::Invoke(uint32 method, uint32* args, uint32 argsSize, uint32* ret
|
||||
case 0x00:
|
||||
LoadModule(args, argsSize, ret, retSize);
|
||||
break;
|
||||
case 0x01:
|
||||
LoadExecutable(args, argsSize, ret, retSize);
|
||||
break;
|
||||
case 0x06:
|
||||
LoadModuleFromMemory(args, argsSize, ret, retSize);
|
||||
break;
|
||||
@ -86,6 +89,11 @@ bool CLoadcore::Invoke(uint32 method, uint32* args, uint32 argsSize, uint32* ret
|
||||
return true;
|
||||
}
|
||||
|
||||
void CLoadcore::SetLoadExecutableHandler(const LoadExecutableHandler& loadExecutableHandler)
|
||||
{
|
||||
m_loadExecutableHandler = loadExecutableHandler;
|
||||
}
|
||||
|
||||
uint32 CLoadcore::RegisterLibraryEntries(uint32* exportTable)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
@ -97,8 +105,8 @@ uint32 CLoadcore::RegisterLibraryEntries(uint32* exportTable)
|
||||
|
||||
void CLoadcore::LoadModule(uint32* args, uint32 argsSize, uint32* ret, uint32 retSize)
|
||||
{
|
||||
char moduleName[PATH_MAX_SIZE + 1];
|
||||
char moduleArgs[ARGS_MAX_SIZE + 1];
|
||||
char moduleName[PATH_MAX_SIZE];
|
||||
char moduleArgs[ARGS_MAX_SIZE];
|
||||
|
||||
assert(argsSize == 512);
|
||||
|
||||
@ -107,14 +115,8 @@ void CLoadcore::LoadModule(uint32* args, uint32 argsSize, uint32* ret, uint32 re
|
||||
|
||||
uint32 moduleArgsSize = args[0];
|
||||
|
||||
memset(moduleName, 0, PATH_MAX_SIZE + 1);
|
||||
memset(moduleArgs, 0, ARGS_MAX_SIZE + 1);
|
||||
|
||||
strncpy(moduleName, reinterpret_cast<const char*>(args) + 8, PATH_MAX_SIZE);
|
||||
if(moduleArgsSize != 0)
|
||||
{
|
||||
strncpy(moduleArgs, reinterpret_cast<const char*>(args) + 8 + PATH_MAX_SIZE, ARGS_MAX_SIZE);
|
||||
}
|
||||
memcpy(moduleName, reinterpret_cast<const char*>(args) + 8, PATH_MAX_SIZE);
|
||||
memcpy(moduleArgs, reinterpret_cast<const char*>(args) + 8 + PATH_MAX_SIZE, ARGS_MAX_SIZE);
|
||||
|
||||
//Load the module
|
||||
CLog::GetInstance().Print(LOG_NAME, "Request to load module '%s' received with %d bytes arguments payload.\r\n", moduleName, moduleArgsSize);
|
||||
@ -125,6 +127,32 @@ void CLoadcore::LoadModule(uint32* args, uint32 argsSize, uint32* ret, uint32 re
|
||||
ret[0] = 0x00000000;
|
||||
}
|
||||
|
||||
void CLoadcore::LoadExecutable(uint32* args, uint32 argsSize, uint32* ret, uint32 retSize)
|
||||
{
|
||||
char moduleName[PATH_MAX_SIZE];
|
||||
char sectionName[ARGS_MAX_SIZE];
|
||||
|
||||
assert(argsSize == 512);
|
||||
assert(retSize >= 8);
|
||||
|
||||
memcpy(moduleName, reinterpret_cast<const char*>(args) + 8, PATH_MAX_SIZE);
|
||||
memcpy(sectionName, reinterpret_cast<const char*>(args) + 8 + PATH_MAX_SIZE, ARGS_MAX_SIZE);
|
||||
|
||||
CLog::GetInstance().Print(LOG_NAME, "Request to load section '%s' from executable '%s' received.\r\n", sectionName, moduleName);
|
||||
|
||||
uint32 result = 0;
|
||||
|
||||
//Load executable in EE memory
|
||||
if(m_loadExecutableHandler)
|
||||
{
|
||||
result = m_loadExecutableHandler(moduleName, sectionName);
|
||||
}
|
||||
|
||||
//This function returns something negative upon failure
|
||||
ret[0] = result; //epc or result (if negative)
|
||||
ret[1] = 0x00000000; //gp
|
||||
}
|
||||
|
||||
void CLoadcore::LoadModuleFromMemory(uint32* args, uint32 argsSize, uint32* ret, uint32 retSize)
|
||||
{
|
||||
CLog::GetInstance().Print(LOG_NAME, "Request to load module at 0x%0.8X received with %d bytes arguments payload.\r\n", args[0], 0);
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "Iop_Module.h"
|
||||
#include "Iop_SifMan.h"
|
||||
#include <functional>
|
||||
|
||||
class CIopBios;
|
||||
|
||||
@ -11,13 +12,17 @@ namespace Iop
|
||||
class CLoadcore : public CModule, public CSifModule
|
||||
{
|
||||
public:
|
||||
CLoadcore(CIopBios&, uint8*, CSifMan&);
|
||||
virtual ~CLoadcore();
|
||||
typedef std::function<uint32 (const char*, const char*)> LoadExecutableHandler;
|
||||
|
||||
std::string GetId() const;
|
||||
std::string GetFunctionName(unsigned int) const;
|
||||
void Invoke(CMIPS&, unsigned int);
|
||||
bool Invoke(uint32, uint32*, uint32, uint32*, uint32, uint8*);
|
||||
CLoadcore(CIopBios&, uint8*, CSifMan&);
|
||||
virtual ~CLoadcore();
|
||||
|
||||
std::string GetId() const;
|
||||
std::string GetFunctionName(unsigned int) const;
|
||||
void Invoke(CMIPS&, unsigned int);
|
||||
bool Invoke(uint32, uint32*, uint32, uint32*, uint32, uint8*);
|
||||
|
||||
void SetLoadExecutableHandler(const LoadExecutableHandler&);
|
||||
|
||||
private:
|
||||
enum MODULE_ID
|
||||
@ -25,13 +30,16 @@ namespace Iop
|
||||
MODULE_ID = 0x80000006
|
||||
};
|
||||
|
||||
uint32 RegisterLibraryEntries(uint32*);
|
||||
void LoadModule(uint32*, uint32, uint32*, uint32);
|
||||
void LoadModuleFromMemory(uint32*, uint32, uint32*, uint32);
|
||||
void Initialize(uint32*, uint32, uint32*, uint32);
|
||||
uint32 RegisterLibraryEntries(uint32*);
|
||||
void LoadModule(uint32*, uint32, uint32*, uint32);
|
||||
void LoadExecutable(uint32*, uint32, uint32*, uint32);
|
||||
void LoadModuleFromMemory(uint32*, uint32, uint32*, uint32);
|
||||
void Initialize(uint32*, uint32, uint32*, uint32);
|
||||
|
||||
CIopBios& m_bios;
|
||||
uint8* m_ram;
|
||||
CIopBios& m_bios;
|
||||
uint8* m_ram;
|
||||
|
||||
LoadExecutableHandler m_loadExecutableHandler;
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user