From 5b8e983478963bbdff2841f9c9eb7529ad7121a7 Mon Sep 17 00:00:00 2001 From: Christian Kenny Date: Fri, 17 Sep 2021 22:03:45 -0400 Subject: [PATCH] ELFHeader: Detect CRC properly for PSX games, improve formatting of game serial output. --- pcsx2/CDVD/CDVD.cpp | 47 +++++++++++++++++++++++++++++++++++++-------- pcsx2/Elfheader.cpp | 18 ++++++++++------- pcsx2/Elfheader.h | 14 ++++---------- 3 files changed, 54 insertions(+), 25 deletions(-) diff --git a/pcsx2/CDVD/CDVD.cpp b/pcsx2/CDVD/CDVD.cpp index 0d3e7df92f..95bcf677c3 100644 --- a/pcsx2/CDVD/CDVD.cpp +++ b/pcsx2/CDVD/CDVD.cpp @@ -381,10 +381,10 @@ s32 cdvdWriteConfig(const u8* config) static MutexRecursive Mutex_NewDiskCB; // 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")) - return new ElfObject(filename.After(':'), Path::GetFileSize(filename.After(':'))); + return new ElfObject(filename.After(':'), Path::GetFileSize(filename.After(':')), isPSXElf); // Mimic PS2 behavior! // 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; IsoFile file(isofs, fixedname); - return new ElfObject(fixedname, file); + return new ElfObject(fixedname, file, isPSXElf); } static __fi void _reloadElfInfo(wxString elfpath) @@ -427,8 +427,8 @@ static __fi void _reloadElfInfo(wxString elfpath) fname = elfpath.AfterLast(':'); if (fname.Matches(L"????_???.??*")) DiscSerial = fname(0, 4) + L"-" + fname(5, 3) + fname(9, 2); + std::unique_ptr elfptr(loadElf(elfpath, false)); - std::unique_ptr elfptr(loadElf(elfpath)); elfptr->loadHeaders(); ElfCRC = elfptr->getCRC(); @@ -443,6 +443,36 @@ static __fi void _reloadElfInfo(wxString elfpath) // 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 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) { // 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. // 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. - wxString fname = elfpath.AfterLast('\\').AfterLast(':'); // Also catch elf paths which lack a backslash, and only have a colon. - wxString fname2 = fname.BeforeFirst(';'); - DiscSerial = fname2; - Console.SetTitle(DiscSerial); + wxString fname = elfpath.AfterLast('\\').BeforeFirst('_'); + wxString fname2 = elfpath.AfterLast('_').BeforeFirst('.'); + wxString fname3 = elfpath.AfterLast('.').BeforeFirst(';'); + DiscSerial = fname + "-" + fname2 + fname3; + _reloadPSXElfInfo(elfpath); return; } diff --git a/pcsx2/Elfheader.cpp b/pcsx2/Elfheader.cpp index 9e5009d64d..d1e666841f 100644 --- a/pcsx2/Elfheader.cpp +++ b/pcsx2/Elfheader.cpp @@ -25,36 +25,40 @@ u32 ElfCRC; u32 ElfEntry; std::pair ElfTextRange; wxString LastELF; +bool isPSXElf; // 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" ) , proghead( NULL ) , secthead( NULL ) , filename( srcfile ) , header( *(ELF_HEADER*)data.GetPtr() ) { - isCdvd = true; checkElfSize(data.GetSizeInBytes()); 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" ) , proghead( NULL ) , secthead( NULL ) , filename( srcfile ) , header( *(ELF_HEADER*)data.GetPtr() ) { - isCdvd = false; checkElfSize(data.GetSizeInBytes()); readFile(); - initElfHeaders(); + initElfHeaders(isPSXElf); } -void ElfObject::initElfHeaders() +void ElfObject::initElfHeaders(bool isPSXElf) { + if (isPSXElf) + { + return; + } + DevCon.WriteLn( L"Initializing Elf: %d bytes", data.GetSizeInBytes()); if ( header.e_phnum > 0 ) diff --git a/pcsx2/Elfheader.h b/pcsx2/Elfheader.h index 04f775f308..7fa40de9a6 100644 --- a/pcsx2/Elfheader.h +++ b/pcsx2/Elfheader.h @@ -19,12 +19,6 @@ #include "CDVD/IsoFS/IsoFSCDVD.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 { u8 e_ident[16]; //0x7f,"ELF" (ELF file identifier) u16 e_type; //ELF type: 0=NONE, 1=REL, 2=EXEC, 3=SHARED, 4=CORE @@ -131,21 +125,20 @@ class ElfObject ELF_SHR* secthead; wxString filename; - void initElfHeaders(); + void initElfHeaders(bool isPSXElf); void readIso(IsoFile& file); void readFile(); void checkElfSize(s64 elfsize); public: - bool isCdvd; ELF_HEADER& header; // Destructor! // C++ does all the cleanup automagically for us. virtual ~ElfObject() = default; - ElfObject(const wxString& srcfile, IsoFile& isofile); - ElfObject( const wxString& srcfile, uint hdrsize ); + ElfObject(const wxString& srcfile, IsoFile& isofile, bool isPSXElf); + ElfObject( const wxString& srcfile, uint hdrsize, bool isPSXElf ); void loadProgramHeaders(); void loadSectionHeaders(); @@ -168,5 +161,6 @@ extern u32 ElfCRC; extern u32 ElfEntry; extern std::pair ElfTextRange; extern wxString LastELF; +extern bool isPSXElf; #endif