void readFile() { int rsize = 0; if ((strnicmp( filename.c_str(), "cdrom0:", strlen("cdromN:")) == 0) || (strnicmp( filename.c_str(), "cdrom1:", strlen("cdromN:")) == 0)) { int fi; fi = CDVDFS_open(filename.c_str() + strlen("cdromN:"), 1);//RDONLY if (fi < 0) throw Exception::FileNotFound( filename ); CDVDFS_lseek( fi, 0, SEEK_SET ); rsize = CDVDFS_read( fi, (char*)data.GetPtr(), data.GetSizeInBytes() ); CDVDFS_close( fi ); } else { FILE *f; f = fopen( filename.c_str(), "rb" ); if( f == NULL ) Exception::FileNotFound( filename ); fseek( f, 0, SEEK_SET ); rsize = fread( data.GetPtr(), 1, data.GetSizeInBytes(), f ); fclose( f ); } if( rsize < data.GetSizeInBytes() ) throw Exception::EndOfStream( filename ); }
s32 FileMemoryCard::Save( uint slot, const u8 *src, u32 adr, int size ) { wxFFile& mcfp( m_file[slot] ); if( !mcfp.IsOpened() ) { DevCon.Error( "(FileMcd) Ignoring attempted save/write to disabled slot." ); return 1; } if(m_ispsx[slot]) { m_currentdata.MakeRoomFor( size ); for (int i=0; i<size; i++) m_currentdata[i] = src[i]; } else { if( !Seek(mcfp, adr) ) return 0; m_currentdata.MakeRoomFor( size ); mcfp.Read( m_currentdata.GetPtr(), size); for (int i=0; i<size; i++) { if ((m_currentdata[i] & src[i]) != src[i]) Console.Warning("(FileMcd) Warning: writing to uncleared data. (%d) [%08X]", slot, adr); m_currentdata[i] &= src[i]; } // Checksumness { if(adr == m_chkaddr) Console.Warning("(FileMcd) Warning: checksum sector overwritten. (%d)", slot); u64 *pdata = (u64*)&m_currentdata[0]; u32 loops = size / 8; for(u32 i = 0; i < loops; i++) m_chksum[slot] ^= pdata[i]; } } if( !Seek(mcfp, adr) ) return 0; return mcfp.Write( m_currentdata.GetPtr(), size ) != 0; }
void loadProgramHeaders() { if ( proghead == NULL ) return; for( int i = 0 ; i < header.e_phnum ; i++ ) { ELF_LOG( "Elf32 Program Header\n" ); ELF_LOG( "type: " ); switch ( proghead[ i ].p_type ) { default: ELF_LOG( "unknown %x", (int)proghead[ i ].p_type ); break; case 0x1: { ELF_LOG("load"); const uint elfsize = data.GetLength(); if (proghead[ i ].p_offset < elfsize) { int size; if ((proghead[ i ].p_filesz + proghead[ i ].p_offset) > elfsize) size = elfsize - proghead[ i ].p_offset; else size = proghead[ i ].p_filesz; if( proghead[ i ].p_vaddr != proghead[ i ].p_paddr ) Console::Notice( "ElfProgram different load addrs: paddr=0x%8.8x, vaddr=0x%8.8x", params proghead[ i ].p_paddr, proghead[ i ].p_vaddr); // used to be paddr memcpy( &PS2MEM_BASE[proghead[ i ].p_vaddr & 0x1ffffff], data.GetPtr(proghead[ i ].p_offset), size ); ELF_LOG("\t*LOADED*"); } } break; } ELF_LOG("\n"); ELF_LOG("offset: %08x\n",(int)proghead[i].p_offset); ELF_LOG("vaddr: %08x\n",(int)proghead[i].p_vaddr); ELF_LOG("paddr: %08x\n",proghead[i].p_paddr); ELF_LOG("file size: %08x\n",proghead[i].p_filesz); ELF_LOG("mem size: %08x\n",proghead[i].p_memsz); ELF_LOG("flags: %08x\n",proghead[i].p_flags); ELF_LOG("palign: %08x\n",proghead[i].p_align); ELF_LOG("\n"); } }
u32 GetCRC() const { u32 CRC = 0; const u32* srcdata = (u32*)data.GetPtr(); for(u32 i=data.GetSizeInBytes()/4; i; --i, ++srcdata) CRC ^= *srcdata; return CRC; }
void loadSectionHeaders() { if( secthead == NULL || header.e_shoff > (u32)data.GetLength() ) return; const u8* sections_names = data.GetPtr( secthead[ (header.e_shstrndx == 0xffff ? 0 : header.e_shstrndx) ].sh_offset ); int i_st = -1; int i_dt = -1; for( int i = 0 ; i < header.e_shnum ; i++ ) { ELF_LOG( "Elf32 Section Header [%x] %s", i, §ions_names[ secthead[ i ].sh_name ] ); if ( secthead[i].sh_flags & 0x2 ) args_ptr = min( args_ptr, secthead[ i ].sh_addr & 0x1ffffff ); #ifdef PCSX2_DEVBULD ELF_LOG("\n"); ELF_LOG("type: "); switch ( secthead[ i ].sh_type ) { default: ELF_LOG("unknown %08x",secthead[i].sh_type); break; case 0x0: ELF_LOG("null"); break; case 0x1: ELF_LOG("progbits"); break; case 0x2: ELF_LOG("symtab"); break; case 0x3: ELF_LOG("strtab"); break; case 0x4: ELF_LOG("rela"); break; case 0x8: ELF_LOG("no bits"); break; case 0x9: ELF_LOG("rel"); break; } ELF_LOG("\n"); ELF_LOG("flags: %08x\n", secthead[i].sh_flags); ELF_LOG("addr: %08x\n", secthead[i].sh_addr); ELF_LOG("offset: %08x\n", secthead[i].sh_offset); ELF_LOG("size: %08x\n", secthead[i].sh_size); ELF_LOG("link: %08x\n", secthead[i].sh_link); ELF_LOG("info: %08x\n", secthead[i].sh_info); ELF_LOG("addralign: %08x\n", secthead[i].sh_addralign); ELF_LOG("entsize: %08x\n", secthead[i].sh_entsize); // dump symbol table if( secthead[ i ].sh_type == 0x02 ) { i_st = i; i_dt = secthead[i].sh_link; } #endif } if( ( i_st >= 0 ) && ( i_dt >= 0 ) ) { const char * SymNames; Elf32_Sym * eS; SymNames = (char*)data.GetPtr( secthead[ i_dt ].sh_offset ); eS = (Elf32_Sym*)data.GetPtr( secthead[ i_st ].sh_offset ); Console::WriteLn("found %d symbols", params secthead[ i_st ].sh_size / sizeof( Elf32_Sym )); for( uint i = 1; i < ( secthead[ i_st ].sh_size / sizeof( Elf32_Sym ) ); i++ ) { if ( ( eS[ i ].st_value != 0 ) && ( ELF32_ST_TYPE( eS[ i ].st_info ) == 2 ) ) { R5900::disR5900AddSym( eS[i].st_value, &SymNames[ eS[ i ].st_name ] ); } } } }
ElfObject( const string& srcfile, uint hdrsize ) : filename( srcfile ) , data( hdrsize, "ELF headers" ) , header( *(ELF_HEADER*)data.GetPtr() ) , proghead( NULL ) , secthead( NULL ) { readFile(); 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 ) { default: ELF_LOG( "unknown %x", header.e_type ); break; case 0x0: ELF_LOG( "no file type" ); break; case 0x1: ELF_LOG( "relocatable" ); break; case 0x2: ELF_LOG( "executable" ); break; } ELF_LOG( "\n" ); ELF_LOG( "machine: " ); switch ( header.e_machine ) { default: ELF_LOG( "unknown" ); break; case 0x8: ELF_LOG( "mips_rs3000" ); break; } ELF_LOG("\n"); ELF_LOG("version: %d\n",header.e_version); ELF_LOG("entry: %08x\n",header.e_entry); ELF_LOG("flags: %08x\n",header.e_flags); ELF_LOG("eh size: %08x\n",header.e_ehsize); ELF_LOG("ph off: %08x\n",header.e_phoff); ELF_LOG("ph entsiz: %08x\n",header.e_phentsize); ELF_LOG("ph num: %08x\n",header.e_phnum); ELF_LOG("sh off: %08x\n",header.e_shoff); ELF_LOG("sh entsiz: %08x\n",header.e_shentsize); ELF_LOG("sh num: %08x\n",header.e_shnum); ELF_LOG("sh strndx: %08x\n",header.e_shstrndx); ELF_LOG("\n"); }
s32 FileMemoryCard::Save( uint slot, const u8 *src, u32 adr, int size ) { wxFFile& mcfp( m_file[slot] ); if( !mcfp.IsOpened() ) { DevCon.Error( "(FileMcd) Ignoring attempted save/write to disabled slot." ); return 1; } if(m_ispsx[slot]) { m_currentdata.MakeRoomFor( size ); for (int i=0; i<size; i++) m_currentdata[i] = src[i]; } else { if( !Seek(mcfp, adr) ) return 0; m_currentdata.MakeRoomFor( size ); mcfp.Read( m_currentdata.GetPtr(), size); for (int i=0; i<size; i++) { if ((m_currentdata[i] & src[i]) != src[i]) Console.Warning("(FileMcd) Warning: writing to uncleared data. (%d) [%08X]", slot, adr); m_currentdata[i] &= src[i]; } // Checksumness { if(adr == m_chkaddr) Console.Warning("(FileMcd) Warning: checksum sector overwritten. (%d)", slot); u64 *pdata = (u64*)&m_currentdata[0]; u32 loops = size / 8; for(u32 i = 0; i < loops; i++) m_chksum[slot] ^= pdata[i]; } } if( !Seek(mcfp, adr) ) return 0; int status = mcfp.Write( m_currentdata.GetPtr(), size ); if( status ) { static auto last = std::chrono::time_point<std::chrono::system_clock>(); std::chrono::duration<float> elapsed = std::chrono::system_clock::now() - last; if(elapsed > std::chrono::seconds(5)) { wxString name, ext; wxFileName::SplitPath(m_file[slot].GetName(), NULL, NULL, &name, &ext); OSDlog( Color_StrongYellow, false, "Memory Card %s written.", (const char *)(name + "." + ext).c_str() ); last = std::chrono::system_clock::now(); } return 1; } return 0; }