mirror of https://github.com/PCSX2/pcsx2.git
Mucked around with Elfheaders a bit. Cranked up the number of chars in DisR3000A (Because I own a few games with symbols over 64 chars). A few other things.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2407 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
e4ff3b8014
commit
a38a27aa9c
|
@ -305,30 +305,50 @@ s32 cdvdWriteConfig(const u8* config)
|
||||||
|
|
||||||
static MutexLockRecursive Mutex_NewDiskCB;
|
static MutexLockRecursive Mutex_NewDiskCB;
|
||||||
|
|
||||||
static void reloadElfInfo(const char* str)
|
static __forceinline void _reloadElfInfo(wxString str)
|
||||||
{
|
{
|
||||||
// Now's a good time to reload the ELF info...
|
// Now's a good time to reload the ELF info...
|
||||||
if (ElfCRC == 0)
|
|
||||||
{
|
|
||||||
ScopedLock locker( Mutex_NewDiskCB );
|
ScopedLock locker( Mutex_NewDiskCB );
|
||||||
|
|
||||||
ElfCRC = loadElfCRC( str );
|
ElfCRC = loadElfCRC(str);
|
||||||
|
|
||||||
ElfApplyPatches();
|
ElfApplyPatches();
|
||||||
GetMTGS().SendGameCRC( ElfCRC );
|
GetMTGS().SendGameCRC(ElfCRC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __forceinline void reloadElfInfo(u32 discType, wxString str)
|
||||||
|
{
|
||||||
|
if (ElfCRC == 0)
|
||||||
|
{
|
||||||
|
switch (discType)
|
||||||
|
{
|
||||||
|
case 2: // Is a PS2 disc.
|
||||||
|
_reloadElfInfo(str);
|
||||||
|
break;
|
||||||
|
case 1: // Is a PS1 disc.
|
||||||
|
if (ENABLE_LOADING_PS1_GAMES) _reloadElfInfo(str);
|
||||||
|
break;
|
||||||
|
default: // Isn't a disc we recognise.
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdvdReadKey(u8 arg0, u16 arg1, u32 arg2, u8* key) {
|
void cdvdReadKey(u8 arg0, u16 arg1, u32 arg2, u8* key)
|
||||||
wxString fname;
|
{
|
||||||
char exeName[12];
|
|
||||||
s32 numbers, letters;
|
s32 numbers, letters;
|
||||||
u32 key_0_3;
|
u32 key_0_3;
|
||||||
u8 key_4, key_14;
|
u8 key_4, key_14;
|
||||||
|
|
||||||
// get main elf name
|
wxString fname;
|
||||||
bool IsPs2 = (GetPS2ElfName(fname) == 2);
|
char exeName[12];
|
||||||
|
|
||||||
|
// Get the main elf name.
|
||||||
|
u32 discType = GetPS2ElfName(fname);
|
||||||
|
|
||||||
const wxCharBuffer crap( fname.To8BitData() );
|
const wxCharBuffer crap( fname.To8BitData() );
|
||||||
const char* str = crap.data();
|
const char* str = crap.data();
|
||||||
|
|
||||||
sprintf(exeName, "%c%c%c%c%c%c%c%c%c%c%c",str[8],str[9],str[10],str[11],str[12],str[13],str[14],str[15],str[16],str[17],str[18]);
|
sprintf(exeName, "%c%c%c%c%c%c%c%c%c%c%c",str[8],str[9],str[10],str[11],str[12],str[13],str[14],str[15],str[16],str[17],str[18]);
|
||||||
DevCon.Warning("exeName = %s", &str[8]);
|
DevCon.Warning("exeName = %s", &str[8]);
|
||||||
|
|
||||||
|
@ -390,7 +410,7 @@ void cdvdReadKey(u8 arg0, u16 arg1, u32 arg2, u8* key) {
|
||||||
Console.WriteLn( "CDVD.KEY = %02X,%02X,%02X,%02X,%02X,%02X,%02X",
|
Console.WriteLn( "CDVD.KEY = %02X,%02X,%02X,%02X,%02X,%02X,%02X",
|
||||||
cdvd.Key[0],cdvd.Key[1],cdvd.Key[2],cdvd.Key[3],cdvd.Key[4],cdvd.Key[14],cdvd.Key[15] );
|
cdvd.Key[0],cdvd.Key[1],cdvd.Key[2],cdvd.Key[3],cdvd.Key[4],cdvd.Key[14],cdvd.Key[15] );
|
||||||
|
|
||||||
if (IsPs2) reloadElfInfo(str);
|
reloadElfInfo(discType, fname);
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 cdvdGetToc(void* toc)
|
s32 cdvdGetToc(void* toc)
|
||||||
|
@ -512,12 +532,10 @@ void SaveStateBase::cdvdFreeze()
|
||||||
|
|
||||||
static void cdvdDetectDisk()
|
static void cdvdDetectDisk()
|
||||||
{
|
{
|
||||||
|
wxString str;
|
||||||
cdvd.Type = DoCDVDdetectDiskType();
|
cdvd.Type = DoCDVDdetectDiskType();
|
||||||
|
|
||||||
wxString str;
|
reloadElfInfo(GetPS2ElfName(str), str);
|
||||||
bool IsPs2 = (GetPS2ElfName(str) == 2);
|
|
||||||
|
|
||||||
if (IsPs2) reloadElfInfo( str.ToUTF8() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdvdNewDiskCB()
|
void cdvdNewDiskCB()
|
||||||
|
|
|
@ -181,12 +181,18 @@ isoFile *isoOpen(const char *filename)
|
||||||
iso->blocks = (u32)((_tellfile(iso->handle) - iso->offset) / (iso->blocksize));
|
iso->blocks = (u32)((_tellfile(iso->handle) - iso->offset) / (iso->blocksize));
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLn("isoOpen: %s ok", iso->filename);
|
switch(iso->type)
|
||||||
Console.WriteLn("offset = %d", iso->offset);
|
{
|
||||||
Console.WriteLn("blockofs = %d", iso->blockofs);
|
case ISOTYPE_CD: Console.Write("isoOpen(CD): "); break;
|
||||||
Console.WriteLn("blocksize = %u", iso->blocksize);
|
case ISOTYPE_DVD: Console.Write("isoOpen(DVD): "); break;
|
||||||
Console.WriteLn("blocks = %u", iso->blocks);
|
case ISOTYPE_AUDIO: Console.Write("isoOpen(Audio CD): "); break;
|
||||||
Console.WriteLn("type = %u", iso->type);
|
case ISOTYPE_DVDDL: Console.Write("isoOpen(DVDDL): "); break;
|
||||||
|
case ISOTYPE_ILLEGAL:
|
||||||
|
default: Console.Write("isoOpen(illegal media): "); break;
|
||||||
|
}
|
||||||
|
Console.WriteLn("%s ok.", iso->filename);
|
||||||
|
Console.WriteLn("The iso has %u blocks (size %u).", iso->blocks, iso->blocksize);
|
||||||
|
Console.WriteLn("The isos offset is %d, and the block offset is %d.", iso->offset, iso->blockofs);
|
||||||
|
|
||||||
return iso;
|
return iso;
|
||||||
}
|
}
|
||||||
|
|
|
@ -619,11 +619,11 @@ TraceLogFilters& SetTraceConfig();
|
||||||
|
|
||||||
#define EE_CONST_PROP // rec2 - enables constant propagation (faster)
|
#define EE_CONST_PROP // rec2 - enables constant propagation (faster)
|
||||||
|
|
||||||
// Uncomment this if working on getting PS1 emulation working.
|
// Change to 1 if working on getting PS1 emulation working.
|
||||||
// This disables the exception normally caused by trying to load PS1
|
// This disables the exception normally caused by trying to load PS1
|
||||||
// games. Note: currently PS1 games will error out even without this
|
// games. Note: currently PS1 games will error out even without this
|
||||||
// commented, so this is for development purposes only.
|
// commented, so this is for development purposes only.
|
||||||
//#define ENABLE_LOADING_PS1_GAMES
|
#define ENABLE_LOADING_PS1_GAMES 0
|
||||||
|
|
||||||
// Change to 1 to enable SIF wakeup hack:
|
// Change to 1 to enable SIF wakeup hack:
|
||||||
#define IOP_ENABLE_SIF_HACK 0
|
#define IOP_ENABLE_SIF_HACK 0
|
||||||
|
|
|
@ -164,7 +164,7 @@ typedef void (*TdisR5900F)DisFInterface;
|
||||||
|
|
||||||
struct sSymbol {
|
struct sSymbol {
|
||||||
u32 addr;
|
u32 addr;
|
||||||
char name[64];
|
char name[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
static sSymbol *dSyms = NULL;
|
static sSymbol *dSyms = NULL;
|
||||||
|
@ -186,7 +186,7 @@ void disR5900AddSym(u32 addr, const char *name) {
|
||||||
|
|
||||||
if (dSyms == NULL) return;
|
if (dSyms == NULL) return;
|
||||||
dSyms[nSyms].addr = addr;
|
dSyms[nSyms].addr = addr;
|
||||||
strncpy(dSyms[nSyms].name, name, 64);
|
strncpy(dSyms[nSyms].name, name, 256);
|
||||||
nSyms++;
|
nSyms++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,113 +17,13 @@
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
#include "GS.h" // for sending game crc to mtgs
|
#include "GS.h" // for sending game crc to mtgs
|
||||||
|
#include "Elfheader.h"
|
||||||
#include "CDVD/IsoFS/IsoFSCDVD.h"
|
|
||||||
#include "CDVD/IsoFS/IsoFS.h"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
extern void InitPatch(const wxString& crc);
|
extern void InitPatch(const wxString& crc);
|
||||||
|
|
||||||
u32 ElfCRC;
|
u32 ElfCRC;
|
||||||
|
|
||||||
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
|
|
||||||
u16 e_machine; //Processor: 8=MIPS R3000
|
|
||||||
u32 e_version; //Version: 1=current
|
|
||||||
u32 e_entry; //Entry point address
|
|
||||||
u32 e_phoff; //Start of program headers (offset from file start)
|
|
||||||
u32 e_shoff; //Start of section headers (offset from file start)
|
|
||||||
u32 e_flags; //Processor specific flags = 0x20924001 noreorder, mips
|
|
||||||
u16 e_ehsize; //ELF header size (0x34 = 52 bytes)
|
|
||||||
u16 e_phentsize; //Program headers entry size
|
|
||||||
u16 e_phnum; //Number of program headers
|
|
||||||
u16 e_shentsize; //Section headers entry size
|
|
||||||
u16 e_shnum; //Number of section headers
|
|
||||||
u16 e_shstrndx; //Section header stringtable index
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ELF_PHR {
|
|
||||||
u32 p_type; //see notes1
|
|
||||||
u32 p_offset; //Offset from file start to program segment.
|
|
||||||
u32 p_vaddr; //Virtual address of the segment
|
|
||||||
u32 p_paddr; //Physical address of the segment
|
|
||||||
u32 p_filesz; //Number of bytes in the file image of the segment
|
|
||||||
u32 p_memsz; //Number of bytes in the memory image of the segment
|
|
||||||
u32 p_flags; //Flags for segment
|
|
||||||
u32 p_align; //Alignment. The address of 0x08 and 0x0C must fit this alignment. 0=no alignment
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
notes1
|
|
||||||
------
|
|
||||||
0=Inactive
|
|
||||||
1=Load the segment into memory, no. of bytes specified by 0x10 and 0x14
|
|
||||||
2=Dynamic linking
|
|
||||||
3=Interpreter. The array element must specify a path name
|
|
||||||
4=Note. The array element must specify the location and size of aux. info
|
|
||||||
5=reserved
|
|
||||||
6=The array element must specify location and size of the program header table.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct ELF_SHR {
|
|
||||||
u32 sh_name; //No. to the index of the Section header stringtable index
|
|
||||||
u32 sh_type; //See notes2
|
|
||||||
u32 sh_flags; //see notes3
|
|
||||||
u32 sh_addr; //Section start address
|
|
||||||
u32 sh_offset; //Offset from start of file to section
|
|
||||||
u32 sh_size; //Size of section
|
|
||||||
u32 sh_link; //Section header table index link
|
|
||||||
u32 sh_info; //Info
|
|
||||||
u32 sh_addralign; //Alignment. The adress of 0x0C must fit this alignment. 0=no alignment.
|
|
||||||
u32 sh_entsize; //Fixed size entries.
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
notes 2
|
|
||||||
-------
|
|
||||||
Type:
|
|
||||||
0=Inactive
|
|
||||||
1=PROGBITS
|
|
||||||
2=SYMTAB symbol table
|
|
||||||
3=STRTAB string table
|
|
||||||
4=RELA relocation entries
|
|
||||||
5=HASH hash table
|
|
||||||
6=DYNAMIC dynamic linking information
|
|
||||||
7=NOTE
|
|
||||||
8=NOBITS
|
|
||||||
9=REL relocation entries
|
|
||||||
10=SHLIB
|
|
||||||
0x70000000=LOPROC processor specifc
|
|
||||||
0x7fffffff=HIPROC
|
|
||||||
0x80000000=LOUSER lower bound
|
|
||||||
0xffffffff=HIUSER upper bound
|
|
||||||
|
|
||||||
notes 3
|
|
||||||
-------
|
|
||||||
Section Flags: (1 bit, you may combine them like 3 = alloc & write permission)
|
|
||||||
1=Write section contains data the is be writeable during execution.
|
|
||||||
2=Alloc section occupies memory during execution
|
|
||||||
4=Exec section contains executable instructions
|
|
||||||
0xf0000000=Mask bits processor-specific
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct Elf32_Sym {
|
|
||||||
u32 st_name;
|
|
||||||
u32 st_value;
|
|
||||||
u32 st_size;
|
|
||||||
u8 st_info;
|
|
||||||
u8 st_other;
|
|
||||||
u16 st_shndx;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define ELF32_ST_TYPE(i) ((i)&0xf)
|
|
||||||
|
|
||||||
struct Elf32_Rel {
|
|
||||||
u32 r_offset;
|
|
||||||
u32 r_info;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// fixme: ELF command line option system.
|
// fixme: ELF command line option system.
|
||||||
// It parses a command line and pastes it into PS2 memory, and then points the a0 register at it.
|
// It parses a command line and pastes it into PS2 memory, and then points the a0 register at it.
|
||||||
|
@ -238,31 +138,42 @@ static uint parseCommandLine( const wxString& filename )
|
||||||
#endif
|
#endif
|
||||||
//---------------
|
//---------------
|
||||||
|
|
||||||
struct ElfObject
|
// All of ElfObjects functions.
|
||||||
{
|
ElfObject::ElfObject(const wxString& srcfile, IsoFile isofile)
|
||||||
wxString filename;
|
|
||||||
SafeArray<u8> data;
|
|
||||||
ELF_HEADER& header;
|
|
||||||
ELF_PHR* proghead;
|
|
||||||
ELF_SHR* secthead;
|
|
||||||
|
|
||||||
// Destructor!
|
|
||||||
// C++ does all the cleanup automagically for us.
|
|
||||||
virtual ~ElfObject() throw() { }
|
|
||||||
|
|
||||||
ElfObject( const wxString& srcfile, uint hdrsize )
|
|
||||||
: filename( srcfile )
|
: filename( srcfile )
|
||||||
, data( hdrsize, L"ELF headers" )
|
|
||||||
|
, data( wxULongLong(isofile.getLength()).GetLo(), L"ELF headers" )
|
||||||
, header( *(ELF_HEADER*)data.GetPtr() )
|
, header( *(ELF_HEADER*)data.GetPtr() )
|
||||||
, proghead( NULL )
|
, proghead( NULL )
|
||||||
, secthead( NULL )
|
, secthead( NULL )
|
||||||
{
|
{
|
||||||
readFile();
|
isCdvd = true;
|
||||||
|
checkElfSize(data.GetSizeInBytes());
|
||||||
|
readIso(isofile);
|
||||||
|
initElfHeaders();
|
||||||
|
}
|
||||||
|
|
||||||
if( header.e_phnum > 0 )
|
ElfObject::ElfObject( const wxString& srcfile, uint hdrsize )
|
||||||
|
: filename( srcfile )
|
||||||
|
, data( wxULongLong(hdrsize).GetLo(), L"ELF headers" )
|
||||||
|
, header( *(ELF_HEADER*)data.GetPtr() )
|
||||||
|
, proghead( NULL )
|
||||||
|
, secthead( NULL )
|
||||||
|
{
|
||||||
|
isCdvd = false;
|
||||||
|
checkElfSize(data.GetSizeInBytes());
|
||||||
|
readFile();
|
||||||
|
initElfHeaders();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElfObject::initElfHeaders()
|
||||||
|
{
|
||||||
|
Console.WriteLn( L"Initializing Elf: %d bytes", data.GetSizeInBytes());
|
||||||
|
|
||||||
|
if ( header.e_phnum > 0 )
|
||||||
proghead = (ELF_PHR*)&data[header.e_phoff];
|
proghead = (ELF_PHR*)&data[header.e_phoff];
|
||||||
|
|
||||||
if( header.e_shnum > 0 )
|
if ( header.e_shnum > 0 )
|
||||||
secthead = (ELF_SHR*)&data[header.e_shoff];
|
secthead = (ELF_SHR*)&data[header.e_shoff];
|
||||||
|
|
||||||
if ( ( header.e_shnum > 0 ) && ( header.e_shentsize != sizeof(ELF_SHR) ) )
|
if ( ( header.e_shnum > 0 ) && ( header.e_shentsize != sizeof(ELF_SHR) ) )
|
||||||
|
@ -282,10 +193,12 @@ struct ElfObject
|
||||||
case 0x1: elftype = "relocatable"; break;
|
case 0x1: elftype = "relocatable"; break;
|
||||||
case 0x2: elftype = "executable"; break;
|
case 0x2: elftype = "executable"; break;
|
||||||
}
|
}
|
||||||
if( elftype != NULL ) ELF_LOG( "type: %s", elftype );
|
|
||||||
|
if (elftype != NULL) ELF_LOG( "type: %s", elftype );
|
||||||
|
|
||||||
const char* machine = NULL;
|
const char* machine = NULL;
|
||||||
switch ( header.e_machine )
|
|
||||||
|
switch(header.e_machine)
|
||||||
{
|
{
|
||||||
case 1: machine = "AT&T WE 32100"; break;
|
case 1: machine = "AT&T WE 32100"; break;
|
||||||
case 2: machine = "SPARC"; break;
|
case 2: machine = "SPARC"; break;
|
||||||
|
@ -300,8 +213,7 @@ struct ElfObject
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( machine != NULL )
|
if (machine != NULL) ELF_LOG( "machine: %s", machine );
|
||||||
ELF_LOG( "machine: %s", machine );
|
|
||||||
|
|
||||||
ELF_LOG("version: %d",header.e_version);
|
ELF_LOG("version: %d",header.e_version);
|
||||||
ELF_LOG("entry: %08x",header.e_entry);
|
ELF_LOG("entry: %08x",header.e_entry);
|
||||||
|
@ -316,39 +228,47 @@ struct ElfObject
|
||||||
ELF_LOG("sh strndx: %08x",header.e_shstrndx);
|
ELF_LOG("sh strndx: %08x",header.e_shstrndx);
|
||||||
|
|
||||||
ELF_LOG("\n");
|
ELF_LOG("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void readFile()
|
bool ElfObject::hasProgramHeaders() { return (proghead != NULL); }
|
||||||
{
|
bool ElfObject::hasSectionHeaders() { return (secthead != NULL); }
|
||||||
|
bool ElfObject::hasHeaders() { return (hasProgramHeaders() && hasSectionHeaders()); }
|
||||||
|
|
||||||
|
void ElfObject::readIso(IsoFile file)
|
||||||
|
{
|
||||||
|
int rsize = file.read(data.GetPtr(), data.GetSizeInBytes());
|
||||||
|
if (rsize < data.GetSizeInBytes()) throw Exception::EndOfStream( filename );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElfObject::readFile()
|
||||||
|
{
|
||||||
int rsize = 0;
|
int rsize = 0;
|
||||||
const wxCharBuffer work( filename.ToUTF8() );
|
|
||||||
if ((strnicmp( work, "cdrom:", strlen("cdrom:" )) == 0) ||
|
|
||||||
(strnicmp( work, "cdrom0:", strlen("cdromN:")) == 0) ||
|
|
||||||
(strnicmp( work, "cdrom1:", strlen("cdromN:")) == 0))
|
|
||||||
{
|
|
||||||
IsoFSCDVD isofs;
|
|
||||||
IsoFile file( isofs, fromUTF8(work) );
|
|
||||||
|
|
||||||
//int size = file.getLength();
|
|
||||||
rsize = file.read(data.GetPtr(), data.GetSizeInBytes());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
|
||||||
f = fopen( work.data(), "rb" );
|
f = fopen( filename.ToUTF8(), "rb" );
|
||||||
if( f == NULL ) Exception::FileNotFound( filename );
|
if (f == NULL) Exception::FileNotFound( filename );
|
||||||
|
|
||||||
fseek( f, 0, SEEK_SET );
|
fseek(f, 0, SEEK_SET);
|
||||||
rsize = fread( data.GetPtr(), 1, data.GetSizeInBytes(), f );
|
rsize = fread(data.GetPtr(), 1, data.GetSizeInBytes(), f);
|
||||||
fclose( f );
|
fclose( f );
|
||||||
}
|
|
||||||
|
|
||||||
if( rsize < data.GetSizeInBytes() ) throw Exception::EndOfStream( filename );
|
if (rsize < data.GetSizeInBytes()) throw Exception::EndOfStream( filename );
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 GetCRC() const
|
void ElfObject::checkElfSize(s64 elfsize)
|
||||||
{
|
{
|
||||||
|
if (elfsize > 0xfffffff)
|
||||||
|
throw Exception::BadStream( filename, wxLt("Illegal ELF file size, over 2GB!") );
|
||||||
|
|
||||||
|
if (elfsize == -1)
|
||||||
|
throw Exception::BadStream( filename, wxLt("Elf file does not exist! ") );
|
||||||
|
|
||||||
|
if (elfsize == 0)
|
||||||
|
throw Exception::BadStream( filename, wxLt("Unexpected end of ELF file: ") );
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 ElfObject::getCRC() const
|
||||||
|
{
|
||||||
u32 CRC = 0;
|
u32 CRC = 0;
|
||||||
|
|
||||||
const u32* srcdata = (u32*)data.GetPtr();
|
const u32* srcdata = (u32*)data.GetPtr();
|
||||||
|
@ -356,20 +276,19 @@ struct ElfObject
|
||||||
CRC ^= *srcdata;
|
CRC ^= *srcdata;
|
||||||
|
|
||||||
return CRC;
|
return CRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ElfObject::loadProgramHeaders()
|
||||||
void loadProgramHeaders()
|
{
|
||||||
{
|
if (proghead == NULL) return;
|
||||||
if ( proghead == NULL )
|
|
||||||
return;
|
|
||||||
|
|
||||||
for( int i = 0 ; i < header.e_phnum ; i++ )
|
for( int i = 0 ; i < header.e_phnum ; i++ )
|
||||||
{
|
{
|
||||||
ELF_LOG( "Elf32 Program Header" );
|
ELF_LOG( "Elf32 Program Header" );
|
||||||
ELF_LOG( "type: " );
|
ELF_LOG( "type: " );
|
||||||
|
|
||||||
switch ( proghead[ i ].p_type ) {
|
switch(proghead[ i ].p_type)
|
||||||
|
{
|
||||||
default:
|
default:
|
||||||
ELF_LOG( "unknown %x", (int)proghead[ i ].p_type );
|
ELF_LOG( "unknown %x", (int)proghead[ i ].p_type );
|
||||||
break;
|
break;
|
||||||
|
@ -379,7 +298,8 @@ struct ElfObject
|
||||||
ELF_LOG("load");
|
ELF_LOG("load");
|
||||||
const uint elfsize = data.GetLength();
|
const uint elfsize = data.GetLength();
|
||||||
|
|
||||||
if (proghead[ i ].p_offset < elfsize) {
|
if (proghead[ i ].p_offset < elfsize)
|
||||||
|
{
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
if ((proghead[ i ].p_filesz + proghead[ i ].p_offset) > elfsize)
|
if ((proghead[ i ].p_filesz + proghead[ i ].p_offset) > elfsize)
|
||||||
|
@ -387,7 +307,7 @@ struct ElfObject
|
||||||
else
|
else
|
||||||
size = proghead[ i ].p_filesz;
|
size = proghead[ i ].p_filesz;
|
||||||
|
|
||||||
if( proghead[ i ].p_vaddr != proghead[ i ].p_paddr )
|
if (proghead[ i ].p_vaddr != proghead[ i ].p_paddr)
|
||||||
Console.Warning( "ElfProgram different load addrs: paddr=0x%8.8x, vaddr=0x%8.8x",
|
Console.Warning( "ElfProgram different load addrs: paddr=0x%8.8x, vaddr=0x%8.8x",
|
||||||
proghead[ i ].p_paddr, proghead[ i ].p_vaddr);
|
proghead[ i ].p_paddr, proghead[ i ].p_vaddr);
|
||||||
|
|
||||||
|
@ -413,17 +333,15 @@ struct ElfObject
|
||||||
ELF_LOG("palign: %08x",proghead[i].p_align);
|
ELF_LOG("palign: %08x",proghead[i].p_align);
|
||||||
ELF_LOG("\n");
|
ELF_LOG("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadSectionHeaders()
|
void ElfObject::loadSectionHeaders()
|
||||||
{
|
{
|
||||||
if( secthead == NULL || header.e_shoff > (u32)data.GetLength() )
|
if (secthead == NULL || header.e_shoff > (u32)data.GetLength()) return;
|
||||||
return;
|
|
||||||
|
|
||||||
const u8* sections_names = data.GetPtr( secthead[ (header.e_shstrndx == 0xffff ? 0 : header.e_shstrndx) ].sh_offset );
|
const u8* sections_names = data.GetPtr( secthead[ (header.e_shstrndx == 0xffff ? 0 : header.e_shstrndx) ].sh_offset );
|
||||||
|
|
||||||
int i_st = -1;
|
int i_st = -1, i_dt = -1;
|
||||||
int i_dt = -1;
|
|
||||||
|
|
||||||
for( int i = 0 ; i < header.e_shnum ; i++ )
|
for( int i = 0 ; i < header.e_shnum ; i++ )
|
||||||
{
|
{
|
||||||
|
@ -436,7 +354,7 @@ struct ElfObject
|
||||||
ELF_LOG("\n");
|
ELF_LOG("\n");
|
||||||
|
|
||||||
const char* sectype = NULL;
|
const char* sectype = NULL;
|
||||||
switch ( secthead[ i ].sh_type )
|
switch(secthead[ i ].sh_type)
|
||||||
{
|
{
|
||||||
case 0x0: sectype = "null"; break;
|
case 0x0: sectype = "null"; break;
|
||||||
case 0x1: sectype = "progbits"; break;
|
case 0x1: sectype = "progbits"; break;
|
||||||
|
@ -462,56 +380,59 @@ struct ElfObject
|
||||||
ELF_LOG("entsize: %08x", secthead[i].sh_entsize);
|
ELF_LOG("entsize: %08x", secthead[i].sh_entsize);
|
||||||
// dump symbol table
|
// dump symbol table
|
||||||
|
|
||||||
if( secthead[ i ].sh_type == 0x02 )
|
if (secthead[ i ].sh_type == 0x02)
|
||||||
{
|
{
|
||||||
i_st = i;
|
i_st = i;
|
||||||
i_dt = secthead[i].sh_link;
|
i_dt = secthead[i].sh_link;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( i_st >= 0 ) && ( i_dt >= 0 ) )
|
if ((i_st >= 0) && (i_dt >= 0))
|
||||||
{
|
{
|
||||||
const char * SymNames;
|
const char * SymNames;
|
||||||
Elf32_Sym * eS;
|
Elf32_Sym * eS;
|
||||||
|
|
||||||
SymNames = (char*)data.GetPtr( secthead[ i_dt ].sh_offset );
|
SymNames = (char*)data.GetPtr(secthead[i_dt].sh_offset);
|
||||||
eS = (Elf32_Sym*)data.GetPtr( secthead[ i_st ].sh_offset );
|
eS = (Elf32_Sym*)data.GetPtr(secthead[i_st].sh_offset);
|
||||||
Console.WriteLn("found %d symbols", secthead[ i_st ].sh_size / sizeof( Elf32_Sym ));
|
Console.WriteLn("found %d symbols", secthead[i_st].sh_size / sizeof(Elf32_Sym));
|
||||||
|
|
||||||
for( uint i = 1; i < ( secthead[ i_st ].sh_size / sizeof( Elf32_Sym ) ); i++ ) {
|
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 ) ) {
|
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 ] );
|
{
|
||||||
|
R5900::disR5900AddSym(eS[i].st_value, &SymNames[eS[i].st_name]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
void ElfObject::loadHeaders()
|
||||||
|
{
|
||||||
|
loadProgramHeaders();
|
||||||
|
loadSectionHeaders();
|
||||||
|
}
|
||||||
|
|
||||||
void ElfApplyPatches()
|
void ElfApplyPatches()
|
||||||
{
|
{
|
||||||
wxString filename( wxsFormat( L"%8.8x", ElfCRC ) );
|
wxString filename( wxsFormat( L"%8.8x", ElfCRC ) );
|
||||||
|
|
||||||
// if patches found the following status msg will be overwritten
|
// if patches found the following status msg will be overwritten
|
||||||
Console.SetTitle( wxsFormat( _("Game running [CRC=%s]"), filename.c_str() ) );
|
Console.SetTitle(L"Game running [CRC=" + filename +L"]");
|
||||||
|
|
||||||
if( !EmuConfig.EnablePatches ) return;
|
if (EmuConfig.EnablePatches) InitPatch(filename);
|
||||||
|
|
||||||
InitPatch(filename);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetches the CRC of the game bound to the CDVD plugin.
|
// Fetches the CRC of the game bound to the CDVD plugin.
|
||||||
u32 loadElfCRC( const char* filename )
|
u32 loadElfCRC( const wxString filename )
|
||||||
{
|
{
|
||||||
|
// Note: calling loadElfFile here causes bad things to happen.
|
||||||
u32 crcval = 0;
|
u32 crcval = 0;
|
||||||
Console.WriteLn("loadElfCRC: %s", filename);
|
|
||||||
|
|
||||||
IsoFSCDVD isofs;
|
IsoFSCDVD isofs;
|
||||||
const int filesize = IsoDirectory(isofs).GetFileSize( fromUTF8(filename) );
|
IsoFile file(isofs, filename);
|
||||||
|
|
||||||
DevCon.WriteLn( "loadElfFile: %d bytes", filesize );
|
crcval = ElfObject(filename, file).getCRC();
|
||||||
crcval = ElfObject( fromUTF8(filename), filesize ).GetCRC();
|
|
||||||
Console.WriteLn( "loadElfFile: %s; CRC = %8.8X", filename, crcval );
|
|
||||||
|
|
||||||
|
Console.WriteLn(wxsFormat(L"loadElfCRC(" + filename + L") = %8.8X", crcval));
|
||||||
return crcval;
|
return crcval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -525,54 +446,39 @@ u32 loadElfCRC( const char* filename )
|
||||||
// If the specified filename is empty then no action is taken (PS2 will continue booting
|
// If the specified filename is empty then no action is taken (PS2 will continue booting
|
||||||
// normally as if it has no CD.
|
// normally as if it has no CD.
|
||||||
//
|
//
|
||||||
// Throws exception on error:
|
// Throws exceptions on errors. Not called if not skipping the bios.
|
||||||
//
|
//
|
||||||
void loadElfFile(const wxString& filename)
|
void loadElfFile(const wxString& filename)
|
||||||
{
|
{
|
||||||
if( filename.IsEmpty() ) return;
|
ElfObject *elfptr;
|
||||||
|
|
||||||
|
if (filename.IsEmpty()) return;
|
||||||
|
|
||||||
s64 elfsize;
|
|
||||||
Console.WriteLn( L"loadElfFile: " + filename );
|
Console.WriteLn( L"loadElfFile: " + filename );
|
||||||
|
|
||||||
const wxCharBuffer fnptr( filename.ToUTF8() );
|
if (filename.StartsWith(L"cdrom:") && !ENABLE_LOADING_PS1_GAMES)
|
||||||
bool useCdvdSource = false;
|
|
||||||
|
|
||||||
#ifndef ENABLE_LOADING_PS1_GAMES
|
|
||||||
if( filename.StartsWith( L"cdrom:" ) )
|
|
||||||
throw Exception::RuntimeError( wxLt("This is not a Ps2 disc. (And we don't currently emulate PS1 games)") );
|
throw Exception::RuntimeError( wxLt("This is not a Ps2 disc. (And we don't currently emulate PS1 games)") );
|
||||||
#endif
|
|
||||||
|
|
||||||
if( !filename.StartsWith( L"cdrom:" ) && !filename.StartsWith( L"cdrom0:" ) && !filename.StartsWith( L"cdrom1:" ) )
|
if (filename.StartsWith(L"cdrom:") || filename.StartsWith(L"cdrom0:") || filename.StartsWith(L"cdrom1:"))
|
||||||
{
|
{
|
||||||
DevCon.WriteLn("Loading from a file (or non-cd image)");
|
// It's a game disc.
|
||||||
elfsize = Path::GetFileSize( filename );
|
DevCon.WriteLn(L"Loading from a CD rom or CD image.");
|
||||||
|
|
||||||
|
IsoFSCDVD isofs;
|
||||||
|
IsoFile file(isofs, filename);
|
||||||
|
|
||||||
|
elfptr = new ElfObject(filename, file);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DevCon.WriteLn("Loading from a CD rom or CD image");
|
// It's an elf file.
|
||||||
useCdvdSource = true;
|
DevCon.WriteLn("Loading from a file (or non-cd image)");
|
||||||
|
elfptr = new ElfObject(filename, Path::GetFileSize(filename));
|
||||||
Console.WriteLn(L"loadElfCRC: " + filename);
|
|
||||||
IsoFSCDVD isofs;
|
|
||||||
elfsize = IsoDirectory( isofs ).GetFileSize( fromUTF8(fnptr) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( elfsize > 0xfffffff )
|
if (!elfptr->hasProgramHeaders())
|
||||||
throw Exception::BadStream( filename, wxLt("Illegal ELF file size, over 2GB!") );
|
|
||||||
|
|
||||||
if( elfsize == -1 )
|
|
||||||
throw Exception::BadStream( filename, wxLt("Elf file does not exist! ") );
|
|
||||||
|
|
||||||
if( elfsize == 0 )
|
|
||||||
throw Exception::BadStream( filename, wxLt("Unexpected end of ELF file: ") );
|
|
||||||
|
|
||||||
Console.WriteLn( L"loadElfFile: %d bytes", wxULongLong(elfsize).GetLo() );
|
|
||||||
|
|
||||||
ElfObject elfobj( filename, wxULongLong(elfsize).GetLo() );
|
|
||||||
|
|
||||||
if( elfobj.proghead == NULL )
|
|
||||||
{
|
{
|
||||||
throw Exception::BadStream( filename, useCdvdSource ?
|
throw Exception::BadStream( filename, elfptr->isCdvd ?
|
||||||
wxLt("Invalid ELF file header. The CD-Rom may be damaged, or the ISO image corrupted.") :
|
wxLt("Invalid ELF file header. The CD-Rom may be damaged, or the ISO image corrupted.") :
|
||||||
wxLt("Invalid ELF file.")
|
wxLt("Invalid ELF file.")
|
||||||
);
|
);
|
||||||
|
@ -581,10 +487,9 @@ void loadElfFile(const wxString& filename)
|
||||||
//2002-09-19 (Florin)
|
//2002-09-19 (Florin)
|
||||||
//args_ptr = 0xFFFFFFFF; //big value, searching for minimum [used by parseCommandLine]
|
//args_ptr = 0xFFFFFFFF; //big value, searching for minimum [used by parseCommandLine]
|
||||||
|
|
||||||
elfobj.loadProgramHeaders();
|
elfptr->loadHeaders();
|
||||||
elfobj.loadSectionHeaders();
|
|
||||||
|
|
||||||
cpuRegs.pc = elfobj.header.e_entry; //set pc to proper place
|
cpuRegs.pc = elfptr->header.e_entry; //set pc to proper place
|
||||||
ELF_LOG( "PC set to: %8.8lx", cpuRegs.pc );
|
ELF_LOG( "PC set to: %8.8lx", cpuRegs.pc );
|
||||||
|
|
||||||
cpuRegs.GPR.n.sp.UL[0] = 0x81f00000;
|
cpuRegs.GPR.n.sp.UL[0] = 0x81f00000;
|
||||||
|
@ -595,11 +500,11 @@ void loadElfFile(const wxString& filename)
|
||||||
{
|
{
|
||||||
if( memcmp( "rom0:OSDSYS", (char*)PSM( i ), 11 ) == 0 )
|
if( memcmp( "rom0:OSDSYS", (char*)PSM( i ), 11 ) == 0 )
|
||||||
{
|
{
|
||||||
strcpy( (char*)PSM( i ), fnptr );
|
strcpy( (char*)PSM( i ), filename.ToUTF8() );
|
||||||
DevCon.WriteLn( "loadElfFile: addr %x \"%s\" -> \"%s\"", i, "rom0:OSDSYS", fnptr.data() );
|
DevCon.WriteLn( wxsFormat(L"loadElfFile: addr %x \"rom0:OSDSYS\" -> \"" + filename + L"\"", i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ElfCRC = elfobj.GetCRC();
|
ElfCRC = elfptr->getCRC();
|
||||||
Console.WriteLn( L"loadElfFile: %s; CRC = %8.8X", filename.c_str(), ElfCRC );
|
Console.WriteLn( L"loadElfFile: %s; CRC = %8.8X", filename.c_str(), ElfCRC );
|
||||||
ElfApplyPatches();
|
ElfApplyPatches();
|
||||||
GetMTGS().SendGameCRC( ElfCRC );
|
GetMTGS().SendGameCRC( ElfCRC );
|
||||||
|
@ -613,6 +518,8 @@ void loadElfFile(const wxString& filename)
|
||||||
// 2 - PS2 CD
|
// 2 - PS2 CD
|
||||||
int GetPS2ElfName( wxString& name )
|
int GetPS2ElfName( wxString& name )
|
||||||
{
|
{
|
||||||
|
int retype = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
IsoFSCDVD isofs;
|
IsoFSCDVD isofs;
|
||||||
IsoFile file( isofs, L"SYSTEM.CNF;1");
|
IsoFile file( isofs, L"SYSTEM.CNF;1");
|
||||||
|
@ -620,7 +527,6 @@ int GetPS2ElfName( wxString& name )
|
||||||
int size = file.getLength();
|
int size = file.getLength();
|
||||||
if( size == 0 ) return 0;
|
if( size == 0 ) return 0;
|
||||||
|
|
||||||
int retype = 0;
|
|
||||||
|
|
||||||
while( !file.eof() )
|
while( !file.eof() )
|
||||||
{
|
{
|
||||||
|
@ -697,5 +603,5 @@ int GetPS2ElfName( wxString& name )
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 2;
|
return retype;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,13 +16,151 @@
|
||||||
#ifndef __ELF_H__
|
#ifndef __ELF_H__
|
||||||
#define __ELF_H__
|
#define __ELF_H__
|
||||||
|
|
||||||
|
#include "CDVD/IsoFS/IsoFSCDVD.h"
|
||||||
|
#include "CDVD/IsoFS/IsoFS.h"
|
||||||
|
|
||||||
|
#if 0
|
||||||
//2002-09-20 (Florin)
|
//2002-09-20 (Florin)
|
||||||
extern char args[256]; //to be filled by GUI
|
extern char args[256]; //to be filled by GUI
|
||||||
extern unsigned int args_ptr;
|
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
|
||||||
|
u16 e_machine; //Processor: 8=MIPS R3000
|
||||||
|
u32 e_version; //Version: 1=current
|
||||||
|
u32 e_entry; //Entry point address
|
||||||
|
u32 e_phoff; //Start of program headers (offset from file start)
|
||||||
|
u32 e_shoff; //Start of section headers (offset from file start)
|
||||||
|
u32 e_flags; //Processor specific flags = 0x20924001 noreorder, mips
|
||||||
|
u16 e_ehsize; //ELF header size (0x34 = 52 bytes)
|
||||||
|
u16 e_phentsize; //Program headers entry size
|
||||||
|
u16 e_phnum; //Number of program headers
|
||||||
|
u16 e_shentsize; //Section headers entry size
|
||||||
|
u16 e_shnum; //Number of section headers
|
||||||
|
u16 e_shstrndx; //Section header stringtable index
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ELF_PHR {
|
||||||
|
u32 p_type; //see notes1
|
||||||
|
u32 p_offset; //Offset from file start to program segment.
|
||||||
|
u32 p_vaddr; //Virtual address of the segment
|
||||||
|
u32 p_paddr; //Physical address of the segment
|
||||||
|
u32 p_filesz; //Number of bytes in the file image of the segment
|
||||||
|
u32 p_memsz; //Number of bytes in the memory image of the segment
|
||||||
|
u32 p_flags; //Flags for segment
|
||||||
|
u32 p_align; //Alignment. The address of 0x08 and 0x0C must fit this alignment. 0=no alignment
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
notes1
|
||||||
|
------
|
||||||
|
0=Inactive
|
||||||
|
1=Load the segment into memory, no. of bytes specified by 0x10 and 0x14
|
||||||
|
2=Dynamic linking
|
||||||
|
3=Interpreter. The array element must specify a path name
|
||||||
|
4=Note. The array element must specify the location and size of aux. info
|
||||||
|
5=reserved
|
||||||
|
6=The array element must specify location and size of the program header table.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct ELF_SHR {
|
||||||
|
u32 sh_name; //No. to the index of the Section header stringtable index
|
||||||
|
u32 sh_type; //See notes2
|
||||||
|
u32 sh_flags; //see notes3
|
||||||
|
u32 sh_addr; //Section start address
|
||||||
|
u32 sh_offset; //Offset from start of file to section
|
||||||
|
u32 sh_size; //Size of section
|
||||||
|
u32 sh_link; //Section header table index link
|
||||||
|
u32 sh_info; //Info
|
||||||
|
u32 sh_addralign; //Alignment. The adress of 0x0C must fit this alignment. 0=no alignment.
|
||||||
|
u32 sh_entsize; //Fixed size entries.
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
notes 2
|
||||||
|
-------
|
||||||
|
Type:
|
||||||
|
0=Inactive
|
||||||
|
1=PROGBITS
|
||||||
|
2=SYMTAB symbol table
|
||||||
|
3=STRTAB string table
|
||||||
|
4=RELA relocation entries
|
||||||
|
5=HASH hash table
|
||||||
|
6=DYNAMIC dynamic linking information
|
||||||
|
7=NOTE
|
||||||
|
8=NOBITS
|
||||||
|
9=REL relocation entries
|
||||||
|
10=SHLIB
|
||||||
|
0x70000000=LOPROC processor specifc
|
||||||
|
0x7fffffff=HIPROC
|
||||||
|
0x80000000=LOUSER lower bound
|
||||||
|
0xffffffff=HIUSER upper bound
|
||||||
|
|
||||||
|
notes 3
|
||||||
|
-------
|
||||||
|
Section Flags: (1 bit, you may combine them like 3 = alloc & write permission)
|
||||||
|
1=Write section contains data the is be writeable during execution.
|
||||||
|
2=Alloc section occupies memory during execution
|
||||||
|
4=Exec section contains executable instructions
|
||||||
|
0xf0000000=Mask bits processor-specific
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct Elf32_Sym {
|
||||||
|
u32 st_name;
|
||||||
|
u32 st_value;
|
||||||
|
u32 st_size;
|
||||||
|
u8 st_info;
|
||||||
|
u8 st_other;
|
||||||
|
u16 st_shndx;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ELF32_ST_TYPE(i) ((i)&0xf)
|
||||||
|
|
||||||
|
struct Elf32_Rel {
|
||||||
|
u32 r_offset;
|
||||||
|
u32 r_info;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ElfObject
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
SafeArray<u8> data;
|
||||||
|
ELF_PHR* proghead;
|
||||||
|
ELF_SHR* secthead;
|
||||||
|
wxString filename;
|
||||||
|
|
||||||
|
void initElfHeaders();
|
||||||
|
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() throw() { }
|
||||||
|
|
||||||
|
ElfObject(const wxString& srcfile, IsoFile isofile);
|
||||||
|
ElfObject( const wxString& srcfile, uint hdrsize );
|
||||||
|
|
||||||
|
void loadProgramHeaders();
|
||||||
|
void loadSectionHeaders();
|
||||||
|
void loadHeaders();
|
||||||
|
|
||||||
|
bool hasProgramHeaders();
|
||||||
|
bool hasSectionHeaders();
|
||||||
|
bool hasHeaders();
|
||||||
|
|
||||||
|
u32 getCRC() const;
|
||||||
|
};
|
||||||
|
|
||||||
//-------------------
|
//-------------------
|
||||||
extern void loadElfFile(const wxString& filename);
|
extern void loadElfFile(const wxString& filename);
|
||||||
extern u32 loadElfCRC(const char *filename);
|
extern u32 loadElfCRC(const wxString filename);
|
||||||
extern void ElfApplyPatches();
|
extern void ElfApplyPatches();
|
||||||
extern int GetPS2ElfName( wxString& dest );
|
extern int GetPS2ElfName( wxString& dest );
|
||||||
|
|
||||||
|
|
|
@ -420,7 +420,6 @@ void inifile_command( const wxString& cmd )
|
||||||
// Then sends the command to be parsed.
|
// Then sends the command to be parsed.
|
||||||
void inifile_process(wxTextFile &f1 )
|
void inifile_process(wxTextFile &f1 )
|
||||||
{
|
{
|
||||||
Console.WriteLn("inifile_process");
|
|
||||||
for (uint i = 0; i < f1.GetLineCount(); i++)
|
for (uint i = 0; i < f1.GetLineCount(); i++)
|
||||||
{
|
{
|
||||||
inifile_trim(f1[i]);
|
inifile_trim(f1[i]);
|
||||||
|
|
|
@ -292,6 +292,7 @@ void SysCoreThread::CpuInitializeMess()
|
||||||
throw Exception::RuntimeError( wxLt("Fast Boot failed: CDVD image is not a PS1 or PS2 game.") );
|
throw Exception::RuntimeError( wxLt("Fast Boot failed: CDVD image is not a PS1 or PS2 game.") );
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
|
if (!ENABLE_LOADING_PS1_GAMES)
|
||||||
throw Exception::RuntimeError( wxLt("Fast Boot failed: PCSX2 does not support emulation of PS1 games.") );
|
throw Exception::RuntimeError( wxLt("Fast Boot failed: PCSX2 does not support emulation of PS1 games.") );
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
|
@ -310,7 +311,7 @@ void SysCoreThread::CpuInitializeMess()
|
||||||
// injects the cpuRegs.pc with the address of the execution start point.
|
// injects the cpuRegs.pc with the address of the execution start point.
|
||||||
//
|
//
|
||||||
// This hack is necessary for non-CD ELF files, and is optional for game CDs as a
|
// This hack is necessary for non-CD ELF files, and is optional for game CDs as a
|
||||||
// fast bott up option. (though not recommended for games because of rare ill side
|
// fast boot up option. (though not recommended for games because of rare ill side
|
||||||
// effects).
|
// effects).
|
||||||
|
|
||||||
SetCPUState( EmuConfig.Cpu.sseMXCSR, EmuConfig.Cpu.sseVUMXCSR );
|
SetCPUState( EmuConfig.Cpu.sseMXCSR, EmuConfig.Cpu.sseVUMXCSR );
|
||||||
|
|
|
@ -336,8 +336,15 @@ void VXITOP() { VU0.code = cpuRegs.code; _vuXITOP(&VU0); }
|
||||||
// fixme: Shouldn't anything calling this function be calling vu0WaitMicro instead?
|
// fixme: Shouldn't anything calling this function be calling vu0WaitMicro instead?
|
||||||
// Meaning that this function stalls, but doesn't increment the cpuRegs.cycle like
|
// Meaning that this function stalls, but doesn't increment the cpuRegs.cycle like
|
||||||
// you would think it should.
|
// you would think it should.
|
||||||
|
|
||||||
|
// Well, we can always test that out...
|
||||||
|
//#define USE_WAIT_MICRO
|
||||||
|
|
||||||
void vu0Finish()
|
void vu0Finish()
|
||||||
{
|
{
|
||||||
|
#ifdef USE_WAIT_MICRO
|
||||||
|
_vu0WaitMicro();
|
||||||
|
#else
|
||||||
if( (VU0.VI[REG_VPU_STAT].UL & 0x1) ) {
|
if( (VU0.VI[REG_VPU_STAT].UL & 0x1) ) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
@ -352,4 +359,5 @@ void vu0Finish()
|
||||||
//Console.Warning("vu0Finish > stall aborted by force.");
|
//Console.Warning("vu0Finish > stall aborted by force.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue