diff -r 3ff3fecb12fe -r 6a82cd05fb1e memana/analyzetoolclient/commandlineengine/internal/src/catromsymbol.cpp --- a/memana/analyzetoolclient/commandlineengine/internal/src/catromsymbol.cpp Thu Feb 11 15:52:57 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,656 +0,0 @@ -/* -* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: Reads rom symbol file and provides interface to acquire -* binary and function information using memory addresss. -* -*/ - -#include "../inc/ATCommonDefines.h" -#include "../inc/catromsymbol.h" -#include "../inc/catfilereader.h" -#include "../inc/CATBase.h" -#include "../inc/CATMemoryAddress.h" - -// ----------------------------------------------------------------------------- -// RofsBinary::RofsBinary -// Default construcor -// ----------------------------------------------------------------------------- -RofsBinary::RofsBinary() -{ - LOG_LOW_FUNC_ENTRY("RofsBinary::RofsBinary"); - m_sBinary = ""; - vSymbols.clear(); -} - -// ----------------------------------------------------------------------------- -// RofsBinary::RofsBinary -// Construcor -// ----------------------------------------------------------------------------- -RofsBinary::RofsBinary( const string& sBinary ) -{ - LOG_LOW_FUNC_ENTRY("RofsBinary::RofsBinary"); - m_sBinary = sBinary; - vSymbols.clear(); -} - -// ----------------------------------------------------------------------------- -// RofsBinary::~RofsBinary -// Destructor -// ----------------------------------------------------------------------------- -RofsBinary::~RofsBinary() -{ - LOG_LOW_FUNC_ENTRY("RofsBinary::~RofsBinary"); - for ( vector::iterator it = vSymbols.begin() ; it != vSymbols.end() ; it++ ) - delete *it; - vSymbols.clear(); -} - -// ----------------------------------------------------------------------------- -// CATRomSymbol::CATRomSymbol -// Constructor. -// ----------------------------------------------------------------------------- -CATRomSymbol::CATRomSymbol() -{ - LOG_FUNC_ENTRY("CATRomSymbol::CATRomSymbol"); - m_bSymbolsRead = false; - m_iRomEndAddress = 0; - m_iRomStartAddress = 0; - m_vRomFiles.clear(); - m_sErrorMessage = ""; - m_vRomCache.clear(); - m_vRomSymbols.clear(); - m_bShowProgressMessages = false; -} - -// ----------------------------------------------------------------------------- -// CATRomSymbol::~CATRomSymbol -// Destructor. -// ----------------------------------------------------------------------------- -CATRomSymbol::~CATRomSymbol() -{ - LOG_FUNC_ENTRY("CATRomSymbol::~CATRomSymbol"); - // Rom - for ( vector::iterator it = m_vRomSymbols.begin() ; it != m_vRomSymbols.end() ; it++ ) - { - delete *it; - } - m_vRomSymbols.clear(); - // Rofs - for ( vector::iterator it = m_vRofsBinaries.begin() ; it != m_vRofsBinaries.end() ; it++ ) - { - delete *it; - } - m_vRofsBinaries.clear(); -} - -// ----------------------------------------------------------------------------- -// CATRomSymbol::Open -// This funtion should not be used anymore since -// we support multiple rom/rofs files. -// ----------------------------------------------------------------------------- -bool CATRomSymbol::Open( const string& /*sString*/, const unsigned long /*iLong*/) -{ - LOG_FUNC_ENTRY("CATRomSymbol::Open"); - return false; -} - -// ----------------------------------------------------------------------------- -// CATRomSymbol::SetSymbols -// Set symbol file(s) to be used. -// This also checks that files exists and identifies them as rom/rofs. -// ----------------------------------------------------------------------------- -bool CATRomSymbol::SetSymbols( const vector& vSymbols ) -{ - LOG_FUNC_ENTRY("CATRomSymbol::SetSymbols"); - bool ok = true; - // Check no same symbol defined twice. - for( vector::const_iterator it = vSymbols.begin() ; - it != vSymbols.end(); it++ ) - { - for( vector::const_iterator it2 = vSymbols.begin() ; - it2 != vSymbols.end(); it2++ ) - { - if ( it == it2 ) - continue; - if ( _stricmp( (*it).c_str(), (*it2).c_str() ) == 0 ) - { - m_sErrorMessage.append( "Same symbol file defined twice (" ); - m_sErrorMessage.append( (*it) ); - m_sErrorMessage.append( ")\n" ); - return false; - } - } - } - // Loop given symbol files. - for( vector::const_iterator it = vSymbols.begin() ; - it != vSymbols.end(); it++ ) - { - // Symbol file exists? - if ( ! CATBase::FileExists( (*it).c_str() ) ) - { - ok = false; - m_sErrorMessage.append( "Symbol file does not exists (" ); - m_sErrorMessage.append( *it ); - m_sErrorMessage.append( ").\n"); - continue; - } - // Identify symbol file. - int type = IdentifySymbolFile( *it ); - // Depending on type move it correct vector. - switch( type ) - { - case SYMBOL_FILE_INVALID: - ok = false; - m_sErrorMessage.append( "Symbol file with invalid content (" ); - m_sErrorMessage.append( *it ); - m_sErrorMessage.append( ").\n"); - break; - case SYMBOL_FILE_ROM: - m_vRomFiles.push_back( *it ); - break; - case SYMBOL_FILE_ROFS: - m_vRofsFiles.push_back( *it ); - break; - default: - ok = false; - LOG_STRING("IdentifySymbolFile returned unknown type."); - break; - } - } - if ( ok ) - { - // Read symbols. - if ( m_vRomFiles.size() > 0 ) - { - if ( ! ReadRomFiles() ) - ok = false; - else - m_bSymbolsRead = true; - } - if ( m_vRofsFiles.size() > 0 ) - { - if ( ! ReadRofsFiles() ) - ok = false; - else - m_bSymbolsRead = true; - } - } - return ok; -} - -// ----------------------------------------------------------------------------- -// CATRomSymbol::IdentifySymbolFile -// Identify given file is it rom / rofs. -// ----------------------------------------------------------------------------- -int CATRomSymbol::IdentifySymbolFile( const string& sFile ) -{ - LOG_FUNC_ENTRY("CATRomSymbol::IdentifySymbolFile"); - // Set type as invalid. - int iType = SYMBOL_FILE_INVALID; - // Line counter. - int iLineCount = 0; - // Minimun line length to identify it. - size_t iLineMinLength = MAX_LINE_LENGTH; - if ( ROFS_SYMBOL_IDENTIFY_STRING.length() > ROM_SYMBOL_IDENTIFY_STRING.length() ) - iLineMinLength = ROFS_SYMBOL_IDENTIFY_STRING.length(); - else - iLineMinLength = ROM_SYMBOL_IDENTIFY_STRING.length(); - try { - ifstream in; - in.open( sFile.c_str(), ios::in ); - if ( ! in.good() ) - return SYMBOL_FILE_INVALID; - char cLine[MAX_LINE_LENGTH]; - do { - // Dont read too many lines. (File might be contain invalid data). - iLineCount++; - if ( iLineCount > IDENTIFY_MAX_LINES_READ ) - break; - - // Get line -> string. - in.getline( cLine, MAX_LINE_LENGTH ); - string sLine(cLine); - - // Check its not too short. - if( sLine.length() < iLineMinLength ) - continue; - - // Take substring from start of line to identify it to rofs/rom. - if ( ! sLine.substr( 0, ROFS_SYMBOL_IDENTIFY_STRING.length() ).compare( ROFS_SYMBOL_IDENTIFY_STRING ) ) - { - iType = SYMBOL_FILE_ROFS; - break; - } - else if ( ! sLine.substr( 0, ROM_SYMBOL_IDENTIFY_STRING.length() ).compare( ROM_SYMBOL_IDENTIFY_STRING ) ) - { - iType = SYMBOL_FILE_ROM; - break; - } - } while ( in.good() ); - in.close(); - } - catch(...) - { - LOG_STRING("CATRomSymbol::IdentifySymbolFile unhandled exception."); - } - return iType; -} - -// ----------------------------------------------------------------------------- -// CATRomSymbol::ReadRomFiles -// Reads rom file(s) and creates symbols to vector. -// ----------------------------------------------------------------------------- -bool CATRomSymbol::ReadRomFiles() -{ - LOG_FUNC_ENTRY("CATRomSymbol::ReadRomFile"); - - // Clear symbols. - for ( vector::iterator it = m_vRomSymbols.begin() ; it != m_vRomSymbols.end() ; it++ ) - { - delete *it; - } - m_vRomSymbols.clear(); - - // Clear cache. note cache is just pointers dont delete them. - m_vRomCache.clear(); - - // Any errors? - bool ok = true; - - for( vector::iterator it = m_vRomFiles.begin(); - it != m_vRomFiles.end() ; it++ ) - ok = ReadRomFile( *it ); - - // If size smaller than 1 it is not good rom file(s). - if ( m_vRomSymbols.size() < 1 || ok != true) - return false; - - // Rom start and end addresses. - m_iRomStartAddress = (*m_vRomSymbols.begin())->iStartAddress; - m_iRomEndAddress = (*m_vRomSymbols.rbegin())->iEndAddress; - return true; -} - -// ----------------------------------------------------------------------------- -// CATRomSymbol::ReadRofsFiles -// Read rofs files. -// ----------------------------------------------------------------------------- -bool CATRomSymbol::ReadRofsFiles() -{ - LOG_FUNC_ENTRY("CATRomSymbol::ReadRofsFiles"); - // Clear. - for ( vector::iterator it = m_vRofsBinaries.begin() ; it != m_vRofsBinaries.end() ; it++ ) - { - delete *it; - } - m_vRofsBinaries.clear(); - - // Any errors? - bool ok = true; - - for( vector::iterator it = m_vRofsFiles.begin(); - it != m_vRofsFiles.end() ; it++ ) - ok = ReadRofsFile( *it ); - - // If size smaller than 1 it is not good rofs file(s). - if ( m_vRofsBinaries.size() < 1 || ok != true) - return false; - return true; -} - -// ----------------------------------------------------------------------------- -// CATRomSymbol::ReadRomFile -// Read given rom file -// ----------------------------------------------------------------------------- -bool CATRomSymbol::ReadRomFile( const string& sFile ) -{ - LOG_FUNC_ENTRY("CATRomSymbol::ReadRomfile"); - // Open rom file. - CATFileReader* reader = new CATFileReader(); - // Show progress message if flag set. - if ( m_bShowProgressMessages ) - cout << AT_MSG << "Reading rom symbol file: " << sFile << "..." << endl; - if ( ! reader->Open( sFile.c_str() ) ) - { - reader->Close(); - delete reader; - return false; - } - - // Show progress message if flag set. - if ( m_bShowProgressMessages ) - cout << AT_MSG << "Parsing rom symbol file: " << sFile << "..." << endl; - - // Loop thrue lines. - string sLine(""); - string sBinary(""); - while( reader->GetLine( sLine ) ) - { - // From rom we just read symbols that have lenght, no need to separate them into diff binaries. - try { - if ( sLine.size() < 2 ) - { - continue; - } - else if ( sLine.at(0) == '8' ) - { - // Create new item. - Symbol* symbol = new Symbol(); - ParseSymbolFromLine( sLine, symbol); - // Ignore symbols which have same start & end address (zero length). - if ( symbol->iStartAddress != symbol->iEndAddress ) - m_vRomSymbols.push_back( symbol ); - else - delete symbol; - } - } catch(...) - { - // Catch all possible exception here so analyze will succeed even rom file invalid. - m_sErrorMessage.append( "Unhandled exception parsing rom symbol file.\n" ); - // Close and delete reader. - reader->Close(); - delete reader; - return false; - } - } - // Close and delete reader. - reader->Close(); - delete reader; - return true; -} - -// ----------------------------------------------------------------------------- -// CATRomSymbol::ReadRofsFile -// Read given rofs file -// ----------------------------------------------------------------------------- -bool CATRomSymbol::ReadRofsFile( const string& sFile ) -{ - LOG_FUNC_ENTRY("CATRomSymbol::ReadRofsFile"); - // open/read rofs file. - CATFileReader* reader = new CATFileReader(); - // Show progress message if flag set. - if ( m_bShowProgressMessages ) - cout << AT_MSG << "Reading rofs symbol file: " << sFile << "..." << endl; - if ( ! reader->Open( sFile.c_str() ) ) - { - reader->Close(); - delete reader; - return false; - } - - // Show progress message if flag set. - if ( m_bShowProgressMessages ) - cout << AT_MSG << "Parsing rofs symbol file: " << sFile << "..." << endl; - - // Loop thrue lines. - string sLine(""); - string sBinary(""); - RofsBinary* rb = NULL; - while( reader->GetLine( sLine ) ) - { - try { - if ( sLine.size() < 2 ) - { - continue; - } - else if ( sLine.at(0) == 'F' ) - { - if ( rb != NULL ) - { - // Check last binary if no symbols in it dont add it. - if ( rb->vSymbols.size() == 0 ) - { - delete rb; - rb = NULL; - } - else - m_vRofsBinaries.push_back( rb ); - } - // new binary name. - size_t i = sLine.rfind("\\"); - sLine.erase(0, i+1); - rb = new RofsBinary( sLine ); - - } - else if ( sLine.at(0) == '0' ) - { - // Cannot pickup symbols if no binary defined. - if ( rb == NULL ) - continue; - // Create new item. - Symbol* symbol = new Symbol(); - ParseSymbolFromLine( sLine, symbol); - // Ignore symbols which have same start & end address (zero length). - if ( symbol->iStartAddress != symbol->iEndAddress ) - rb->vSymbols.push_back( symbol ); - else - delete symbol; - } - } catch(...) - { - // Catch all possible exception here so analyze will succeed even rofs file invalid. - m_sErrorMessage.append( "Unhandled exception parsing rofs symbol file.\n" ); - // Close and delete reader. - reader->Close(); - delete reader; - return false; - } - } - // Last added binary. - if ( rb != NULL ) - { - if ( rb->vSymbols.size() == 0 ) - { - delete rb; - rb = NULL; - } - else - m_vRofsBinaries.push_back( rb ); - } - // Close and delete reader. - reader->Close(); - delete reader; - return true; -} - -// ----------------------------------------------------------------------------- -// CATRomSymbol::ParseSymbolFromLine -// Parses given line into given symbol. -// ----------------------------------------------------------------------------- -void CATRomSymbol::ParseSymbolFromLine( const string& sLine, Symbol* pSymbol ) -{ - LOG_LOW_FUNC_ENTRY("CATRomSymbol::ParseSymbolFromLine"); - if ( pSymbol == NULL ) - return; - size_t s,x; - string temp; - // address. - x = sLine.find( ' ' ); - temp = sLine.substr( 0, x ); - pSymbol->iStartAddress = CATBase::_httoi( temp.c_str() ); - // "Erase spaces" move starting point. - s = x; - s = sLine.find_first_not_of( ' ', s ); - // length. - x = sLine.find( ' ', s ); - temp = sLine.substr(s,x-s); - unsigned long length = CATBase::_httoi( temp.c_str() ); - pSymbol->iEndAddress = pSymbol->iStartAddress + length; - // "Erase spaces" move starting point. - s = x; - s = sLine.find_first_not_of( ' ', s); - // function. Function might have spaces so we find 2 spaces which indicates end of it. - x = sLine.find( " ", s ); - temp = sLine.substr( s, x-s ); - pSymbol->sFunction = temp; -} - -// ----------------------------------------------------------------------------- -// CATRomSymbol::GetError -// Get error string if error occured in other methods. -// ----------------------------------------------------------------------------- -string CATRomSymbol::GetError( void ) -{ - LOG_FUNC_ENTRY("CATRomSymbol::GetError"); - return m_sErrorMessage; -} - -// ----------------------------------------------------------------------------- -// CATRomSymbol::Close -// Close (stop using). -// ----------------------------------------------------------------------------- -bool CATRomSymbol::Close( void ) -{ - LOG_FUNC_ENTRY("CATRomSymbol::Close"); - return true; -} - -// ----------------------------------------------------------------------------- -// CATRomSymbol::AddressToLine -// Try locate binary and function name for given memory address. -// ----------------------------------------------------------------------------- -bool CATRomSymbol::AddressToLine( CATMemoryAddress* result ) -{ - LOG_LOW_FUNC_ENTRY("CATRomSymbol::AddressToLine"); - // Have symbols been read. - if ( ! m_bSymbolsRead ) - return false; - // check that its lenght > 2 - if ( result->GetAddressString().size() < 2 ) - return false; - /* Check first is address in range of rom */ - if ( result->GetAddress() < m_iRomStartAddress - || result->GetAddress() > m_iRomEndAddress ) - { - return AddressToLineRofs( result ); - } - return AddressToLineRom( result ); -} - -// ----------------------------------------------------------------------------- -// CATRomSymbol::AddressToLineRom -// Locate function from rom address range. -// ----------------------------------------------------------------------------- -bool CATRomSymbol::AddressToLineRom( CATMemoryAddress* result ) -{ - LOG_LOW_FUNC_ENTRY( "CATRomSymbol::AddressToLineRom" ); - // Address to find in integer & string. - unsigned long iAddressToFind = result->GetAddress(); - string sAddressToFind = result->GetAddressString(); - - // Find symbol. - Symbol* pFound = NULL; - - // Check from cache first. - vector::iterator it; - for ( it = m_vRomCache.begin(); it != m_vRomCache.end(); it++ ) - { - if ( iAddressToFind >= (*it)->iStartAddress - && (*it)->iEndAddress > iAddressToFind ) - { - pFound = *it; - break; - } - } - - if ( pFound == NULL ) - { - // From all symbols. - bool reverse = false; - int offSetFromStart = iAddressToFind - m_iRomStartAddress; - int offSetFromEnd = m_iRomEndAddress - iAddressToFind; - if ( offSetFromEnd < offSetFromStart ) - reverse = true; - - if ( reverse ) - { - // Iterate vector in reverse. - vector::reverse_iterator it; - for ( it = m_vRomSymbols.rbegin(); it != m_vRomSymbols.rend(); ++it ) - { - if ( iAddressToFind >= (*it)->iStartAddress - && (*it)->iEndAddress > iAddressToFind ) - { - pFound = *it; - break; - } - } - } - else - { - // Iterate vector normal direction. - vector::iterator it; - for ( it = m_vRomSymbols.begin(); it != m_vRomSymbols.end(); it++ ) - { - if ( iAddressToFind >= (*it)->iStartAddress - && (*it)->iEndAddress > iAddressToFind ) - { - pFound = *it; - break; - } - } - } - } - - // Set result if found. - if ( pFound != NULL ) - { - result->SetFunctionName( pFound->sFunction ); - result->SetAddressToLineState( CATMemoryAddress::SYMBOL ); - // Add found symbols pointer to cache. - m_vRomCache.push_back( pFound ); - return true; - } - return false; -} - -// ----------------------------------------------------------------------------- -// CATRomSymbol::AddressToLineRofs -// Locate function from rofs address range. -// ----------------------------------------------------------------------------- -bool CATRomSymbol::AddressToLineRofs( CATMemoryAddress* result) -{ - LOG_LOW_FUNC_ENTRY("CATRomSymbol::AddressToLineRofs"); - // Check that binary name is defined in memory address. - string sBinary = result->GetModuleName(); - if ( sBinary.empty() ) - return false; - // Try find that named module. - vector::iterator rofs = m_vRofsBinaries.begin(); - while( rofs != m_vRofsBinaries.end() ) - { - if ( (*rofs)->m_sBinary.compare( sBinary ) == 0 ) - break; - rofs++; - } - if ( rofs == m_vRofsBinaries.end() ) - return false; - - // Offset what we are looking from binary - unsigned long offSet = result->GetAddress(); - offSet -= result->GetModuleStartAddress(); - for( vector::iterator it = (*rofs)->vSymbols.begin() ; - it != (*rofs)->vSymbols.end(); it++ ) - { - if ( (*it)->iStartAddress <= offSet && offSet < (*it)->iEndAddress ) - { - result->SetFunctionName( (*it)->sFunction ); - result->SetAddressToLineState( CATMemoryAddress::SYMBOL ); - return true; - } - } - return false; -} - -//EOF