From c433291c678d5a0a506f9bf3d1e2d925b2acc9e9 Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Tue, 10 Feb 2009 11:34:35 +0000 Subject: [PATCH] Bugfixed the Elfloader; resolves a bootup crash in Psychonauts. Renamed MemoryAlloc to SafeArray, and added linux files to the Win32 solutions (they're disabled, so they don't compile or anything -- I just needed them in the solution so that I can more easily update Linux code when I make API changes to the GUI) git-svn-id: http://pcsx2.googlecode.com/svn/trunk@467 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/Elfheader.cpp | 21 +- pcsx2/Linux/LnxMain.h | 2 +- pcsx2/Linux/LnxSysExec.cpp | 10 +- pcsx2/Linux/LnxThreads.cpp | 14 +- pcsx2/Misc.cpp | 4 +- pcsx2/SafeArray.h | 25 +- pcsx2/SaveState.cpp | 6 +- pcsx2/SaveState.h | 8 +- pcsx2/windows/VCprojects/pcsx2_2008.vcproj | 332 +++++++++++++++++++++ pcsx2/windows/Win32.h | 4 +- pcsx2/windows/WinSysExec.cpp | 8 +- pcsx2/windows/WinThreads.cpp | 14 +- pcsx2/windows/ini.cpp | 2 +- 13 files changed, 385 insertions(+), 65 deletions(-) diff --git a/pcsx2/Elfheader.cpp b/pcsx2/Elfheader.cpp index c26d3b9143..dcc3505e99 100644 --- a/pcsx2/Elfheader.cpp +++ b/pcsx2/Elfheader.cpp @@ -226,7 +226,7 @@ static uint parseCommandLine( const char *filename ) struct ElfObject { string filename; - MemoryAlloc data; + SafeArray data; ELF_HEADER& header; ELF_PHR* proghead; ELF_SHR* secthead; @@ -243,18 +243,18 @@ struct ElfObject , secthead( NULL ) { readFile(); - proghead = (ELF_PHR*)&data[header.e_phoff]; - secthead = (ELF_SHR*)&data[header.e_shoff]; + + if( header.e_phnum > 0 ) + proghead = (ELF_PHR*)&data[header.e_phoff]; + + if( header.e_shnum > 0 ) + secthead = (ELF_SHR*)&data[header.e_shoff]; if ( ( header.e_shnum > 0 ) && ( header.e_shentsize != sizeof(ELF_SHR) ) ) - { Console::Error( "ElfLoader Warning > Size of section headers is not standard" ); - } if ( ( header.e_phnum > 0 ) && ( header.e_phentsize != sizeof(ELF_PHR) ) ) - { Console::Error( "ElfLoader Warning > Size of program headers is not standard" ); - } ELF_LOG( "type: " ); switch( header.e_type ) @@ -349,7 +349,7 @@ struct ElfObject void loadProgramHeaders() { - if ( header.e_phnum == 0 ) + if ( proghead == NULL ) return; for( int i = 0 ; i < header.e_phnum ; i++ ) @@ -407,7 +407,7 @@ struct ElfObject void loadSectionHeaders() { - if( header.e_shnum == 0 || header.e_shoff > (u32)data.GetLength() ) + if( secthead == NULL || header.e_shoff > (u32)data.GetLength() ) return; const u8* sections_names = data.GetPtr( secthead[ header.e_shstrndx ].sh_offset ); @@ -576,6 +576,9 @@ int loadElfFile(const char *filename) Console::Status( "loadElfFile: %d", params elfsize); ElfObject elfobj( filename, elfsize ); + if( elfobj.proghead == NULL ) + throw Exception::CpuStateShutdown( fmt_string( "%s > This ELF has no program headers; Pcsx2 can't run what doesn't exist...", filename ) ); + //2002-09-19 (Florin) args_ptr = 0xFFFFFFFF; //big value, searching for minimum diff --git a/pcsx2/Linux/LnxMain.h b/pcsx2/Linux/LnxMain.h index fdfb88e139..615d631d7a 100644 --- a/pcsx2/Linux/LnxMain.h +++ b/pcsx2/Linux/LnxMain.h @@ -24,7 +24,7 @@ void SignalExit(int sig); extern bool applychanges; -extern MemoryAlloc* g_RecoveryState; +extern SafeArray* g_RecoveryState; extern bool g_EmulationInProgress; // Set TRUE if a game is actively running (set to false on reset) extern void RunExecute(const char* elf_file, bool use_bios = false); diff --git a/pcsx2/Linux/LnxSysExec.cpp b/pcsx2/Linux/LnxSysExec.cpp index 5bdb70e800..c6fb515440 100644 --- a/pcsx2/Linux/LnxSysExec.cpp +++ b/pcsx2/Linux/LnxSysExec.cpp @@ -21,8 +21,8 @@ bool UseGui = true; -MemoryAlloc* g_RecoveryState = NULL; -MemoryAlloc* g_gsRecoveryState = NULL; +SafeArray* g_RecoveryState = NULL; +SafeArray* g_gsRecoveryState = NULL; bool g_ReturnToGui = false; // set to exit the execution of the emulator and return control to the GUI bool g_EmulationInProgress = false; // Set TRUE if a game is actively running (set to false on reset) @@ -128,7 +128,7 @@ void RunExecute(const char* elf_file, bool use_bios) // (air notes:) // If you want to use the new to-memory savestate feature, take a look at the new // RunExecute in WinMain.c, and secondly the CpuDlg.c or AdvancedDlg.cpp. The - // objects used are MemoryAlloc, memLoadingState, and memSavingState. + // objects used are SafeArray, memLoadingState, and memSavingState. // It's important to make sure to reset the CPU and the plugins correctly, which is // where the new RunExecute comes into play. It can be kind of tricky knowing @@ -620,7 +620,7 @@ void KeyEvent(keyEvent* ev) { safe_delete( g_gsRecoveryState ); safe_delete( g_RecoveryState ); - g_gsRecoveryState = new MemoryAlloc(); + g_gsRecoveryState = new SafeArray(); JustGsSavingState eddie; eddie.FreezePlugin( "GS", gsSafeFreeze ) ; eddie.gsFreeze(); @@ -672,7 +672,7 @@ void SysRestorableReset() try { - g_RecoveryState = new MemoryAlloc( "Memory Savestate Recovery" ); + g_RecoveryState = new SafeArray( "Memory Savestate Recovery" ); RecoveryMemSavingState().FreezeAll(); safe_delete( g_gsRecoveryState ); g_EmulationInProgress = false; diff --git a/pcsx2/Linux/LnxThreads.cpp b/pcsx2/Linux/LnxThreads.cpp index 837227ef31..3918f95119 100644 --- a/pcsx2/Linux/LnxThreads.cpp +++ b/pcsx2/Linux/LnxThreads.cpp @@ -64,19 +64,11 @@ namespace Threading void* Thread::_internal_callback( void* itsme ) { jASSUME( itsme != NULL ); + Thread& owner = *((Thread*)itsme); - - try - { - owner.m_returncode = owner.Callback(); - } - catch( std::exception& ex ) - { - Console::Error( "Thread terminated abnormally with error:\n%s", params ex.what() ); - owner.m_returncode = -1; - } - + owner.m_returncode = owner.Callback(); owner.m_terminated = true; + return NULL; } diff --git a/pcsx2/Misc.cpp b/pcsx2/Misc.cpp index 87d55e6898..5a02abb815 100644 --- a/pcsx2/Misc.cpp +++ b/pcsx2/Misc.cpp @@ -527,13 +527,13 @@ void ProcessFKeys(int fkey, int shift) SaveState::GetFilename( Text, StatesC ); gzSavingState( Text ).FreezeAll(); } - catch( std::exception& ex ) + catch( Exception::BaseException& ex ) { // 99% of the time this is a file permission error and the // cpu state is intact so just display a passive msg to console. Console::Error( _( "Error > Could not save state to slot %d" ), params StatesC ); - Console::Error( ex.what() ); + Console::Error( ex.cMessage() ); } break; diff --git a/pcsx2/SafeArray.h b/pcsx2/SafeArray.h index 745c391cff..461f9488b8 100644 --- a/pcsx2/SafeArray.h +++ b/pcsx2/SafeArray.h @@ -72,7 +72,7 @@ extern void pcsx2_aligned_free(void* pmem); // exception-based error handling and automatic cleanup. template< typename T > -class MemoryAlloc : public NoncopyableObject +class SafeArray : public NoncopyableObject { public: static const int DefaultChunkSize = 0x1000 * sizeof(T); @@ -91,7 +91,7 @@ protected: // use its own memory allocation (with an aligned memory, for example). // Throws: // Exception::OutOfMemory if the allocated_mem pointr is NULL. - explicit MemoryAlloc( const std::string& name, T* allocated_mem, int initSize ) : + explicit SafeArray( const std::string& name, T* allocated_mem, int initSize ) : Name( name ) , ChunkSize( DefaultChunkSize ) , m_ptr( allocated_mem ) @@ -107,12 +107,12 @@ protected: } public: - virtual ~MemoryAlloc() + virtual ~SafeArray() { safe_free( m_ptr ); } - explicit MemoryAlloc( const std::string& name="Unnamed" ) : + explicit SafeArray( const std::string& name="Unnamed" ) : Name( name ) , ChunkSize( DefaultChunkSize ) , m_ptr( NULL ) @@ -120,7 +120,7 @@ public: { } - explicit MemoryAlloc( int initialSize, const std::string& name="Unnamed" ) : + explicit SafeArray( int initialSize, const std::string& name="Unnamed" ) : Name( name ) , ChunkSize( DefaultChunkSize ) , m_ptr( (T*)malloc( initialSize * sizeof(T) ) ) @@ -167,9 +167,9 @@ public: T& operator[]( int idx ) { return *_getPtr( (uint)idx ); } const T& operator[]( int idx ) const { return *_getPtr( (uint)idx ); } - virtual MemoryAlloc* Clone() const + virtual SafeArray* Clone() const { - MemoryAlloc* retval = new MemoryAlloc( m_size ); + SafeArray* retval = new SafeArray( m_size ); memcpy_fast( retval->GetPtr(), m_ptr, sizeof(T) * m_size ); return retval; } @@ -179,15 +179,16 @@ protected: // is outside the bounds of the array. // Performance Considerations: This function adds quite a bit of overhead // to array indexing and thus should be done infrequently if used in - // time-critical situations. Indead of using it from inside loops, cache + // time-critical situations. Instead of using it from inside loops, cache // the pointer into a local variable and use stad (unsafe) C indexes. T* _getPtr( uint i ) const { #ifdef PCSX2_DEVBUILD if( i >= (uint)m_size ) { + assert( 0 ); // makes debugging easier sometimes. :) throw Exception::IndexBoundsFault( - "Index out of bounds on MemoryAlloc: " + Name + + "Index out of bounds on SafeArray: " + Name + " (index=" + to_string(i) + ", size=" + to_string(m_size) + ")" ); @@ -204,7 +205,7 @@ protected: // This one supports aligned data allocations too! template< typename T, uint Alignment > -class SafeAlignedArray : public MemoryAlloc +class SafeAlignedArray : public SafeArray { protected: T* _virtual_realloc( int newsize ) @@ -230,12 +231,12 @@ public: } explicit SafeAlignedArray( const std::string& name="Unnamed" ) : - MemoryAlloc::MemoryAlloc( name ) + SafeArray::SafeArray( name ) { } explicit SafeAlignedArray( int initialSize, const std::string& name="Unnamed" ) : - MemoryAlloc::MemoryAlloc( + SafeArray::SafeArray( _getName(name), (T*)_aligned_malloc( initialSize * sizeof(T), Alignment ), initialSize diff --git a/pcsx2/SaveState.cpp b/pcsx2/SaveState.cpp index 9ffba35c58..258f33528f 100644 --- a/pcsx2/SaveState.cpp +++ b/pcsx2/SaveState.cpp @@ -281,7 +281,7 @@ void gzLoadingState::FreezePlugin( const char* name, s32 (CALLBACK *freezer)(int ////////////////////////////////////////////////////////////////////////////////// // uncompressed to/from memory state saves implementation -memBaseStateInfo::memBaseStateInfo( MemoryAlloc& memblock, const char* msg ) : +memBaseStateInfo::memBaseStateInfo( SafeArray& memblock, const char* msg ) : SaveState( msg, "Memory" ) , m_memory( memblock ) , m_idx( 0 ) @@ -290,7 +290,7 @@ memBaseStateInfo::memBaseStateInfo( MemoryAlloc& memblock, const char* msg ) mtgsWaitGS(); } -memSavingState::memSavingState( MemoryAlloc& save_to ) : memBaseStateInfo( save_to, _("Saving state to: ") ) +memSavingState::memSavingState( SafeArray& save_to ) : memBaseStateInfo( save_to, _("Saving state to: ") ) { save_to.ChunkSize = ReallocThreshold; save_to.MakeRoomFor( MemoryBaseAllocSize ); @@ -309,7 +309,7 @@ void memSavingState::FreezeMem( void* data, int size ) dest[m_idx] = *src; } -memLoadingState::memLoadingState(MemoryAlloc& load_from ) : +memLoadingState::memLoadingState(SafeArray& load_from ) : memBaseStateInfo( load_from, _("Loading state from: ") ) { } diff --git a/pcsx2/SaveState.h b/pcsx2/SaveState.h index 325567630f..2a91dc1f74 100644 --- a/pcsx2/SaveState.h +++ b/pcsx2/SaveState.h @@ -166,12 +166,12 @@ public: class memBaseStateInfo : public SaveState { protected: - MemoryAlloc& m_memory; + SafeArray& m_memory; int m_idx; // current read/write index of the allocation public: virtual ~memBaseStateInfo() { } - memBaseStateInfo( MemoryAlloc& memblock, const char* msg ); + memBaseStateInfo( SafeArray& memblock, const char* msg ); }; class memSavingState : public memBaseStateInfo @@ -182,7 +182,7 @@ protected: public: virtual ~memSavingState() { } - memSavingState( MemoryAlloc& save_to ); + memSavingState( SafeArray& save_to ); void FreezePlugin( const char* name, s32(CALLBACK *freezer)(int mode, freezeData *data) ); // Saving of state data to a memory buffer @@ -194,7 +194,7 @@ class memLoadingState : public memBaseStateInfo { public: virtual ~memLoadingState(); - memLoadingState(MemoryAlloc& load_from ); + memLoadingState(SafeArray& load_from ); void FreezePlugin( const char* name, s32(CALLBACK *freezer)(int mode, freezeData *data) ); // Loading of state data from a memory buffer... diff --git a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj index 10f1a246c0..2a6db861a3 100644 --- a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj +++ b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj @@ -1573,6 +1573,338 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + * g_RecoveryState; -extern MemoryAlloc* g_gsRecoveryState; +extern SafeArray* g_RecoveryState; +extern SafeArray* g_gsRecoveryState; extern const char* g_pRunGSState; extern int g_SaveGSStream; diff --git a/pcsx2/windows/WinSysExec.cpp b/pcsx2/windows/WinSysExec.cpp index ed760f4017..9244be7d50 100644 --- a/pcsx2/windows/WinSysExec.cpp +++ b/pcsx2/windows/WinSysExec.cpp @@ -31,8 +31,8 @@ int UseGui = 1; int nDisableSC = 0; // screensaver -MemoryAlloc* g_RecoveryState = NULL; -MemoryAlloc* g_gsRecoveryState = NULL; +SafeArray* g_RecoveryState = NULL; +SafeArray* g_gsRecoveryState = NULL; bool g_ReturnToGui = false; // set to exit the execution of the emulator and return control to the GUI @@ -681,7 +681,7 @@ static void __fastcall KeyEvent(keyEvent* ev) { safe_delete( g_gsRecoveryState ); safe_delete( g_RecoveryState ); - g_gsRecoveryState = new MemoryAlloc(); + g_gsRecoveryState = new SafeArray(); JustGsSavingState eddie; eddie.FreezePlugin( "GS", gsSafeFreeze ) ; eddie.gsFreeze(); @@ -710,7 +710,7 @@ void SysRestorableReset() try { - g_RecoveryState = new MemoryAlloc( "Memory Savestate Recovery" ); + g_RecoveryState = new SafeArray( "Memory Savestate Recovery" ); RecoveryMemSavingState().FreezeAll(); safe_delete( g_gsRecoveryState ); g_EmulationInProgress = false; diff --git a/pcsx2/windows/WinThreads.cpp b/pcsx2/windows/WinThreads.cpp index 94ff95796c..16d7031edb 100644 --- a/pcsx2/windows/WinThreads.cpp +++ b/pcsx2/windows/WinThreads.cpp @@ -72,20 +72,12 @@ namespace Threading { jASSUME( itsme != NULL ); - Thread& owner = *((Thread*)itsme); pthread_win32_thread_attach_np(); - try - { - owner.m_returncode = owner.Callback(); - } - catch( std::exception& ex ) - { - Console::Error( "Thread terminated abnormally with error:\n\t%s", params ex.what() ); - owner.m_returncode = -1; - } - + Thread& owner = *((Thread*)itsme); + owner.m_returncode = owner.Callback(); owner.m_terminated = true; + pthread_win32_thread_detach_np(); return NULL; diff --git a/pcsx2/windows/ini.cpp b/pcsx2/windows/ini.cpp index 137ec6a4b1..1cf1ac6419 100644 --- a/pcsx2/windows/ini.cpp +++ b/pcsx2/windows/ini.cpp @@ -140,7 +140,7 @@ public: class IniFileLoader : public IniFile { protected: - MemoryAlloc m_workspace; + SafeArray m_workspace; public: virtual ~IniFileLoader() {}