* symbolizer: handle HA and HI relacotians differently. use unique function names in IDC

This commit is contained in:
giantpune 2011-12-15 00:41:41 +00:00
parent 62f2666c5d
commit 59a7f2fcc7
3 changed files with 76 additions and 38 deletions

View File

@ -348,6 +348,7 @@ bool ElfParser::ParseFileText( const QStringList &strs, const QStringList &secti
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;
} }

View File

@ -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

View File

@ -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;
@ -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,9 +1663,10 @@ 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\" );" )
@ -1661,9 +1690,10 @@ 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;
@ -1687,9 +1717,10 @@ 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() )
@ -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 ) )
{ {