mirror of
https://github.com/martravi/wiiqt6.git
synced 2024-11-22 05:29:14 +01:00
* symbolizer: handle HA and HI relacotians differently. use unique function names in IDC
git-svn-id: http://wiiqt.googlecode.com/svn/trunk@115 389f4c8b-5dfe-645f-db0e-df882bc27289
This commit is contained in:
parent
ea3e04d2c0
commit
a4648d8cac
@ -348,6 +348,7 @@ bool ElfParser::ParseFileText( const QStringList &strs, const QStringList §i
|
|||||||
|
|
||||||
switch( refType )
|
switch( refType )
|
||||||
{
|
{
|
||||||
|
case SymRef::R_PPC_ADDR16_HA:
|
||||||
case SymRef::R_PPC_ADDR16_HI:
|
case SymRef::R_PPC_ADDR16_HI:
|
||||||
case SymRef::R_PPC_ADDR16_LO:
|
case SymRef::R_PPC_ADDR16_LO:
|
||||||
{
|
{
|
||||||
@ -560,7 +561,11 @@ QString ElfParser::GetNonOperRef( const QString &str, quint32 *off, SymRef::Type
|
|||||||
{
|
{
|
||||||
*type = SymRef::R_PPC_EMB_SDA21;
|
*type = SymRef::R_PPC_EMB_SDA21;
|
||||||
}
|
}
|
||||||
else if( str.contains( "R_PPC_ADDR16_HA" ) || str.contains( "R_PPC_ADDR16_HI" ) )
|
else if( str.contains( "R_PPC_ADDR16_HA" ) )
|
||||||
|
{
|
||||||
|
*type = SymRef::R_PPC_ADDR16_HA;
|
||||||
|
}
|
||||||
|
else if( str.contains( "R_PPC_ADDR16_HI" ) )
|
||||||
{
|
{
|
||||||
*type = SymRef::R_PPC_ADDR16_HI;
|
*type = SymRef::R_PPC_ADDR16_HI;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,8 @@ struct SymRef
|
|||||||
{
|
{
|
||||||
enum Type
|
enum Type
|
||||||
{
|
{
|
||||||
R_PPC_ADDR16_HI, // reference to the upper 16 bits of the variable. ie "lis"
|
R_PPC_ADDR16_HA, // reference to the upper 16 bits of the variable and treats stuff as signed. ie "lis, addi"
|
||||||
|
R_PPC_ADDR16_HI, // reference to the upper 16 bits of the variable and treats the valuas as unsigned. ie "lis, ori"
|
||||||
R_PPC_ADDR16_LO, // refers to the lower 16 bits. ie "addi"
|
R_PPC_ADDR16_LO, // refers to the lower 16 bits. ie "addi"
|
||||||
R_PPC_REL24, // refers by branching. ie "bl"
|
R_PPC_REL24, // refers by branching. ie "bl"
|
||||||
R_PPC_SDAREL16, // no clue wtf this one does
|
R_PPC_SDAREL16, // no clue wtf this one does
|
||||||
|
@ -37,7 +37,7 @@ struct KnownFunction
|
|||||||
struct KnownVariable
|
struct KnownVariable
|
||||||
{
|
{
|
||||||
quint32 sig; // signature for opcodes dealing with this variable when GLOBALVAR_MASK()'d
|
quint32 sig; // signature for opcodes dealing with this variable when GLOBALVAR_MASK()'d
|
||||||
//! given lwz %r0, -0x5460(%r13), it will store the -0x5460(%r13)
|
//! given lwz %r0, -0x5460(%r13), it will store the -0x5460(%r13)
|
||||||
QString name; // symbol name
|
QString name; // symbol name
|
||||||
ElfParser::File *file; // pointer to the file object that contains the data
|
ElfParser::File *file; // pointer to the file object that contains the data
|
||||||
};
|
};
|
||||||
@ -744,7 +744,7 @@ void TryToMatchData()
|
|||||||
{
|
{
|
||||||
if( alias.containerName == kd.name )
|
if( alias.containerName == kd.name )
|
||||||
{
|
{
|
||||||
qDebug() << hex << " " << ( kd.addr + alias.offset ) << alias.size << alias.name;
|
qDebug() << hex << " " << ( kd.addr + alias.offset ) << alias.size << alias.name;
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
@ -950,9 +950,24 @@ void TryToMatchFunctions1()
|
|||||||
|
|
||||||
switch( ref.type )
|
switch( ref.type )
|
||||||
{
|
{
|
||||||
|
case SymRef::R_PPC_ADDR16_HA:// upper 16 bits
|
||||||
|
{
|
||||||
|
quint32 symbol = ( it.second->addr + ref.symOff + aliasDiff );
|
||||||
|
quint16 upper = ( ( symbol & 0xffff0000 ) >> 16 ) + ( ( symbol & 0x8000 ) ? 1 : 0 );
|
||||||
|
if( ( opcode & 0xffff ) != upper )
|
||||||
|
{
|
||||||
|
fail = true;
|
||||||
|
|
||||||
|
//qDebug() << "bad high" << hex << opcode << refOff << ref.name << ref.symOff;
|
||||||
|
//qDebug() << hex << "expected" << (quint32)( ( ( it.second->addr + ref.symOff + aliasDiff ) & 0xffff0000 ) >> 16 );
|
||||||
|
//DumpRefs( *( it.first ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SymRef::R_PPC_ADDR16_HI:// upper 16 bits
|
case SymRef::R_PPC_ADDR16_HI:// upper 16 bits
|
||||||
{
|
{
|
||||||
if( ( opcode & 0xffff ) != ( ( ( it.second->addr + ref.symOff + aliasDiff ) & 0xffff0000 ) >> 16 ) )
|
quint16 upper = ( ( ( it.second->addr + ref.symOff + aliasDiff ) & 0xffff0000 ) >> 16 );
|
||||||
|
if( ( opcode & 0xffff ) != upper )
|
||||||
{
|
{
|
||||||
fail = true;
|
fail = true;
|
||||||
//qDebug() << "bad high" << hex << opcode << refOff << ref.name << ref.symOff;
|
//qDebug() << "bad high" << hex << opcode << refOff << ref.name << ref.symOff;
|
||||||
@ -1059,18 +1074,18 @@ void FindGlobalVariables()
|
|||||||
newVariables << nw;
|
newVariables << nw;
|
||||||
|
|
||||||
/*qDebug() << "opcode" << hex << opcode << "addr" << addr;
|
/*qDebug() << "opcode" << hex << opcode << "addr" << addr;
|
||||||
qDebug() << kf1.function->Name() << ref.name;
|
qDebug() << kf1.function->Name() << ref.name;
|
||||||
qDebug();
|
qDebug();
|
||||||
quint32 z = GLOBALVAR_MASK( opcode );
|
quint32 z = GLOBALVAR_MASK( opcode );
|
||||||
opcode = z;
|
opcode = z;
|
||||||
quint32 s = (quint32)PPCGETD( opcode );
|
quint32 s = (quint32)PPCGETD( opcode );
|
||||||
quint32 a = (quint32)PPCGETA( opcode );
|
quint32 a = (quint32)PPCGETA( opcode );
|
||||||
quint32 d = (quint32)( opcode & 0xffff );
|
quint32 d = (quint32)( opcode & 0xffff );
|
||||||
quint32 o = (quint32)( PPCGETIDX( opcode ) - 32 );
|
quint32 o = (quint32)( PPCGETIDX( opcode ) - 32 );
|
||||||
DU32( o );
|
DU32( o );
|
||||||
DU32( d );
|
DU32( d );
|
||||||
DU32( s );
|
DU32( s );
|
||||||
DU32( a );*/
|
DU32( a );*/
|
||||||
//exit( 0 );
|
//exit( 0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1288,15 +1303,15 @@ void TryToMatchFunctions2( QMap< const ElfParser::Function *, quint32 > &nonMatc
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*if( fun2.Name() == "NANDPrivateCreateAsync" )
|
/*if( fun2.Name() == "NANDPrivateCreateAsync" )
|
||||||
{
|
{
|
||||||
qDebug() << "expected" << fun2.Name() << "at" << hex << res << "but pattern didnt match";
|
qDebug() << "expected" << fun2.Name() << "at" << hex << res << "but pattern didnt match";
|
||||||
qDebug() << "being called from" << fun->Name() << "at" << hex << addr;
|
qDebug() << "being called from" << fun->Name() << "at" << hex << addr;
|
||||||
qDebug() << "offset" << NStr( textOffset ) << "in section" << dolIdx;
|
qDebug() << "offset" << NStr( textOffset ) << "in section" << dolIdx;
|
||||||
qDebug() << fun2.Pattern();
|
qDebug() << fun2.Pattern();
|
||||||
qDebug() << wholeDolHex.at( dolIdx ).mid( textOffset, fun2.Pattern().size() );
|
qDebug() << wholeDolHex.at( dolIdx ).mid( textOffset, fun2.Pattern().size() );
|
||||||
exit( 0 );
|
exit( 0 );
|
||||||
|
|
||||||
}*/
|
}*/
|
||||||
//qDebug() << "expected" << fun2.Name() << "at" << hex << res << "but pattern didnt match";
|
//qDebug() << "expected" << fun2.Name() << "at" << hex << res << "but pattern didnt match";
|
||||||
//qDebug() << "being called from" << fun->Name() << "at" << hex << addr;
|
//qDebug() << "being called from" << fun->Name() << "at" << hex << addr;
|
||||||
nonMatchingBranches[ &fun2 ] = res;
|
nonMatchingBranches[ &fun2 ] = res;
|
||||||
@ -1533,6 +1548,18 @@ QList< QPair< const ElfParser::Function *, quint32> > TryToMatchFunctions4( QLis
|
|||||||
|
|
||||||
#define INDENT_TXT QString( " " )
|
#define INDENT_TXT QString( " " )
|
||||||
|
|
||||||
|
QString MakeUniqueName( const QString &name, QStringList &list )
|
||||||
|
{
|
||||||
|
quint32 fix = 0;
|
||||||
|
QString ret( name );
|
||||||
|
while( list.contains( ret ) )
|
||||||
|
{
|
||||||
|
ret = name + QString( "_%1" ).arg( fix++ );
|
||||||
|
}
|
||||||
|
list << ret;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
QString CleanupNameString( const QString &name )// gcc puts the section name at the front of the user-given name
|
QString CleanupNameString( const QString &name )// gcc puts the section name at the front of the user-given name
|
||||||
{
|
{
|
||||||
if( name.startsWith( ".sbss." ) )
|
if( name.startsWith( ".sbss." ) )
|
||||||
@ -1579,6 +1606,7 @@ QString MakeIDC( const QString &dolPath, const QString &libPath, const QMap< con
|
|||||||
+ INDENT_TXT + "MakeFunction( addr, len );\n"
|
+ INDENT_TXT + "MakeFunction( addr, len );\n"
|
||||||
+ INDENT_TXT + "MakeName( addr, name );\n"
|
+ INDENT_TXT + "MakeName( addr, name );\n"
|
||||||
+"}\n\n";
|
+"}\n\n";
|
||||||
|
QStringList uniquiFunctionNames;
|
||||||
bool insertedMakeCode = false;
|
bool insertedMakeCode = false;
|
||||||
bool haveData = knownData.size() != 0;
|
bool haveData = knownData.size() != 0;
|
||||||
if( haveData )
|
if( haveData )
|
||||||
@ -1635,16 +1663,17 @@ QString MakeIDC( const QString &dolPath, const QString &libPath, const QMap< con
|
|||||||
QString line;
|
QString line;
|
||||||
if( kf.function )
|
if( kf.function )
|
||||||
{
|
{
|
||||||
|
QString name = MakeUniqueName( CleanupNameString( kf.function->Name() ), uniquiFunctionNames );
|
||||||
line += INDENT_TXT + QString( "CreateFunction( 0x%1, 0x%2, \"%3\" ); " )
|
line += INDENT_TXT + QString( "CreateFunction( 0x%1, 0x%2, \"%3\" ); " )
|
||||||
.arg( kf.addr, 8, 16, QChar( '0' ) ).arg( kf.function->Pattern().size() / 2, 4, 16, QChar( '0' ) )
|
.arg( kf.addr, 8, 16, QChar( '0' ) ).arg( kf.function->Pattern().size() / 2, 4, 16, QChar( '0' ) )
|
||||||
.arg( CleanupNameString( kf.function->Name() ) );
|
.arg( name );
|
||||||
if( kf.file->Name() != libPath )
|
if( kf.file->Name() != libPath )
|
||||||
{
|
{
|
||||||
line += QString( "MakeComm( 0x%1, \"File: %2\" );" )
|
line += QString( "MakeComm( 0x%1, \"File: %2\" );" )
|
||||||
.arg( kf.addr, 8, 16, QChar( '0' ) ).arg( kf.file->Name() );
|
.arg( kf.addr, 8, 16, QChar( '0' ) ).arg( kf.file->Name() );
|
||||||
}
|
}
|
||||||
|
|
||||||
// line += " // " + kf.debug;
|
// line += " // " + kf.debug;
|
||||||
|
|
||||||
line += '\n';
|
line += '\n';
|
||||||
|
|
||||||
@ -1661,11 +1690,12 @@ QString MakeIDC( const QString &dolPath, const QString &libPath, const QMap< con
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
QString name = MakeUniqueName( CleanupNameString( kf.name ), uniquiFunctionNames );
|
||||||
line += INDENT_TXT + QString( "CreateFunction( 0x%1, BADADDR, \"%2\" );" )
|
line += INDENT_TXT + QString( "CreateFunction( 0x%1, BADADDR, \"%2\" );" )
|
||||||
.arg( kf.addr, 8, 16, QChar( '0' ) )
|
.arg( kf.addr, 8, 16, QChar( '0' ) )
|
||||||
.arg( CleanupNameString( kf.name ) );
|
.arg( name );
|
||||||
|
|
||||||
// line += " // " + kf.debug;
|
// line += " // " + kf.debug;
|
||||||
|
|
||||||
line += '\n';
|
line += '\n';
|
||||||
}
|
}
|
||||||
@ -1687,20 +1717,21 @@ QString MakeIDC( const QString &dolPath, const QString &libPath, const QMap< con
|
|||||||
while( it.hasNext() )
|
while( it.hasNext() )
|
||||||
{
|
{
|
||||||
it.next();
|
it.next();
|
||||||
|
QString name = MakeUniqueName( CleanupNameString( it.key()->Name() ), uniquiFunctionNames );
|
||||||
ret += INDENT_TXT + QString( "CreateFunction( 0x%1, BADADDR, \"%2\" );\n" ) // BADADDR because we cant trust the pattern size when it doesnt match the expected
|
ret += INDENT_TXT + QString( "CreateFunction( 0x%1, BADADDR, \"%2\" );\n" ) // BADADDR because we cant trust the pattern size when it doesnt match the expected
|
||||||
.arg( it.value(), 8, 16, QChar( '0' ) )
|
.arg( it.value(), 8, 16, QChar( '0' ) )
|
||||||
.arg( CleanupNameString( it.key()->Name() ) );
|
.arg( name );
|
||||||
// do something cool here with the r13/rtoc references
|
// do something cool here with the r13/rtoc references
|
||||||
// these cant be trusted since the functions here dont match expected patterns
|
// these cant be trusted since the functions here dont match expected patterns
|
||||||
/*foreach( const SymRef &ref, it.key()->References() )
|
/*foreach( const SymRef &ref, it.key()->References() )
|
||||||
{
|
{
|
||||||
if( ref.type == SymRef::R_PPC_EMB_SDA21 )
|
if( ref.type == SymRef::R_PPC_EMB_SDA21 )
|
||||||
{
|
{
|
||||||
ret += INDENT_TXT + INDENT_TXT + QString( "MakeComm( 0x%1, \"%2\" );\n" )
|
ret += INDENT_TXT + INDENT_TXT + QString( "MakeComm( 0x%1, \"%2\" );\n" )
|
||||||
.arg( it.value() + ( ref.off & ~3 ), 8, 16, QChar( '0' ) )
|
.arg( it.value() + ( ref.off & ~3 ), 8, 16, QChar( '0' ) )
|
||||||
.arg( CleanupNameString( ref.name ) );
|
.arg( CleanupNameString( ref.name ) );
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
ret += "\n}\n";
|
ret += "\n}\n";
|
||||||
}
|
}
|
||||||
@ -1748,6 +1779,7 @@ int main(int argc, char *argv[])
|
|||||||
QString libPath( argv[ 2 ] );
|
QString libPath( argv[ 2 ] );
|
||||||
QString outName( argv[ 3 ] );
|
QString outName( argv[ 3 ] );
|
||||||
|
|
||||||
|
|
||||||
qDebug() << "Loading dol...";
|
qDebug() << "Loading dol...";
|
||||||
if( !LoadDol( dolPath ) )
|
if( !LoadDol( dolPath ) )
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user