bool ElfParser::ParseFileText( const QStringList &strs, const QStringList §ionStrs, const QStringList &symbolStrs, ElfParser::File &file ) { quint32 cnt = strs.size(); quint32 fOff = 0; quint32 fStart = 0; QString name; QString pattern; QList< SymRef > refs; //DBG << file.Name() << sectionStrs.size() << symbolStrs.size() << strs.size(); QMap< QString, QByteArray >sections = ParseSectionText( sectionStrs ); QList< SymAlias > aliases = ParseSymbolTable( symbolStrs ); //DBG << file.Name() << sections.size() << aliases.size(); for( quint32 i = 0; i < cnt; i++ ) { const QString &str = strs.at( i ); /*if( name == "WII_Initialize" ) { qDebug() << str; }*/ // start a new funciton if( IsFunctionStart( str, &fStart ) ) { // add this function to the list if( !name.isEmpty() && fOff ) { Function fun( name ); fun.references = refs; fun.pattern = pattern; fun.file = &file; file.functions << fun; //qDebug() << "pattern:" << pattern; } //qDebug() << GetFunctionName( str ); name = GetFunctionName( str ); //DBG << name; if( fOff != (quint32)pattern.size() / 2 ) { qDebug() << "size bad"; exit( 0 ); } fOff = 0; pattern.clear(); refs.clear(); sections.remove( name );// remove functions from the section list continue; } if( name.isEmpty() ) { continue; } if( IsBlank( str ) ) { //qDebug() << str << "is blank"; continue; } if( IsSymbolLine( str ) ) { //qDebug() << str << "IsSymbolLine"; continue; } QString hex; QString oper; QString symbol; quint32 refOff = 0xdeadbeef; if( !ParseOpLine( str, hex, oper ) ) { qDebug() << str << strs.at( i - 1 ); return false; } /*if( name == "WII_Initialize" ) { qDebug() << "hex" << hex; }*/ if( ( i < cnt - 1 ) && IsSymbolLine( strs.at( i + 1 ) ) ) { SymRef::Type refType; symbol = GetNonOperRef( strs.at( i + 1 ), &refOff, &refType ); if( refOff < fStart ) { WRN << "refOff < fStart" << str; return false; } SymRef ref; quint32 deRef; ref.name = DeReferenceSymbol( symbol, &deRef ); ref.symOff = deRef; switch( refType ) { case SymRef::R_PPC_ADDR16_HA: case SymRef::R_PPC_ADDR16_HI: case SymRef::R_PPC_ADDR16_LO: { hex[ 4 ] = '.'; hex[ 5 ] = '.'; hex[ 6 ] = '.'; hex[ 7 ] = '.'; } break; case SymRef::R_PPC_REL24: case SymRef::R_PPC_EMB_SDA21: { hex[ 1 ] = '.'; hex[ 2 ] = '.'; hex[ 3 ] = '.'; hex[ 4 ] = '.'; hex[ 5 ] = '.'; hex[ 6 ] = '.'; hex[ 7 ] = '.'; } break; case SymRef::R_PPC_SDAREL16: { hex = "........"; } break; default: WRN << "unhandled reference type"; return false; break; } ref.type = refType; ref.off = refOff - fStart; refs << ref; if( ref.off & 0xff000000 ) { qDebug() << "ref.off is busted 1" << name << str; qDebug() << ::hex << refOff << fStart; exit( 0 ); } } else if( OpNeedsWildCard( oper ) ) { //DBG << "bl called without symbol reference\n" << str; hex = "........"; if( symbol.isEmpty() ) { symbol = GetOpersymRef( str ); } SymRef ref; ref.name = symbol; ref.off = (quint32)(pattern.size()); ref.type = SymRef::R_PPC_REL24; refs << ref; if( ref.off & 0xff000000 ) { DBG << "ref.off is busted 2" << name << str; exit( 0 ); } } pattern += hex.toUpper(); /*if( name == "WII_Initialize" ) { qDebug() << "hex" << pattern; }*/ fOff += 4; } if( !name.isEmpty() ) { Function fun( name ); fun.references = refs; fun.pattern = pattern; fun.file = &file; file.functions << fun; } file.sections = sections; file.aliases = aliases; return true; }
//=========================================================================== Update_t CmdSymbolsLoad (int nArgs) { TCHAR sFileName[MAX_PATH]; _tcscpy(sFileName,g_sProgramDir); int iSymbolTable = GetSymbolTableFromCommand(); if ((iSymbolTable < 0) || (iSymbolTable >= NUM_SYMBOL_TABLES)) { wsprintf( sFileName, "Only %d symbol tables supported!", NUM_SYMBOL_TABLES ); return ConsoleDisplayError( sFileName ); } int nSymbols = 0; if (! nArgs) { // Default to main table // if (g_iCommand == CMD_SYMBOLS_MAIN) // _tcscat(sFileName, g_sFileNameSymbolsMain ); // else // { // if (! _tcslen( g_sFileNameSymbolsUser )) // { // return ConsoleDisplayError(TEXT("No user symbol file to reload.")); // } // // load user symbols // _tcscat( sFileName, g_sFileNameSymbolsUser ); // } _tcscat(sFileName, g_sFileNameSymbols[ iSymbolTable ]); nSymbols = ParseSymbolTable( sFileName, (SymbolTable_Index_e) iSymbolTable ); } int iArg = 1; if (iArg <= nArgs) { TCHAR *pFileName = NULL; if( g_aArgs[ iArg ].bType & TYPE_QUOTED_2 ) { pFileName = g_aArgs[ iArg ].sArg; _tcscpy(sFileName,g_sProgramDir); _tcscat(sFileName, pFileName); // Remember File Name of last symbols loaded _tcscpy( g_sFileNameSymbolsUser, pFileName ); } // SymbolOffset // sym load "filename" [,symbol_offset] unsigned int nOffsetAddr = 0; iArg++; if( iArg <= nArgs) { if (g_aArgs[ iArg ].eToken == TOKEN_COMMA) { iArg++; if( iArg <= nArgs ) { nOffsetAddr = g_aArgs[ iArg ].nValue; if( (nOffsetAddr < _6502_MEM_BEGIN) || (nOffsetAddr > _6502_MEM_END) ) { nOffsetAddr = 0; } } } } if( pFileName ) { nSymbols = ParseSymbolTable( sFileName, (SymbolTable_Index_e) iSymbolTable, nOffsetAddr ); } } if( nSymbols > 0 ) { g_nSymbolsLoaded = nSymbols; } Update_t bUpdateDisplay = UPDATE_DISASM; bUpdateDisplay |= (nSymbols > 0) ? UPDATE_SYMBOLS : 0; return bUpdateDisplay; }