--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/imglib/symbolutil/bsymutil.cpp Wed Nov 17 16:47:32 2010 +0800
@@ -0,0 +1,120 @@
+/*
+* Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include "bsymutil.h"
+#include <stdio.h>
+
+
+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;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/imglib/symbolutil/bsymutil.h Wed Nov 17 16:47:32 2010 +0800
@@ -0,0 +1,172 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef __BSYMUTIL_H__
+#define __BSYMUTIL_H__
+
+#include <e32std.h>
+#include <vector>
+#include <string>
+
+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<TDbgUnitPCEntry> TDbgUnitEntrySet;
+typedef vector<TSymbolPCEntry> TSymbolPCEntrySet;
+typedef vector<string> StringList;
+
+struct MapFileInfo
+{
+ TDbgUnitPCEntry iDbgUnitPCEntry;
+ TSymbolPCEntrySet iSymbolPCEntrySet;
+};
+
+typedef vector<MapFileInfo> 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/imglib/symbolutil/loggingexception.cpp Wed Nov 17 16:47:32 2010 +0800
@@ -0,0 +1,60 @@
+/*
+* Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include "loggingexception.h"
+
+
+int LoggingException::RESOURCE_ALLOCATION_FAILURE = 1;
+int LoggingException::INVALID_LOG_FILENAME = 2;
+int LoggingException::UNKNOWN_IMAGE_TYPE = 3;
+
+
+LoggingException::LoggingException(int ErrorCode)
+{
+ this->errcode = ErrorCode;
+
+ return;
+}
+
+
+int LoggingException::GetErrorCode(void)
+{
+ return this->errcode;
+}
+
+
+const char* LoggingException::GetErrorMessage(void)
+{
+ if(this->errcode == LoggingException::RESOURCE_ALLOCATION_FAILURE)
+ return "Not enough system resources to initialize logging module.";
+ else if(this->errcode == LoggingException::INVALID_LOG_FILENAME)
+ return "Invalid log filename as input.";
+ else if(this->errcode == LoggingException::UNKNOWN_IMAGE_TYPE)
+ return "the image type not supported.";
+// else if(this->errcode == CacheException::CACHE_IS_EMPTY)
+// return "Cache is empty.";
+// else if(this->errcode == CacheException::HARDDRIVE_FAILURE)
+// return "A hard drive failure occurred in Cache operations.";
+
+ return "Undefined error type.";
+}
+
+
+LoggingException::~LoggingException(void)
+{
+ return;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/imglib/symbolutil/loggingexception.h Wed Nov 17 16:47:32 2010 +0800
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef ROM_TOOLS_ROFSBUILD_LOGGING_LOGGINGEXCEPTION_H_
+#define ROM_TOOLS_ROFSBUILD_LOGGING_LOGGINGEXCEPTION_H_
+
+
+/*
+ * @class LoggingException
+ */
+class LoggingException
+{
+public:
+ LoggingException(int ErrorCode);
+
+ int GetErrorCode(void);
+
+ const char* GetErrorMessage(void);
+
+ static int RESOURCE_ALLOCATION_FAILURE;
+ static int INVALID_LOG_FILENAME ;
+ static int UNKNOWN_IMAGE_TYPE ;
+
+ virtual ~LoggingException(void);
+protected:
+ int errcode;
+private:
+ LoggingException(void);
+
+ LoggingException& operator = (const LoggingException&);
+};
+
+
+#endif /* defined ROM_TOOLS_ROFSBUILD_LOGGING_LOGGINGEXCEPTION_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/imglib/symbolutil/logparser.cpp Wed Nov 17 16:47:32 2010 +0800
@@ -0,0 +1,218 @@
+/*
+* Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <new>
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <boost/regex.hpp>
+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);
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/imglib/symbolutil/logparser.h Wed Nov 17 16:47:32 2010 +0800
@@ -0,0 +1,63 @@
+/*
+* Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef ROM_TOOLS_ROFSBUILD_LOGGING_LOGPARSER_H_
+#define ROM_TOOLS_ROFSBUILD_LOGGING_LOGPARSER_H_
+
+#include "loggingexception.h"
+#include "symbolgenerator.h"
+
+/**
+ * @class LogParser
+ */
+class LogParser
+{
+public:
+ static LogParser* GetInstance(TImageType aImageType) throw (LoggingException);
+
+ virtual void ParseSymbol(const char* LogFilename) throw (LoggingException) = 0;
+
+ void Cleanup(void);
+ virtual ~LogParser() {}
+protected:
+ LogParser(void);
+ static LogParser* Only;
+ TImageType iImageType;
+private:
+ LogParser(const LogParser&);
+
+ LogParser& operator = (const LogParser&);
+};
+
+class RofsLogParser : public LogParser
+{
+public:
+ virtual void ParseSymbol(const char* LogFilename) throw (LoggingException);
+ RofsLogParser(void);
+};
+
+class RomLogParser : public LogParser
+{
+public:
+ virtual void ParseSymbol(const char* LogFilename) throw (LoggingException);
+ RomLogParser(void);
+};
+
+
+
+#endif /* defined ROM_TOOLS_ROFSBUILD_LOGGING_LOGPARSER_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/imglib/symbolutil/symbolgenerator.cpp Wed Nov 17 16:47:32 2010 +0800
@@ -0,0 +1,384 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <vector>
+#include <boost/regex.hpp>
+#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;
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/imglib/symbolutil/symbolgenerator.h Wed Nov 17 16:47:32 2010 +0800
@@ -0,0 +1,94 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef __SYMBOLGENERATOR_H__
+#define __SYMBOLGENERATOR_H__
+#include <queue>
+#include <string>
+#include <fstream>
+using namespace std;
+#include <boost/thread/thread.hpp>
+#include <boost/thread/condition.hpp>
+#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<TPlacedEntry> 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/imglib/symbolutil/symbolprocessunit.cpp Wed Nov 17 16:47:32 2010 +0800
@@ -0,0 +1,997 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+#include <boost/regex.hpp>
+#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<TUint32,ArmSymbolInfo> 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<char*>& 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<char*> 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<TUint32,ArmSymbolInfo>(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<TUint32,ArmSymbolInfo>(addr,info));
+ }
+ }
+
+ TUint32 textSectAddr = 0x00008000; // .text gets linked at 0x00008000
+ TUint32 dataSectAddr = 0x00400000 ; // .data gets linked at 0x00400000
+ vector<pair<int,char*> > 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<int,char*>(len,outputLine));
+
+ }
+
+ for (vector<pair<int,char*> >::iterator i = lines.begin() ; i < lines.end(); i ++ ) {
+ char* line = i->second;
+ iSymbolContentLog.push_back(line);
+ delete[] line;
+ }
+}
+
+template<typename M, typename K,typename V>
+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>(k,v));
+ }
+ else {
+ it->second = v ;
+ }
+}
+
+void CommenRomSymbolProcessUnit::ProcessGcceOrArm4File(const string& aFile, ifstream& aMap)
+{
+ char* lineStart;
+ vector<char*> 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<TUint32,string> 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 <addr> <len> <library(member)>
+ // .text$something
+ // <addr> <len> <library(member)>
+ // <addr> <len> 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){
+ //# <addr> <symbol name possibly including spaces>
+ //(/^\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<TUint32,string>::iterator it = symbols.begin();
+ TUint32 lastAddr = it->first;
+ string lastSymName = it->second;
+ vector<pair<int,char*> >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<int,char*>(n,outputLine));
+ }
+ lastAddr = addr ;
+ lastSymName = it->second;
+ it ++ ;
+ }
+
+ vector<pair<int,char*> >::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<pair<int, char*> >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<int, char*>(n,outputLine));
+ }
+ }
+
+ vector<pair<int,char*> >::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<unsigned int,string> 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<unsigned int,string>::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<unsigned int,string> 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<unsigned int,string>::iterator it = syms.begin();
+ map<unsigned int,string>::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<unsigned int, TSymbolPCEntry> 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<unsigned int, TSymbolPCEntry>::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<unsigned int,string> 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<unsigned int,string>::iterator it = syms.begin();
+ map<unsigned int,string>::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);
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/imglib/symbolutil/symbolprocessunit.h Wed Nov 17 16:47:32 2010 +0800
@@ -0,0 +1,120 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+#ifndef __SYMBOLPROCESSUNIT_H__
+#define __SYMBOLPROCESSUNIT_H__
+#include <vector>
+#include <string>
+#include <iostream>
+#include <fstream>
+
+#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<string> 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
--- a/imgtools/romtools/rofsbuild/inc/logging/loggingexception.hpp Wed Nov 17 16:47:23 2010 +0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
-* Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the License "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:
-*
-*/
-
-
-#ifndef ROM_TOOLS_ROFSBUILD_LOGGING_LOGGINGEXCEPTION_H_
-#define ROM_TOOLS_ROFSBUILD_LOGGING_LOGGINGEXCEPTION_H_
-
-
-/*
- * @class LoggingException
- */
-class LoggingException
-{
-public:
- LoggingException(int ErrorCode);
-
- int GetErrorCode(void);
-
- const char* GetErrorMessage(void);
-
- static int RESOURCE_ALLOCATION_FAILURE;
- static int INVALID_LOG_FILENAME ;
-
- virtual ~LoggingException(void);
-protected:
- int errcode;
-private:
- LoggingException(void);
-
- LoggingException& operator = (const LoggingException&);
-};
-
-
-#endif /* defined ROM_TOOLS_ROFSBUILD_LOGGING_LOGGINGEXCEPTION_H_ */
--- a/imgtools/romtools/rofsbuild/inc/logging/logparser.hpp Wed Nov 17 16:47:23 2010 +0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
-* Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the License "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:
-*
-*/
-
-
-#ifndef ROM_TOOLS_ROFSBUILD_LOGGING_LOGPARSER_H_
-#define ROM_TOOLS_ROFSBUILD_LOGGING_LOGPARSER_H_
-
-
-/**
- * @class LogParser
- */
-class LogParser
-{
-public:
- static LogParser* GetInstance(void) throw (LoggingException);
-
- void ParseSymbol(const char* LogFilename) throw (LoggingException);
-
- void Cleanup(void);
-protected:
- static LogParser* Only;
-private:
- LogParser(void);
-
- LogParser(const LogParser&);
-
- LogParser& operator = (const LogParser&);
-};
-
-
-
-#endif /* defined ROM_TOOLS_ROFSBUILD_LOGGING_LOGPARSER_H_ */
--- a/imgtools/romtools/rofsbuild/src/logging/loggingexception.cpp Wed Nov 17 16:47:23 2010 +0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
-* Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the License "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:
-*
-*/
-
-#include "logging/loggingexception.hpp"
-
-
-int LoggingException::RESOURCE_ALLOCATION_FAILURE = 1;
-int LoggingException::INVALID_LOG_FILENAME = 2;
-
-
-LoggingException::LoggingException(int ErrorCode)
-{
- this->errcode = ErrorCode;
-
- return;
-}
-
-
-int LoggingException::GetErrorCode(void)
-{
- return this->errcode;
-}
-
-
-const char* LoggingException::GetErrorMessage(void)
-{
- if(this->errcode == LoggingException::RESOURCE_ALLOCATION_FAILURE)
- return "Not enough system resources to initialize logging module.";
- else if(this->errcode == LoggingException::INVALID_LOG_FILENAME)
- return "Invalid log filename as input.";
-// else if(this->errcode == CacheException::CACHE_INVALID)
-// return "Cache is invalid.";
-// else if(this->errcode == CacheException::CACHE_IS_EMPTY)
-// return "Cache is empty.";
-// else if(this->errcode == CacheException::HARDDRIVE_FAILURE)
-// return "A hard drive failure occurred in Cache operations.";
-
- return "Undefined error type.";
-}
-
-
-LoggingException::~LoggingException(void)
-{
- return;
-}
--- a/imgtools/romtools/rofsbuild/src/logging/logparser.cpp Wed Nov 17 16:47:23 2010 +0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,116 +0,0 @@
-/*
-* Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the License "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:
-*
-*/
-
-
-#include <new>
-#include <iostream>
-#include <fstream>
-#include <string>
-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;
-}
--- a/imgtools/romtools/rofsbuild/symbolgenerator.cpp Wed Nov 17 16:47:23 2010 +0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
-/*
-* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the License "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:
-*
-*/
-
-#include <vector>
-#include <boost/regex.hpp>
-#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;
-}
--- a/imgtools/romtools/rofsbuild/symbolgenerator.h Wed Nov 17 16:47:23 2010 +0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/*
-* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the License "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:
-*
-*/
-
-#ifndef __SYMBOLGENERATOR_H__
-#define __SYMBOLGENERATOR_H__
-#include <queue>
-#include <string>
-#include <fstream>
-using namespace std;
-#include <boost/thread/thread.hpp>
-#include <boost/thread/condition.hpp>
-#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<TPlacedEntry> 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
--- a/imgtools/romtools/rofsbuild/symbolprocessunit.cpp Wed Nov 17 16:47:23 2010 +0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,258 +0,0 @@
-/*
-* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the License "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:
-*
-*/
-#include <boost/regex.hpp>
-#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<unsigned int,string> 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<unsigned int,string>::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<unsigned int,string> 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<unsigned int,string>::iterator it = syms.begin();
- map<unsigned int,string>::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;
-}
--- a/imgtools/romtools/rofsbuild/symbolprocessunit.h Wed Nov 17 16:47:23 2010 +0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
-* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the License "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:
-*
-*/
-#ifndef __SYMBOLPROCESSUNIT_H__
-#define __SYMBOLPROCESSUNIT_H__
-#include <vector>
-#include <string>
-#include <iostream>
-#include <fstream>
-using namespace std;
-
-
-typedef vector<string> 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
--- a/imgtools/romtools/rombuild/symbolgenerator.cpp Wed Nov 17 16:47:23 2010 +0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,553 +0,0 @@
-/*
-* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the License "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:
-*
-*/
-
-#include <e32rom.h>
-#include <algorithm>
-#include "symbolgenerator.h"
-#include "r_rom.h"
-#include <string.h>
-#include "h_utl.h"
-typedef boost::unique_lock<boost::mutex> scoped_lock ;
-typedef boost::lock_guard<boost::mutex> 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 \""<<aSymbolFileName << "\" ! \nPlease make sure this file is not locked by other application or you have write permission!"<<endl;
- }
-}
-void SymbolGenerator::WaitThreads() {
- iThreads.join_all();
-}
-SymbolGenerator::~SymbolGenerator() {
- if(iOutput.is_open()){
- iOutput.flush();
- iOutput.close();
- }
- for(vector<char*>::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<char*>& 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<TUint32,ArmSymbolInfo> ArmSymMap ;
-
-bool SymbolGenerator::ProcessARMV5Map(ifstream& aStream, const SymGenContext& aContext) {
- string symName ;
- ArmSymMap symbols ;
- vector<char*> 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<TUint32,ArmSymbolInfo>(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<TUint32,ArmSymbolInfo>(addr,info));
- }
- }
-
- TUint32 textSectAddr = 0x00008000; // .text gets linked at 0x00008000
- TUint32 dataSectAddr = 0x00400000 ; // .data gets linked at 0x00400000
- vector<pair<int,char*> > 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<int,char*>(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<pair<int,char*> >::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<typename M, typename K,typename V>
-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>(k,v));
- }
- else {
- it->second = v ;
- }
-}
-bool SymbolGenerator::ProcessGCCMap(ifstream& aStream, const SymGenContext& aContext){
- char* lineStart;
- vector<char*> 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<TUint32,string> 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 <addr> <len> <library(member)>
- // .text$something
- // <addr> <len> <library(member)>
- // <addr> <len> 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){
- //# <addr> <symbol name possibly including spaces>
- //(/^\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<TUint32,string>::iterator it = symbols.begin();
- TUint32 lastAddr = it->first;
- string lastSymName = it->second;
- vector<pair<int,char*> >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<int,char*>(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<pair<int,char*> >::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<pair<int, char*> >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<int, char*>(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<pair<int,char*> >::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 ;
-}
--- a/imgtools/romtools/rombuild/symbolgenerator.h Wed Nov 17 16:47:23 2010 +0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
-* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the License "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:
-*
-*/
-
-#ifndef __SYMBOLSCREATER_H__
-#define __SYMBOLSCREATER_H__
-#include <queue>
-#include <string>
-#include <fstream>
-#include <vector>
-#include <map>
-
-using namespace std;
-
-#include <boost/thread/thread.hpp>
-#include <boost/thread/condition.hpp>
-
-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<SymGenContext> iEntries ;
- vector<char*> iErrMsgs ;
-
-};
-
-#endif //__ROMSYMBOLGENERATOR_H__