ELFHeader: Detect CRC properly for PSX games, improve formatting of game serial output.

This commit is contained in:
Christian Kenny 2021-09-17 22:03:45 -04:00 committed by refractionpcsx2
parent 24d47cb10b
commit 5b8e983478
3 changed files with 54 additions and 25 deletions

View File

@ -381,10 +381,10 @@ s32 cdvdWriteConfig(const u8* config)
static MutexRecursive Mutex_NewDiskCB; static MutexRecursive Mutex_NewDiskCB;
// Sets ElfCRC to the CRC of the game bound to the CDVD source. // Sets ElfCRC to the CRC of the game bound to the CDVD source.
static __fi ElfObject* loadElf(const wxString filename) static __fi ElfObject* loadElf(const wxString filename, bool isPSXElf)
{ {
if (filename.StartsWith(L"host")) if (filename.StartsWith(L"host"))
return new ElfObject(filename.After(':'), Path::GetFileSize(filename.After(':'))); return new ElfObject(filename.After(':'), Path::GetFileSize(filename.After(':')), isPSXElf);
// Mimic PS2 behavior! // Mimic PS2 behavior!
// Much trial-and-error with changing the ISOFS and BOOT2 contents of an image have shown that // Much trial-and-error with changing the ISOFS and BOOT2 contents of an image have shown that
@ -408,7 +408,7 @@ static __fi ElfObject* loadElf(const wxString filename)
IsoFSCDVD isofs; IsoFSCDVD isofs;
IsoFile file(isofs, fixedname); IsoFile file(isofs, fixedname);
return new ElfObject(fixedname, file); return new ElfObject(fixedname, file, isPSXElf);
} }
static __fi void _reloadElfInfo(wxString elfpath) static __fi void _reloadElfInfo(wxString elfpath)
@ -427,8 +427,8 @@ static __fi void _reloadElfInfo(wxString elfpath)
fname = elfpath.AfterLast(':'); fname = elfpath.AfterLast(':');
if (fname.Matches(L"????_???.??*")) if (fname.Matches(L"????_???.??*"))
DiscSerial = fname(0, 4) + L"-" + fname(5, 3) + fname(9, 2); DiscSerial = fname(0, 4) + L"-" + fname(5, 3) + fname(9, 2);
std::unique_ptr<ElfObject> elfptr(loadElf(elfpath, false));
std::unique_ptr<ElfObject> elfptr(loadElf(elfpath));
elfptr->loadHeaders(); elfptr->loadHeaders();
ElfCRC = elfptr->getCRC(); ElfCRC = elfptr->getCRC();
@ -443,6 +443,36 @@ static __fi void _reloadElfInfo(wxString elfpath)
// binary). // binary).
} }
static __fi void _reloadPSXElfInfo(wxString elfpath)
{
// Now's a good time to reload the ELF info...
ScopedLock locker(Mutex_NewDiskCB);
if (elfpath == LastELF)
return;
LastELF = elfpath;
wxString fname = elfpath.AfterLast('\\');
if (!fname)
fname = elfpath.AfterLast('/');
if (!fname)
fname = elfpath.AfterLast(':');
if (fname.Matches(L"????_???.??*"))
DiscSerial = fname(0, 4) + L"-" + fname(5, 3) + fname(9, 2);
std::unique_ptr<ElfObject> elfptr(loadElf(elfpath, true));
ElfCRC = elfptr->getCRC();
ElfTextRange = elfptr->getTextRange();
Console.WriteLn(Color_StrongBlue, L"PSX ELF (%s) Game CRC = 0x%08X", WX_STR(elfpath), ElfCRC);
// Note: Do not load game database info here. This code is generic and called from
// BIOS key encryption as well as eeloadReplaceOSDSYS. The first is actually still executing
// BIOS code, and patches and cheats should not be applied yet. (they are applied when
// eeGameStarting is invoked, which is when the VM starts executing the actual game ELF
// binary).
}
void cdvdReloadElfInfo(wxString elfoverride) void cdvdReloadElfInfo(wxString elfoverride)
{ {
// called from context of executing VM code (recompilers), so we need to trap exceptions // called from context of executing VM code (recompilers), so we need to trap exceptions
@ -465,10 +495,11 @@ void cdvdReloadElfInfo(wxString elfoverride)
// PCSX2 currently only recognizes *.elf executables in proper PS2 format. // PCSX2 currently only recognizes *.elf executables in proper PS2 format.
// To support different PSX titles in the console title and for savestates, this code bypasses all the detection, // To support different PSX titles in the console title and for savestates, this code bypasses all the detection,
// simply using the exe name, stripped of problematic characters. // simply using the exe name, stripped of problematic characters.
wxString fname = elfpath.AfterLast('\\').AfterLast(':'); // Also catch elf paths which lack a backslash, and only have a colon. wxString fname = elfpath.AfterLast('\\').BeforeFirst('_');
wxString fname2 = fname.BeforeFirst(';'); wxString fname2 = elfpath.AfterLast('_').BeforeFirst('.');
DiscSerial = fname2; wxString fname3 = elfpath.AfterLast('.').BeforeFirst(';');
Console.SetTitle(DiscSerial); DiscSerial = fname + "-" + fname2 + fname3;
_reloadPSXElfInfo(elfpath);
return; return;
} }

View File

@ -25,36 +25,40 @@ u32 ElfCRC;
u32 ElfEntry; u32 ElfEntry;
std::pair<u32,u32> ElfTextRange; std::pair<u32,u32> ElfTextRange;
wxString LastELF; wxString LastELF;
bool isPSXElf;
// All of ElfObjects functions. // All of ElfObjects functions.
ElfObject::ElfObject(const wxString& srcfile, IsoFile& isofile) ElfObject::ElfObject(const wxString& srcfile, IsoFile& isofile, bool isPSXElf)
: data( wxULongLong(isofile.getLength()).GetLo(), L"ELF headers" ) : data( wxULongLong(isofile.getLength()).GetLo(), L"ELF headers" )
, proghead( NULL ) , proghead( NULL )
, secthead( NULL ) , secthead( NULL )
, filename( srcfile ) , filename( srcfile )
, header( *(ELF_HEADER*)data.GetPtr() ) , header( *(ELF_HEADER*)data.GetPtr() )
{ {
isCdvd = true;
checkElfSize(data.GetSizeInBytes()); checkElfSize(data.GetSizeInBytes());
readIso(isofile); readIso(isofile);
initElfHeaders(); initElfHeaders(isPSXElf);
} }
ElfObject::ElfObject( const wxString& srcfile, uint hdrsize ) ElfObject::ElfObject( const wxString& srcfile, uint hdrsize, bool isPSXElf )
: data( wxULongLong(hdrsize).GetLo(), L"ELF headers" ) : data( wxULongLong(hdrsize).GetLo(), L"ELF headers" )
, proghead( NULL ) , proghead( NULL )
, secthead( NULL ) , secthead( NULL )
, filename( srcfile ) , filename( srcfile )
, header( *(ELF_HEADER*)data.GetPtr() ) , header( *(ELF_HEADER*)data.GetPtr() )
{ {
isCdvd = false;
checkElfSize(data.GetSizeInBytes()); checkElfSize(data.GetSizeInBytes());
readFile(); readFile();
initElfHeaders(); initElfHeaders(isPSXElf);
} }
void ElfObject::initElfHeaders() void ElfObject::initElfHeaders(bool isPSXElf)
{ {
if (isPSXElf)
{
return;
}
DevCon.WriteLn( L"Initializing Elf: %d bytes", data.GetSizeInBytes()); DevCon.WriteLn( L"Initializing Elf: %d bytes", data.GetSizeInBytes());
if ( header.e_phnum > 0 ) if ( header.e_phnum > 0 )

View File

@ -19,12 +19,6 @@
#include "CDVD/IsoFS/IsoFSCDVD.h" #include "CDVD/IsoFS/IsoFSCDVD.h"
#include "CDVD/IsoFS/IsoFS.h" #include "CDVD/IsoFS/IsoFS.h"
#if 0
//2002-09-20 (Florin)
extern char args[256]; //to be filled by GUI
extern unsigned int args_ptr;
#endif
struct ELF_HEADER { struct ELF_HEADER {
u8 e_ident[16]; //0x7f,"ELF" (ELF file identifier) u8 e_ident[16]; //0x7f,"ELF" (ELF file identifier)
u16 e_type; //ELF type: 0=NONE, 1=REL, 2=EXEC, 3=SHARED, 4=CORE u16 e_type; //ELF type: 0=NONE, 1=REL, 2=EXEC, 3=SHARED, 4=CORE
@ -131,21 +125,20 @@ class ElfObject
ELF_SHR* secthead; ELF_SHR* secthead;
wxString filename; wxString filename;
void initElfHeaders(); void initElfHeaders(bool isPSXElf);
void readIso(IsoFile& file); void readIso(IsoFile& file);
void readFile(); void readFile();
void checkElfSize(s64 elfsize); void checkElfSize(s64 elfsize);
public: public:
bool isCdvd;
ELF_HEADER& header; ELF_HEADER& header;
// Destructor! // Destructor!
// C++ does all the cleanup automagically for us. // C++ does all the cleanup automagically for us.
virtual ~ElfObject() = default; virtual ~ElfObject() = default;
ElfObject(const wxString& srcfile, IsoFile& isofile); ElfObject(const wxString& srcfile, IsoFile& isofile, bool isPSXElf);
ElfObject( const wxString& srcfile, uint hdrsize ); ElfObject( const wxString& srcfile, uint hdrsize, bool isPSXElf );
void loadProgramHeaders(); void loadProgramHeaders();
void loadSectionHeaders(); void loadSectionHeaders();
@ -168,5 +161,6 @@ extern u32 ElfCRC;
extern u32 ElfEntry; extern u32 ElfEntry;
extern std::pair<u32,u32> ElfTextRange; extern std::pair<u32,u32> ElfTextRange;
extern wxString LastELF; extern wxString LastELF;
extern bool isPSXElf;
#endif #endif