2009-09-08 12:08:10 +00:00
|
|
|
/* PCSX2 - PS2 Emulator for PCs
|
|
|
|
* Copyright (C) 2002-2009 PCSX2 Dev Team
|
2009-11-06 01:50:11 +00:00
|
|
|
*
|
2009-09-08 12:08:10 +00:00
|
|
|
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
|
|
|
* of the GNU Lesser General Public License as published by the Free Software Found-
|
|
|
|
* ation, either version 3 of the License, or (at your option) any later version.
|
2009-02-09 21:15:56 +00:00
|
|
|
*
|
2009-09-08 12:08:10 +00:00
|
|
|
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
|
|
* PURPOSE. See the GNU General Public License for more details.
|
2009-04-28 05:56:22 +00:00
|
|
|
*
|
2009-09-08 12:08:10 +00:00
|
|
|
* You should have received a copy of the GNU General Public License along with PCSX2.
|
|
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
2009-02-09 21:15:56 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "PrecompiledHeader.h"
|
|
|
|
|
|
|
|
#include "Common.h"
|
2009-07-11 16:39:58 +00:00
|
|
|
#include "CDVD/IsoFSdrv.h"
|
2009-09-12 02:58:22 +00:00
|
|
|
#include "DebugTools/Debug.h"
|
2009-10-10 11:50:39 +00:00
|
|
|
#include "GS.h" // for sending game crc to mtgs
|
2009-02-09 21:15:56 +00:00
|
|
|
|
|
|
|
using namespace std;
|
2009-11-06 04:45:21 +00:00
|
|
|
extern void InitPatch(wxString crc);
|
2009-11-06 01:50:11 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
u32 ElfCRC;
|
|
|
|
|
|
|
|
struct ELF_HEADER {
|
|
|
|
u8 e_ident[16]; //0x7f,"ELF" (ELF file identifier)
|
2009-11-03 20:36:47 +00:00
|
|
|
u16 e_type; //ELF type: 0=NONE, 1=REL, 2=EXEC, 3=SHARED, 4=CORE
|
2009-02-09 21:15:56 +00:00
|
|
|
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)
|
2009-04-28 05:56:22 +00:00
|
|
|
u16 e_phentsize; //Program headers entry size
|
2009-02-09 21:15:56 +00:00
|
|
|
u16 e_phnum; //Number of program headers
|
|
|
|
u16 e_shentsize; //Section headers entry size
|
|
|
|
u16 e_shnum; //Number of section headers
|
2009-04-28 05:56:22 +00:00
|
|
|
u16 e_shstrndx; //Section header stringtable index
|
2009-02-09 21:15:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
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
|
2009-04-28 05:56:22 +00:00
|
|
|
8=NOBITS
|
2009-02-09 21:15:56 +00:00
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
2009-04-27 02:04:31 +00:00
|
|
|
#if 0
|
|
|
|
// 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.
|
|
|
|
// A user-written ELF can then load the data and respond accordingly. Needs a rewrite using modern
|
|
|
|
// string parsing utils. :)
|
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
//2002-09-19 (Florin)
|
|
|
|
char args[256]="ez.m2v"; //to be accessed by other files
|
|
|
|
uptr args_ptr; //a big value; in fact, it is an address
|
|
|
|
|
2009-08-06 12:00:06 +00:00
|
|
|
static bool isEmpty(int addr)
|
|
|
|
{
|
|
|
|
return ((PS2MEM_BASE[addr] == 0) || (PS2MEM_BASE[addr] == 32));
|
|
|
|
}
|
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
//in a0 is passed the address of the command line args,
|
|
|
|
//i.e. a pointer to an area like this:
|
|
|
|
//+00 unknown/unused
|
|
|
|
//+04 argc; number of arguments
|
|
|
|
//+08 argv[0]; address of the first parameter - program name (char*) -
|
|
|
|
//+08 argv[1]; address of the second parameter (char*) |
|
|
|
|
//+0C argv[2]; and so on |
|
|
|
|
//........ |
|
|
|
|
//+08+4*argc the program name(first param) <--
|
|
|
|
//+08+4*argc+strlen(argv[0]+1) the rest of params; i.e. a copy of 'args'
|
|
|
|
// see above 'char args[256];'
|
2009-08-06 12:00:06 +00:00
|
|
|
|
|
|
|
// The results of this function will normally be that it finds an arg at 13 chars, and another at 0.
|
|
|
|
// It'd probably be easier to 0 out all 256 chars, split args, copy all the arguments in, and note
|
|
|
|
// the locations of each split... --arcum42
|
2009-08-07 01:55:59 +00:00
|
|
|
|
2009-04-27 02:04:31 +00:00
|
|
|
static uint parseCommandLine( const wxString& filename )
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
2009-08-06 12:00:06 +00:00
|
|
|
if ( ( args_ptr != 0xFFFFFFFF ) && ( args_ptr > (4 + 4 + 256) ) )
|
|
|
|
{
|
|
|
|
const char *p;
|
|
|
|
int argc, i, ret = 0;
|
2009-08-07 01:55:59 +00:00
|
|
|
u32 args_end;
|
2009-02-09 21:15:56 +00:00
|
|
|
|
|
|
|
args_ptr -= 256;
|
|
|
|
|
|
|
|
args[ 255 ] = 0;
|
2009-11-06 01:50:11 +00:00
|
|
|
|
|
|
|
// Copy the parameters into the section of memory at args_ptr,
|
2009-08-06 12:00:06 +00:00
|
|
|
// then zero out anything past the end of args till 256 chars is reached.
|
|
|
|
memcpy( &PS2MEM_BASE[ args_ptr ], args, 256 );
|
2009-02-09 21:15:56 +00:00
|
|
|
memset( &PS2MEM_BASE[ args_ptr + strlen( args ) ], 0, 256 - strlen( args ) );
|
2009-08-07 01:55:59 +00:00
|
|
|
args_end = args_ptr + strlen( args );
|
2009-11-06 01:50:11 +00:00
|
|
|
|
2009-08-06 12:00:06 +00:00
|
|
|
// Set p to just the filename, no path.
|
2009-02-09 21:15:56 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
p = strrchr( filename, '\\' );
|
|
|
|
#else //linux
|
|
|
|
p = strrchr( filename, '/' );
|
2009-03-13 04:49:23 +00:00
|
|
|
if( p == NULL ) p = strchr(filename, '\\');
|
2009-02-09 21:15:56 +00:00
|
|
|
#endif
|
2009-03-13 04:49:23 +00:00
|
|
|
if (p)
|
|
|
|
p++;
|
2009-02-09 21:15:56 +00:00
|
|
|
else
|
2009-03-13 04:49:23 +00:00
|
|
|
p = filename;
|
2009-04-28 05:56:22 +00:00
|
|
|
|
2009-11-06 01:50:11 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
args_ptr -= strlen( p ) + 1;
|
2009-04-28 05:56:22 +00:00
|
|
|
|
2009-08-06 12:00:06 +00:00
|
|
|
//fill param 0; i.e. name of the program
|
|
|
|
strcpy( (char*)&PS2MEM_BASE[ args_ptr ], p );
|
2009-11-06 01:50:11 +00:00
|
|
|
|
2009-08-07 01:55:59 +00:00
|
|
|
// Start from the end of where we wrote to, not including all the zero'd out area.
|
|
|
|
for ( i = args_end - args_ptr + 1, argc = 0; i > 0; i-- )
|
2009-03-13 04:49:23 +00:00
|
|
|
{
|
2009-08-06 12:00:06 +00:00
|
|
|
while (i && isEmpty(args_ptr + i )) { i--; }
|
2009-04-28 05:56:22 +00:00
|
|
|
|
2009-08-06 12:00:06 +00:00
|
|
|
// If the last char is a space, set it to 0.
|
2009-03-13 04:49:23 +00:00
|
|
|
if ( PS2MEM_BASE[ args_ptr + i + 1 ] == ' ') PS2MEM_BASE[ args_ptr + i + 1 ] = 0;
|
2009-04-28 05:56:22 +00:00
|
|
|
|
2009-08-06 12:00:06 +00:00
|
|
|
while (i && !isEmpty(args_ptr + i )) { i--; }
|
2009-04-28 05:56:22 +00:00
|
|
|
|
2009-11-06 01:50:11 +00:00
|
|
|
// Now that we've gone back a word, increase the number of arguments,
|
|
|
|
// and mark the location of the argument.
|
2009-08-09 10:43:29 +00:00
|
|
|
if (!isEmpty(args_ptr + i )) // i <= 0
|
2009-08-06 12:00:06 +00:00
|
|
|
{
|
2009-08-09 10:43:29 +00:00
|
|
|
// If the spot we are on is not a space or null , use it.
|
2009-02-09 21:15:56 +00:00
|
|
|
argc++;
|
2009-08-06 12:00:06 +00:00
|
|
|
ret = args_ptr - 4 - 4 - argc * 4;
|
2009-11-06 01:50:11 +00:00
|
|
|
|
2009-08-06 12:00:06 +00:00
|
|
|
if (ret < 0 ) return 0;
|
2009-02-09 21:15:56 +00:00
|
|
|
((u32*)PS2MEM_BASE)[ args_ptr / 4 - argc ] = args_ptr + i;
|
|
|
|
}
|
2009-03-13 04:49:23 +00:00
|
|
|
else
|
|
|
|
{
|
2009-08-06 12:00:06 +00:00
|
|
|
if (!isEmpty(args_ptr + i + 1))
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
2009-08-09 10:43:29 +00:00
|
|
|
// Otherwise, use the next character .
|
2009-02-09 21:15:56 +00:00
|
|
|
argc++;
|
2009-08-06 12:00:06 +00:00
|
|
|
ret = args_ptr - 4 - 4 - argc * 4;
|
2009-11-06 01:50:11 +00:00
|
|
|
|
2009-08-06 12:00:06 +00:00
|
|
|
if (ret < 0 ) return 0;
|
2009-02-09 21:15:56 +00:00
|
|
|
((u32*)PS2MEM_BASE)[ args_ptr / 4 - argc ] = args_ptr + i + 1;
|
|
|
|
}
|
2009-03-13 04:49:23 +00:00
|
|
|
}
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
2009-11-06 01:50:11 +00:00
|
|
|
|
2009-08-06 12:00:06 +00:00
|
|
|
// Pass the number of arguments, and if we have arguments.
|
2009-02-09 21:15:56 +00:00
|
|
|
((u32*)PS2MEM_BASE)[ args_ptr /4 - argc - 1 ] = argc; //how many args
|
|
|
|
((u32*)PS2MEM_BASE)[ args_ptr /4 - argc - 2 ] = ( argc > 0); //have args? //not used, cannot be filled at all
|
2009-11-06 01:50:11 +00:00
|
|
|
|
2009-08-06 12:00:06 +00:00
|
|
|
return ret;
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2009-04-27 02:04:31 +00:00
|
|
|
#endif
|
2009-02-09 21:15:56 +00:00
|
|
|
//---------------
|
|
|
|
|
|
|
|
struct ElfObject
|
|
|
|
{
|
2009-04-27 02:04:31 +00:00
|
|
|
wxString filename;
|
2009-02-10 11:34:35 +00:00
|
|
|
SafeArray<u8> data;
|
2009-02-09 21:15:56 +00:00
|
|
|
ELF_HEADER& header;
|
|
|
|
ELF_PHR* proghead;
|
|
|
|
ELF_SHR* secthead;
|
|
|
|
|
|
|
|
// Destructor!
|
|
|
|
// C++ does all the cleanup automagically for us.
|
2009-11-03 20:36:47 +00:00
|
|
|
virtual ~ElfObject() { }
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-04-27 02:04:31 +00:00
|
|
|
ElfObject( const wxString& srcfile, uint hdrsize ) :
|
2009-02-09 21:15:56 +00:00
|
|
|
filename( srcfile )
|
2009-07-03 00:49:40 +00:00
|
|
|
, data( hdrsize, L"ELF headers" )
|
2009-02-09 21:15:56 +00:00
|
|
|
, header( *(ELF_HEADER*)data.GetPtr() )
|
|
|
|
, proghead( NULL )
|
|
|
|
, secthead( NULL )
|
|
|
|
{
|
|
|
|
readFile();
|
2009-02-10 11:34:35 +00:00
|
|
|
|
|
|
|
if( header.e_phnum > 0 )
|
|
|
|
proghead = (ELF_PHR*)&data[header.e_phoff];
|
2009-04-28 05:56:22 +00:00
|
|
|
|
2009-02-10 11:34:35 +00:00
|
|
|
if( header.e_shnum > 0 )
|
|
|
|
secthead = (ELF_SHR*)&data[header.e_shoff];
|
2009-02-09 21:15:56 +00:00
|
|
|
|
|
|
|
if ( ( header.e_shnum > 0 ) && ( header.e_shentsize != sizeof(ELF_SHR) ) )
|
Lots of new code maintenance stuffs:
* Completely new assertion macros: pxAssert, pxAssertMsg, and pxFail, pxAssertDev (both which default to using a message). These replace *all* wxASSERT, DevAssert, and jASSUME varieties of macros. New macros borrow the best of all assertion worlds: MSVCRT, wxASSERT, and AtlAssume. :)
* Rewrote the Console namespace as a structure called IConsoleWriter, and created several varieties of ConsoleWriters for handling different states of log and console availability (should help reduce overhead of console logging nicely).
* More improvements to the PersistentThread model, using safely interlocked "Do*" style callbacks for starting and cleaning up threads.
* Fixed console logs so that they're readable in Win32 notepad again (the log writer adds CRs to naked LFs).
* Added AppInit.cpp -- contains constructor, destructor, OnInit, and command line parsing mess.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1950 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-04 08:27:27 +00:00
|
|
|
Console.Error( "ElfLoader Warning > Size of section headers is not standard" );
|
2009-02-09 21:15:56 +00:00
|
|
|
|
|
|
|
if ( ( header.e_phnum > 0 ) && ( header.e_phentsize != sizeof(ELF_PHR) ) )
|
Lots of new code maintenance stuffs:
* Completely new assertion macros: pxAssert, pxAssertMsg, and pxFail, pxAssertDev (both which default to using a message). These replace *all* wxASSERT, DevAssert, and jASSUME varieties of macros. New macros borrow the best of all assertion worlds: MSVCRT, wxASSERT, and AtlAssume. :)
* Rewrote the Console namespace as a structure called IConsoleWriter, and created several varieties of ConsoleWriters for handling different states of log and console availability (should help reduce overhead of console logging nicely).
* More improvements to the PersistentThread model, using safely interlocked "Do*" style callbacks for starting and cleaning up threads.
* Fixed console logs so that they're readable in Win32 notepad again (the log writer adds CRs to naked LFs).
* Added AppInit.cpp -- contains constructor, destructor, OnInit, and command line parsing mess.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1950 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-04 08:27:27 +00:00
|
|
|
Console.Error( "ElfLoader Warning > Size of program headers is not standard" );
|
2009-02-09 21:15:56 +00:00
|
|
|
|
|
|
|
ELF_LOG( "type: " );
|
2009-04-28 05:56:22 +00:00
|
|
|
switch( header.e_type )
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
2009-04-28 05:56:22 +00:00
|
|
|
default:
|
2009-02-09 21:15:56 +00:00
|
|
|
ELF_LOG( "unknown %x", header.e_type );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x0:
|
|
|
|
ELF_LOG( "no file type" );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x1:
|
|
|
|
ELF_LOG( "relocatable" );
|
|
|
|
break;
|
|
|
|
|
2009-04-28 05:56:22 +00:00
|
|
|
case 0x2:
|
2009-02-09 21:15:56 +00:00
|
|
|
ELF_LOG( "executable" );
|
|
|
|
break;
|
2009-04-28 05:56:22 +00:00
|
|
|
}
|
2009-02-09 21:15:56 +00:00
|
|
|
ELF_LOG( "\n" );
|
|
|
|
ELF_LOG( "machine: " );
|
2009-04-28 05:56:22 +00:00
|
|
|
|
|
|
|
switch ( header.e_machine )
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
|
|
|
default:
|
|
|
|
ELF_LOG( "unknown" );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x8:
|
|
|
|
ELF_LOG( "mips_rs3000" );
|
|
|
|
break;
|
|
|
|
}
|
2009-04-28 05:56:22 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
ELF_LOG("\n");
|
2009-03-27 06:34:51 +00:00
|
|
|
ELF_LOG("version: %d",header.e_version);
|
|
|
|
ELF_LOG("entry: %08x",header.e_entry);
|
|
|
|
ELF_LOG("flags: %08x",header.e_flags);
|
|
|
|
ELF_LOG("eh size: %08x",header.e_ehsize);
|
|
|
|
ELF_LOG("ph off: %08x",header.e_phoff);
|
|
|
|
ELF_LOG("ph entsiz: %08x",header.e_phentsize);
|
|
|
|
ELF_LOG("ph num: %08x",header.e_phnum);
|
|
|
|
ELF_LOG("sh off: %08x",header.e_shoff);
|
|
|
|
ELF_LOG("sh entsiz: %08x",header.e_shentsize);
|
|
|
|
ELF_LOG("sh num: %08x",header.e_shnum);
|
|
|
|
ELF_LOG("sh strndx: %08x",header.e_shstrndx);
|
2009-04-28 05:56:22 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
ELF_LOG("\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
void readFile()
|
|
|
|
{
|
|
|
|
int rsize = 0;
|
2009-11-03 20:36:47 +00:00
|
|
|
const wxCharBuffer work( filename.ToUTF8() );
|
|
|
|
if ((strnicmp( work, "cdrom0:", strlen("cdromN:")) == 0) ||
|
|
|
|
(strnicmp( work, "cdrom1:", strlen("cdromN:")) == 0))
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
2009-11-03 20:36:47 +00:00
|
|
|
int fi = IsoFS_open(work + strlen("cdromN:"), 1);//RDONLY
|
2009-11-06 01:50:11 +00:00
|
|
|
|
2009-03-13 04:49:23 +00:00
|
|
|
if (fi < 0) throw Exception::FileNotFound( filename );
|
2009-04-28 05:56:22 +00:00
|
|
|
|
2009-07-11 23:24:23 +00:00
|
|
|
IsoFS_lseek( fi, 0, SEEK_SET );
|
|
|
|
rsize = IsoFS_read( fi, (char*)data.GetPtr(), data.GetSizeInBytes() );
|
|
|
|
IsoFS_close( fi );
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
FILE *f;
|
|
|
|
|
2009-04-27 02:04:31 +00:00
|
|
|
f = fopen( work.data(), "rb" );
|
2009-03-13 04:49:23 +00:00
|
|
|
if( f == NULL ) Exception::FileNotFound( filename );
|
2009-04-28 05:56:22 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
fseek( f, 0, SEEK_SET );
|
|
|
|
rsize = fread( data.GetPtr(), 1, data.GetSizeInBytes(), f );
|
|
|
|
fclose( f );
|
|
|
|
}
|
|
|
|
|
2009-03-13 04:49:23 +00:00
|
|
|
if( rsize < data.GetSizeInBytes() ) throw Exception::EndOfStream( filename );
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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 loadProgramHeaders()
|
|
|
|
{
|
2009-02-10 11:34:35 +00:00
|
|
|
if ( proghead == NULL )
|
2009-02-09 21:15:56 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
for( int i = 0 ; i < header.e_phnum ; i++ )
|
|
|
|
{
|
2009-04-28 05:56:22 +00:00
|
|
|
ELF_LOG( "Elf32 Program Header" );
|
2009-02-09 21:15:56 +00:00
|
|
|
ELF_LOG( "type: " );
|
2009-04-28 05:56:22 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
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 )
|
2009-10-29 13:32:40 +00:00
|
|
|
Console.Warning( "ElfProgram different load addrs: paddr=0x%8.8x, vaddr=0x%8.8x",
|
2009-02-09 21:15:56 +00:00
|
|
|
proghead[ i ].p_paddr, proghead[ i ].p_vaddr);
|
|
|
|
|
|
|
|
// used to be paddr
|
2009-03-09 21:52:33 +00:00
|
|
|
memcpy_fast(
|
2009-02-09 21:15:56 +00:00
|
|
|
&PS2MEM_BASE[proghead[ i ].p_vaddr & 0x1ffffff],
|
|
|
|
data.GetPtr(proghead[ i ].p_offset), size
|
|
|
|
);
|
|
|
|
|
|
|
|
ELF_LOG("\t*LOADED*");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2009-04-28 05:56:22 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
ELF_LOG("\n");
|
2009-03-27 06:34:51 +00:00
|
|
|
ELF_LOG("offset: %08x",(int)proghead[i].p_offset);
|
|
|
|
ELF_LOG("vaddr: %08x",(int)proghead[i].p_vaddr);
|
|
|
|
ELF_LOG("paddr: %08x",proghead[i].p_paddr);
|
|
|
|
ELF_LOG("file size: %08x",proghead[i].p_filesz);
|
|
|
|
ELF_LOG("mem size: %08x",proghead[i].p_memsz);
|
|
|
|
ELF_LOG("flags: %08x",proghead[i].p_flags);
|
|
|
|
ELF_LOG("palign: %08x",proghead[i].p_align);
|
2009-02-09 21:15:56 +00:00
|
|
|
ELF_LOG("\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-04-28 05:56:22 +00:00
|
|
|
void loadSectionHeaders()
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
2009-02-10 11:34:35 +00:00
|
|
|
if( secthead == NULL || header.e_shoff > (u32)data.GetLength() )
|
2009-02-09 21:15:56 +00:00
|
|
|
return;
|
|
|
|
|
2009-02-12 23:19:54 +00:00
|
|
|
const u8* sections_names = data.GetPtr( secthead[ (header.e_shstrndx == 0xffff ? 0 : header.e_shstrndx) ].sh_offset );
|
2009-04-28 05:56:22 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
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 ] );
|
|
|
|
|
2009-04-27 02:04:31 +00:00
|
|
|
// used by parseCommandLine
|
|
|
|
//if ( secthead[i].sh_flags & 0x2 )
|
|
|
|
// args_ptr = min( args_ptr, secthead[ i ].sh_addr & 0x1ffffff );
|
2009-04-28 05:56:22 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
#ifdef PCSX2_DEVBULD
|
|
|
|
ELF_LOG("\n");
|
|
|
|
ELF_LOG("type: ");
|
2009-04-28 05:56:22 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
switch ( secthead[ i ].sh_type )
|
|
|
|
{
|
2009-03-13 04:49:23 +00:00
|
|
|
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;
|
|
|
|
default: ELF_LOG("unknown %08x",secthead[i].sh_type); break;
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
2009-04-28 05:56:22 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
ELF_LOG("\n");
|
2009-03-27 06:34:51 +00:00
|
|
|
ELF_LOG("flags: %08x", secthead[i].sh_flags);
|
|
|
|
ELF_LOG("addr: %08x", secthead[i].sh_addr);
|
|
|
|
ELF_LOG("offset: %08x", secthead[i].sh_offset);
|
|
|
|
ELF_LOG("size: %08x", secthead[i].sh_size);
|
|
|
|
ELF_LOG("link: %08x", secthead[i].sh_link);
|
|
|
|
ELF_LOG("info: %08x", secthead[i].sh_info);
|
|
|
|
ELF_LOG("addralign: %08x", secthead[i].sh_addralign);
|
|
|
|
ELF_LOG("entsize: %08x", secthead[i].sh_entsize);
|
2009-02-09 21:15:56 +00:00
|
|
|
// dump symbol table
|
2009-04-28 05:56:22 +00:00
|
|
|
|
|
|
|
if( secthead[ i ].sh_type == 0x02 )
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
2009-04-28 05:56:22 +00:00
|
|
|
i_st = i;
|
|
|
|
i_dt = secthead[i].sh_link;
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
#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 );
|
Lots of new code maintenance stuffs:
* Completely new assertion macros: pxAssert, pxAssertMsg, and pxFail, pxAssertDev (both which default to using a message). These replace *all* wxASSERT, DevAssert, and jASSUME varieties of macros. New macros borrow the best of all assertion worlds: MSVCRT, wxASSERT, and AtlAssume. :)
* Rewrote the Console namespace as a structure called IConsoleWriter, and created several varieties of ConsoleWriters for handling different states of log and console availability (should help reduce overhead of console logging nicely).
* More improvements to the PersistentThread model, using safely interlocked "Do*" style callbacks for starting and cleaning up threads.
* Fixed console logs so that they're readable in Win32 notepad again (the log writer adds CRs to naked LFs).
* Added AppInit.cpp -- contains constructor, destructor, OnInit, and command line parsing mess.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1950 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-04 08:27:27 +00:00
|
|
|
Console.WriteLn("found %d symbols", secthead[ i_st ].sh_size / sizeof( Elf32_Sym ));
|
2009-02-09 21:15:56 +00:00
|
|
|
|
|
|
|
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 ] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
void ElfApplyPatches()
|
|
|
|
{
|
2009-05-01 02:15:18 +00:00
|
|
|
wxString filename( wxsFormat( L"%8.8x", ElfCRC ) );
|
2009-02-09 21:15:56 +00:00
|
|
|
|
|
|
|
// if patches found the following status msg will be overwritten
|
Lots of new code maintenance stuffs:
* Completely new assertion macros: pxAssert, pxAssertMsg, and pxFail, pxAssertDev (both which default to using a message). These replace *all* wxASSERT, DevAssert, and jASSUME varieties of macros. New macros borrow the best of all assertion worlds: MSVCRT, wxASSERT, and AtlAssume. :)
* Rewrote the Console namespace as a structure called IConsoleWriter, and created several varieties of ConsoleWriters for handling different states of log and console availability (should help reduce overhead of console logging nicely).
* More improvements to the PersistentThread model, using safely interlocked "Do*" style callbacks for starting and cleaning up threads.
* Fixed console logs so that they're readable in Win32 notepad again (the log writer adds CRs to naked LFs).
* Added AppInit.cpp -- contains constructor, destructor, OnInit, and command line parsing mess.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1950 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-04 08:27:27 +00:00
|
|
|
Console.SetTitle( wxsFormat( _("Game running [CRC=%s]"), filename.c_str() ) );
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-08-04 08:21:10 +00:00
|
|
|
if( !EmuConfig.EnablePatches ) return;
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-11-06 04:45:21 +00:00
|
|
|
InitPatch(filename);
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Fetches the CRC of the game bound to the CDVD plugin.
|
|
|
|
u32 loadElfCRC( const char* filename )
|
|
|
|
{
|
|
|
|
TocEntry toc;
|
|
|
|
|
2009-07-11 23:24:23 +00:00
|
|
|
IsoFS_init( );
|
2009-11-06 01:50:11 +00:00
|
|
|
|
2009-10-29 13:32:40 +00:00
|
|
|
Console.WriteLn("loadElfCRC: %s", filename);
|
2009-11-06 01:50:11 +00:00
|
|
|
|
2009-08-06 12:00:06 +00:00
|
|
|
int mylen = strlen( "cdromN:" );
|
|
|
|
if ( IsoFS_findFile( filename + mylen, &toc ) == -1 ) return 0;
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-10-29 13:32:40 +00:00
|
|
|
DevCon.WriteLn( "loadElfFile: %d bytes", toc.fileSize );
|
2009-10-29 13:51:49 +00:00
|
|
|
u32 crcval = ElfObject( fromUTF8( filename ), toc.fileSize ).GetCRC();
|
2009-10-29 13:32:40 +00:00
|
|
|
Console.WriteLn( "loadElfFile: %s; CRC = %8.8X", filename, crcval );
|
2009-02-09 21:15:56 +00:00
|
|
|
|
|
|
|
return crcval;
|
|
|
|
}
|
|
|
|
|
2009-08-15 06:17:43 +00:00
|
|
|
// Loads the elf binary data from the specified file into PS2 memory, and injects the ELF's
|
|
|
|
// starting execution point into cpuRegs.pc. If the filename is a cdrom URI in the form
|
|
|
|
// of "cdrom0:" or "cdrom1:" then the CDVD is used as the source; otherwise the ELF is loaded
|
|
|
|
// from the host filesystem.
|
|
|
|
//
|
|
|
|
// If the specified filename is empty then no action is taken (PS2 will continue booting
|
|
|
|
// normally as if it has no CD
|
|
|
|
//
|
|
|
|
// Throws exception on error:
|
|
|
|
//
|
|
|
|
void loadElfFile(const wxString& filename)
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
2009-08-15 06:17:43 +00:00
|
|
|
if( filename.IsEmpty() ) return;
|
2009-11-06 01:50:11 +00:00
|
|
|
|
2009-09-13 17:11:35 +00:00
|
|
|
s64 elfsize;
|
2009-11-03 20:36:47 +00:00
|
|
|
Console.WriteLn( L"loadElfFile: " + filename );
|
2009-04-27 02:04:31 +00:00
|
|
|
|
2009-11-03 20:36:47 +00:00
|
|
|
const wxCharBuffer buffer( filename.ToUTF8() );
|
2009-04-27 02:04:31 +00:00
|
|
|
const char* fnptr = buffer.data();
|
2009-08-15 06:17:43 +00:00
|
|
|
bool useCdvdSource=false;
|
2009-11-06 01:50:11 +00:00
|
|
|
|
2009-04-27 02:04:31 +00:00
|
|
|
if( !filename.StartsWith( L"cdrom0:" ) && !filename.StartsWith( L"cdrom1:" ) )
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
Lots of new code maintenance stuffs:
* Completely new assertion macros: pxAssert, pxAssertMsg, and pxFail, pxAssertDev (both which default to using a message). These replace *all* wxASSERT, DevAssert, and jASSUME varieties of macros. New macros borrow the best of all assertion worlds: MSVCRT, wxASSERT, and AtlAssume. :)
* Rewrote the Console namespace as a structure called IConsoleWriter, and created several varieties of ConsoleWriters for handling different states of log and console availability (should help reduce overhead of console logging nicely).
* More improvements to the PersistentThread model, using safely interlocked "Do*" style callbacks for starting and cleaning up threads.
* Fixed console logs so that they're readable in Win32 notepad again (the log writer adds CRs to naked LFs).
* Added AppInit.cpp -- contains constructor, destructor, OnInit, and command line parsing mess.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1950 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-04 08:27:27 +00:00
|
|
|
DevCon.WriteLn("Loading from a file (or non-cd image)");
|
2009-09-13 17:11:35 +00:00
|
|
|
elfsize = Path::GetFileSize( filename );
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
Lots of new code maintenance stuffs:
* Completely new assertion macros: pxAssert, pxAssertMsg, and pxFail, pxAssertDev (both which default to using a message). These replace *all* wxASSERT, DevAssert, and jASSUME varieties of macros. New macros borrow the best of all assertion worlds: MSVCRT, wxASSERT, and AtlAssume. :)
* Rewrote the Console namespace as a structure called IConsoleWriter, and created several varieties of ConsoleWriters for handling different states of log and console availability (should help reduce overhead of console logging nicely).
* More improvements to the PersistentThread model, using safely interlocked "Do*" style callbacks for starting and cleaning up threads.
* Fixed console logs so that they're readable in Win32 notepad again (the log writer adds CRs to naked LFs).
* Added AppInit.cpp -- contains constructor, destructor, OnInit, and command line parsing mess.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1950 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-04 08:27:27 +00:00
|
|
|
DevCon.WriteLn("Loading from a CD rom or CD image");
|
2009-08-15 06:17:43 +00:00
|
|
|
useCdvdSource = true;
|
2009-02-09 21:15:56 +00:00
|
|
|
TocEntry toc;
|
2009-07-11 23:24:23 +00:00
|
|
|
IsoFS_init( );
|
2009-07-23 14:58:17 +00:00
|
|
|
if ( IsoFS_findFile( fnptr + strlen( "cdromN:" ), &toc ) == -1 )
|
2009-08-15 06:17:43 +00:00
|
|
|
throw Exception::FileNotFound( filename, wxLt("ELF file was not found on the CDVD source media.") );
|
2009-02-09 21:15:56 +00:00
|
|
|
elfsize = toc.fileSize;
|
|
|
|
}
|
|
|
|
|
2009-09-13 17:11:35 +00:00
|
|
|
if( elfsize > 0xfffffff )
|
|
|
|
throw Exception::BadStream( filename, wxLt("Illegal ELF file size, over 2GB!") );
|
2009-09-12 01:03:44 +00:00
|
|
|
|
2009-10-29 13:32:40 +00:00
|
|
|
Console.WriteLn( L"loadElfFile: %d", wxULongLong(elfsize).GetLo() );
|
2009-08-15 06:17:43 +00:00
|
|
|
if( elfsize == 0 )
|
|
|
|
throw Exception::BadStream( filename, wxLt("Unexpected end of ELF file: ") );
|
2009-04-27 02:04:31 +00:00
|
|
|
|
2009-09-13 17:11:35 +00:00
|
|
|
ElfObject elfobj( filename, wxULongLong(elfsize).GetLo() );
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-02-10 11:34:35 +00:00
|
|
|
if( elfobj.proghead == NULL )
|
2009-04-27 02:04:31 +00:00
|
|
|
{
|
2009-08-15 06:17:43 +00:00
|
|
|
throw Exception::BadStream( filename, useCdvdSource ?
|
|
|
|
wxLt("Invalid ELF file header. The CD-Rom may be damaged, or the ISO image corrupted.") :
|
|
|
|
wxLt("Invalid ELF file.")
|
2009-04-27 02:04:31 +00:00
|
|
|
);
|
|
|
|
}
|
2009-02-10 11:34:35 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
//2002-09-19 (Florin)
|
2009-04-27 02:04:31 +00:00
|
|
|
//args_ptr = 0xFFFFFFFF; //big value, searching for minimum [used by parseCommandLine]
|
2009-02-09 21:15:56 +00:00
|
|
|
|
|
|
|
elfobj.loadProgramHeaders();
|
|
|
|
elfobj.loadSectionHeaders();
|
2009-04-28 05:56:22 +00:00
|
|
|
|
|
|
|
cpuRegs.pc = elfobj.header.e_entry; //set pc to proper place
|
2009-03-27 06:34:51 +00:00
|
|
|
ELF_LOG( "PC set to: %8.8lx", cpuRegs.pc );
|
2009-04-28 05:56:22 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
cpuRegs.GPR.n.sp.UL[0] = 0x81f00000;
|
|
|
|
cpuRegs.GPR.n.gp.UL[0] = 0x81f80000; // might not be 100% ok
|
2009-04-27 02:04:31 +00:00
|
|
|
//cpuRegs.GPR.n.a0.UL[0] = parseCommandLine( filename ); // see #ifdef'd out parseCommendLine for details.
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-04-27 02:04:31 +00:00
|
|
|
for( uint i = 0; i < 0x100000; i++ )
|
|
|
|
{
|
|
|
|
if( memcmp( "rom0:OSDSYS", (char*)PSM( i ), 11 ) == 0 )
|
|
|
|
{
|
|
|
|
strcpy( (char*)PSM( i ), fnptr );
|
2009-10-29 13:32:40 +00:00
|
|
|
DevCon.WriteLn( "loadElfFile: addr %x \"%s\" -> \"%s\"", i, "rom0:OSDSYS", fnptr );
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ElfCRC = elfobj.GetCRC();
|
2009-10-29 13:32:40 +00:00
|
|
|
Console.WriteLn( L"loadElfFile: %s; CRC = %8.8X", filename.c_str(), ElfCRC );
|
2009-02-09 21:15:56 +00:00
|
|
|
ElfApplyPatches();
|
2009-10-10 11:50:39 +00:00
|
|
|
mtgsThread.SendGameCRC( ElfCRC );
|
2009-11-06 01:50:11 +00:00
|
|
|
|
2009-08-15 06:17:43 +00:00
|
|
|
return;
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
|
2009-09-12 02:58:22 +00:00
|
|
|
// return value:
|
|
|
|
// 0 - Invalid or unknown disc.
|
|
|
|
// 1 - PS1 CD
|
|
|
|
// 2 - PS2 CD
|
|
|
|
int GetPS2ElfName( wxString& name )
|
|
|
|
{
|
|
|
|
int f;
|
|
|
|
char buffer[g_MaxPath];//if a file is longer...it should be shorter :D
|
|
|
|
char *pos;
|
|
|
|
TocEntry tocEntry;
|
|
|
|
|
|
|
|
IsoFS_init();
|
|
|
|
|
|
|
|
// check if the file exists
|
|
|
|
if (IsoFS_findFile("SYSTEM.CNF;1", &tocEntry) != TRUE){
|
2009-10-29 13:32:40 +00:00
|
|
|
Console.Warning("GetElfName: SYSTEM.CNF not found; invalid cd image or no disc present.");
|
2009-09-12 02:58:22 +00:00
|
|
|
return 0;//could not find; not a PS/PS2 cdvd
|
|
|
|
}
|
|
|
|
|
|
|
|
f=IsoFS_open("SYSTEM.CNF;1", 1);
|
|
|
|
IsoFS_read(f, buffer, g_MaxPath);
|
|
|
|
IsoFS_close(f);
|
|
|
|
|
|
|
|
buffer[tocEntry.fileSize]='\0';
|
|
|
|
|
|
|
|
pos=strstr(buffer, "BOOT2");
|
|
|
|
if (pos==NULL){
|
|
|
|
pos=strstr(buffer, "BOOT");
|
|
|
|
if (pos==NULL) {
|
Lots of new code maintenance stuffs:
* Completely new assertion macros: pxAssert, pxAssertMsg, and pxFail, pxAssertDev (both which default to using a message). These replace *all* wxASSERT, DevAssert, and jASSUME varieties of macros. New macros borrow the best of all assertion worlds: MSVCRT, wxASSERT, and AtlAssume. :)
* Rewrote the Console namespace as a structure called IConsoleWriter, and created several varieties of ConsoleWriters for handling different states of log and console availability (should help reduce overhead of console logging nicely).
* More improvements to the PersistentThread model, using safely interlocked "Do*" style callbacks for starting and cleaning up threads.
* Fixed console logs so that they're readable in Win32 notepad again (the log writer adds CRs to naked LFs).
* Added AppInit.cpp -- contains constructor, destructor, OnInit, and command line parsing mess.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1950 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-04 08:27:27 +00:00
|
|
|
Console.Error("PCSX2 Boot Error: This is not a Playstation or PS2 game!");
|
2009-09-12 02:58:22 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
pos+=strlen("BOOT2");
|
|
|
|
while (pos && *pos && pos<&buffer[g_MaxPath]
|
|
|
|
&& (*pos<'A' || (*pos>'Z' && *pos<'a') || *pos>'z'))
|
|
|
|
pos++;
|
|
|
|
if (!pos || *pos==0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
// the filename is everything up to the first CR/LF/tab.. ?
|
|
|
|
// Or up to any whitespace? (I'm opting for first CRLF/tab, although the old code
|
|
|
|
// apparently stopped on spaces too) --air
|
2009-10-29 13:51:49 +00:00
|
|
|
name = wxStringTokenizer( fromUTF8( pos ) ).GetNextToken();
|
2009-09-12 02:58:22 +00:00
|
|
|
|
|
|
|
#ifdef PCSX2_DEVBUILD
|
|
|
|
FILE *fp;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
fp = fopen("System.map", "r");
|
|
|
|
if( fp == NULL ) return 2;
|
|
|
|
|
|
|
|
u32 addr;
|
|
|
|
|
Lots of new code maintenance stuffs:
* Completely new assertion macros: pxAssert, pxAssertMsg, and pxFail, pxAssertDev (both which default to using a message). These replace *all* wxASSERT, DevAssert, and jASSUME varieties of macros. New macros borrow the best of all assertion worlds: MSVCRT, wxASSERT, and AtlAssume. :)
* Rewrote the Console namespace as a structure called IConsoleWriter, and created several varieties of ConsoleWriters for handling different states of log and console availability (should help reduce overhead of console logging nicely).
* More improvements to the PersistentThread model, using safely interlocked "Do*" style callbacks for starting and cleaning up threads.
* Fixed console logs so that they're readable in Win32 notepad again (the log writer adds CRs to naked LFs).
* Added AppInit.cpp -- contains constructor, destructor, OnInit, and command line parsing mess.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1950 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-04 08:27:27 +00:00
|
|
|
Console.WriteLn("Loading System.map...");
|
2009-09-12 02:58:22 +00:00
|
|
|
while (!feof(fp)) {
|
|
|
|
fseek(fp, 8, SEEK_CUR);
|
|
|
|
buffer[0] = '0'; buffer[1] = 'x';
|
|
|
|
for (i=2; i<10; i++) buffer[i] = fgetc(fp); buffer[i] = 0;
|
|
|
|
addr = strtoul(buffer, (char**)NULL, 0);
|
|
|
|
fseek(fp, 3, SEEK_CUR);
|
|
|
|
for (i=0; i<g_MaxPath; i++) {
|
|
|
|
buffer[i] = fgetc(fp);
|
|
|
|
if (buffer[i] == '\n' || buffer[i] == 0) break;
|
|
|
|
}
|
|
|
|
if (buffer[i] == 0) break;
|
|
|
|
buffer[i] = 0;
|
|
|
|
|
|
|
|
R5900::disR5900AddSym(addr, buffer);
|
|
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return 2;
|
|
|
|
}
|