diff -r 3ff3fecb12fe -r 6a82cd05fb1e memana/analyzetoolclient/commandlineengine/internal/src/cataddr2line.cpp --- a/memana/analyzetoolclient/commandlineengine/internal/src/cataddr2line.cpp Thu Feb 11 15:52:57 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,388 +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: Main module for addr2line pinpointing. -* -*/ - -#include "../inc/cataddr2line.h" -#include "../inc/CATMemoryAddress.h" -#include "../inc/CATBase.h" -#include "../inc/CATDatParser.h" - -#define ASCII_CHAR_CARRIAGE_RETURN 0x0D - -CATAddr2line::CATAddr2line() -{ - LOG_FUNC_ENTRY("CATAddr2line::CATAddr2line"); -} - -bool CATAddr2line::Open( const string& sParameter, const unsigned long /* iLong */ ) -{ - LOG_FUNC_ENTRY("CATAddr2line::Open"); - //Debugging for addr2line task. - //debug.open( "addr2line-lines.txt", ios_base::trunc ); - - m_sMapFileName.clear(); - // Add .map extendsion - m_sMapFileName.append( sParameter ); - m_sMapFileName.append( ".map" ); - - ReadMapFileArmv5(); - - //Make symfile path+name - string sFullPathToSymFile(sParameter); - sFullPathToSymFile.erase( sFullPathToSymFile.find_last_of( "." ), string::npos ); - sFullPathToSymFile.append( ".sym" ); - - // Check with extension + .sym also. - if ( ! CATBase::FileExists( sFullPathToSymFile.c_str() ) ) - { - sFullPathToSymFile.clear(); - sFullPathToSymFile.append( sParameter ); - sFullPathToSymFile.append( ".sym" ); - } - - return server.Initialize( sFullPathToSymFile ); -} - -string CATAddr2line::GetError( void ) -{ - LOG_FUNC_ENTRY("CATAddr2line::GetError"); - string s; - return s; -} - -bool CATAddr2line::Close( void ) -{ - LOG_FUNC_ENTRY("CATAddr2line::Close"); - //Debugging for addr2line task. - //debug.close(); - return true; -} - -bool CATAddr2line::AddressToLine( CATMemoryAddress* result ) -{ - LOG_FUNC_ENTRY("CATAddr2line::AddressToLine"); - - result->SetAddressToLineState( CATMemoryAddress::ADDRESS_TO_LINE_STATE::OUT_OF_RANGE); - - if( !server.GetProcessCreatedState() ) - return false; - //Count address - ULONG uStartA = result->GetModuleStartAddress(); - ULONG uMemoryA = result->GetAddress(); - ULONG uCountedA = uMemoryA - uStartA; - uCountedA += FUNCTIONS_OFFSET_IN_GCCE; - - string sTemp = CATBase::NumberToHexString( uCountedA ); - //Remove "0x" - size_t iCounter = sTemp.find_first_of('x'); - if( iCounter != string::npos ) - { - sTemp.erase( 0, (int)iCounter+1 ); - } - // Write to pipe that is the standard input for a child process. - server.WriteToPipe( sTemp ); - - // Read from pipe that is the standard output for child process. - string s = server.ReadFromPipe(); - - //If output not empty, parse output - if( !s.empty() ) - { - //Debugging code for addr2line task. - //debug.write( "##########\n", 12 ); - //debug.write( s.c_str(), s.size() ); - result->SetAddressToLineState( CATMemoryAddress::ADDRESS_TO_LINE_STATE::EXACT ); - - string s2; - size_t iLocation = s.find_first_of( ASCII_CHAR_CARRIAGE_RETURN ); - - bool bFunctionNameFoundUsingAddr2line = false; - - //Function name - - if(iLocation != string::npos ) - { - s2 = s.substr( 0, iLocation ); - //All characters ascii? - if( CATBase::IsAscii( s2.c_str(), (int)s2.length() ) ) - { - //addr2line returns $x if function name not found - //length must over 2 to be real function name - if( s2.length() > 2 ) - { - bFunctionNameFoundUsingAddr2line = true; - result->SetFunctionName( s2 ); - s.erase( 0, iLocation+2 ); - } - } - } - //If function name not found using addr2line find it from map file - if( !bFunctionNameFoundUsingAddr2line ) - { - string sFuncName( GetFunctionNameUsingAddress( uCountedA ) ); - //If function name empty, print "???" - if( sFuncName.empty() ) - { - s2 = "???"; - result->SetFunctionName( s2 ); - if(iLocation != string::npos ) - { - s.erase( 0, iLocation+2 ); - } - } - else - result->SetFunctionName( sFuncName ); - } - iLocation = s.find_first_of( ':' ); - - //Filename and location - - if(iLocation != string::npos ) - { - s2 = s.substr( 0, iLocation ); - result->SetFileName( s2 ); - s.erase( 0, iLocation+1 ); - } - - //Exact line number - - s2 = s.substr( 0, s.find_first_of( ASCII_CHAR_CARRIAGE_RETURN ) ); - result->SetExactLineNumber( atoi( s2.c_str() ) ); - } - return true; -} - -bool CATAddr2line::ReadMapFileArmv5() -{ - LOG_FUNC_ENTRY("CATModule2::ReadMapFileArmv5"); - // Open .map file - ifstream in( m_sMapFileName.c_str() ); - // File open ok? - if( ! in.good() ) - { - in.close(); - return false; - } - char cTemp[MAX_LINE_LENGTH]; - bool bFirstFuncFound = false; - bool bFirstLine = true; - // Get all lines where is "Thumb" - do - { - // Load one line from .map file - in.getline( cTemp, MAX_LINE_LENGTH ); - if( bFirstLine ) - { - bFirstLine = false; - if( strstr( cTemp, "ARM Linker" ) == NULL ) - return false; - } - // Find _E32Startup - if( !bFirstFuncFound && ( strstr( cTemp, "_E32Startup" ) != NULL) ) - { - bFirstFuncFound = true; - } - else if( !bFirstFuncFound && ( strstr( cTemp, "_E32Dll" ) != NULL) ) - { - bFirstFuncFound = true; - } - else if( !bFirstFuncFound ) - // Skip if _E32Startup not found - continue; - - if( strstr( cTemp, "Thumb Code" ) != NULL || strstr( cTemp, "ARM Code" ) != NULL) - { - MAP_FUNC_INFO structMapFileLineInfo; - structMapFileLineInfo.sWholeLine.append( cTemp ); - - // Get memory string address from line - char* pStart = strstr( cTemp, "0x" ); - // Check did strstr return null. - if ( pStart == NULL ) - continue; - char* pTemp = pStart; - char TempString[MAX_LINE_LENGTH]; - TempString[0] = 0; - size_t iLength = 0; - while( *pTemp != ' ' ) - { - TempString[iLength] = *pTemp; - pTemp++; - iLength++; - } - TempString[iLength] = 0; - - structMapFileLineInfo.iAddress = CATDatParser::_httoi( TempString ); - - pTemp = cTemp; - TempString[0] = 0; - - // Get function name - - // Skip spaces - while( *pTemp == ' ' ) - { - pTemp++; - } - iLength = 0; - // Find end of function name - string sTemp( pTemp ); - - // Location of character ')' - iLength = sTemp.find_first_of(')'); - - // Location of character ' ' - size_t iLength2 = sTemp.find_first_of(' '); - - // If ')' character is the last char and - // character ' ' is closer than ')' use location of ' ' - if( ( iLength + 1 ) == sTemp.length() && iLength2 < iLength ) - iLength = iLength2 - 1; - - if( iLength != string::npos ) - sTemp.resize( (iLength + 1) ); - - structMapFileLineInfo.sFunctionName.append( sTemp.c_str() ); - - bool bARM = false; - // Find function length - pStart = strstr( cTemp, "Thumb Code" ); - if( pStart == NULL ) - { - pStart = strstr( cTemp, "ARM Code" ); - bARM = true; - } - if( pStart != NULL ) - { - if( bARM ) - pStart += 8; - else - pStart += 10; - while(*pStart == ' ') - { - pStart++; - } - sTemp.clear(); - sTemp.append( pStart ); - size_t iSize = sTemp.find_first_of(' '); - if( iSize != string::npos ) - sTemp.resize( iSize ); - } - - structMapFileLineInfo.iFuncLength = atoi( sTemp.c_str() ); - if( bFirstFuncFound && structMapFileLineInfo.iFuncLength > 0 ) - // Save to list - m_vMapFileFuncList.push_back( structMapFileLineInfo ); - } - } - while( in.good() ); - in.close(); - return true; -} - -// Find function name of given address -string CATAddr2line::GetFunctionNameUsingAddress( unsigned long iAddress ) -{ - LOG_LOW_FUNC_ENTRY("CATAddr2line::GetSymbolIndexUsingAddress"); - string sRet; - for( size_t i = 0; i < m_vMapFileFuncList.size(); i++ ) - { - unsigned long iStart = m_vMapFileFuncList.at( i ).iAddress; - unsigned long iEnd = ( m_vMapFileFuncList.at( i ).iAddress - + m_vMapFileFuncList.at( i ).iFuncLength ); - - if ( iAddress >= iStart && iAddress < iEnd ) - return m_vMapFileFuncList.at( i ).sFunctionName; - } - return sRet; -} - -//Note: New filtering functions commented out until they are taken into use. -/** -* Filter string out of unwanted characters. -*/ -/* -void CATAddr2line::FilterString( string &sString ) -{ - LOG_LOW_FUNC_ENTRY("CATAddr2line::FilterString"); - string sFiltered(""); - for( size_t i = 0 ; i < sString.length() ; i++ ) - { - const char p = sString.at( i ); - if ( p != 0 && strchr( ADDR2LINEALLOWEDCHARS, p ) != 0 ) - sFiltered.push_back( p ); - } - sString = sFiltered; -} -*/ -/** -* Find line feed position from string. -*/ -/* -size_t CATAddr2line::FindLineFeed( const string& sString ) -{ - LOG_LOW_FUNC_ENTRY("CATAddr2line::FindLineFeed"); - size_t iLineFeed1 = sString.find( 12 ); - size_t iLineFeed2 = sString.find( 15 ); - if ( iLineFeed1 < iLineFeed2 && iLineFeed1 != string::npos ) - return iLineFeed1; - else if ( iLineFeed2 != string::npos ) - return iLineFeed2; - else - return string::npos; -} -*/ -/** -* Erase characters from start of the string until other char than linefeed found. -*/ -/* -void CATAddr2line::EraseUntilNoLineFeed( string& sString ) -{ - LOG_LOW_FUNC_ENTRY("CATAddr2line::EraseUntilNoLineFeed"); - for ( size_t i = 0 ; i < sString.length() ; i++ ) - { - if ( sString.at( i ) != 15 && sString.at( i ) != 12 ) - break; - } - sString.erase( 0, i ); -} -*/ -/** -* Split multiple line string with unexpected line feeds to vector of strings. -*/ -/* -vector CATAddr2line::SplitToStrings( string& sMultiLineString ) -{ - LOG_LOW_FUNC_ENTRY("CATAddr2line::SplitToStrings"); - vector vLines; - while ( 1 ) - { - size_t iLineFeed = FindLineFeed( sMultiLineString ); - if ( iLineFeed == string::npos ) - break; - string sCell = sMultiLineString.substr(0, iLineFeed ); - sMultiLineString.erase(0, iLineFeed ); - EraseUntilNoLineFeed( sMultiLineString ); - FilterString( sCell ); - vLines.push_back( sCell ); - } - // If no lines were found set single one. - if ( vLines.size() == 0 ) - vLines.push_back( sMultiLineString ); - return vLines; -} -*/ -//EOF