# HG changeset patch # User marvin shi # Date 1289983652 -28800 # Node ID 46ca13b54f56e2e40dc2ec8544e063ccd2b043c5 # Parent c3fbb20e86f0d876e840fa25f3ddc1a1a998fde6 features: bsym for rofsbuild and log input support for rombuild diff -r c3fbb20e86f0 -r 46ca13b54f56 imgtools/imglib/symbolutil/bsymutil.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imgtools/imglib/symbolutil/bsymutil.cpp Wed Nov 17 16:47:32 2010 +0800 @@ -0,0 +1,120 @@ +/* +* Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ + +#include "bsymutil.h" +#include + + +MemoryWriter::MemoryWriter() +{ + iChar = new char[4*MaxSize]; + iOffset = 0; + iTotalSize = 4*MaxSize; + iStringTableStart = 0; +} +MemoryWriter::~MemoryWriter() +{ + delete[] iChar; +} +int MemoryWriter::WriteBytes(const char* pChar, int size) +{ + while(iOffset + size > iTotalSize) + { + ExtendMemory(); + } + memcpy(iChar + iOffset, pChar, size); + iOffset += size; + return size; +} +TUint32 MemoryWriter::GetOffset() +{ + return iOffset; +} +char* MemoryWriter::GetDataPointer() +{ + return iChar; +} +bool MemoryWriter::ExtendMemory() +{ + char* pTmp = new char[iTotalSize + MaxSize]; + memcpy(pTmp, iChar, iOffset); + delete[] iChar; + iChar = pTmp; + iTotalSize += MaxSize; + return true; +} +bool MemoryWriter::SetOffset(TUint32 aOffset) +{ + while(aOffset > iTotalSize) + { + ExtendMemory(); + } + iOffset = aOffset; + return true; +} +void MemoryWriter::AddEmptyString() +{ + unsigned char len = 0; + WriteBytes((char *)&len, 1); +} +TUint32 MemoryWriter::AddString(const string& aStr) +{ + TUint32 result = 0; + if(aStr.empty()) + return result; + result = iOffset - iStringTableStart; + int len = aStr.length(); + if(len >= 255) + { + TUint16 wlen = len; + unsigned char mark = 0xff; + WriteBytes((char*)&mark, 1); + WriteBytes((char*)&wlen, 2); + WriteBytes(aStr.c_str(), len); + } + else + { + unsigned char clen = len; + WriteBytes((char *)&clen, 1); + WriteBytes(aStr.c_str(), len); + } + return result; +} +TUint32 MemoryWriter::AddScopeName(const string& aStr) +{ + TUint32 result = 0; + if(aStr.empty()) + return result; + if(aStr == iLastScopeName) + { + return iLastScopeNameOffset; + } + else + { + iLastScopeName = aStr; + iLastScopeNameOffset = AddString(aStr); + } + return iLastScopeNameOffset; +} +void MemoryWriter::SetStringTableStart(TUint32 aOffset) +{ + iStringTableStart = aOffset; +} +TUint32 MemoryWriter::GetStringTableStart() +{ + return iStringTableStart; +} diff -r c3fbb20e86f0 -r 46ca13b54f56 imgtools/imglib/symbolutil/bsymutil.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imgtools/imglib/symbolutil/bsymutil.h Wed Nov 17 16:47:32 2010 +0800 @@ -0,0 +1,172 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ + +#ifndef __BSYMUTIL_H__ +#define __BSYMUTIL_H__ + +#include +#include +#include + +using namespace std; + +const int BSYM_PAGE_SIZE = 4096; + +const int MaxSize = 4*1024*1024; +const TUint16 BsymMajorVer = 3; +const TUint16 BsymMinorVer = 0; +struct TBsymHeader { + char iMagic[4]; // 'B','S','Y','M' always big-endian + char iMajorVer[2]; // always big-endian, currently 3 + char iMinorVer[2]; // always big-endian, currently 0. + char iEndiannessFlag; + char iCompressionFlag; + char iReservered[2]; + TUint32 iDbgUnitOffset; + TUint32 iDbgUnitCount; + TUint32 iSymbolOffset; + TUint32 iSymbolCount; + TUint32 iStringTableOffset; + TUint32 iStringTableBytes; + TUint32 iCompressedSize; + TUint32 iUncompressSize; + TUint32 iCompressInfoOffset; +}; +struct TDbgUnitEntry { + TUint32 iCodeAddress; + TUint32 iCodeSymbolCount; + TUint32 iDataAddress; + TUint32 iDataSymbolCount; + TUint32 iBssAddress; + TUint32 iBssSymbolCount; + TUint32 iPCNameOffset; + TUint32 iDevNameOffset; + TUint32 iStartSymbolIndex; + TDbgUnitEntry() + { + iCodeAddress =0; + iCodeSymbolCount =0; + iDataAddress =0; + iDataSymbolCount =0; + iBssAddress =0; + iBssSymbolCount =0; + iPCNameOffset =0; + iDevNameOffset =0; + iStartSymbolIndex =0; + } + void Reset() + { + iCodeAddress =0; + iCodeSymbolCount =0; + iDataAddress =0; + iDataSymbolCount =0; + iBssAddress =0; + iBssSymbolCount =0; + iPCNameOffset =0; + iDevNameOffset =0; + iStartSymbolIndex =0; + } +}; +struct TDbgUnitPCEntry { + TDbgUnitEntry iDbgUnitEntry; + string iPCName; + string iDevName; +}; +struct TSymbolEntry { + TUint32 iAddress; + TUint32 iLength; + TUint32 iScopeNameOffset; + TUint32 iNameOffset; + TUint32 iSecNameOffset; + TSymbolEntry() + { + iAddress =0; + iLength =0; + iScopeNameOffset =0; + iNameOffset =0; + iSecNameOffset =0; + } +}; + +struct TSymbolPCEntry { + TSymbolEntry iSymbolEntry; + string iScopeName; + string iName; + string iSecName; +}; + +struct TPageInfo { + TUint32 iPageStartOffset; + TUint32 iPageDataSize; +}; + +struct TCompressedHeaderInfo +{ + TUint32 iPageSize; + TUint32 iTotalPageNumber; + TPageInfo iPages[1]; +}; + +typedef vector TDbgUnitEntrySet; +typedef vector TSymbolPCEntrySet; +typedef vector StringList; + +struct MapFileInfo +{ + TDbgUnitPCEntry iDbgUnitPCEntry; + TSymbolPCEntrySet iSymbolPCEntrySet; +}; + +typedef vector MapFileInfoSet; +class ByteOrderUtil +{ +public: + static bool IsLittleEndian() + { + union { + unsigned int a; + unsigned char b; + } c; + c.a = 1; + return (c.b == 1); + } +}; + +class MemoryWriter +{ +public: + MemoryWriter(); + ~MemoryWriter(); + int WriteBytes(const char* pChar, int size); + TUint32 GetOffset(); + char* GetDataPointer(); + bool ExtendMemory(); + bool SetOffset(TUint32 aOffset); + void AddEmptyString(); + TUint32 AddString(const string& aStr); + TUint32 AddScopeName(const string& aStr); + void SetStringTableStart(TUint32 aOffset); + TUint32 GetStringTableStart(); +private: + char* iChar; + TUint32 iOffset; + TUint32 iStringTableStart; + string iLastScopeName; + TUint32 iLastScopeNameOffset; + TUint32 iTotalSize; +}; +#endif diff -r c3fbb20e86f0 -r 46ca13b54f56 imgtools/imglib/symbolutil/loggingexception.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imgtools/imglib/symbolutil/loggingexception.cpp Wed Nov 17 16:47:32 2010 +0800 @@ -0,0 +1,60 @@ +/* +* Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ + +#include "loggingexception.h" + + +int LoggingException::RESOURCE_ALLOCATION_FAILURE = 1; +int LoggingException::INVALID_LOG_FILENAME = 2; +int LoggingException::UNKNOWN_IMAGE_TYPE = 3; + + +LoggingException::LoggingException(int ErrorCode) +{ + this->errcode = ErrorCode; + + return; +} + + +int LoggingException::GetErrorCode(void) +{ + return this->errcode; +} + + +const char* LoggingException::GetErrorMessage(void) +{ + if(this->errcode == LoggingException::RESOURCE_ALLOCATION_FAILURE) + return "Not enough system resources to initialize logging module."; + else if(this->errcode == LoggingException::INVALID_LOG_FILENAME) + return "Invalid log filename as input."; + else if(this->errcode == LoggingException::UNKNOWN_IMAGE_TYPE) + return "the image type not supported."; +// else if(this->errcode == CacheException::CACHE_IS_EMPTY) +// return "Cache is empty."; +// else if(this->errcode == CacheException::HARDDRIVE_FAILURE) +// return "A hard drive failure occurred in Cache operations."; + + return "Undefined error type."; +} + + +LoggingException::~LoggingException(void) +{ + return; +} diff -r c3fbb20e86f0 -r 46ca13b54f56 imgtools/imglib/symbolutil/loggingexception.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imgtools/imglib/symbolutil/loggingexception.h Wed Nov 17 16:47:32 2010 +0800 @@ -0,0 +1,49 @@ +/* +* Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ + + +#ifndef ROM_TOOLS_ROFSBUILD_LOGGING_LOGGINGEXCEPTION_H_ +#define ROM_TOOLS_ROFSBUILD_LOGGING_LOGGINGEXCEPTION_H_ + + +/* + * @class LoggingException + */ +class LoggingException +{ +public: + LoggingException(int ErrorCode); + + int GetErrorCode(void); + + const char* GetErrorMessage(void); + + static int RESOURCE_ALLOCATION_FAILURE; + static int INVALID_LOG_FILENAME ; + static int UNKNOWN_IMAGE_TYPE ; + + virtual ~LoggingException(void); +protected: + int errcode; +private: + LoggingException(void); + + LoggingException& operator = (const LoggingException&); +}; + + +#endif /* defined ROM_TOOLS_ROFSBUILD_LOGGING_LOGGINGEXCEPTION_H_ */ diff -r c3fbb20e86f0 -r 46ca13b54f56 imgtools/imglib/symbolutil/logparser.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imgtools/imglib/symbolutil/logparser.cpp Wed Nov 17 16:47:32 2010 +0800 @@ -0,0 +1,218 @@ +/* +* Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ + + +#include +#include +#include +#include +#include +using namespace std; + +#include "loggingexception.h" +#include "logparser.h" + + +LogParser* LogParser::Only = (LogParser*)0; + + +LogParser* LogParser::GetInstance(TImageType aImageType) throw (LoggingException) +{ + if(! LogParser::Only) + { + if(aImageType == ERomImage) + { + LogParser::Only = new (std::nothrow) RomLogParser(); + } + else if(aImageType == ERofsImage) + { + LogParser::Only = new (std::nothrow) RofsLogParser(); + } + else + { + throw LoggingException(LoggingException::UNKNOWN_IMAGE_TYPE); + } + if(! LogParser::Only) + throw LoggingException(LoggingException::RESOURCE_ALLOCATION_FAILURE); + } + + return LogParser::Only; +} + +void LogParser::Cleanup(void) +{ + return; +} + + +LogParser::LogParser(void) +{ + iImageType = EUnknownType; + return; +} + +RofsLogParser::RofsLogParser() +{ + iImageType = ERofsImage; +} + +void RofsLogParser::ParseSymbol(const char* LogFilename) throw (LoggingException) +{ + string linebuf; + SymbolGenerator* symgen = SymbolGenerator::GetInstance(); + symgen->SetImageType(iImageType); + symgen->SetSymbolFileName(string(LogFilename)); + + ifstream logfd(LogFilename); + if(logfd.is_open()) + { + while(! logfd.eof()) + { + getline(logfd, linebuf); + if(linebuf.compare(0,4,"File") == 0) + { + if(linebuf.find("size:", 4) != string::npos) + { + size_t startpos = linebuf.find('\'') ; + size_t endpos = linebuf.rfind('\''); + if((startpos!=string::npos) && (endpos!=string::npos)) + { + symgen->AddFile(linebuf.substr(startpos+1,endpos-startpos-1), false); + } + } + } + else if(linebuf.compare(0,26,"Compressed executable File") == 0) + { + if(linebuf.find("size:", 26) != string::npos) + { + size_t startpos = linebuf.find('\'') ; + size_t endpos = linebuf.rfind('\''); + if((startpos!=string::npos) && (endpos!=string::npos)) + { + symgen->AddFile(linebuf.substr(startpos+1,endpos-startpos-1), true); + } + } + } + } + symgen->SetFinished(); + symgen->Release(); + } + else + { + throw LoggingException(LoggingException::INVALID_LOG_FILENAME); + } + + return; +} + +RomLogParser::RomLogParser() +{ + iImageType = ERomImage; +} + +void RomLogParser::ParseSymbol(const char* LogFilename) throw (LoggingException) +{ + string linebuf; + SymbolGenerator* symgen = SymbolGenerator::GetInstance(); + symgen->SetImageType(iImageType); + symgen->SetSymbolFileName(string(LogFilename)); + + ifstream logfd(LogFilename); + if(logfd.is_open()) + { + //boost::regex beginFlag("^Creating Rom image (\\S*)"); + boost::regex endFlag("^Writing Rom image"); + boost::regex sourceFile("^Reading resource (.*) to rom linear address (.*)"); + boost::regex executableFile("^Processing file (.*)"); + boost::regex codeStart("^Code start addr:\\s*(\\w+)"); + boost::regex dataStart("^Data start addr:\\s+(\\w+)"); + boost::regex dataBssStart("^DataBssLinearBase:\\s+(\\w+)"); + boost::regex textSize("^Text size:\\s+(\\w+)"); + boost::regex dataSize("^Data size:\\s+(\\w+)"); + boost::regex bssSize("Bsssize:\\s+(\\w+)"); + boost::regex totalDataSize("^Total data size:\\s+(\\w+)"); + string tmpline, tmpaddr; + boost::cmatch what; + while(getline(logfd, tmpline)) + { + TPlacedEntry tmpEntry; + if(regex_search(tmpline, what, endFlag)) + { + break; + } + if(regex_search(tmpline, what, sourceFile)) + { + tmpEntry.iFileName.assign(what[1].first, what[1].second-what[1].first); + tmpaddr.assign(what[2].first, what[2].second-what[2].first); + tmpEntry.iDataAddress = strtol(tmpaddr.c_str(), NULL, 16); + symgen->AddEntry(tmpEntry); + } + else if(regex_search(tmpline, what, executableFile)) + { + tmpEntry.iFileName.assign(what[1].first, what[1].second-what[1].first); + while(getline(logfd, tmpline) && tmpline != "") + { + if(regex_search(tmpline, what, codeStart)) + { + tmpaddr.assign(what[1].first, what[1].second-what[1].first); + tmpEntry.iCodeAddress = strtol(tmpaddr.c_str(), NULL, 16); + } + else if(regex_search(tmpline, what, dataStart)) + { + tmpaddr.assign(what[1].first, what[1].second-what[1].first); + tmpEntry.iDataAddress = strtol(tmpaddr.c_str(), NULL, 16); + } + else if(regex_search(tmpline, what, dataBssStart)) + { + tmpaddr.assign(what[1].first, what[1].second-what[1].first); + tmpEntry.iDataBssLinearBase = strtol(tmpaddr.c_str(), NULL, 16); + } + else if(regex_search(tmpline, what, textSize)) + { + tmpaddr.assign(what[1].first, what[1].second-what[1].first); + tmpEntry.iTextSize = strtol(tmpaddr.c_str(), NULL, 16); + } + else if(regex_search(tmpline, what, dataSize)) + { + tmpaddr.assign(what[1].first, what[1].second-what[1].first); + tmpEntry.iDataSize = strtol(tmpaddr.c_str(), NULL, 16); + } + else if(regex_search(tmpline, what, bssSize)) + { + tmpaddr.assign(what[1].first, what[1].second-what[1].first); + tmpEntry.iBssSize = strtol(tmpaddr.c_str(), NULL, 16); + } + else if(regex_search(tmpline, what, totalDataSize)) + { + tmpaddr.assign(what[1].first, what[1].second-what[1].first); + tmpEntry.iTotalDataSize = strtol(tmpaddr.c_str(), NULL, 16); + } + } + symgen->AddEntry(tmpEntry); + } + + + } + symgen->SetFinished(); + symgen->Release(); + } + else + { + throw LoggingException(LoggingException::INVALID_LOG_FILENAME); + } +} + diff -r c3fbb20e86f0 -r 46ca13b54f56 imgtools/imglib/symbolutil/logparser.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imgtools/imglib/symbolutil/logparser.h Wed Nov 17 16:47:32 2010 +0800 @@ -0,0 +1,63 @@ +/* +* Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ + + +#ifndef ROM_TOOLS_ROFSBUILD_LOGGING_LOGPARSER_H_ +#define ROM_TOOLS_ROFSBUILD_LOGGING_LOGPARSER_H_ + +#include "loggingexception.h" +#include "symbolgenerator.h" + +/** + * @class LogParser + */ +class LogParser +{ +public: + static LogParser* GetInstance(TImageType aImageType) throw (LoggingException); + + virtual void ParseSymbol(const char* LogFilename) throw (LoggingException) = 0; + + void Cleanup(void); + virtual ~LogParser() {} +protected: + LogParser(void); + static LogParser* Only; + TImageType iImageType; +private: + LogParser(const LogParser&); + + LogParser& operator = (const LogParser&); +}; + +class RofsLogParser : public LogParser +{ +public: + virtual void ParseSymbol(const char* LogFilename) throw (LoggingException); + RofsLogParser(void); +}; + +class RomLogParser : public LogParser +{ +public: + virtual void ParseSymbol(const char* LogFilename) throw (LoggingException); + RomLogParser(void); +}; + + + +#endif /* defined ROM_TOOLS_ROFSBUILD_LOGGING_LOGPARSER_H_ */ diff -r c3fbb20e86f0 -r 46ca13b54f56 imgtools/imglib/symbolutil/symbolgenerator.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imgtools/imglib/symbolutil/symbolgenerator.cpp Wed Nov 17 16:47:32 2010 +0800 @@ -0,0 +1,384 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ + +#include +#include +#define MAX_LINE 65535 +#include "symbolgenerator.h" +#include "e32image.h" +#include "h_utl.h" + +#if defined(__LINUX__) +#define PATH_SEPARATOR '/' +#else +#define PATH_SEPARATOR '\\' +#endif +extern TInt gThreadNum; +extern TBool gGenBsymbols; + +boost::mutex SymbolGenerator::iMutexSingleton; +SymbolGenerator* SymbolGenerator::iInst = NULL; +SymbolGenerator* SymbolGenerator::GetInstance(){ + iMutexSingleton.lock(); + if(iInst == NULL) { + iInst = new SymbolGenerator(); + } + iMutexSingleton.unlock(); + return iInst; +} +void SymbolGenerator::Release() { + if(iInst != NULL) { + iInst->join(); + } + iMutexSingleton.lock(); + if(iInst != NULL) { + delete iInst; + iInst = NULL; + } + iMutexSingleton.unlock(); +} +void SymbolGenerator::SetSymbolFileName( const string& fileName ){ + if(iSymFile.is_open()) + iSymFile.close(); + if(gGenBsymbols) + { + string s = fileName.substr(0,fileName.rfind('.'))+".bsym"; + if(iImageType == ERofsImage) + { + printf("* Writing %s - ROFS BSymbol file\n", s.c_str()); + } + else + { + printf("* Writing %s - ROM BSymbol file\n", s.c_str()); + } + iSymFile.open(s.c_str(), ios_base::binary); + } + else + { + string s = fileName.substr(0,fileName.rfind('.'))+".symbol"; + if(iImageType == ERofsImage) + { + printf("* Writing %s - ROFS Symbol file\n", s.c_str()); + } + else + { + printf("* Writing %s - ROM Symbol file\n", s.c_str()); + } + iSymFile.open(s.c_str()); + } + +} +void SymbolGenerator::AddFile( const string& fileName, bool isExecutable ){ + iMutex.lock(); + iQueueFiles.push(TPlacedEntry(fileName, "" , isExecutable)); + iMutex.unlock(); + iCond.notify_all(); +} + +void SymbolGenerator::AddEntry(const TPlacedEntry& aEntry) +{ + iMutex.lock(); + iQueueFiles.push(aEntry); + iMutex.unlock(); + iCond.notify_all(); +} + +void SymbolGenerator::SetFinished() +{ + + iFinished = true; + iCond.notify_all(); +} +TPlacedEntry SymbolGenerator::GetNextPlacedEntry() +{ + TPlacedEntry pe("", "", false); + if(1) + { + boost::mutex::scoped_lock lock(iMutex); + while(!iFinished && iQueueFiles.empty()) + iCond.wait(lock); + if(!iQueueFiles.empty()) + { + pe = iQueueFiles.front(); + iQueueFiles.pop(); + } + } + return pe; +} +void SymbolGenerator::thrd_func(){ + boost::thread_group threads; + SymbolWorker worker; + for(int i=0; i < gThreadNum; i++) + { + threads.create_thread(worker); + } + threads.join_all(); + SymbolGenerator::GetInstance()->FlushSymbolFileContent(); + } +SymbolGenerator::SymbolGenerator() : boost::thread(thrd_func),iFinished(false) { + if(gGenBsymbols) + { + iSymbolType = ESymBsym; + } + else + { + iSymbolType = ESymCommon; + } + } +SymbolGenerator::~SymbolGenerator(){ + if(joinable()) + join(); + iSymFile.flush(); + iSymFile.close(); +} +void SymbolGenerator::FlushSymbolFileContent() +{ + if(iSymbolType == ESymCommon) + { + return; + } + TBsymHeader tmpBsymHeader; + memset(&tmpBsymHeader, 0, sizeof(tmpBsymHeader)); + tmpBsymHeader.iMagic[0] = 'B'; + tmpBsymHeader.iMagic[1] = 'S'; + tmpBsymHeader.iMagic[2] = 'Y'; + tmpBsymHeader.iMagic[3] = 'M'; + tmpBsymHeader.iMajorVer[0] = BsymMajorVer >> 8; + tmpBsymHeader.iMajorVer[1] = BsymMajorVer & 0xff; + tmpBsymHeader.iMinorVer[0] = BsymMinorVer >> 8; + tmpBsymHeader.iMinorVer[1] = BsymMinorVer & 0xff; + if(ByteOrderUtil::IsLittleEndian()) + { + tmpBsymHeader.iEndiannessFlag = 0; + } + else + { + tmpBsymHeader.iEndiannessFlag = 1; + } + tmpBsymHeader.iCompressionFlag = 1; + //count the space for TDbgUnitEntries and TSymbolEntries + int fileCount = iMapFileInfoSet.size(); + TUint32 sizeNeeded = fileCount * sizeof(TDbgUnitEntry); + for(int i = 0; i < fileCount; i++) + { + sizeNeeded += iMapFileInfoSet[i].iSymbolPCEntrySet.size() * sizeof(TSymbolEntry); + } + //write string to the temporary memory area + MemoryWriter mWriter; + mWriter.SetOffset(sizeNeeded); + mWriter.SetStringTableStart(sizeNeeded); + mWriter.AddEmptyString(); + + //first to prepare the file info entries TDbgUnitEntry + TUint32 startSymbolIndex = 0; + for(int i = 0; i < fileCount; i++) + { + iMapFileInfoSet[i].iDbgUnitPCEntry.iDbgUnitEntry.iStartSymbolIndex = startSymbolIndex; + iMapFileInfoSet[i].iDbgUnitPCEntry.iDbgUnitEntry.iPCNameOffset = mWriter.AddString(iMapFileInfoSet[i].iDbgUnitPCEntry.iPCName); + iMapFileInfoSet[i].iDbgUnitPCEntry.iDbgUnitEntry.iDevNameOffset = mWriter.AddString(iMapFileInfoSet[i].iDbgUnitPCEntry.iDevName); + startSymbolIndex += iMapFileInfoSet[i].iSymbolPCEntrySet.size(); + } + //second to layout the symbols unit for the mapfile + for(int i = 0; i < fileCount; i++) + { + int symbolcount = iMapFileInfoSet[i].iSymbolPCEntrySet.size(); + for(int j =0; j< symbolcount; j++) + { + iMapFileInfoSet[i].iSymbolPCEntrySet[j].iSymbolEntry.iScopeNameOffset = mWriter.AddScopeName(iMapFileInfoSet[i].iSymbolPCEntrySet[j].iScopeName); + iMapFileInfoSet[i].iSymbolPCEntrySet[j].iSymbolEntry.iNameOffset = mWriter.AddString(iMapFileInfoSet[i].iSymbolPCEntrySet[j].iName); + iMapFileInfoSet[i].iSymbolPCEntrySet[j].iSymbolEntry.iSecNameOffset = mWriter.AddString(iMapFileInfoSet[i].iSymbolPCEntrySet[j].iSecName); + } + } + + //write out the BSym file content + char* pstart = mWriter.GetDataPointer(); + //write out the map file info + int unitlen = sizeof(TDbgUnitEntry); + for(int i = 0; i < fileCount; i++) + { + memcpy(pstart, &iMapFileInfoSet[i].iDbgUnitPCEntry.iDbgUnitEntry, unitlen); + pstart += unitlen; + } + //wirte out the symbol unit info + unitlen = sizeof(TSymbolEntry); + for(int i = 0; i < fileCount; i++) + { + int symbolcount = iMapFileInfoSet[i].iSymbolPCEntrySet.size(); + for(int j =0; j < symbolcount; j++) + { + memcpy(pstart, &iMapFileInfoSet[i].iSymbolPCEntrySet[j].iSymbolEntry, unitlen); + pstart += unitlen; + } + } + //write out the memory out to the symbol file + + int totalPages = (mWriter.GetOffset() + ( BSYM_PAGE_SIZE -1)) / 4096; + TUint32 compressInfoLength = sizeof(TCompressedHeaderInfo) + sizeof(TPageInfo)*(totalPages -1); + char* tmpBuffer = new char[compressInfoLength]; + TCompressedHeaderInfo * pCompressedHeaderInfo = (TCompressedHeaderInfo *) tmpBuffer; + pCompressedHeaderInfo->iPageSize = BSYM_PAGE_SIZE; + pCompressedHeaderInfo->iTotalPageNumber = totalPages; + TPageInfo* tmpPage = &pCompressedHeaderInfo->iPages[0]; + for(int i = 0; i < totalPages; i++) + { + tmpPage->iPageStartOffset = i * BSYM_PAGE_SIZE; + if(tmpPage->iPageStartOffset + BSYM_PAGE_SIZE < mWriter.GetOffset()) + { + tmpPage->iPageDataSize = BSYM_PAGE_SIZE; + } + else + { + tmpPage->iPageDataSize = mWriter.GetOffset() - tmpPage->iPageStartOffset; + } + tmpPage++; + } + + //prepare the TBsymHeader, TDbgUnitEntry and TSymbolEntry to the memory + tmpBsymHeader.iDbgUnitOffset = sizeof(TBsymHeader) + compressInfoLength; + tmpBsymHeader.iDbgUnitCount = fileCount; + tmpBsymHeader.iSymbolOffset = fileCount*sizeof(TDbgUnitEntry); + tmpBsymHeader.iSymbolCount = startSymbolIndex; + tmpBsymHeader.iStringTableOffset = mWriter.GetStringTableStart(); + tmpBsymHeader.iStringTableBytes = mWriter.GetOffset() - tmpBsymHeader.iStringTableOffset; + tmpBsymHeader.iUncompressSize = mWriter.GetOffset(); + //start the compress threads + Print(EAlways, "Start compress for Bsymbol file\n"); + PageCompressWorker compressWorker(pCompressedHeaderInfo, mWriter.GetDataPointer()); + boost::thread_group threads; + for(int i=0; i < gThreadNum; i++) + { + threads.create_thread(compressWorker); + } + threads.join_all(); + Print(EAlways, "Complete compress for Bsymbol file\n"); + //pack all the pages together + tmpPage = &pCompressedHeaderInfo->iPages[0]; + TPageInfo* prePage = NULL; + char* pchar = mWriter.GetDataPointer(); + for(int i=0; i < totalPages -1; i++) + { + prePage = tmpPage; + tmpPage++; + memcpy(pchar + prePage->iPageStartOffset + prePage->iPageDataSize, pchar + tmpPage->iPageStartOffset, tmpPage->iPageDataSize); + tmpPage->iPageStartOffset = prePage->iPageStartOffset + prePage->iPageDataSize; + + } + tmpBsymHeader.iCompressedSize = tmpPage->iPageStartOffset + tmpPage->iPageDataSize; + mWriter.SetOffset(tmpBsymHeader.iCompressedSize); + tmpBsymHeader.iCompressInfoOffset = sizeof(TBsymHeader); + + iSymFile.write((char*)&tmpBsymHeader, sizeof(TBsymHeader)); + iSymFile.write((char*)pCompressedHeaderInfo, compressInfoLength); + iSymFile.write(mWriter.GetDataPointer(), mWriter.GetOffset()); + delete[] tmpBuffer; + for(int i = 0; i < fileCount; i++) + { + iMapFileInfoSet[i].iSymbolPCEntrySet.clear(); + } + iMapFileInfoSet.clear(); +} + +SymbolWorker::SymbolWorker() +{ +} +SymbolWorker::~SymbolWorker() +{ + } +void SymbolWorker::operator()() +{ + SymbolProcessUnit* aSymbolProcessUnit; + SymbolGenerator* symbolgenerator = SymbolGenerator::GetInstance(); + if(symbolgenerator->GetImageType() == ERomImage) + { + aSymbolProcessUnit = new CommenRomSymbolProcessUnit(); + } + else + { + if(gGenBsymbols) + { + aSymbolProcessUnit = new BsymRofsSymbolProcessUnit(symbolgenerator); + } + else + { + aSymbolProcessUnit = new CommenRofsSymbolProcessUnit(); + } + } + + while(1) + { + if(symbolgenerator->HasFinished() && symbolgenerator->IsEmpty()) + { + break; + } + TPlacedEntry pe = symbolgenerator->GetNextPlacedEntry(); + if(pe.iFileName.empty()) + continue; + + aSymbolProcessUnit->ProcessEntry(pe); + + symbolgenerator->LockOutput(); + aSymbolProcessUnit->FlushStdOut(cout); + aSymbolProcessUnit->FlushSymbolContent(symbolgenerator->GetOutputFileStream()); + symbolgenerator->UnlockOutput(); + } + delete aSymbolProcessUnit; +} +TCompressedHeaderInfo* PageCompressWorker::pHeaderInfo = NULL; +int PageCompressWorker::currentPage = 0; +boost::mutex PageCompressWorker::m_mutex; +int PageCompressWorker::m_error = 0; +char* PageCompressWorker::iChar = NULL; + +PageCompressWorker::PageCompressWorker(TCompressedHeaderInfo* aHeaderInfo, char* aChar) +{ + pHeaderInfo = aHeaderInfo; + iChar = aChar; +} + +PageCompressWorker::~PageCompressWorker() {} +void PageCompressWorker::operator()() +{ + int tobecompress = 0; + CBytePair bpe; + while(1) + { + m_mutex.lock(); + tobecompress =currentPage; + currentPage++; + m_mutex.unlock(); + if(tobecompress >= (int) pHeaderInfo->iTotalPageNumber) + break; + TPageInfo* current = &pHeaderInfo->iPages[0] + tobecompress; + TUint8* in = (TUint8*)(iChar + current->iPageStartOffset); + TUint8* out = in; + TInt outSize = BytePairCompress(out, in, current->iPageDataSize, &bpe); + if(outSize == KErrTooBig) + { + outSize = BSYM_PAGE_SIZE; + } + if(outSize < 0) + { + m_mutex.lock(); + m_error = -1; + m_mutex.unlock(); + break; + } + current->iPageDataSize = outSize; + } + +} + diff -r c3fbb20e86f0 -r 46ca13b54f56 imgtools/imglib/symbolutil/symbolgenerator.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imgtools/imglib/symbolutil/symbolgenerator.h Wed Nov 17 16:47:32 2010 +0800 @@ -0,0 +1,94 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ + +#ifndef __SYMBOLGENERATOR_H__ +#define __SYMBOLGENERATOR_H__ +#include +#include +#include +using namespace std; +#include +#include +#include "symbolprocessunit.h" + + +enum TSymbolType { + ESymCommon = 0, + ESymBsym , +}; +enum TImageType { + ERomImage = 0, + ERofsImage, + EUnknownType, +}; + + +class SymbolGenerator : public boost::thread { + public: + static SymbolGenerator* GetInstance(); + static void Release(); + void SetSymbolFileName( const string& fileName ); + void AddFile( const string& fileName, bool isExecutable ); + void AddEntry(const TPlacedEntry& aEntry); + bool HasFinished() { return iFinished; } + void SetFinished(); + bool IsEmpty() { return iQueueFiles.empty(); } + void LockOutput() { iOutputMutex.lock(); } + void UnlockOutput() { iOutputMutex.unlock(); } + TPlacedEntry GetNextPlacedEntry(); + ofstream& GetOutputFileStream() { return iSymFile; }; + void AppendMapFileInfo(MapFileInfo& aMapFileInfo) { iMapFileInfoSet.push_back(aMapFileInfo); } + void FlushSymbolFileContent(); + void SetImageType(TImageType aImageType) { iImageType = aImageType; }; + TImageType GetImageType() { return iImageType; }; + private: + SymbolGenerator(); + ~SymbolGenerator(); + static void thrd_func(); + + queue iQueueFiles; + boost::mutex iMutex; + boost::mutex iOutputMutex; + static boost::mutex iMutexSingleton; + static SymbolGenerator* iInst; + boost::condition_variable iCond; + bool iFinished; + TSymbolType iSymbolType; + TImageType iImageType; + + ofstream iSymFile; + MapFileInfoSet iMapFileInfoSet; +}; +class SymbolWorker{ +public: + SymbolWorker(); + ~SymbolWorker(); + void operator()(); +private: +}; +class PageCompressWorker { +public: + PageCompressWorker(TCompressedHeaderInfo* aHeaderInfo, char* aChar); + ~PageCompressWorker(); + void operator()(); + static TCompressedHeaderInfo * pHeaderInfo; + static int currentPage; + static boost::mutex m_mutex; + static int m_error; + static char* iChar; +}; +#endif diff -r c3fbb20e86f0 -r 46ca13b54f56 imgtools/imglib/symbolutil/symbolprocessunit.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imgtools/imglib/symbolutil/symbolprocessunit.cpp Wed Nov 17 16:47:32 2010 +0800 @@ -0,0 +1,997 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ +#include +#include "symbolprocessunit.h" +#include "e32image.h" +#include "symbolgenerator.h" +#include "h_utl.h" + + +#define MAX_LINE 65535 + +#if defined(__LINUX__) +#define PATH_SEPARATOR '/' +#else +#define PATH_SEPARATOR '\\' +#endif + +void SymbolProcessUnit::ProcessEntry(const TPlacedEntry& aEntry) +{ + if(aEntry.iFileName == "") + return; + else if(aEntry.iExecutable) + ProcessExecutableFile(aEntry.iFileName); + else + ProcessDataFile(aEntry.iFileName); +} +// CommenRomSymbolProcessUnit start +void CommenRomSymbolProcessUnit::FlushStdOut(ostream& aOut) +{ + for(int i = 0; i < (int) iStdoutLog.size(); i++) + { + aOut << iStdoutLog[i]; + } +} + +void CommenRomSymbolProcessUnit::FlushSymbolContent(ostream &aOut) +{ + for(int i = 0; i < (int) iSymbolContentLog.size(); i++) + { + aOut << iSymbolContentLog[i]; + } +} + +void CommenRomSymbolProcessUnit::ResetContentLog() +{ + iStdoutLog.clear(); + iSymbolContentLog.clear(); +} + +void CommenRomSymbolProcessUnit::ProcessEntry(const TPlacedEntry& aEntry) +{ + iPlacedEntry = aEntry; + SymbolProcessUnit::ProcessEntry(aEntry); +} + +void CommenRomSymbolProcessUnit::ProcessExecutableFile(const string& aFile) +{ + ResetContentLog(); + char str[MAX_LINE]; + string outString; + outString = "\nFrom "; + outString += aFile + "\n\n"; + iSymbolContentLog.push_back(outString); + string mapFile2 = aFile+".map"; + size_t dot = aFile.rfind('.'); + string mapFile = aFile.substr(0,dot)+".map"; + ifstream fMap; + fMap.open(mapFile2.c_str()); + if(!fMap.is_open()) { + fMap.open(mapFile.c_str()); + } + + if(!fMap.is_open()) { + sprintf(str, "\nWarning: Can't open \"%s\" or \"%s\"\n",mapFile2.c_str(),mapFile.c_str()); + iStdoutLog.push_back(str); + memset(str,0,sizeof(str)); + sprintf(str, "%08x %04x ", (unsigned int)iPlacedEntry.iCodeAddress, (unsigned int)iPlacedEntry.iTotalSize); + outString = str; + outString += aFile.substr(aFile.rfind(PATH_SEPARATOR)+1)+"\n"; + iSymbolContentLog.push_back(outString); + } + else { + if(!fMap.good()) fMap.clear(); + char buffer[100]; + fMap.getline(buffer, 100); + boost::regex regARMV5("ARM Linker", boost::regex::icase); + boost::regex regGCCEoARMV4("Archive member included", boost::regex::icase); + boost::cmatch what; + if(regex_search(buffer, what, regARMV5)) { + ProcessArmv5File(aFile, fMap); + } + else if(regex_search(buffer, what, regGCCEoARMV4)) { + ProcessGcceOrArm4File(aFile, fMap); + } + else { + fMap.seekg(0, ios_base::beg); + ProcessX86File(aFile, fMap); + } + } +} + +void CommenRomSymbolProcessUnit::ProcessDataFile(const string& aFile) +{ + ResetContentLog(); + char str[MAX_LINE]; + memset(str,0,sizeof(str)); + string basename = aFile.substr(aFile.rfind(PATH_SEPARATOR)+1); + sprintf(str, "\nFrom %s\n\n%08x 0000 %s\n", aFile.c_str(), (unsigned int) iPlacedEntry.iDataAddress, basename.c_str()); + iSymbolContentLog.push_back(str); +} + +struct ArmSymbolInfo { + string name ; + TUint size ; + string section ; +}; +typedef multimap ArmSymMap ; + +#define SKIP_WS(p) while((*p) == ' ' || (*p) == '\t') (p)++ +#define FIND_WS(p) while((*p) != ' ' && (*p) != '\t' && (*p) != 0) (p)++ +static void split(char* str, vector& result) { + result.clear(); + while(*str) { + SKIP_WS(str); + char* saved = str ; + FIND_WS(str); + bool end = (0 == *str); + *str = 0 ; + if(saved != str) + result.push_back(saved); + if(!end) str ++ ; + } +} +static void make_lower(char* str){ + while(*str){ + if(*str >= 'A' && *str >= 'Z') { + *str += ('a' - 'A'); + } + str++; + } +} + +void CommenRomSymbolProcessUnit::ProcessArmv5File(const string& aFile, ifstream& aMap) +{ + string symName ; + ArmSymMap symbols ; + vector words ; + ArmSymbolInfo info; + char* lineStart ; + char buffer[MAX_LINE]; + while(aMap.good() && (!aMap.eof())){ + *buffer = 0; + aMap.getline(buffer,MAX_LINE); + lineStart = buffer ; + SKIP_WS(lineStart); + if(strstr(lineStart,"Global Symbols")) + break ; + char* armstamp = strstr(lineStart,"ARM Code"); + if(0 == armstamp) + armstamp = strstr(lineStart,"Thumb Code") ; + if(0 == armstamp) continue ; + *(armstamp - 1) = 0 ; + + char* hexStr = lineStart ; + char* nameEnd; + while(1) { + hexStr = strstr(hexStr,"0x"); + if(0 == hexStr) break ; + nameEnd = hexStr - 1; + if(*nameEnd == ' ' || *nameEnd == '\t') break ; + hexStr += 2 ; + } + if(0 == hexStr) continue ; + while(nameEnd > lineStart && (*nameEnd == ' ' || *nameEnd == '\t')) + nameEnd -- ; + + nameEnd[1] = 0; + info.name = lineStart; + char* temp ; + TUint32 addr = strtoul(hexStr + 2,&temp,16); + char* decStr ; + if(*armstamp == 'A') + decStr = armstamp + 9 ; + else + decStr = armstamp + 11 ; + SKIP_WS(decStr); + info.size = strtoul(decStr,&temp,10); + SKIP_WS(temp); + info.section = temp; + if(info.section.find("(StubCode)") != string::npos ) + info.size = 8 ; + if(addr > 0){ + symbols.insert(pair(addr,info)); + } + } + size_t lenOfFileName = iPlacedEntry.iFileName.length(); + while(aMap.good() && (!aMap.eof())){ + *buffer = 0; + aMap.getline(buffer,MAX_LINE); + lineStart = buffer ; + SKIP_WS(lineStart); + char* hexStr = lineStart ; + char* nameEnd; + while(1) { + hexStr = strstr(hexStr,"0x"); + if(0 == hexStr) break ; + nameEnd = hexStr - 1; + if(*nameEnd == ' ' || *nameEnd == '\t') + break ; + hexStr += 2 ; + } + if(0 == hexStr) continue ; + while(nameEnd > lineStart && (*nameEnd == ' ' || *nameEnd == '\t')){ + nameEnd -- ; + } + nameEnd[1] = 0; + info.name = lineStart; + char *temp ; + TUint32 addr = strtoul(hexStr + 2,&temp,16); + while(*temp < '0' || *temp > '9' )//[^\d]* + temp++ ; + char* decStr = temp ; + info.size = strtoul(decStr,&temp,10); + SKIP_WS(temp); + info.section = temp; + if(info.section.find("(StubCode)") != string::npos ) + info.size = 8 ; + if(addr > 0){ + symbols.insert(pair(addr,info)); + } + } + + TUint32 textSectAddr = 0x00008000; // .text gets linked at 0x00008000 + TUint32 dataSectAddr = 0x00400000 ; // .data gets linked at 0x00400000 + vector > lines ; + size_t allocBytes; + for( ArmSymMap::iterator it = symbols.begin(); it != symbols.end() ; it++){ + TUint32 thisAddr = it->first ; + TUint32 romAddr ; + ArmSymbolInfo& info = it->second; + if (thisAddr >= textSectAddr && thisAddr <= (textSectAddr + iPlacedEntry.iTextSize)) { + romAddr = thisAddr - textSectAddr + iPlacedEntry.iCodeAddress ; + } + else if ( iPlacedEntry.iDataAddress && + ( thisAddr >= dataSectAddr && thisAddr <= (dataSectAddr + iPlacedEntry.iTextSize))) { + romAddr = thisAddr-dataSectAddr + iPlacedEntry.iDataBssLinearBase; + } + else if ( iPlacedEntry.iDataBssLinearBase && + ( thisAddr >= dataSectAddr && thisAddr <= (dataSectAddr+ iPlacedEntry.iTotalDataSize))) { + romAddr = thisAddr - dataSectAddr + iPlacedEntry.iDataBssLinearBase; + } + else { + allocBytes = info.name.length() + 60; + char* msg = new char[allocBytes] ; + snprintf(msg,allocBytes,"\r\nWarning: Symbol %s @ 0x%08x not in text or data segments\r\n", \ + info.name.c_str() ,(unsigned int)thisAddr) ; + iStdoutLog.push_back(msg); + allocBytes = lenOfFileName + 80; + msg = new char[allocBytes]; + snprintf(msg,allocBytes,"Warning: The map file for binary %s is out-of-sync with the binary itself\r\n\r\n",iPlacedEntry.iFileName.c_str()); + iStdoutLog.push_back(msg); + continue ; + } + allocBytes = info.section.length() + info.name.length() + 140; + char* outputLine = new char[allocBytes]; + int len = snprintf(outputLine,allocBytes,"%08x %04x %-40s %s\r\n",(unsigned int)romAddr,info.size, + info.name.c_str(),info.section.c_str()); + if((size_t)len > allocBytes) { + allocBytes = len + 4 ; + delete []outputLine; + outputLine = new char[allocBytes]; + len = snprintf(outputLine,allocBytes,"%08x %04x %-40s %s\r\n",(unsigned int)romAddr,info.size, + info.name.c_str(),info.section.c_str()); + } + lines.push_back(pair(len,outputLine)); + + } + + for (vector >::iterator i = lines.begin() ; i < lines.end(); i ++ ) { + char* line = i->second; + iSymbolContentLog.push_back(line); + delete[] line; + } +} + +template +static void put_to_map(M& m,const K& k, const V& v) { + typedef typename M::iterator iterator; + iterator it = m.find(k); + if(m.end() == it){ + m.insert(pair(k,v)); + } + else { + it->second = v ; + } +} + +void CommenRomSymbolProcessUnit::ProcessGcceOrArm4File(const string& aFile, ifstream& aMap) +{ + char* lineStart; + vector words ; + char buffer[MAX_LINE]; + while(aMap.good() && (!aMap.eof())){ + aMap.getline(buffer,MAX_LINE); + lineStart = buffer ; + SKIP_WS(lineStart); + if( 0 == strncmp(lineStart,".text",5)) { + lineStart += 5; + break ; + } + } + split(lineStart,words); + TUint32 codeAddr , codeSize; + size_t allocBytes ; + if(words.size() != 2 || + KErrNone != Val(codeAddr,words.at(0)) || + KErrNone != Val(codeSize,words.at(1))) { + allocBytes = iPlacedEntry.iFileName.length() + 60; + char* msg = new char[allocBytes]; + snprintf(msg,allocBytes,"\nError: Can't get .text section info for \"%s\"\r\n",iPlacedEntry.iFileName.c_str()); + iStdoutLog.push_back(msg); + return; + } + map symbols ; + TUint32 stubHex = 0; + //Slurp symbols 'til the end of the text section + while(aMap.good() && (!aMap.eof())){ + aMap.getline(buffer,MAX_LINE); + lineStart = buffer ; + SKIP_WS(lineStart); + if(0 == *lineStart) break ; //blank line marks the end of the text section + + // .text + // .text$something + // + // LONG 0x0 + // (/^\s(\.text)?\s+(0x\w+)\s+(0x\w+)\s+(.*)$/io) + if(strncmp(lineStart,".text",5) == 0){ + lineStart += 5 ; + SKIP_WS(lineStart); + } + char* hex1 = NULL ; + char* hex2 = NULL ; + char* strAfterhex1 = NULL ; + TUint32 addr,size ; + if(strncmp(lineStart,"0x",2) == 0){ + hex1 = lineStart + 2; + char* temp ; + addr = strtoul(hex1,&temp,16); + SKIP_WS(temp); + strAfterhex1 = temp ; + if(strncmp(temp,"0x",2) == 0){ + hex2 = temp + 2 ; + } + } + if(NULL != hex2){ + char* libraryfile ; + size = strtoul(hex2,&libraryfile,16); + SKIP_WS(libraryfile); + TUint32 key = addr + size ; + put_to_map(symbols,key,string(""));//impossible symbol as end marker + make_lower(libraryfile); + // EUSER.LIB(ds01423.o) + // EUSER.LIB(C:/TEMP/d1000s_01423.o) + size_t len = strlen(libraryfile); + char* p1 = strstr(libraryfile,".lib("); + if(NULL == p1) + continue ; + p1 += 5; + if(strcmp(libraryfile + len - 3,".o)")!= 0) + continue ; + len -= 3 ; + libraryfile[len] = 0; + if(EFalse == IsValidNumber(libraryfile + len - 5)) + continue ; + len -= 7 ; + if('_' == libraryfile[len]) + len -- ; + if('s' != libraryfile[len]) + continue ; + char* p2 = libraryfile + len - 1; + while(p2 > p1 ) { + if(*p2 < '0' || *p2 > '9') + break ; + p2 -- ; + } + if(*p2 != 'd') + continue ; + stubHex = addr ; + } + else if(NULL != hex1 && NULL != strAfterhex1){ + //# + //(/^\s+(\w+)\s\s+([a-zA-Z_].+)/o) + char* symName = strAfterhex1; + if((*symName >= 'A' && *symName <= 'Z') || + (*symName >= 'a' && *symName <= 'z') || *symName == '_') { + string symbol(symName); + if(addr == stubHex) + symbol.insert(0,"stub "); + + put_to_map(symbols,addr,symbol); + + } + } + } + map::iterator it = symbols.begin(); + TUint32 lastAddr = it->first; + string lastSymName = it->second; + vector >lines ; + it ++ ; + while(it != symbols.end()) { + TUint32 addr = it->first ; + unsigned int fixedupAddr = lastAddr - codeAddr + iPlacedEntry.iCodeAddress; + TUint size = addr - lastAddr ; + if(!lastSymName.empty()) { + allocBytes = lastSymName.length() + 40; + char* outputLine = new char[allocBytes]; + int n = snprintf(outputLine,allocBytes,"%08x %04x %s\r\n", fixedupAddr,size,lastSymName.c_str()); + lines.push_back(pair(n,outputLine)); + } + lastAddr = addr ; + lastSymName = it->second; + it ++ ; + } + + vector >::iterator i; + for ( i = lines.begin() ; i < lines.end(); i ++ ) { + char* line = i->second ; + iSymbolContentLog.push_back(line); + delete []line ; + } +} + +void CommenRomSymbolProcessUnit::ProcessX86File(const string& aFile, ifstream& aMap) +{ + char buffer[MAX_LINE]; + char* lineStart; + while(aMap.good() && (!aMap.eof())){ + aMap.getline(buffer,MAX_LINE); + lineStart = buffer ; + SKIP_WS(lineStart); + if( 0 == strncmp(lineStart,"Address",7)) { + break ; + } + } + aMap.getline(buffer,MAX_LINE); + string lastName ; + TUint32 lastAddr = 0; + size_t allocBytes ; + vector >lines ; + while(aMap.good() && (!aMap.eof())){ + aMap.getline(buffer,MAX_LINE); + lineStart = buffer ; + SKIP_WS(lineStart); + if(0 != strncmp(lineStart,"0001:",5)) + break ; + char* end ; + TUint32 addr = strtoul(lineStart + 5,&end,16); + char* name = end + 1; + SKIP_WS(name); + end = name + 1; + FIND_WS(end); + *end = 0 ; + if(!lastName.empty()){ + unsigned int size = addr - lastAddr ; + unsigned int romAddr = lastAddr + iPlacedEntry.iCodeAddress; + allocBytes = lastName.length() + 40; + char* outputLine = new char[allocBytes]; + int n = snprintf(outputLine,allocBytes,"%08x %04x %s\r\n",romAddr,size,lastName.c_str()); + lines.push_back(pair(n,outputLine)); + } + } + + vector >::iterator it; + for ( it = lines.begin() ; it < lines.end(); it ++ ) { + char* line = it->second ; + iSymbolContentLog.push_back(line); + delete []line ; + } + if(!lastName.empty()){ + allocBytes = lastName.length() + 40 ; + char* outputLine = new char[allocBytes]; + unsigned int romAddr = lastAddr + iPlacedEntry.iCodeAddress; + snprintf(outputLine,allocBytes,"%08x 0000 %s\r\n",romAddr,lastName.c_str()); + iSymbolContentLog.push_back(outputLine); + delete []outputLine ; + } +} +// CommenRomSymbolProcessUnit end +// CommenRofsSymbolProcessUnit start +void CommenRofsSymbolProcessUnit::ProcessExecutableFile(const string& aFile) +{ + ResetContentLog(); + char str[MAX_LINE]; + string outString; + outString = "\nFrom "; + outString += aFile + "\n\n"; + iSymbolContentLog.push_back(outString); + string mapFile2 = aFile+".map"; + size_t dot = aFile.rfind('.'); + string mapFile = aFile.substr(0,dot)+".map"; + ifstream fMap; + fMap.open(mapFile2.c_str()); + if(!fMap.is_open()) { + fMap.open(mapFile.c_str()); + } + + if(!fMap.is_open()) { + sprintf(str, "%s\nWarning: Can't open \"%s\" or \"%s\"\n",aFile.c_str(),mapFile2.c_str(),mapFile.c_str()); + iStdoutLog.push_back(str); + int binSize = GetSizeFromBinFile(aFile); + memset(str,0,sizeof(str)); + sprintf(str,"%04x", binSize); + outString = "00000000 "; + outString += str; + outString += " "; + outString += aFile.substr(aFile.rfind(PATH_SEPARATOR)+1)+"\n"; + iSymbolContentLog.push_back(outString); + } + else { + if(!fMap.good()) fMap.clear(); + boost::regex regARMV5("ARMV5", boost::regex::icase); + boost::regex regGCCEoARMV4("(GCCE|ARMV4)", boost::regex::icase); + boost::cmatch what; + if(regex_search(aFile, what, regARMV5)) { + ProcessArmv5File(aFile, fMap); + } + else if(regex_search(aFile, what, regGCCEoARMV4)) { + ProcessGcceOrArm4File(aFile, fMap); + } + else { + sprintf(str, "\nWarning: cannot determine linker type used to create %s\n",aFile.c_str()); + iStdoutLog.push_back(str); + outString = "00000000 0000 "; + outString += aFile.substr(aFile.rfind(PATH_SEPARATOR)+1)+"\n"; + iSymbolContentLog.push_back(outString); + } + } +} +void CommenRofsSymbolProcessUnit::ProcessDataFile(const string& aFile) +{ + ResetContentLog(); + string line = "\nFrom "+aFile+"\n\n00000000 0000 "+aFile.substr(aFile.rfind(PATH_SEPARATOR)+1)+"\n"; + iSymbolContentLog.push_back(line); +} +void CommenRofsSymbolProcessUnit::FlushStdOut(ostream& aOut) +{ + for(int i = 0; i < (int) iStdoutLog.size(); i++) + { + aOut << iStdoutLog[i]; + } +} +void CommenRofsSymbolProcessUnit::FlushSymbolContent(ostream &aOut) +{ + for(int i = 0; i < (int) iSymbolContentLog.size(); i++) + { + aOut << iSymbolContentLog[i]; + } +} +void CommenRofsSymbolProcessUnit::ResetContentLog() +{ + iStdoutLog.clear(); + iSymbolContentLog.clear(); +} +void CommenRofsSymbolProcessUnit::ProcessArmv5File( const string& fileName, ifstream& aMap ){ + aMap.seekg (0, ios::beg); + char str[MAX_LINE]; + char outbuffer[MAX_LINE]; + string outString; + aMap.getline(str,MAX_LINE); + boost::cmatch what; + boost::regex reg("^ARM Linker"); + if(!regex_search(str, what, reg)) { + sprintf(outbuffer, "\nWarning: expecting %s to be generated by ARM linker\n", fileName.c_str()); + iStdoutLog.push_back(outbuffer); + outString = "00000000 0000 "+fileName.substr(fileName.rfind(PATH_SEPARATOR)+1)+"\n"; + iSymbolContentLog.push_back(outString); + } + reg.assign("Global Symbols"); + while(aMap.getline(str,MAX_LINE)) { + if(regex_search(str, what, reg)) { + break; + } + } + + reg.assign("^\\s*(.+)\\s*0x(\\S+)\\s+[^\\d]*(\\d+)\\s+(.*)$"); + string sSym,sTmp,sSection; + unsigned int addr,size,baseOffset = 0; + map syms; + char symString[MAX_LINE]; + while(aMap.getline(str,MAX_LINE)) { + if(regex_search(str, what, reg)) { + sSym.assign(what[1].first,what[1].second-what[1].first); + sTmp.assign(what[2].first,what[2].second-what[2].first); + addr = strtol(sTmp.c_str(), NULL, 16); + sTmp.assign(what[3].first,what[3].second-what[3].first); + size = strtol(sTmp.c_str(), NULL, 10); + sSection.assign(what[4].first,what[4].second-what[4].first); + if(sSection.find("(StubCode)") != string::npos) + size = 8; + if(addr > 0) { + memset(symString,0,sizeof(symString)); + sprintf(symString,"%04x ",size); + outString = symString; + outString += sSym+" "; + outString += sSection; + if(baseOffset == 0) + baseOffset = addr; + unsigned int k = addr - baseOffset; + if( (syms.find(k) == syms.end()) || size != 0) + syms[k] = outString; + } + // end of addr>0 + } + // end of regex_search + } + + map::iterator it; + for(it = syms.begin(); it != syms.end(); it++) { + memset(str,0,sizeof(str)); + sprintf(str,"%08x",it->first); + outString = str; + outString += " "; + outString += it->second+"\n"; + iSymbolContentLog.push_back(outString); + } +} +void CommenRofsSymbolProcessUnit::ProcessGcceOrArm4File( const string& fileName, ifstream& aMap ){ + aMap.seekg (0, ios_base::beg); + char str[MAX_LINE]; + char outbuffer[MAX_LINE]; + aMap.getline(str,MAX_LINE); + boost::cmatch what; + boost::regex reg("^\\.text\\s+"); + while(aMap.getline(str,MAX_LINE)) { + if(regex_search(str, what, reg)) { + break; + } + } + + reg.assign("^\\.text\\s+(\\w+)\\s+\\w+"); + if(!regex_search(str, what, reg)) { + sprintf(outbuffer, "ERROR: Can't get .text section info for \"%s\"\n",fileName.c_str()); + iStdoutLog.push_back(outbuffer); + } + else { + string sTmp, sLibFile; + sTmp.assign(what[1].first,what[1].second-what[1].first); + unsigned int imgText = strtol(sTmp.c_str(), NULL, 16); + + reg.assign("^LONG 0x.*", boost::regex::icase); + boost::cmatch what1; + boost::regex reg1("^\\s(\\.text)?\\s+(0x\\w+)\\s+(0x\\w+)\\s+(.*)$", boost::regex::icase); + boost::regex reg2("^\\s+(\\w+)\\s\\s+([a-zA-Z_].+)", boost::regex::icase); + boost::regex reg3(".*lib\\(.*d\\d*s_?\\d{5}.o\\)$", boost::regex::icase); + + map syms; + unsigned int addr, len, stubhex; + + while(aMap.getline(str,MAX_LINE)) { + if(strlen(str) == 0) + break; + else if(regex_search(str, what, reg1)) { + sLibFile.assign(what[4].first,what[4].second-what[4].first); + if(!regex_search(sLibFile, what1, reg)) { + sTmp.assign(what[2].first,what[2].second-what[2].first); + addr = strtol(sTmp.c_str(), NULL, 16); + sTmp.assign(what[3].first,what[3].second-what[3].first); + len = strtol(sTmp.c_str(), NULL, 16); + syms[addr+len] = ""; + if(regex_search(sLibFile, what, reg3)) { + stubhex = addr; + } + } + } + else if(regex_search(str, what, reg2)) { + sTmp.assign(what[1].first,what[1].second-what[1].first); + addr = strtol(sTmp.c_str(), NULL, 16); + sTmp.assign(what[2].first,what[2].second-what[2].first); + syms[addr] = (addr == stubhex)? ("stub "+sTmp) : sTmp; + } + } + + map::iterator it = syms.begin(); + map::iterator itp = it++; + string outString; + for(; it != syms.end(); itp = it++) { + if(itp->second != "") { + memset(str,0,sizeof(str)); + sprintf(str,"%08x %04x ",(itp->first-imgText), (it->first-itp->first)); + outString = str; + outString += it->second+"\n"; + iSymbolContentLog.push_back(outString); + } + } + } +} +// CommenRofsSymbolProcessUnit end +int SymbolProcessUnit::GetSizeFromBinFile( const string& fileName ){ + TInt ret = 0; + //char outbuffer[MAX_LINE]; + ifstream aIf(fileName.c_str(), ios_base::binary); + if( !aIf.is_open() ) { + printf("Warning: Cannot open file %s\n", fileName.c_str()); + //iStdoutLog.push_back(outbuffer); + } + else { + E32ImageFile e32Image; + TUint32 aSz; + + aIf.seekg(0,ios_base::end); + aSz = aIf.tellg(); + + e32Image.Adjust(aSz); + e32Image.iFileSize = aSz; + + aIf.seekg(0,ios_base::beg); + aIf >> e32Image; + ret = e32Image.iOrigHdr->iCodeSize; + } + return ret; +} + +// for BSym +void BsymRofsSymbolProcessUnit::ProcessEntry(const TPlacedEntry& aEntry) +{ + SymbolProcessUnit::ProcessEntry(aEntry); + if(aEntry.iFileName == "") + return; + else if(aEntry.iExecutable) + ProcessExecutableFile(aEntry.iFileName); + else + ProcessDataFile(aEntry.iFileName); + iMapFileInfo.iDbgUnitPCEntry.iPCName = aEntry.iFileName; + iMapFileInfo.iDbgUnitPCEntry.iDevName = aEntry.iDevFileName; +} + +void BsymRofsSymbolProcessUnit::ProcessExecutableFile(const string& aFile) +{ + ResetContentLog(); + char str[MAX_LINE]; + string mapFile2 = aFile+".map"; + size_t dot = aFile.rfind('.'); + string mapFile = aFile.substr(0,dot)+".map"; + ifstream fMap; + fMap.open(mapFile2.c_str()); + if(!fMap.is_open()) { + fMap.open(mapFile.c_str()); + } + + if(!fMap.is_open()) { + sprintf(str, "%s\nWarning: Can't open \"%s\" or \"%s\"\n",aFile.c_str(),mapFile2.c_str(),mapFile.c_str()); + iStdoutLog.push_back(str); + int binSize = GetSizeFromBinFile(aFile); + TSymbolPCEntry tmpEntry; + tmpEntry.iSymbolEntry.iAddress = 0; + tmpEntry.iSymbolEntry.iLength = binSize; + tmpEntry.iName = aFile.substr(aFile.rfind(PATH_SEPARATOR)+1); + iMapFileInfo.iSymbolPCEntrySet.push_back(tmpEntry); + iMapFileInfo.iDbgUnitPCEntry.iDbgUnitEntry.iDataSymbolCount++; + } + else { + if(!fMap.good()) fMap.clear(); + boost::regex regARMV5("ARMV5", boost::regex::icase); + boost::regex regGCCEoARMV4("(GCCE|ARMV4)", boost::regex::icase); + boost::cmatch what; + if(regex_search(aFile, what, regARMV5)) { + ProcessArmv5File(aFile, fMap); + } + else if(regex_search(aFile, what, regGCCEoARMV4)) { + ProcessGcceOrArm4File(aFile, fMap); + } + else { + sprintf(str, "\nWarning: cannot determine linker type used to create %s\n",aFile.c_str()); + iStdoutLog.push_back(str); + TSymbolPCEntry tmpEntry; + tmpEntry.iSymbolEntry.iAddress = 0; + tmpEntry.iSymbolEntry.iLength = 0; + tmpEntry.iName = aFile.substr(aFile.rfind(PATH_SEPARATOR)+1); + iMapFileInfo.iSymbolPCEntrySet.push_back(tmpEntry); + iMapFileInfo.iDbgUnitPCEntry.iDbgUnitEntry.iDataSymbolCount++; + } + } +} +void BsymRofsSymbolProcessUnit::ProcessDataFile(const string& aFile) +{ + ResetContentLog(); + TSymbolPCEntry tmpEntry; + tmpEntry.iSymbolEntry.iAddress = 0; + tmpEntry.iSymbolEntry.iLength = 0; + tmpEntry.iName = aFile.substr(aFile.rfind(PATH_SEPARATOR)+1); + iMapFileInfo.iSymbolPCEntrySet.push_back(tmpEntry); + iMapFileInfo.iDbgUnitPCEntry.iDbgUnitEntry.iDataSymbolCount++; +} +void BsymRofsSymbolProcessUnit::FlushStdOut(ostream& aOut) +{ + for(int i = 0; i < (int) iStdoutLog.size(); i++) + { + aOut << iStdoutLog[i]; + } +} +void BsymRofsSymbolProcessUnit::FlushSymbolContent(ostream &aOut) +{ + iSymbolGeneratorPtr->AppendMapFileInfo(iMapFileInfo); +} +void BsymRofsSymbolProcessUnit::ResetContentLog() +{ + iStdoutLog.clear(); + iMapFileInfo.iDbgUnitPCEntry.iPCName = ""; + iMapFileInfo.iDbgUnitPCEntry.iDevName = ""; + iMapFileInfo.iDbgUnitPCEntry.iDbgUnitEntry.Reset(); + iMapFileInfo.iSymbolPCEntrySet.clear(); +} +void BsymRofsSymbolProcessUnit::ProcessArmv5File( const string& fileName, ifstream& aMap ){ + aMap.seekg (0, ios::beg); + char str[MAX_LINE]; + char outbuffer[MAX_LINE]; + aMap.getline(str,MAX_LINE); + boost::cmatch what; + boost::regex reg("^ARM Linker"); + if(!regex_search(str, what, reg)) { + sprintf(outbuffer, "\nWarning: expecting %s to be generated by ARM linker\n", fileName.c_str()); + iStdoutLog.push_back(outbuffer); + return; + } + reg.assign("Global Symbols"); + boost::regex bss_search("^\\s*\\.bss\\s*0x(\\S+)\\s*.*$"); + bool hasValue = false; + string bssStart; + TUint32 bssSection = 0; + while(aMap.getline(str,MAX_LINE)) { + if(!hasValue && regex_search(str, what, bss_search)) + { + hasValue = true; + bssStart.assign(what[1].first,what[1].second-what[1].first); + } + if(regex_search(str, what, reg)) { + break; + } + } + if(!bssStart.empty()) + { + bssSection = strtol(bssStart.c_str(), NULL, 16); + } + reg.assign("^\\s*(.+)\\s*0x(\\S+)\\s+[^\\d]*(\\d+)\\s+(.*)$"); + string sSym,sTmp,sSection,scopeName, symName; + boost::regex regScope("^\\s*(\\w+)\\s*::\\s*(.*)$"); + unsigned int addr,size,baseOffset = 0; + map syms; + TUint32 dataStart = 0x400000; + while(aMap.getline(str,MAX_LINE)) { + if(regex_search(str, what, reg)) { + sSym.assign(what[1].first,what[1].second-what[1].first); + sTmp.assign(what[2].first,what[2].second-what[2].first); + addr = strtol(sTmp.c_str(), NULL, 16); + sTmp.assign(what[3].first,what[3].second-what[3].first); + size = strtol(sTmp.c_str(), NULL, 10); + sSection.assign(what[4].first,what[4].second-what[4].first); + if(sSection.find("(StubCode)") != string::npos) + size = 8; + if(addr > 0) { + if(baseOffset == 0) + baseOffset = addr; + unsigned int k = addr - baseOffset; + if( (syms.find(k) == syms.end()) || size != 0) + { + TSymbolPCEntry tmpEntry; + if(regex_search(sSym, what, regScope)) + { + scopeName.assign(what[1].first, what[1].second-what[1].first); + symName.assign(what[2].first, what[2].second-what[2].first); + tmpEntry.iScopeName = scopeName; + tmpEntry.iName = symName; + tmpEntry.iSecName = sSection; + } + else + { + tmpEntry.iScopeName = ""; + tmpEntry.iName = sSym; + tmpEntry.iSecName = sSection; + } + tmpEntry.iSymbolEntry.iAddress = k; + tmpEntry.iSymbolEntry.iLength = size; + syms[k]=tmpEntry; + } + + } + // end of addr>0 + } + // end of regex_search + } + + map::iterator it; + for(it = syms.begin(); it != syms.end(); it++) { + unsigned int addr = it->first; + if(addr < dataStart) + { + iMapFileInfo.iDbgUnitPCEntry.iDbgUnitEntry.iCodeSymbolCount++; + } + else + { + if(bssSection > 0 && addr >= bssSection) + { + iMapFileInfo.iDbgUnitPCEntry.iDbgUnitEntry.iBssSymbolCount++; + } + else + { + iMapFileInfo.iDbgUnitPCEntry.iDbgUnitEntry.iDataSymbolCount++; + } + } + iMapFileInfo.iSymbolPCEntrySet.push_back(it->second); + } +} +void BsymRofsSymbolProcessUnit::ProcessGcceOrArm4File( const string& fileName, ifstream& aMap ){ + aMap.seekg (0, ios_base::beg); + char str[MAX_LINE]; + char outbuffer[MAX_LINE]; + aMap.getline(str,MAX_LINE); + boost::cmatch what; + boost::regex reg("^\\.text\\s+"); + while(aMap.getline(str,MAX_LINE)) { + if(regex_search(str, what, reg)) { + break; + } + } + + reg.assign("^\\.text\\s+(\\w+)\\s+\\w+"); + if(!regex_search(str, what, reg)) { + sprintf(outbuffer, "ERROR: Can't get .text section info for \"%s\"\n",fileName.c_str()); + iStdoutLog.push_back(outbuffer); + } + else { + string sTmp, sLibFile; + sTmp.assign(what[1].first,what[1].second-what[1].first); + unsigned int imgText = strtol(sTmp.c_str(), NULL, 16); + + reg.assign("^LONG 0x.*", boost::regex::icase); + boost::cmatch what1; + boost::regex reg1("^\\s(\\.text)?\\s+(0x\\w+)\\s+(0x\\w+)\\s+(.*)$", boost::regex::icase); + boost::regex reg2("^\\s+(\\w+)\\s\\s+([a-zA-Z_].+)", boost::regex::icase); + boost::regex reg3(".*lib\\(.*d\\d*s_?\\d{5}.o\\)$", boost::regex::icase); + + map syms; + unsigned int addr, len, stubhex; + + while(aMap.getline(str,MAX_LINE)) { + if(strlen(str) == 0) + break; + else if(regex_search(str, what, reg1)) { + sLibFile.assign(what[4].first,what[4].second-what[4].first); + if(!regex_search(sLibFile, what1, reg)) { + sTmp.assign(what[2].first,what[2].second-what[2].first); + addr = strtol(sTmp.c_str(), NULL, 16); + sTmp.assign(what[3].first,what[3].second-what[3].first); + len = strtol(sTmp.c_str(), NULL, 16); + syms[addr+len] = ""; + if(regex_search(sLibFile, what, reg3)) { + stubhex = addr; + } + } + } + else if(regex_search(str, what, reg2)) { + sTmp.assign(what[1].first,what[1].second-what[1].first); + addr = strtol(sTmp.c_str(), NULL, 16); + sTmp.assign(what[2].first,what[2].second-what[2].first); + syms[addr] = (addr == stubhex)? ("stub "+sTmp) : sTmp; + } + } + + map::iterator it = syms.begin(); + map::iterator itp = it++; + TSymbolPCEntry tmpSymbolEntry; + for(; it != syms.end(); itp = it++) { + if(itp->second != "") { + tmpSymbolEntry.iSymbolEntry.iAddress = itp->first-imgText; + tmpSymbolEntry.iSymbolEntry.iLength = it->first-itp->first; + tmpSymbolEntry.iName = it->second; + iMapFileInfo.iDbgUnitPCEntry.iDbgUnitEntry.iCodeSymbolCount++; + iMapFileInfo.iSymbolPCEntrySet.push_back(tmpSymbolEntry); + } + } + } +} diff -r c3fbb20e86f0 -r 46ca13b54f56 imgtools/imglib/symbolutil/symbolprocessunit.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imgtools/imglib/symbolutil/symbolprocessunit.h Wed Nov 17 16:47:32 2010 +0800 @@ -0,0 +1,120 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ +#ifndef __SYMBOLPROCESSUNIT_H__ +#define __SYMBOLPROCESSUNIT_H__ +#include +#include +#include +#include + +#include "bsymutil.h" + +using namespace std; + +struct TPlacedEntry{ + string iFileName; + string iDevFileName; + TUint32 iTotalSize; + TUint32 iCodeAddress; + TUint32 iDataAddress; + TUint32 iDataBssLinearBase; + TUint32 iTextSize; + TUint32 iDataSize; + TUint32 iBssSize; + TUint32 iTotalDataSize; + bool iExecutable; + TPlacedEntry(const string& aName, const string& aDevFileName, bool aExecutable) { + iFileName = aName; + iDevFileName = aDevFileName; + iExecutable = aExecutable; + } + TPlacedEntry() { + } +}; + +typedef vector stringlist; + +class SymbolProcessUnit +{ +public: + virtual void ProcessExecutableFile(const string& aFile) = 0; + virtual void ProcessDataFile(const string& afile) = 0; + virtual void FlushStdOut(ostream& aOut) = 0; + virtual void FlushSymbolContent(ostream &aOut) = 0; + virtual void ResetContentLog() = 0; + virtual ~SymbolProcessUnit() {} + virtual void ProcessEntry(const TPlacedEntry& aEntry); + int GetSizeFromBinFile( const string& fileName ); +}; + +class CommenRomSymbolProcessUnit : public SymbolProcessUnit +{ +public: + virtual void ProcessExecutableFile(const string& aFile); + virtual void ProcessDataFile(const string& afile); + virtual void FlushStdOut(ostream& aOut); + virtual void FlushSymbolContent(ostream &aOut); + virtual void ResetContentLog(); + virtual void ProcessEntry(const TPlacedEntry& aEntry); +private: + void ProcessArmv5File( const string& fileName, ifstream& aMap ); + void ProcessGcceOrArm4File( const string& fileName, ifstream& aMap ); + void ProcessX86File( const string& fileName, ifstream& aMap ); +private: + stringlist iStdoutLog; + stringlist iSymbolContentLog; + TPlacedEntry iPlacedEntry; +}; + +class CommenRofsSymbolProcessUnit : public SymbolProcessUnit +{ +public: + virtual void ProcessExecutableFile(const string& aFile); + virtual void ProcessDataFile(const string& afile); + virtual void FlushStdOut(ostream& aOut); + virtual void FlushSymbolContent(ostream &aOut); + virtual void ResetContentLog(); +private: + void ProcessArmv5File( const string& fileName, ifstream& aMap ); + void ProcessGcceOrArm4File( const string& fileName, ifstream& aMap ); +private: + stringlist iStdoutLog; + stringlist iSymbolContentLog; +}; + +class SymbolGenerator; + +class BsymRofsSymbolProcessUnit : public SymbolProcessUnit +{ +public: + BsymRofsSymbolProcessUnit(SymbolGenerator* aSymbolGeneratorPtr): iSymbolGeneratorPtr(aSymbolGeneratorPtr){} + BsymRofsSymbolProcessUnit(){} + virtual void ProcessExecutableFile(const string& aFile); + virtual void ProcessDataFile(const string& afile); + virtual void FlushStdOut(ostream& aOut); + virtual void FlushSymbolContent(ostream &aOut); + virtual void ResetContentLog(); + virtual void ProcessEntry(const TPlacedEntry& aEntry); +private: + void ProcessArmv5File( const string& fileName, ifstream& aMap ); + void ProcessGcceOrArm4File( const string& fileName, ifstream& aMap ); +private: + stringlist iStdoutLog; + MapFileInfo iMapFileInfo; + SymbolGenerator* iSymbolGeneratorPtr; +}; +#endif diff -r c3fbb20e86f0 -r 46ca13b54f56 imgtools/romtools/rofsbuild/inc/logging/loggingexception.hpp --- a/imgtools/romtools/rofsbuild/inc/logging/loggingexception.hpp Wed Nov 17 16:47:23 2010 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -/* -* Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "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: -* -*/ - - -#ifndef ROM_TOOLS_ROFSBUILD_LOGGING_LOGGINGEXCEPTION_H_ -#define ROM_TOOLS_ROFSBUILD_LOGGING_LOGGINGEXCEPTION_H_ - - -/* - * @class LoggingException - */ -class LoggingException -{ -public: - LoggingException(int ErrorCode); - - int GetErrorCode(void); - - const char* GetErrorMessage(void); - - static int RESOURCE_ALLOCATION_FAILURE; - static int INVALID_LOG_FILENAME ; - - virtual ~LoggingException(void); -protected: - int errcode; -private: - LoggingException(void); - - LoggingException& operator = (const LoggingException&); -}; - - -#endif /* defined ROM_TOOLS_ROFSBUILD_LOGGING_LOGGINGEXCEPTION_H_ */ diff -r c3fbb20e86f0 -r 46ca13b54f56 imgtools/romtools/rofsbuild/inc/logging/logparser.hpp --- a/imgtools/romtools/rofsbuild/inc/logging/logparser.hpp Wed Nov 17 16:47:23 2010 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* -* Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "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: -* -*/ - - -#ifndef ROM_TOOLS_ROFSBUILD_LOGGING_LOGPARSER_H_ -#define ROM_TOOLS_ROFSBUILD_LOGGING_LOGPARSER_H_ - - -/** - * @class LogParser - */ -class LogParser -{ -public: - static LogParser* GetInstance(void) throw (LoggingException); - - void ParseSymbol(const char* LogFilename) throw (LoggingException); - - void Cleanup(void); -protected: - static LogParser* Only; -private: - LogParser(void); - - LogParser(const LogParser&); - - LogParser& operator = (const LogParser&); -}; - - - -#endif /* defined ROM_TOOLS_ROFSBUILD_LOGGING_LOGPARSER_H_ */ diff -r c3fbb20e86f0 -r 46ca13b54f56 imgtools/romtools/rofsbuild/src/logging/loggingexception.cpp --- a/imgtools/romtools/rofsbuild/src/logging/loggingexception.cpp Wed Nov 17 16:47:23 2010 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/* -* Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "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: -* -*/ - -#include "logging/loggingexception.hpp" - - -int LoggingException::RESOURCE_ALLOCATION_FAILURE = 1; -int LoggingException::INVALID_LOG_FILENAME = 2; - - -LoggingException::LoggingException(int ErrorCode) -{ - this->errcode = ErrorCode; - - return; -} - - -int LoggingException::GetErrorCode(void) -{ - return this->errcode; -} - - -const char* LoggingException::GetErrorMessage(void) -{ - if(this->errcode == LoggingException::RESOURCE_ALLOCATION_FAILURE) - return "Not enough system resources to initialize logging module."; - else if(this->errcode == LoggingException::INVALID_LOG_FILENAME) - return "Invalid log filename as input."; -// else if(this->errcode == CacheException::CACHE_INVALID) -// return "Cache is invalid."; -// else if(this->errcode == CacheException::CACHE_IS_EMPTY) -// return "Cache is empty."; -// else if(this->errcode == CacheException::HARDDRIVE_FAILURE) -// return "A hard drive failure occurred in Cache operations."; - - return "Undefined error type."; -} - - -LoggingException::~LoggingException(void) -{ - return; -} diff -r c3fbb20e86f0 -r 46ca13b54f56 imgtools/romtools/rofsbuild/src/logging/logparser.cpp --- a/imgtools/romtools/rofsbuild/src/logging/logparser.cpp Wed Nov 17 16:47:23 2010 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,116 +0,0 @@ -/* -* Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "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: -* -*/ - - -#include -#include -#include -#include -using namespace std; - -#include "logging/loggingexception.hpp" -#include "logging/logparser.hpp" -#include "symbolgenerator.h" - - -LogParser* LogParser::Only = (LogParser*)0; - - -LogParser* LogParser::GetInstance(void) throw (LoggingException) -{ - if(! LogParser::Only) - { - LogParser::Only = new (std::nothrow) LogParser(); - if(! LogParser::Only) - throw LoggingException(LoggingException::RESOURCE_ALLOCATION_FAILURE); - } - - return LogParser::Only; -} - - -void LogParser::ParseSymbol(const char* LogFilename) throw (LoggingException) -{ - string linebuf; - SymbolGenerator* symgen = SymbolGenerator::GetInstance(); - symgen->SetSymbolFileName(string(LogFilename)); - - ifstream logfd(LogFilename); - if(logfd.is_open()) - { - while(! logfd.eof()) - { - getline(logfd, linebuf); - if(linebuf.compare(0,4,"File") == 0) - { - if(linebuf.find("size:", 4) != string::npos) - { - size_t startpos = linebuf.find('\'') ; - size_t endpos = linebuf.rfind('\''); - if((startpos!=string::npos) && (endpos!=string::npos)) - { - symgen->AddFile(linebuf.substr(startpos+1,endpos-startpos-1), false); - } - } - } - else if(linebuf.compare(0,15,"Executable File") == 0) - { - if(linebuf.find("size:", 26) != string::npos) - { - size_t startpos = linebuf.find('\'') ; - size_t endpos = linebuf.rfind('\''); - if((startpos!=string::npos) && (endpos!=string::npos)) - { - symgen->AddFile(linebuf.substr(startpos+1,endpos-startpos-1), true); - } - } - } - else if(linebuf.compare(0,26,"Compressed executable File") == 0) - { - if(linebuf.find("size:", 26) != string::npos) - { - size_t startpos = linebuf.find('\'') ; - size_t endpos = linebuf.rfind('\''); - if((startpos!=string::npos) && (endpos!=string::npos)) - { - symgen->AddFile(linebuf.substr(startpos+1,endpos-startpos-1), true); - } - } - } - } - symgen->SetFinished(); - symgen->Release(); - } - else - { - throw LoggingException(LoggingException::INVALID_LOG_FILENAME); - } - - return; -} - - -void LogParser::Cleanup(void) -{ - return; -} - - -LogParser::LogParser(void) -{ - return; -} diff -r c3fbb20e86f0 -r 46ca13b54f56 imgtools/romtools/rofsbuild/symbolgenerator.cpp --- a/imgtools/romtools/rofsbuild/symbolgenerator.cpp Wed Nov 17 16:47:23 2010 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,150 +0,0 @@ -/* -* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "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: -* -*/ - -#include -#include -#define MAX_LINE 65535 -#include "symbolgenerator.h" -#include "e32image.h" - -#if defined(__LINUX__) -#define PATH_SEPARATOR '/' -#else -#define PATH_SEPARATOR '\\' -#endif -extern TInt gThreadNum; - -boost::mutex SymbolGenerator::iMutexSingleton; -SymbolGenerator* SymbolGenerator::iInst = NULL; -SymbolGenerator* SymbolGenerator::GetInstance(){ - iMutexSingleton.lock(); - if(iInst == NULL) { - iInst = new SymbolGenerator(); - } - iMutexSingleton.unlock(); - return iInst; -} -void SymbolGenerator::Release() { - if(iInst != NULL) { - iInst->join(); - } - iMutexSingleton.lock(); - if(iInst != NULL) { - delete iInst; - iInst = NULL; - } - iMutexSingleton.unlock(); -} -void SymbolGenerator::SetSymbolFileName( const string& fileName ){ - if(iSymFile.is_open()) - iSymFile.close(); - string s = fileName.substr(0,fileName.rfind('.'))+".symbol"; - printf("* Writing %s - ROFS symbol file\n", s.c_str()); - iSymFile.open(s.c_str()); -} -void SymbolGenerator::AddFile( const string& fileName, bool isExecutable ){ - iMutex.lock(); - iQueueFiles.push(TPlacedEntry(fileName,isExecutable)); - iMutex.unlock(); - iCond.notify_all(); -} -void SymbolGenerator::SetFinished() -{ - - iFinished = true; - iCond.notify_all(); - } -TPlacedEntry SymbolGenerator::GetNextPlacedEntry() -{ - TPlacedEntry pe("", false); - if(1) - { - boost::mutex::scoped_lock lock(iMutex); - while(!iFinished && iQueueFiles.empty()) - iCond.wait(lock); - if(!iQueueFiles.empty()) - { - pe = iQueueFiles.front(); - iQueueFiles.pop(); - } - } - return pe; -} -void SymbolGenerator::thrd_func(){ - boost::thread_group threads; - SymbolWorker worker; - for(int i=0; i < gThreadNum; i++) - { - threads.create_thread(worker); - } - threads.join_all(); - } -SymbolGenerator::SymbolGenerator() : boost::thread(thrd_func),iFinished(false) { - } -SymbolGenerator::~SymbolGenerator(){ - if(joinable()) - join(); - iSymFile.flush(); - iSymFile.close(); - } -SymbolWorker::SymbolWorker() -{ - // end of regex_search - } -SymbolWorker::~SymbolWorker() -{ - } -void SymbolWorker::operator()() -{ - SymbolProcessUnit* aSymbolProcessUnit = new CommenSymbolProcessUnit(); - SymbolGenerator* symbolgenerator = SymbolGenerator::GetInstance(); - - while(1) - { - if(symbolgenerator->HasFinished() && symbolgenerator->IsEmpty()) - { - - break; - } - - - - - TPlacedEntry pe = symbolgenerator->GetNextPlacedEntry(); - - //scope the code block with if(1) for lock - /* - if(me->iQueueFiles.empty()) { - boost::this_thread::sleep(boost::posix_time::milliseconds(10)); - continue; - } - */ - - - if(pe.iFileName == "") - continue; - else if(pe.iExecutable) - aSymbolProcessUnit->ProcessExecutableFile(pe.iFileName); - else - aSymbolProcessUnit->ProcessDataFile(pe.iFileName); - symbolgenerator->LockOutput(); - aSymbolProcessUnit->FlushStdOut(cout); - aSymbolProcessUnit->FlushSymbolContent(symbolgenerator->GetOutputFileStream()); - symbolgenerator->UnlockOutput(); -} - delete aSymbolProcessUnit; -} diff -r c3fbb20e86f0 -r 46ca13b54f56 imgtools/romtools/rofsbuild/symbolgenerator.h --- a/imgtools/romtools/rofsbuild/symbolgenerator.h Wed Nov 17 16:47:23 2010 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/* -* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "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: -* -*/ - -#ifndef __SYMBOLGENERATOR_H__ -#define __SYMBOLGENERATOR_H__ -#include -#include -#include -using namespace std; -#include -#include -#include "symbolprocessunit.h" - - -struct TPlacedEntry{ - string iFileName; - bool iExecutable; - TPlacedEntry(const string& aName, bool aExecutable) { - iFileName = aName; - iExecutable = aExecutable; - } -}; -class SymbolGenerator : public boost::thread { - public: - static SymbolGenerator* GetInstance(); - static void Release(); - void SetSymbolFileName( const string& fileName ); - void AddFile( const string& fileName, bool isExecutable ); - bool HasFinished() { return iFinished; } - void SetFinished(); - bool IsEmpty() { return iQueueFiles.empty(); } - void LockOutput() { iOutputMutex.lock(); } - void UnlockOutput() { iOutputMutex.unlock(); } - TPlacedEntry GetNextPlacedEntry(); - ofstream& GetOutputFileStream() { return iSymFile; }; - private: - SymbolGenerator(); - ~SymbolGenerator(); - static void thrd_func(); - - queue iQueueFiles; - boost::mutex iMutex; - boost::mutex iOutputMutex; - static boost::mutex iMutexSingleton; - static SymbolGenerator* iInst; - boost::condition_variable iCond; - bool iFinished; - - ofstream iSymFile; -}; -class SymbolWorker{ -public: - SymbolWorker(); - ~SymbolWorker(); - void operator()(); -private: -}; -#endif diff -r c3fbb20e86f0 -r 46ca13b54f56 imgtools/romtools/rofsbuild/symbolprocessunit.cpp --- a/imgtools/romtools/rofsbuild/symbolprocessunit.cpp Wed Nov 17 16:47:23 2010 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,258 +0,0 @@ -/* -* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "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: -* -*/ -#include -#include "symbolprocessunit.h" -#include "e32image.h" -#define MAX_LINE 65535 - -#if defined(__LINUX__) -#define PATH_SEPARATOR '/' -#else -#define PATH_SEPARATOR '\\' -#endif - -void CommenSymbolProcessUnit::ProcessExecutableFile(const string& aFile) -{ - ResetContentLog(); - char str[MAX_LINE]; - string outString; - outString = "\nFrom "; - outString += aFile + "\n\n"; - iSymbolContentLog.push_back(outString); - string mapFile2 = aFile+".map"; - size_t dot = aFile.rfind('.'); - string mapFile = aFile.substr(0,dot)+".map"; - ifstream fMap; - fMap.open(mapFile2.c_str()); - if(!fMap.is_open()) { - fMap.open(mapFile.c_str()); - } - - if(!fMap.is_open()) { - sprintf(str, "%s\nWarning: Can't open \"%s\" or \"%s\"\n",aFile.c_str(),mapFile2.c_str(),mapFile.c_str()); - iStdoutLog.push_back(str); - int binSize = GetSizeFromBinFile(aFile); - memset(str,0,sizeof(str)); - sprintf(str,"%04x", binSize); - outString = "00000000 "; - outString += str; - outString += " "; - outString += aFile.substr(aFile.rfind(PATH_SEPARATOR)+1)+"\n"; - iSymbolContentLog.push_back(outString); - } - else { - if(!fMap.good()) fMap.clear(); - boost::regex regARMV5("ARMV5", boost::regex::icase); - boost::regex regGCCEoARMV4("(GCCE|ARMV4)", boost::regex::icase); - boost::cmatch what; - if(regex_search(aFile, what, regARMV5)) { - ProcessArmv5File(aFile, fMap); - } - else if(regex_search(aFile, what, regGCCEoARMV4)) { - ProcessGcceOrArm4File(aFile, fMap); - } - else { - sprintf(str, "\nWarning: cannot determine linker type used to create %s\n",aFile.c_str()); - iStdoutLog.push_back(str); - outString = "00000000 0000 "; - outString += aFile.substr(aFile.rfind(PATH_SEPARATOR)+1)+"\n"; - iSymbolContentLog.push_back(outString); - } - } -} -void CommenSymbolProcessUnit::ProcessDataFile(const string& aFile) -{ - ResetContentLog(); - string line = "\nFrom "+aFile+"\n\n00000000 0000 "+aFile.substr(aFile.rfind(PATH_SEPARATOR)+1)+"\n"; - iSymbolContentLog.push_back(line); -} -void CommenSymbolProcessUnit::FlushStdOut(ostream& aOut) -{ - for(int i = 0; i < (int) iStdoutLog.size(); i++) - { - aOut << iStdoutLog[i]; - } -} -void CommenSymbolProcessUnit::FlushSymbolContent(ostream &aOut) -{ - for(int i = 0; i < (int) iSymbolContentLog.size(); i++) - { - aOut << iSymbolContentLog[i]; - } -} -void CommenSymbolProcessUnit::ResetContentLog() -{ - iStdoutLog.clear(); - iSymbolContentLog.clear(); -} -void CommenSymbolProcessUnit::ProcessArmv5File( const string& fileName, ifstream& aMap ){ - aMap.seekg (0, ios::beg); - char str[MAX_LINE]; - char outbuffer[MAX_LINE]; - string outString; - aMap.getline(str,MAX_LINE); - boost::cmatch what; - boost::regex reg("^ARM Linker"); - if(!regex_search(str, what, reg)) { - sprintf(outbuffer, "\nWarning: expecting %s to be generated by ARM linker\n", fileName.c_str()); - iStdoutLog.push_back(outbuffer); - outString = "00000000 0000 "+fileName.substr(fileName.rfind(PATH_SEPARATOR)+1)+"\n"; - iSymbolContentLog.push_back(outString); - } - reg.assign("Global Symbols"); - while(aMap.getline(str,MAX_LINE)) { - if(regex_search(str, what, reg)) { - break; - } - } - - reg.assign("^\\s*(.+)\\s*0x(\\S+)\\s+[^\\d]*(\\d+)\\s+(.*)$"); - string sSym,sTmp,sSection; - unsigned int addr,size,baseOffset = 0; - map syms; - char symString[MAX_LINE]; - while(aMap.getline(str,MAX_LINE)) { - if(regex_search(str, what, reg)) { - sSym.assign(what[1].first,what[1].second-what[1].first); - sTmp.assign(what[2].first,what[2].second-what[2].first); - addr = strtol(sTmp.c_str(), NULL, 16); - sTmp.assign(what[3].first,what[3].second-what[3].first); - size = strtol(sTmp.c_str(), NULL, 10); - sSection.assign(what[4].first,what[4].second-what[4].first); - if(sSection.find("(StubCode)") != string::npos) - size = 8; - if(addr > 0) { - memset(symString,0,sizeof(symString)); - sprintf(symString,"%04x ",size); - outString = symString; - outString += sSym+" "; - outString += sSection; - if(baseOffset == 0) - baseOffset = addr; - unsigned int k = addr - baseOffset; - if( (syms.find(k) == syms.end()) || size != 0) - syms[k] = outString; - } - // end of addr>0 - } - // end of regex_search - } - - map::iterator it; - for(it = syms.begin(); it != syms.end(); it++) { - memset(str,0,sizeof(str)); - sprintf(str,"%08x",it->first); - outString = str; - outString += " "; - outString += it->second+"\n"; - iSymbolContentLog.push_back(outString); - } -} -void CommenSymbolProcessUnit::ProcessGcceOrArm4File( const string& fileName, ifstream& aMap ){ - aMap.seekg (0, ios_base::beg); - char str[MAX_LINE]; - char outbuffer[MAX_LINE]; - aMap.getline(str,MAX_LINE); - boost::cmatch what; - boost::regex reg("^\\.text\\s+"); - while(aMap.getline(str,MAX_LINE)) { - if(regex_search(str, what, reg)) { - break; - } - } - - reg.assign("^\\.text\\s+(\\w+)\\s+\\w+"); - if(!regex_search(str, what, reg)) { - sprintf(outbuffer, "ERROR: Can't get .text section info for \"%s\"\n",fileName.c_str()); - iStdoutLog.push_back(outbuffer); - } - else { - string sTmp, sLibFile; - sTmp.assign(what[1].first,what[1].second-what[1].first); - unsigned int imgText = strtol(sTmp.c_str(), NULL, 16); - - reg.assign("^LONG 0x.*", boost::regex::icase); - boost::cmatch what1; - boost::regex reg1("^\\s(\\.text)?\\s+(0x\\w+)\\s+(0x\\w+)\\s+(.*)$", boost::regex::icase); - boost::regex reg2("^\\s+(\\w+)\\s\\s+([a-zA-Z_].+)", boost::regex::icase); - boost::regex reg3(".*lib\\(.*d\\d*s_?\\d{5}.o\\)$", boost::regex::icase); - - map syms; - unsigned int addr, len, stubhex; - - while(aMap.getline(str,MAX_LINE)) { - if(strlen(str) == 0) - break; - else if(regex_search(str, what, reg1)) { - sLibFile.assign(what[4].first,what[4].second-what[4].first); - if(!regex_search(sLibFile, what1, reg)) { - sTmp.assign(what[2].first,what[2].second-what[2].first); - addr = strtol(sTmp.c_str(), NULL, 16); - sTmp.assign(what[3].first,what[3].second-what[3].first); - len = strtol(sTmp.c_str(), NULL, 16); - syms[addr+len] = ""; - if(regex_search(sLibFile, what, reg3)) { - stubhex = addr; - } - } - } - else if(regex_search(str, what, reg2)) { - sTmp.assign(what[1].first,what[1].second-what[1].first); - addr = strtol(sTmp.c_str(), NULL, 16); - sTmp.assign(what[2].first,what[2].second-what[2].first); - syms[addr] = (addr == stubhex)? ("stub "+sTmp) : sTmp; - } - } - - map::iterator it = syms.begin(); - map::iterator itp = it++; - string outString; - for(; it != syms.end(); itp = it++) { - if(itp->second != "") { - memset(str,0,sizeof(str)); - sprintf(str,"%08x %04x ",(itp->first-imgText), (it->first-itp->first)); - outString = str; - outString += it->second+"\n"; - iSymbolContentLog.push_back(outString); - } - } - } -} -int CommenSymbolProcessUnit::GetSizeFromBinFile( const string& fileName ){ - TInt ret = 0; - char outbuffer[MAX_LINE]; - ifstream aIf(fileName.c_str(), ios_base::binary); - if( !aIf.is_open() ) { - printf(outbuffer, "Warning: Cannot open file \n"); - iStdoutLog.push_back(outbuffer); - } - else { - E32ImageFile e32Image; - TUint32 aSz; - - aIf.seekg(0,ios_base::end); - aSz = aIf.tellg(); - - e32Image.Adjust(aSz); - e32Image.iFileSize = aSz; - - aIf.seekg(0,ios_base::beg); - aIf >> e32Image; - ret = e32Image.iOrigHdr->iCodeSize; - } - return ret; -} diff -r c3fbb20e86f0 -r 46ca13b54f56 imgtools/romtools/rofsbuild/symbolprocessunit.h --- a/imgtools/romtools/rofsbuild/symbolprocessunit.h Wed Nov 17 16:47:23 2010 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* -* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "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: -* -*/ -#ifndef __SYMBOLPROCESSUNIT_H__ -#define __SYMBOLPROCESSUNIT_H__ -#include -#include -#include -#include -using namespace std; - - -typedef vector stringlist; - -class SymbolProcessUnit -{ -public: - virtual void ProcessExecutableFile(const string& aFile) = 0; - virtual void ProcessDataFile(const string& afile) = 0; - virtual void FlushStdOut(ostream& aOut) = 0; - virtual void FlushSymbolContent(ostream &aOut) = 0; - virtual void ResetContentLog() = 0; - virtual ~SymbolProcessUnit() {} -}; - -class CommenSymbolProcessUnit : public SymbolProcessUnit -{ -public: - virtual void ProcessExecutableFile(const string& aFile); - virtual void ProcessDataFile(const string& afile); - virtual void FlushStdOut(ostream& aOut); - virtual void FlushSymbolContent(ostream &aOut); - virtual void ResetContentLog(); -private: - void ProcessArmv5File( const string& fileName, ifstream& aMap ); - void ProcessGcceOrArm4File( const string& fileName, ifstream& aMap ); - int GetSizeFromBinFile( const string& fileName ); -private: - stringlist iStdoutLog; - stringlist iSymbolContentLog; -}; -#endif diff -r c3fbb20e86f0 -r 46ca13b54f56 imgtools/romtools/rombuild/symbolgenerator.cpp --- a/imgtools/romtools/rombuild/symbolgenerator.cpp Wed Nov 17 16:47:23 2010 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,553 +0,0 @@ -/* -* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "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: -* -*/ - -#include -#include -#include "symbolgenerator.h" -#include "r_rom.h" -#include -#include "h_utl.h" -typedef boost::unique_lock scoped_lock ; -typedef boost::lock_guard guarded_lock ; - -SymbolGenerator::SymbolGenerator(const char* aSymbolFileName, int aMultiThreadsCount/* = 1*/) : -iOutput(aSymbolFileName,ios_base::out |ios_base::binary | ios_base::trunc) { - if(iOutput.is_open()){ - if(aMultiThreadsCount < 1) - aMultiThreadsCount = 1; - - for(int i = 0 ; i < aMultiThreadsCount ; i++){ - iThreads.add_thread(new boost::thread(ThreadFunc,this)); - } - } - else { - cerr << "\nWarning: Can't write data to \""<::iterator i = iErrMsgs.begin() ; i != iErrMsgs.end() ; i++){ - char* msg = *i ; - cerr << msg ; - delete []msg ; - } - iErrMsgs.clear(); -} - -void SymbolGenerator::AddEntry(const SymGenContext& aEntry){ - if(iOutput.is_open()){ - guarded_lock lock(iQueueMutex); - iEntries.push(aEntry); - iCond.notify_all(); - } -} -void SymbolGenerator::ThreadFunc(SymbolGenerator* aInst) { - SymGenContext entry ; - while(1){ - entry.iFileName = 0; - if(1) { - scoped_lock lock(aInst->iQueueMutex); - while(aInst->iEntries.empty()){ - aInst->iCond.wait(lock); - } - entry = aInst->iEntries.front(); - if(0 == entry.iFileName) // end , exit - return ; - - aInst->iEntries.pop(); - } - aInst->ProcessEntry(entry); - } - -} -#define MAX_LINE_LENGTH 65535 -#define SKIP_WS(p) while((*p) == ' ' || (*p) == '\t') (p)++ -#define FIND_WS(p) while((*p) != ' ' && (*p) != '\t' && (*p) != 0) (p)++ -static void split(char* str, vector& result) { - result.clear(); - while(*str) { - SKIP_WS(str); - char* saved = str ; - FIND_WS(str); - bool end = (0 == *str); - *str = 0 ; - if(saved != str) - result.push_back(saved); - if(!end) str ++ ; - } -} -static void make_lower(char* str){ - while(*str){ - if(*str >= 'A' && *str >= 'Z') { - *str += ('a' - 'A'); - } - str++; - } -} -bool SymbolGenerator::ProcessEntry(const SymGenContext& aContext) { - size_t allocBytes ; - if(aContext.iExecutable ) { - string mapFileName(aContext.iFileName); - mapFileName += ".map"; - ifstream ifs(mapFileName.c_str()); - if(!ifs.is_open()){ - int index = mapFileName.length() - 5 ; - int count = 1 ; - while(index > 0 && mapFileName.at(index) != '.'){ - index -- ; - count ++ ; - } - mapFileName.erase(index,count); - ifs.open(mapFileName.c_str()); - } - if(!ifs.is_open()){ - guarded_lock lock(iFileMutex); - allocBytes = mapFileName.length() + 60 ; - char* msg = new char[ allocBytes] ; - snprintf(msg,allocBytes,"\nWarning: Can't open \"%s.map\"\n",aContext.iFileName ); - iErrMsgs.push_back(msg); - msg = new char[allocBytes] ; - int n = snprintf(msg,allocBytes,"%08x %04x %s\r\n",(unsigned int)aContext.iCodeAddress,(unsigned int)aContext.iTotalSize,aContext.iFileName); - iOutput.write(msg,n); - iOutput.flush(); - return false ; - } - if(!ifs.good()) ifs.clear(); - char buffer[100]; - *buffer = 0; - //See if we're dealing with the RVCT output - ifs.getline(buffer,100); - if(!ifs.good()) { - ifs.close(); - guarded_lock lock(iFileMutex); - allocBytes = mapFileName.length() + 60; - char* msg = new char[allocBytes] ; - snprintf(msg,allocBytes,"\nWarning: File \"%s\" is opened yet can not be read!",mapFileName.c_str()); - iErrMsgs.push_back(msg); - return false ; - } - if(strncmp(buffer,"ARM Linker",10) == 0){ - return ProcessARMV5Map(ifs,aContext); - } - // See if we're dealing with the GCC output - else if ( 0 == strncmp(buffer,"Archive member included",23)){ - return ProcessGCCMap(ifs,aContext); - } - else { // Must be x86 output - ifs.seekg(0,ios_base::beg); - return ProcessX86Map(ifs,aContext); - } - } - else { - const char* fileName = aContext.iFileName; - size_t len = strlen(fileName); - size_t index = len - 1; - while(index > 0 && (fileName[index] != '\\' && fileName[index] != '/')) - index -- ; - const char* basename = fileName + index + 1 ; - allocBytes = (len << 1) + 40 ; - char* msg = new char[allocBytes] ; - int n = snprintf(msg,allocBytes,"\r\nFrom %s\r\n\r\n%08x 0000 %s\r\n", fileName ,(unsigned int)aContext.iDataAddress,basename); - guarded_lock lock(iFileMutex); - iOutput.write(msg,n); - iOutput.flush(); - delete []msg ; - return true ; - } - return true ; -} -struct ArmSymbolInfo { - string name ; - TUint size ; - string section ; -}; -typedef multimap ArmSymMap ; - -bool SymbolGenerator::ProcessARMV5Map(ifstream& aStream, const SymGenContext& aContext) { - string symName ; - ArmSymMap symbols ; - vector words ; - ArmSymbolInfo info; - char* lineStart ; - char buffer[MAX_LINE_LENGTH]; - while(aStream.good() && (!aStream.eof())){ - *buffer = 0; - aStream.getline(buffer,MAX_LINE_LENGTH); - lineStart = buffer ; - SKIP_WS(lineStart); - if(strstr(lineStart,"Global Symbols")) - break ; - char* armstamp = strstr(lineStart,"ARM Code"); - if(0 == armstamp) - armstamp = strstr(lineStart,"Thumb Code") ; - if(0 == armstamp) continue ; - *(armstamp - 1) = 0 ; - - char* hexStr = lineStart ; - char* nameEnd; - while(1) { - hexStr = strstr(hexStr,"0x"); - if(0 == hexStr) break ; - nameEnd = hexStr - 1; - if(*nameEnd == ' ' || *nameEnd == '\t') break ; - hexStr += 2 ; - } - if(0 == hexStr) continue ; - while(nameEnd > lineStart && (*nameEnd == ' ' || *nameEnd == '\t')) - nameEnd -- ; - - nameEnd[1] = 0; - info.name = lineStart; - char* temp ; - TUint32 addr = strtoul(hexStr + 2,&temp,16); - char* decStr ; - if(*armstamp == 'A') - decStr = armstamp + 9 ; - else - decStr = armstamp + 11 ; - SKIP_WS(decStr); - info.size = strtoul(decStr,&temp,10); - SKIP_WS(temp); - info.section = temp; - if(info.section.find("(StubCode)") != string::npos ) - info.size = 8 ; - if(addr > 0){ - symbols.insert(pair(addr,info)); - } - } - size_t lenOfFileName = strlen(aContext.iFileName); - while(aStream.good() && (!aStream.eof())){ - *buffer = 0; - aStream.getline(buffer,MAX_LINE_LENGTH); - lineStart = buffer ; - SKIP_WS(lineStart); - char* hexStr = lineStart ; - char* nameEnd; - while(1) { - hexStr = strstr(hexStr,"0x"); - if(0 == hexStr) break ; - nameEnd = hexStr - 1; - if(*nameEnd == ' ' || *nameEnd == '\t') - break ; - hexStr += 2 ; - } - if(0 == hexStr) continue ; - while(nameEnd > lineStart && (*nameEnd == ' ' || *nameEnd == '\t')){ - nameEnd -- ; - } - nameEnd[1] = 0; - info.name = lineStart; - char *temp ; - TUint32 addr = strtoul(hexStr + 2,&temp,16); - while(*temp < '0' || *temp > '9' )//[^\d]* - temp++ ; - char* decStr = temp ; - info.size = strtoul(decStr,&temp,10); - SKIP_WS(temp); - info.section = temp; - if(info.section.find("(StubCode)") != string::npos ) - info.size = 8 ; - if(addr > 0){ - symbols.insert(pair(addr,info)); - } - } - - TUint32 textSectAddr = 0x00008000; // .text gets linked at 0x00008000 - TUint32 dataSectAddr = 0x00400000 ; // .data gets linked at 0x00400000 - vector > lines ; - size_t allocBytes; - for( ArmSymMap::iterator it = symbols.begin(); it != symbols.end() ; it++){ - TUint32 thisAddr = it->first ; - TUint32 romAddr ; - ArmSymbolInfo& info = it->second; - if (thisAddr >= textSectAddr && thisAddr <= (textSectAddr + aContext.iTextSize)) { - romAddr = thisAddr - textSectAddr + aContext.iCodeAddress ; - } - else if ( aContext.iDataAddress && - ( thisAddr >= dataSectAddr && thisAddr <= (dataSectAddr + aContext.iTextSize))) { - romAddr = thisAddr-dataSectAddr + aContext.iDataBssLinearBase; - } - else if ( aContext.iDataBssLinearBase && - ( thisAddr >= dataSectAddr && thisAddr <= (dataSectAddr+ aContext.iTotalDataSize))) { - romAddr = thisAddr - dataSectAddr + aContext.iDataBssLinearBase; - } - else { - guarded_lock lock(iFileMutex); - allocBytes = info.name.length() + 60; - char* msg = new char[allocBytes] ; - snprintf(msg,allocBytes,"\r\nWarning: Symbol %s @ 0x%08x not in text or data segments\r\n", \ - info.name.c_str() ,(unsigned int)thisAddr) ; - iErrMsgs.push_back(msg); - allocBytes = lenOfFileName + 80; - msg = new char[allocBytes]; - snprintf(msg,allocBytes,"Warning: The map file for binary %s is out-of-sync with the binary itself\r\n\r\n",aContext.iFileName); - iErrMsgs.push_back(msg); - continue ; - } - allocBytes = info.section.length() + info.name.length() + 140; - char* outputLine = new char[allocBytes]; - int len = snprintf(outputLine,allocBytes,"%08x %04x %-40s %s\r\n",(unsigned int)romAddr,info.size, - info.name.c_str(),info.section.c_str()); - if((size_t)len > allocBytes) { - allocBytes = len + 4 ; - delete []outputLine; - outputLine = new char[allocBytes]; - len = snprintf(outputLine,allocBytes,"%08x %04x %-40s %s\r\n",(unsigned int)romAddr,info.size, - info.name.c_str(),info.section.c_str()); - } - lines.push_back(pair(len,outputLine)); - - } - guarded_lock lock(iFileMutex); - allocBytes = lenOfFileName + 40; - char* outputLine = new char[allocBytes]; - int n = snprintf(outputLine,allocBytes,"\r\nFrom %s\r\n\r\n",aContext.iFileName); - iOutput.write(outputLine,n); - delete []outputLine ; - for (vector >::iterator i = lines.begin() ; i < lines.end(); i ++ ) { - int len = i->first ; - char* line = i->second; - iOutput.write(line,len); - delete []line ; - } - iOutput.flush(); - return true ; - -} -template -static void put_to_map(M& m,const K& k, const V& v) { - typedef typename M::iterator iterator; - iterator it = m.find(k); - if(m.end() == it){ - m.insert(pair(k,v)); - } - else { - it->second = v ; - } -} -bool SymbolGenerator::ProcessGCCMap(ifstream& aStream, const SymGenContext& aContext){ - char* lineStart; - vector words ; - char buffer[MAX_LINE_LENGTH]; - while(aStream.good() && (!aStream.eof())){ - aStream.getline(buffer,MAX_LINE_LENGTH); - lineStart = buffer ; - SKIP_WS(lineStart); - if( 0 == strncmp(lineStart,".text",5)) { - lineStart += 5; - break ; - } - } - split(lineStart,words); - TUint32 codeAddr , codeSize; - size_t allocBytes ; - if(words.size() != 2 || - KErrNone != Val(codeAddr,words.at(0)) || - KErrNone != Val(codeSize,words.at(1))) { - allocBytes = strlen(aContext.iFileName) + 60; - char* msg = new char[allocBytes]; - snprintf(msg,allocBytes,"\nError: Can't get .text section info for \"%s\"\r\n",aContext.iFileName); - guarded_lock lock(iFileMutex); - iErrMsgs.push_back(msg); - return false ; - } - map symbols ; - TUint32 stubHex = 0; - //Slurp symbols 'til the end of the text section - while(aStream.good() && (!aStream.eof())){ - aStream.getline(buffer,MAX_LINE_LENGTH); - lineStart = buffer ; - SKIP_WS(lineStart); - if(0 == *lineStart) break ; //blank line marks the end of the text section - - // .text - // .text$something - // - // LONG 0x0 - // (/^\s(\.text)?\s+(0x\w+)\s+(0x\w+)\s+(.*)$/io) - if(strncmp(lineStart,".text",5) == 0){ - lineStart += 5 ; - SKIP_WS(lineStart); - } - char* hex1 = NULL ; - char* hex2 = NULL ; - char* strAfterhex1 = NULL ; - TUint32 addr,size ; - if(strncmp(lineStart,"0x",2) == 0){ - hex1 = lineStart + 2; - char* temp ; - addr = strtoul(hex1,&temp,16); - SKIP_WS(temp); - strAfterhex1 = temp ; - if(strncmp(temp,"0x",2) == 0){ - hex2 = temp + 2 ; - } - } - if(NULL != hex2){ - char* libraryfile ; - size = strtoul(hex2,&libraryfile,16); - SKIP_WS(libraryfile); - TUint32 key = addr + size ; - put_to_map(symbols,key,string(""));//impossible symbol as end marker - make_lower(libraryfile); - // EUSER.LIB(ds01423.o) - // EUSER.LIB(C:/TEMP/d1000s_01423.o) - size_t len = strlen(libraryfile); - char* p1 = strstr(libraryfile,".lib("); - if(NULL == p1) - continue ; - p1 += 5; - if(strcmp(libraryfile + len - 3,".o)")!= 0) - continue ; - len -= 3 ; - libraryfile[len] = 0; - if(EFalse == IsValidNumber(libraryfile + len - 5)) - continue ; - len -= 7 ; - if('_' == libraryfile[len]) - len -- ; - if('s' != libraryfile[len]) - continue ; - char* p2 = libraryfile + len - 1; - while(p2 > p1 ) { - if(*p2 < '0' || *p2 > '9') - break ; - p2 -- ; - } - if(*p2 != 'd') - continue ; - stubHex = addr ; - } - else if(NULL != hex1 && NULL != strAfterhex1){ - //# - //(/^\s+(\w+)\s\s+([a-zA-Z_].+)/o) - char* symName = strAfterhex1; - if((*symName >= 'A' && *symName <= 'Z') || - (*symName >= 'a' && *symName <= 'z') || *symName == '_') { - string symbol(symName); - if(addr == stubHex) - symbol.insert(0,"stub "); - - put_to_map(symbols,addr,symbol); - - } - } - } - map::iterator it = symbols.begin(); - TUint32 lastAddr = it->first; - string lastSymName = it->second; - vector >lines ; - it ++ ; - while(it != symbols.end()) { - TUint32 addr = it->first ; - unsigned int fixedupAddr = lastAddr - codeAddr + aContext.iCodeAddress; - TUint size = addr - lastAddr ; - if(!lastSymName.empty()) { - allocBytes = lastSymName.length() + 40; - char* outputLine = new char[allocBytes]; - int n = snprintf(outputLine,allocBytes,"%08x %04x %s\r\n", fixedupAddr,size,lastSymName.c_str()); - lines.push_back(pair(n,outputLine)); - } - lastAddr = addr ; - lastSymName = it->second; - it ++ ; - } - - guarded_lock lock(iFileMutex); - allocBytes = strlen(aContext.iFileName) + 40; - char* outputLine = new char[allocBytes]; - int n = snprintf(outputLine,allocBytes,"\r\nFrom %s\r\n\r\n",aContext.iFileName); - iOutput.write(outputLine,n); - delete []outputLine ; - vector >::iterator i; - for ( i = lines.begin() ; i < lines.end(); i ++ ) { - int len = i->first ; - char* line = i->second ; - iOutput.write(line,len); - delete []line ; - } - iOutput.flush(); - return true ; -} -bool SymbolGenerator::ProcessX86Map(ifstream& aStream, const SymGenContext& aContext) { - char buffer[MAX_LINE_LENGTH]; - char* lineStart; - while(aStream.good() && (!aStream.eof())){ - aStream.getline(buffer,MAX_LINE_LENGTH); - lineStart = buffer ; - SKIP_WS(lineStart); - if( 0 == strncmp(lineStart,"Address",7)) { - break ; - } - } - aStream.getline(buffer,MAX_LINE_LENGTH); - string lastName ; - TUint32 lastAddr = 0; - size_t allocBytes ; - vector >lines ; - while(aStream.good() && (!aStream.eof())){ - aStream.getline(buffer,MAX_LINE_LENGTH); - lineStart = buffer ; - SKIP_WS(lineStart); - if(0 != strncmp(lineStart,"0001:",5)) - break ; - char* end ; - TUint32 addr = strtoul(lineStart + 5,&end,16); - char* name = end + 1; - SKIP_WS(name); - end = name + 1; - FIND_WS(end); - *end = 0 ; - if(!lastName.empty()){ - unsigned int size = addr - lastAddr ; - unsigned int romAddr = lastAddr + aContext.iCodeAddress; - allocBytes = lastName.length() + 40; - char* outputLine = new char[allocBytes]; - int n = snprintf(outputLine,allocBytes,"%08x %04x %s\r\n",romAddr,size,lastName.c_str()); - lines.push_back(pair(n,outputLine)); - } - } - guarded_lock lock(iFileMutex); - allocBytes = strlen(aContext.iFileName) + 40; - char* outputLine = new char[allocBytes]; - int n = snprintf(outputLine,allocBytes,"\r\nFrom %s\r\n\r\n",aContext.iFileName); - iOutput.write(outputLine,n); - delete []outputLine ; - vector >::iterator it; - for ( it = lines.begin() ; it < lines.end(); it ++ ) { - int len = it->first ; - char* line = it->second ; - iOutput.write(line,len); - delete []line ; - } - if(!lastName.empty()){ - allocBytes = lastName.length() + 40 ; - outputLine = new char[allocBytes]; - unsigned int romAddr = lastAddr + aContext.iCodeAddress; - n = snprintf(outputLine,allocBytes,"%08x 0000 %s\r\n",romAddr,lastName.c_str()); - iOutput.write(outputLine,n); - delete []outputLine ; - } - iOutput.flush(); - return false ; -} diff -r c3fbb20e86f0 -r 46ca13b54f56 imgtools/romtools/rombuild/symbolgenerator.h --- a/imgtools/romtools/rombuild/symbolgenerator.h Wed Nov 17 16:47:23 2010 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -/* -* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "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: -* -*/ - -#ifndef __SYMBOLSCREATER_H__ -#define __SYMBOLSCREATER_H__ -#include -#include -#include -#include -#include - -using namespace std; - -#include -#include - -struct SymGenContext { - const char* iFileName ; - TUint32 iTotalSize ; - TUint32 iCodeAddress; - TUint32 iDataAddress; - TUint32 iDataBssLinearBase; - TInt iTextSize; - TInt iDataSize; - TInt iBssSize; - TInt iTotalDataSize; - TBool iExecutable ; -}; - -class SymbolGenerator { -public : - SymbolGenerator(const char* aSymbolFileName, int aMultiThreadsCount = 1); - ~SymbolGenerator(); - void AddEntry(const SymGenContext& aEntry); - void WaitThreads(); -private : - SymbolGenerator(); - SymbolGenerator& operator = (const SymbolGenerator& aRight); - static void ThreadFunc(SymbolGenerator* aInst); - bool ProcessEntry(const SymGenContext& aContext); - bool ProcessARMV5Map(ifstream& aStream, const SymGenContext& aContext); - bool ProcessGCCMap(ifstream& aStream, const SymGenContext& aContext); - bool ProcessX86Map(ifstream& aStream, const SymGenContext& aContext); - ofstream iOutput ; - boost::thread_group iThreads ; - boost::condition_variable iCond; - boost::mutex iQueueMutex; - boost::mutex iFileMutex ; - queue iEntries ; - vector iErrMsgs ; - -}; - -#endif //__ROMSYMBOLGENERATOR_H__