# HG changeset patch # User marvin shi # Date 1289983675 -28800 # Node ID 30aa553e9465c752fc5b796ae9a21641c9e9e9d3 # Parent 46ca13b54f56e2e40dc2ec8544e063ccd2b043c5# Parent 9dfe674c217ce8b40bb6cb24be3ffedf6b4db7d5 features: bsym for rofsbuild and log input support for rombuild diff -r 9dfe674c217c -r 30aa553e9465 imgtools/imglib/compress/byte_pair.cpp --- a/imgtools/imglib/compress/byte_pair.cpp Wed Nov 17 16:16:57 2010 +0800 +++ b/imgtools/imglib/compress/byte_pair.cpp Wed Nov 17 16:47:55 2010 +0800 @@ -636,3 +636,12 @@ memcpy(dst,PakBuffer,compressedSize); return compressedSize; } +TInt BytePairDecompress(TUint8* dst, TUint8* src, TInt size, CBytePair *aBPE) +{ + TUint8 UnpakBuffer[MaxBlockSize]; + ASSERT(size<=MaxBlockSize); + TUint8* pakEnd; + TInt us = aBPE->Decompress(UnpakBuffer,MaxBlockSize,src,size,pakEnd); + memcpy(dst,UnpakBuffer,us); + return us; +} diff -r 9dfe674c217c -r 30aa553e9465 imgtools/imglib/compress/byte_pair.h --- a/imgtools/imglib/compress/byte_pair.h Wed Nov 17 16:16:57 2010 +0800 +++ b/imgtools/imglib/compress/byte_pair.h Wed Nov 17 16:47:55 2010 +0800 @@ -343,6 +343,7 @@ TInt Decompress(TUint8* dst, TInt dstSize, TUint8* src, TInt srcSize, TUint8*& srcNext); }; TInt BytePairCompress(TUint8* dst, TUint8* src, TInt size, CBytePair *aBPE); +TInt BytePairDecompress(TUint8* dst, TUint8* src, TInt size, CBytePair *aBPE); #endif diff -r 9dfe674c217c -r 30aa553e9465 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:55 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 9dfe674c217c -r 30aa553e9465 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:55 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 9dfe674c217c -r 30aa553e9465 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:55 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 9dfe674c217c -r 30aa553e9465 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:55 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 9dfe674c217c -r 30aa553e9465 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:55 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 9dfe674c217c -r 30aa553e9465 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:55 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 9dfe674c217c -r 30aa553e9465 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:55 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 9dfe674c217c -r 30aa553e9465 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:55 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 9dfe674c217c -r 30aa553e9465 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:55 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 9dfe674c217c -r 30aa553e9465 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:55 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 9dfe674c217c -r 30aa553e9465 imgtools/romtools/group/release.txt --- a/imgtools/romtools/group/release.txt Wed Nov 17 16:16:57 2010 +0800 +++ b/imgtools/romtools/group/release.txt Wed Nov 17 16:47:55 2010 +0800 @@ -1,7 +1,13 @@ -Version 2.16.3 (ROFSBUILD) + +Version 2.19.0 (ROMBUILD) =============== -Released by Marvin Shi 17/11/2010 - 1) Fix ou1cimx1#651819 rofsbiuld fails to generate correct log info when using multi-thread +Released by Marvin Shi, 17/11/2010 + 1) feature symbol file generation from log file + +Version 2.17.0 (ROFSBUILD) +=============== +Released by Marvin Shi, 17/11/2010 + 1) feature bsym format symbol file generation for rofsbuild Version 2.16.2 (ROFSBUILD) =============== diff -r 9dfe674c217c -r 30aa553e9465 imgtools/romtools/maksym/maksym.pl --- a/imgtools/romtools/maksym/maksym.pl Wed Nov 17 16:16:57 2010 +0800 +++ b/imgtools/romtools/maksym/maksym.pl Wed Nov 17 16:47:55 2010 +0800 @@ -19,6 +19,7 @@ no strict 'vars'; use English; use FindBin; # for FindBin::Bin +use File::Copy; # Version my $MajorVersion = 1; @@ -47,285 +48,16 @@ # sub main() { - my $file; - my $mapfile; - my $mapfile2; - my $text; - my $data; - my $bss; - my $textsize; - my $datasize; - my $bsssize; - my $totaldatasize; - my $totalsize; - - open (ROM, "<$rombuild") - or die "ERROR: Can't open rombuild log file \"$rombuild\"\n"; - if ($maksym ne "") { - open (SYM, ">$maksym") - or die "ERROR: Can't open output file \"$maksym\"\n"; - print "Creating $maksym...\n"; - } - - while () { - # Start of ROM - if (/^Creating Rom image (\S*)/) { - if ($maksym eq "") { - # For backwards compatibility, replace trailing .img with .symbol - # if no trailing .img, just append .symbol anyway - $maksym = $1; - $maksym =~ s/(\.img)?$/.symbol/i; - close SYM; - open (SYM, ">$maksym") - or die "ERROR: Can't open output file \"$maksym\"\n"; - print "\nCreating $maksym...\n"; - } - next; - } - # end of ROM - if (/^Writing Rom image/) { - close SYM; - $maksym = ""; - next; - } - # Data file - if (/^Reading resource (.*) to rom linear address (.*)/) { - $file = $1; - my $data = hex($2); - $file =~ /([^\\]+)$/; - printf SYM "\nFrom $file\n\n%08x 0000 $1\n", $data; - } - # Executable file - elsif (/^Processing file (.*)/) { - $file = $1; - $text = 0; - $data = 0; - $bss = 0; - $textsize = 0; - $datasize = 0; - $bsssize = 0; - $totaldatasize = 0; - - # Work out final addresses of sections - while (defined($_=) && !/^$/) { - if (/^Size:\s+(\w+)/) { - $totalsize = hex($1); - } elsif (/^Code start addr:\s+(\w+)/) { - $text = hex($1); - } elsif (/^Data start addr:\s+(\w+)/) { - $data = hex($1); - } elsif (/^DataBssLinearBase:\s+(\w+)/) { - $bss = hex($1); - } elsif (/^Text size:\s+(\w+)/) { - $textsize = hex($1); - } elsif (/^Data size:\s+(\w+)/) { - $datasize = hex($1); - } elsif (/^Bsssize:\s+(\w+)/) { - $bsssize = hex($1); - } elsif (/^Total data size:\s+(\w+)/) { - $totaldatasize = hex($1); - } - } - - # Sanity check - text section can't be zero - die "ERROR: Can't find rombuild info for \"$file\"\n" - if (!$text); - - print SYM "\nFrom $file\n\n"; + my $symbolfile = $rombuild; + $symbolfile =~ s/\.log$/\.symbol/i; + my @cmdres = `rombuild -loginput=$rombuild`; + print "@cmdres\n"; - # Look in map file for symbols in .text and relocate them - $mapfile2 = $file.".map"; - $mapfile = $file; - $mapfile =~ s/\.\w+$/\.map/; - if (!(open (MAP, "$mapfile2") || open (MAP, "$mapfile"))) { - print "$file\nWarning: Can't open \"$mapfile2\" or \"$mapfile\"\n"; - $file =~ /([^\\]+)$/; - printf SYM "%08x %04x $1\n", $text, $totalsize; - } else { - local $/ = undef; - my (@maplines) = split(/\n/, ); - close MAP; - # See if we're dealing with the RVCT output - if ($maplines[0] =~ /^ARM Linker/) { - print "$file\n"; - - my %syms; - my @hasharray; - # Starts from begining of map file. - while (@maplines) { - $_ = shift @maplines; - if (/Global Symbols/) { - last; - } elsif (!/(ARM Code|Thumb Code)/) { - next; - } - # name address type size section - if (/^\s*(.+)\s*(0x\S+)\s+(ARM Code|Thumb Code)\s+[^\d]*(\d+)\s+(.*)$/) { - # Check for static methods in local symbols section. - my $sym = $1; - my $addr = hex($2); - my $size = sprintf("%04x",$4); - my $section = $5; - $size = sprintf("%04x", 8) if ($section =~ /\(StubCode\)/); - if(exists($syms{$addr})) { - push @{ $syms{$addr} }, "$size $sym $section"; - } - elsif ($addr > 0){ - @hasharray = "$size $sym $section"; - $syms{$addr} = [@hasharray]; - } - } - } - - foreach (@maplines) { - # name address ignore size section - if (/^\s*(.+)\s*(0x\S+)\s+[^\d]*(\d+)\s+(.*)$/) { - my $sym = $1; - my $addr = hex($2); - my $size = sprintf("%04x",$3); - my $section = $4; - $size = sprintf("%04x", 8) if ($section =~ /\(StubCode\)/); - if(exists($syms{$addr})) { - push @{ $syms{$addr} }, "$size $sym $section"; - } - elsif ($addr > 0) { - @hasharray = "$size $sym $section"; - $syms{$addr} = [@hasharray]; - } - } - } # end of foreach - - # .text gets linked at 0x00008000 - # .data gets linked at 0x00400000 - my $srctext = hex(8000); - my $srcdata = hex(400000); - my $j; - # Write symbols in address order - my @addrs = sort CompareAddrs keys %syms; - for ($i = 0; $i < @addrs ; $i++) { - my $thisaddr = $addrs[$i]; - my $romaddr = 0; - # see if its in the text segment - if ($thisaddr >= $srctext && $thisaddr <= ($srctext+$textsize)) { - $romaddr = $thisaddr-$srctext+$text; - } elsif ( $data && ( $thisaddr >= $srcdata && $thisaddr <= ($srcdata+$datasize))) { - # its in the data segment - # is it from .data or .bss - - # confusingly (?) $bss is the right value to use here - # since we're interested in where the data gets copied to - # in RAM rather than where it sits in ROM - $romaddr = $thisaddr-$srcdata+$bss; - } elsif ( $bss && ( $thisaddr >= $srcdata && $thisaddr <= ($srcdata+$totaldatasize))) { - # its BSS - $romaddr = $thisaddr-$srcdata+$bss; - } else { - my $errsym = $syms{$thisaddr}[0]; - my $erraddr = sprintf("%08x", $thisaddr); - print "WARNING: Symbol $errsym @ $erraddr not in text or data segments\n"; - print "WARNING: The map file for binary $file is out-of-sync with the binary itself\n\n"; - next; - } - - printf SYM "%08x %s\n", $romaddr, $_ for @{$syms{$addrs[$i]}}; - } # end of for. - # See if we're dealing with the GCC output - } elsif ($maplines[0] =~ /^Archive member included/) { - - my $imgtext; - my $textlen; - my %syms; - my $stubhex=1; - - # Find text section - while (@maplines) { - $_ = shift @maplines; - last if /^\.text\s+/; - } - - /^\.text\s+(\w+)\s+(\w+)/ - or die "ERROR: Can't get .text section info for \"$file\"\n"; - - $imgtext=hex($1); - $textlen=hex($2); - - print "$file\n"; - - # Slurp symbols 'til the end of the text section - foreach (@maplines) { - - # blank line marks the end of the text section - last if (/^$/); - - # .text - # .text$something - # - # LONG 0x0 - - if (/^\s(\.text)?\s+(0x\w+)\s+(0x\w+)\s+(.*)$/io) { - my $address = hex($2); - my $length = hex($3); - my $libraryfile = $4; - next if ($libraryfile =~ /^LONG 0x/); - $syms{$address+$length} = ' '; # impossible symbol as end marker - - # EUSER.LIB(ds01423.o) - # EUSER.LIB(C:/TEMP/d1000s_01423.o) - if ($libraryfile =~ /.*lib\(.*d\d*s_?\d{5}.o\)$/io) { - $stubhex=$address; - } - next; - } - - # - if (/^\s+(\w+)\s\s+([a-zA-Z_].+)/o) { - my $addr = hex($1); - my $symbol = $2; - $symbol = "stub $symbol" if ($addr == $stubhex); - $syms{$addr} = $symbol; - next; - } - } - - # Write symbols in address order - @addrs = sort CompareAddrs keys %syms; - for ($i = 0; $i < @addrs - 1; $i++) { - my $symbol = $syms{$addrs[$i]}; - next if ($symbol eq ' '); - printf SYM "%08x %04x %s\n", - $addrs[$i]-$imgtext+$text, $addrs[$i+1]-$addrs[$i], $symbol; - } - # last address assumed to be imgtext+lentext - - close MAP; - } - # Must be x86 output - else { - while (@maplines) { - $_ = shift @maplines; - last if /^ Address/; - } - shift @maplines; - - my ($lastname, $lastaddr); - while (@maplines) { - $_ = shift @maplines; - last unless /^ 0001:(\w+)\s+(\S+)/; - my ($addr, $name) = (hex $1, $2); - if ($lastname) { - my $size = $addr - $lastaddr; - printf SYM "%08x %04x %s\n", $lastaddr + $text, $size, $lastname; - } - ($lastname, $lastaddr) = ($name, $addr); - } - printf SYM "%08x %04x %s\n", $lastaddr + $text, 0, $lastname if $lastname; - } - - } - } - } - close SYM; - close ROM; + if(($maksym ne "") && ($maksym ne $symbolfile)) + { + copy($symbolfile, $maksym); + unlink $symbolfile; + } } # diff -r 9dfe674c217c -r 30aa553e9465 imgtools/romtools/rofsbuild/inc/logging/loggingexception.hpp --- a/imgtools/romtools/rofsbuild/inc/logging/loggingexception.hpp Wed Nov 17 16:16:57 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 9dfe674c217c -r 30aa553e9465 imgtools/romtools/rofsbuild/inc/logging/logparser.hpp --- a/imgtools/romtools/rofsbuild/inc/logging/logparser.hpp Wed Nov 17 16:16:57 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 9dfe674c217c -r 30aa553e9465 imgtools/romtools/rofsbuild/r_build.cpp --- a/imgtools/romtools/rofsbuild/r_build.cpp Wed Nov 17 16:16:57 2010 +0800 +++ b/imgtools/romtools/rofsbuild/r_build.cpp Wed Nov 17 16:47:55 2010 +0800 @@ -59,9 +59,6 @@ #include "cache/cachemanager.hpp" #include "uniconv.hpp" - -#define MAX_LINE 65535 - extern TUint checkSum(const void* aPtr); extern ECompression gCompress; @@ -628,7 +625,7 @@ if(offset > 0xFFFF) { - printf("ERROR: Offset overflow: name=%s, OFFSET = %d\n", node->iName, (unsigned int)offset); + printf("ERROR: Offset overflow: name=%s, OFFSET = %d\n", node->iName, (int)offset); throw "fail"; } @@ -643,7 +640,7 @@ TUint32 offset = ((((TUint8*) entry) - dirBlockBase) >> 2); if(offset > 0xFFFF) { - printf("ERROR: Offset overflow: name=%s, OFFSET = %d\n", node->iName, (unsigned int)offset); + printf("ERROR: Offset overflow: name=%s, OFFSET = %d\n", node->iName, (int)offset); throw "fail"; } @@ -793,18 +790,7 @@ iNextNodeForSameFile = aPreviousNode; } -void TRomNode::FlushLogMessages() -{ - if(iEntry) - { - for(int i=0; i < (int) iEntry->iLogMessages.size(); i++) - { - std::string& log = iEntry->iLogMessages[i]; - Print(ELog, log.c_str()); - } - iEntry->iLogMessages.clear(); - } -} + @@ -877,12 +863,9 @@ TInt TRomBuilderEntry::PlaceFile( TUint8* &aDest,TUint aMaxSize, CBytePair *aBPE ){ - char tmpbuf[MAX_LINE]; TUint compression = 0; TBool executable = iExecutable; - sprintf(tmpbuf,"Reading file %s to image\n", iFileName ); - iLogMessages.push_back(tmpbuf); - + Print(ELog,"Reading file %s to image\n", iFileName ); TUint32 size = HFile::GetLength(iFileName); if (size==0) Print(EWarning, "File %s does not exist or is 0 bytes in length.\n",iFileName); @@ -1087,14 +1070,12 @@ if( newFileComp == 0) { - sprintf(tmpbuf,"Decompressing executable '%s'\n", iFileName); - iLogMessages.push_back(tmpbuf); + Print(ELog,"Decompressing executable '%s'\n", iFileName); f.iHdr->iCompressionType = 0; } else { - sprintf(tmpbuf,"Compressing executable '%s' with method:%08x\n", iFileName, (unsigned int)newFileComp); - iLogMessages.push_back(tmpbuf); + Print(ELog,"Compressing executable '%s' with method:%08x\n", iFileName, newFileComp); f.iHdr->iCompressionType = newFileComp; } f.UpdateHeaderCrc(); @@ -1143,12 +1124,11 @@ compression = atoi(entryref->GetCachedFileCompressionID()); memcpy(&iUids[0], aDest, sizeof(iUids)); if (compression) - sprintf(tmpbuf,"Compressed executable File '%s' size: %08x, mode:%08x\n", iFileName, (unsigned int) size, (unsigned int)compression); + Print(ELog,"Compressed executable File '%s' size: %08x, mode:%08x\n", iFileName, size, compression); else if (iExecutable) - sprintf(tmpbuf,"Executable File '%s' size: %08x\n", iFileName, (unsigned int)size); + Print(ELog,"Executable File '%s' size: %08x\n", iFileName, size); else - sprintf(tmpbuf,"File '%s' size: %08x\n", iFileName, (unsigned int) size); - iLogMessages.push_back(tmpbuf); + Print(ELog,"File '%s' size: %08x\n", iFileName, size); iRealFileSize = size; // required later when directory is written return size; @@ -1226,12 +1206,11 @@ } if (compression) - sprintf(tmpbuf,"Compressed executable File '%s' size: %08x, mode:%08x\n", iFileName, (unsigned int) size, (unsigned int) compression); + Print(ELog,"Compressed executable File '%s' size: %08x, mode:%08x\n", iFileName, size, compression); else if (iExecutable) - sprintf(tmpbuf,"Executable File '%s' size: %08x\n", iFileName, (unsigned int) size); + Print(ELog,"Executable File '%s' size: %08x\n", iFileName, size); else - sprintf(tmpbuf,"File '%s' size: %08x\n", iFileName, (unsigned int) size); - iLogMessages.push_back(tmpbuf); + Print(ELog,"File '%s' size: %08x\n", iFileName, size); iCompressEnabled = compression; iRealFileSize = size; // required later when directory is written @@ -1372,3 +1351,11 @@ } } +char* TRomBuilderEntry::GetSystemFullName() +{ + TBool aIgnoreHiddenAttrib = ETrue; + TInt aLen = iRomNode->FullNameLength(aIgnoreHiddenAttrib); + char *aBuf = new char[aLen+1]; + iRomNode->GetFullName(aBuf, aIgnoreHiddenAttrib); + return aBuf; +} diff -r 9dfe674c217c -r 30aa553e9465 imgtools/romtools/rofsbuild/r_rofs.cpp --- a/imgtools/romtools/rofsbuild/r_rofs.cpp Wed Nov 17 16:16:57 2010 +0800 +++ b/imgtools/romtools/rofsbuild/r_rofs.cpp Wed Nov 17 16:47:55 2010 +0800 @@ -32,6 +32,7 @@ extern TBool gLowMem; extern TInt gThreadNum; extern TBool gGenSymbols; +extern TBool gGenBsymbols; //////////////////////////////////////////////////////////////////////// @@ -49,8 +50,10 @@ // : iObey( aObey ), iOverhead(0) { - if(gGenSymbols) + if(gGenSymbols || gGenBsymbols) { iSymGen = SymbolGenerator::GetInstance(); + iSymGen->SetImageType(ERofsImage); + } else iSymGen = NULL; @@ -263,7 +266,6 @@ } class Worker : public boost::thread { public: - static boost::mutex iOutputMutex; static void thrd_func(E32Rofs* rofs){ CBytePair bpe; @@ -274,9 +276,12 @@ p->len = p->node->PlaceFile(p->buf, (TUint32)-1, 0, &bpe); //no symbol for hidden file if(rofs->iSymGen && !p->node->iEntry->iHidden) - rofs->iSymGen->AddFile(p->node->iEntry->iFileName,(p->node->iEntry->iCompressEnabled|| p->node->iEntry->iExecutable)); - boost::mutex::scoped_lock lock(iOutputMutex); - p->node->FlushLogMessages(); + { + char* fullsystemname= p->node->iEntry->GetSystemFullName(); + TPlacedEntry tmpEntry(p->node->iEntry->iFileName, fullsystemname, (p->node->iEntry->iCompressEnabled|| p->node->iEntry->iExecutable)); + rofs->iSymGen->AddEntry(tmpEntry); + delete[] fullsystemname; + } } p = rofs->GetFileNode(deferred); } @@ -284,9 +289,6 @@ p = rofs->GetDeferredJob(); while(p) { p->len = p->node->PlaceFile(p->buf, (TUint32)-1, 0, &bpe); - iOutputMutex.lock(); - p->node->FlushLogMessages(); - iOutputMutex.unlock(); p = rofs->GetDeferredJob(); } } @@ -294,8 +296,6 @@ } }; -boost::mutex Worker::iOutputMutex; - TPlacingSection* E32Rofs::GetFileNode(bool &aDeferred) { //get a node from the node list, the node list is protected by mutex iMuxTree. //The iMuxTree also helps to make sure the order in iVPS is consistent with the node list. diff -r 9dfe674c217c -r 30aa553e9465 imgtools/romtools/rofsbuild/r_romnode.h --- a/imgtools/romtools/rofsbuild/r_romnode.h Wed Nov 17 16:16:57 2010 +0800 +++ b/imgtools/romtools/rofsbuild/r_romnode.h Wed Nov 17 16:47:55 2010 +0800 @@ -20,8 +20,6 @@ #define __R_ROMNODE_H__ #include -#include -#include #include #include "rofs.h" #include "e32image.h" @@ -125,8 +123,7 @@ TInt GetFullName(char* aBuf, TBool aIgnoreHiddenAttrib = EFalse) const; static void InitializeCount(); // Accessor Function. - inline TRomNode* GetParent() const { return iParent; } - void FlushLogMessages(); + inline TRomNode* GetParent() const { return iParent; } private: void Remove(TRomNode* aChild); @@ -202,6 +199,7 @@ inline TInt RealFileSize() const { return iRealFileSize; }; inline void SetRealFileSize(TInt aFileSize) { iRealFileSize=aFileSize;}; void DisplaySize(TPrintType aWhere); + char* GetSystemFullName(); private: TRomBuilderEntry(); @@ -212,7 +210,6 @@ public: char *iName; char *iFileName; - std::vector iLogMessages; TRomBuilderEntry* iNext; TRomBuilderEntry* iNextInArea; diff -r 9dfe674c217c -r 30aa553e9465 imgtools/romtools/rofsbuild/rofsbuild.cpp --- a/imgtools/romtools/rofsbuild/rofsbuild.cpp Wed Nov 17 16:16:57 2010 +0800 +++ b/imgtools/romtools/rofsbuild/rofsbuild.cpp Wed Nov 17 16:47:55 2010 +0800 @@ -34,8 +34,7 @@ #include "cache/cachevalidator.hpp" #include "cache/cacheablelist.hpp" #include "cache/cachemanager.hpp" -#include "logging/loggingexception.hpp" -#include "logging/logparser.hpp" +#include "logparser.h" #include #ifndef WIN32 @@ -48,8 +47,8 @@ #endif static const TInt RofsbuildMajorVersion=2; -static const TInt RofsbuildMinorVersion=16; -static const TInt RofsbuildPatchVersion=3; +static const TInt RofsbuildMinorVersion=17; +static const TInt RofsbuildPatchVersion=0; static TBool SizeSummary=EFalse; static TPrintType SizeWhere=EAlways; @@ -61,6 +60,7 @@ TInt gThreadNum = 0; TInt gCPUNum = 0; TBool gGenSymbols = EFalse; +TBool gGenBsymbols = EFalse; TInt gCodePagingOverride = -1; TInt gDataPagingOverride = -1; TInt gLogLevel = 0; // Information is logged based on logging level. @@ -101,6 +101,7 @@ " -compress compress executable files where possible\n" " -j do the main job with threads\n" " -symbols generate symbol file\n" + " -bsymbols generate binary symbol file\n" " -compressionmethod none|inflate|bytepair to set the compression\n" " none uncompress the image.\n" " inflate compress the image.\n" @@ -172,6 +173,9 @@ }else if (stricmp(argv[i], "-SYMBOLS") == 0) { gGenSymbols = ETrue; } + else if (stricmp(argv[i], "-BSYMBOLS") == 0 ) { + gGenBsymbols = ETrue; + } else if (((argv[i][1] | 0x20) == 's') && (((argv[i][2]| 0x20) == 'l')||((argv[i][2] | 0x20) == 's'))) { SizeSummary = ETrue; @@ -353,6 +357,11 @@ if (paramFileFlag) return; + if(gGenSymbols && gGenBsymbols) + { + Print(EWarning, "Options symbols and bsymbols cannot be used at the same time, the common symbols file will be created this time!\n"); + gGenBsymbols = EFalse; + } if((gDriveImage == EFalse) && (gSmrImage == EFalse) && (filename.empty() || (gUseCoreImage && gImageFilename.length() == 0)) && (loginput.length() == 0)){ @@ -496,11 +505,11 @@ processCommandLine(argc, argv); if(gThreadNum == 0) { if(gCPUNum > 0) { - printf("WARNING: The number of processors (%d) is used as the number of concurrent jobs.\n", gCPUNum); - gThreadNum = gCPUNum; + printf("The double number of processors (%d) is used as the number of concurrent jobs.\n", gCPUNum * 2); + gThreadNum = gCPUNum * 2; } else { - printf("WARNING: Can't automatically get the valid number of concurrent jobs and %d is used.\n", DEFAULT_THREADS); + printf("Can't automatically get the valid number of concurrent jobs and %d is used.\n", DEFAULT_THREADS); gThreadNum = DEFAULT_THREADS; } } @@ -508,7 +517,7 @@ { try { - LogParser::GetInstance()->ParseSymbol(loginput.c_str()); + LogParser::GetInstance(ERofsImage)->ParseSymbol(loginput.c_str()); } catch(LoggingException le) { diff -r 9dfe674c217c -r 30aa553e9465 imgtools/romtools/rofsbuild/rofsbuild.mmp --- a/imgtools/romtools/rofsbuild/rofsbuild.mmp Wed Nov 17 16:16:57 2010 +0800 +++ b/imgtools/romtools/rofsbuild/rofsbuild.mmp Wed Nov 17 16:47:55 2010 +0800 @@ -23,15 +23,15 @@ // rofsbuild SOURCEPATH ../rofsbuild SOURCE r_obey.cpp r_build.cpp r_rofs.cpp r_driveimage.cpp r_driveutl.cpp -SOURCE rofsbuild.cpp r_coreimage.cpp r_smrimage.cpp symbolgenerator.cpp +SOURCE rofsbuild.cpp r_coreimage.cpp r_smrimage.cpp SOURCE fatcluster.cpp fsnode.cpp fatimagegenerator.cpp -SOURCE symbolprocessunit.cpp +SOURCEPATH ../../imglib/symbolutil +SOURCE symbolprocessunit.cpp bsymutil.cpp loggingexception.cpp logparser.cpp +SOURCE symbolgenerator.cpp SOURCEPATH ../../imglib/host SOURCE h_utl.cpp h_file.cpp h_mem.cpp utf16string.cpp SOURCEPATH ../rofsbuild/src/cache SOURCE cachemanager.cpp cacheexception.cpp cache.cpp cacheablelist.cpp cachevalidator.cpp cachegenerator.cpp cacheentry.cpp -SOURCEPATH ../rofsbuild/src/logging -SOURCE loggingexception.cpp logparser.cpp // executable compression SOURCEPATH ../../imglib/e32uid @@ -46,7 +46,7 @@ OS_LAYER_SYSTEMINCLUDE_SYMBIAN -USERINCLUDE ../../imglib/inc ../../imglib/compress +USERINCLUDE ../../imglib/inc ../../imglib/compress ../../imglib/symbolutil USERINCLUDE ../../imglib/patchdataprocessor/include ../../imglib/parameterfileprocessor/include USERINCLUDE ../../imglib/memmap/include USERINCLUDE ../../imglib/uniconv/include diff -r 9dfe674c217c -r 30aa553e9465 imgtools/romtools/rofsbuild/src/logging/loggingexception.cpp --- a/imgtools/romtools/rofsbuild/src/logging/loggingexception.cpp Wed Nov 17 16:16:57 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 9dfe674c217c -r 30aa553e9465 imgtools/romtools/rofsbuild/src/logging/logparser.cpp --- a/imgtools/romtools/rofsbuild/src/logging/logparser.cpp Wed Nov 17 16:16:57 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 9dfe674c217c -r 30aa553e9465 imgtools/romtools/rofsbuild/symbolgenerator.cpp --- a/imgtools/romtools/rofsbuild/symbolgenerator.cpp Wed Nov 17 16:16:57 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 9dfe674c217c -r 30aa553e9465 imgtools/romtools/rofsbuild/symbolgenerator.h --- a/imgtools/romtools/rofsbuild/symbolgenerator.h Wed Nov 17 16:16:57 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 9dfe674c217c -r 30aa553e9465 imgtools/romtools/rofsbuild/symbolprocessunit.cpp --- a/imgtools/romtools/rofsbuild/symbolprocessunit.cpp Wed Nov 17 16:16:57 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 9dfe674c217c -r 30aa553e9465 imgtools/romtools/rofsbuild/symbolprocessunit.h --- a/imgtools/romtools/rofsbuild/symbolprocessunit.h Wed Nov 17 16:16:57 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 9dfe674c217c -r 30aa553e9465 imgtools/romtools/rombuild/r_mromimage.h --- a/imgtools/romtools/rombuild/r_mromimage.h Wed Nov 17 16:16:57 2010 +0800 +++ b/imgtools/romtools/rombuild/r_mromimage.h Wed Nov 17 16:47:55 2010 +0800 @@ -44,9 +44,7 @@ virtual TUint32 DataRunAddress() const = 0 ; virtual TUint32 RomAlign() const = 0 ; -#ifdef __LINUX__ virtual ~MRomImage() { }; -#endif }; #endif //__R_MROMIMAGE_H__ diff -r 9dfe674c217c -r 30aa553e9465 imgtools/romtools/rombuild/r_rom.cpp --- a/imgtools/romtools/rombuild/r_rom.cpp Wed Nov 17 16:16:57 2010 +0800 +++ b/imgtools/romtools/rombuild/r_rom.cpp Wed Nov 17 16:47:55 2010 +0800 @@ -399,7 +399,7 @@ E32Rom::~E32Rom() { if(iSymGen){ - delete iSymGen; + SymbolGenerator::Release(); iSymGen = NULL ; } if(gLowMem) @@ -699,8 +699,6 @@ if (r!=KErrNone) { Print(EError, "LoadContents failed - return code %d\n", r); - if(iSymGen) - iSymGen->WaitThreads(); return r; } iExtensionRomHeader->iRomRootDirectoryList = dummy.iRomRootDirectoryList; @@ -708,8 +706,6 @@ iLoaderHeader->SetUp(iObey); FinaliseExtensionHeader(aKernelRom); DisplayExtensionHeader(); - if(iSymGen) - iSymGen->WaitThreads(); return KErrNone; } @@ -740,8 +736,6 @@ if (r!=KErrNone) { Print(EError, "LoadContents failed - return code %d\n", r); - if(iSymGen) - iSymGen->WaitThreads(); return r; } @@ -749,16 +743,12 @@ if(r!=KErrNone) { Print(EError, "Setup pages information failed - return code %d\n", r); - if(iSymGen) - iSymGen->WaitThreads(); return r; } r = CheckUnpagedMemSize(); // check for unpaged memory overflow if(r!=KErrNone) { - if(iSymGen) - iSymGen->WaitThreads(); return r; } @@ -766,8 +756,6 @@ if(r!=KErrNone) { Print(EError, "CompressPages failed - return code %d\n", r); - if(iSymGen) - iSymGen->WaitThreads(); return r; } @@ -795,8 +783,6 @@ TUint testCheckSum = HMem::CheckSum((TUint *)iHeader, iHeader->iRomSize); Print(ELog, "Rom 32bit words sum to %08x\n", testCheckSum); if (testCheckSum != iObey->iCheckSum){ - if(iSymGen) - iSymGen->WaitThreads(); return Print(EError, "Rom checksum is incorrect: %08x should be %08x\n", testCheckSum, iObey->iCheckSum); } @@ -836,8 +822,6 @@ } } } - if(iSymGen) - iSymGen->WaitThreads(); return KErrNone; } @@ -1325,9 +1309,9 @@ TInt fileCount=0; if(gGenSymbols && !iSymGen) { string filename(iObey->GetFileName()); - filename.erase(filename.length() - 3,3); - filename.append("symbol"); - iSymGen = new SymbolGenerator(filename.c_str(),gThreadNum - 1); + iSymGen = SymbolGenerator::GetInstance(); + iSymGen ->SetImageType(ERomImage); + iSymGen ->SetSymbolFileName(filename); } // @@ -1399,9 +1383,7 @@ mainptr->Extend(offset); iOverhead +=offset; if(iSymGen){ - SymGenContext context ; - memset(&context,0,sizeof(SymGenContext)); - iSymGen->AddEntry(context); + iSymGen->SetFinished(); } return (char*)mainptr->iImagePtr; } @@ -1454,8 +1436,7 @@ return; // first section has overflowed current->FixupRomEntries(size); if(iSymGen) { - SymGenContext context ; - memset(&context,0,sizeof(SymGenContext)); + TPlacedEntry context ; context.iFileName = current->iFileName ; context.iDataAddress = savedAddr ; iSymGen->AddEntry(context); @@ -1470,8 +1451,7 @@ iHeader->iHcrFileAddress = current->iHeaderRange.iImageAddr ; TRACE(TAREA, Print(ELog, "iHeader->iHcrFileAddress = %08x\n", iHeader->iHcrFileAddress)); if(iSymGen) { - SymGenContext context ; - memset(&context,0,sizeof(SymGenContext)); + TPlacedEntry context ; context.iFileName = current->iFileName ; context.iDataAddress = savedAddr ; iSymGen->AddEntry(context); @@ -1535,7 +1515,7 @@ LoadFileToRom(current); TRomImageHeader *header = current->iRomImageHeader; if(iSymGen){ - SymGenContext context ; + TPlacedEntry context ; context.iFileName = current->iFileName ; context.iTotalSize = section1size; context.iCodeAddress = header->iCodeAddress; diff -r 9dfe674c217c -r 30aa553e9465 imgtools/romtools/rombuild/rombuild.cpp --- a/imgtools/romtools/rombuild/rombuild.cpp Wed Nov 17 16:16:57 2010 +0800 +++ b/imgtools/romtools/rombuild/rombuild.cpp Wed Nov 17 16:47:55 2010 +0800 @@ -26,14 +26,15 @@ #include "r_dir.h" #include "r_coreimage.h" +#include "logparser.h" const TInt KRomLoaderHeaderNone=0; const TInt KRomLoaderHeaderEPOC=1; const TInt KRomLoaderHeaderCOFF=2; static const TInt RombuildMajorVersion=2; -static const TInt RombuildMinorVersion=18; -static const TInt RombuildPatchVersion=4; +static const TInt RombuildMinorVersion=19; +static const TInt RombuildPatchVersion=0; static TBool SizeSummary=EFalse; static TPrintType SizeWhere=EAlways; static string compareROMName = ""; @@ -49,11 +50,13 @@ TBool gGenDepGraph = EFalse; string gDepInfoFile = ""; TBool gGenSymbols = EFalse ; +TBool gGenBsymbols = EFalse ; TBool gIsOBYUTF8 = EFalse; +static string loginput = ""; void PrintVersion() { - Print(EAlways,"\nROMBUILD - Rom builder"); - Print(EAlways, " V%d.%d.%d\n", RombuildMajorVersion, RombuildMinorVersion, RombuildPatchVersion); - Print(EAlways,Copyright); + printf("\nROMBUILD - Rom builder"); + printf(" V%d.%d.%d\n", RombuildMajorVersion, RombuildMinorVersion, RombuildPatchVersion); + printf(Copyright); } char HelpText[] = @@ -82,7 +85,8 @@ " -lowmem use memory-mapped file for image build to reduce physical memory consumption\n" " -coreimage= to pass the core image as input for extension ROM image generation\n" " -k to enable keepgoing when duplicate files exist in oby\n" - " -logfile= specify log file\n"; + " -logfile= specify log file\n" + " -loginput= specify as input a log file and produce as output symbol file.\n"; char ReallyHelpText[] = @@ -349,6 +353,9 @@ else if (strnicmp(arg, "logfile=",8) ==0) { romlogfile = arg + 8; } + else if (strnicmp(arg, "loginput=",9) ==0) { + loginput = arg + 9; + } else #ifdef WIN32 cout << "Unrecognised option " << argv[i] << "\n"; @@ -366,7 +373,7 @@ } if (paramFileFlag) return; - if (filename.empty()) { + if (filename.empty() && loginput.empty()) { PrintVersion(); cout << HelpText; if (reallyHelp) { @@ -450,29 +457,42 @@ ParseCapabilitiesArg(gPlatSecAllCaps, "all"); processCommandLine(argc, argv); - if(filename.empty()) + if(filename.empty() && loginput.empty()) return KErrGeneral; - if (romlogfile[romlogfile.size()-1] == '\\' || romlogfile[romlogfile.size()-1] == '/') - romlogfile += "ROMBUILD.LOG"; - H.SetLogFile(romlogfile.c_str()); if(gThreadNum == 0) { if(gCPUNum > 0 && gCPUNum <= MAXIMUM_THREADS) { - Print(EAlways, "The number of processors (%d) is used as the number of concurrent jobs.\n", gCPUNum); - gThreadNum = gCPUNum; + printf("The double number of processors (%d) is used as the number of concurrent jobs.\n", gCPUNum * 2); + gThreadNum = gCPUNum * 2; } else if(g_pCharCPUNum) { - Print(EWarning, "The NUMBER_OF_PROCESSORS is invalid, and the default value %d will be used.\n", DEFAULT_THREADS); + printf("The NUMBER_OF_PROCESSORS is invalid, and the default value %d will be used.\n", DEFAULT_THREADS); gThreadNum = DEFAULT_THREADS; } else { - Print(EWarning, "The NUMBER_OF_PROCESSORS is not available, and the default value %d will be used.\n", DEFAULT_THREADS); + printf("The NUMBER_OF_PROCESSORS is not available, and the default value %d will be used.\n", DEFAULT_THREADS); gThreadNum = DEFAULT_THREADS; } } PrintVersion(); + if(loginput.length() >= 1) + { + try + { + LogParser::GetInstance(ERomImage)->ParseSymbol(loginput.c_str()); + } + catch(LoggingException le) + { + printf("ERROR: %s\r\n", le.GetErrorMessage()); + return 1; + } + return 0; + } + if (romlogfile[romlogfile.size()-1] == '\\' || romlogfile[romlogfile.size()-1] == '/') + romlogfile += "ROMBUILD.LOG"; + H.SetLogFile(romlogfile.c_str()); ObeyFileReader *reader=new ObeyFileReader(filename.c_str()); if (!reader->Open()) { delete reader; diff -r 9dfe674c217c -r 30aa553e9465 imgtools/romtools/rombuild/rombuild.mmp --- a/imgtools/romtools/rombuild/rombuild.mmp Wed Nov 17 16:16:57 2010 +0800 +++ b/imgtools/romtools/rombuild/rombuild.mmp Wed Nov 17 16:47:55 2010 +0800 @@ -24,7 +24,10 @@ source r_dir.cpp r_header.cpp r_obey.cpp r_srec.cpp source r_rom.cpp rombuild.cpp r_build.cpp r_collapse.cpp source r_global.cpp r_areaset.cpp -source r_coreimage.cpp r_coreimagereader.cpp symbolgenerator.cpp +source r_coreimage.cpp r_coreimagereader.cpp +sourcepath ../../imglib/symbolutil +source symbolgenerator.cpp symbolprocessunit.cpp bsymutil.cpp +source loggingexception.cpp logparser.cpp sourcepath ../../imglib/e32uid source e32uid.cpp sourcepath ../../imglib/host @@ -38,7 +41,7 @@ source byte_pair.cpp source pagedcompress.cpp -userinclude ../../imglib/compress ../../imglib/inc +userinclude ../../imglib/compress ../../imglib/inc ../../imglib/symbolutil userinclude ../../imglib/patchdataprocessor/include ../../imglib/parameterfileprocessor/include userinclude ../../imglib/uniconv/include userinclude ../../imglib/memmap/include @@ -46,7 +49,7 @@ OS_LAYER_SYSTEMINCLUDE_SYMBIAN -staticlibrary patchdataprocessor parameterfileprocessor memmap boost_thread-1.39 uniconv +staticlibrary patchdataprocessor parameterfileprocessor memmap boost_thread-1.39 boost_regex-1.39 uniconv #ifdef TOOLS2_LINUX OPTION GCC -O2 -Wno-uninitialized -pthread diff -r 9dfe674c217c -r 30aa553e9465 imgtools/romtools/rombuild/symbolgenerator.cpp --- a/imgtools/romtools/rombuild/symbolgenerator.cpp Wed Nov 17 16:16:57 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 9dfe674c217c -r 30aa553e9465 imgtools/romtools/rombuild/symbolgenerator.h --- a/imgtools/romtools/rombuild/symbolgenerator.h Wed Nov 17 16:16:57 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__