imgtools/imglib/symbolutil/symbolgenerator.cpp
changeset 695 46ca13b54f56
child 714 e5a58c351011
equal deleted inserted replaced
694:c3fbb20e86f0 695:46ca13b54f56
       
     1 /*
       
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 #include <vector>
       
    19 #include <boost/regex.hpp>
       
    20 #define MAX_LINE 65535
       
    21 #include "symbolgenerator.h"
       
    22 #include "e32image.h"
       
    23 #include "h_utl.h"
       
    24 
       
    25 #if defined(__LINUX__)
       
    26 #define PATH_SEPARATOR '/'
       
    27 #else
       
    28 #define PATH_SEPARATOR '\\'
       
    29 #endif
       
    30 extern TInt gThreadNum;
       
    31 extern TBool gGenBsymbols;
       
    32 
       
    33 boost::mutex SymbolGenerator::iMutexSingleton;
       
    34 SymbolGenerator* SymbolGenerator::iInst = NULL;
       
    35 SymbolGenerator* SymbolGenerator::GetInstance(){
       
    36     iMutexSingleton.lock();
       
    37     if(iInst == NULL) {
       
    38         iInst = new SymbolGenerator();
       
    39     }
       
    40     iMutexSingleton.unlock();
       
    41     return iInst;
       
    42 }
       
    43 void SymbolGenerator::Release() {
       
    44     if(iInst != NULL) {
       
    45         iInst->join();
       
    46     }
       
    47     iMutexSingleton.lock();
       
    48     if(iInst != NULL) {
       
    49         delete iInst;
       
    50         iInst = NULL;
       
    51     }
       
    52     iMutexSingleton.unlock();
       
    53 }
       
    54 void SymbolGenerator::SetSymbolFileName( const string& fileName ){
       
    55     if(iSymFile.is_open())
       
    56         iSymFile.close();
       
    57     if(gGenBsymbols)
       
    58     {
       
    59     	string s = fileName.substr(0,fileName.rfind('.'))+".bsym";
       
    60     	if(iImageType == ERofsImage)
       
    61     	{
       
    62     		printf("* Writing %s - ROFS BSymbol file\n", s.c_str());
       
    63     	}
       
    64     	else
       
    65     	{
       
    66     		printf("* Writing %s - ROM BSymbol file\n", s.c_str());
       
    67     	}
       
    68     	iSymFile.open(s.c_str(), ios_base::binary);
       
    69     }
       
    70     else
       
    71     {
       
    72     	string s = fileName.substr(0,fileName.rfind('.'))+".symbol";
       
    73     	if(iImageType == ERofsImage)
       
    74     	{
       
    75     		printf("* Writing %s - ROFS Symbol file\n", s.c_str());
       
    76     	}
       
    77     	else
       
    78     	{
       
    79     		printf("* Writing %s - ROM Symbol file\n", s.c_str());
       
    80     	}
       
    81     iSymFile.open(s.c_str());
       
    82     }
       
    83 	   
       
    84 }
       
    85 void SymbolGenerator::AddFile( const string& fileName, bool isExecutable ){
       
    86     iMutex.lock();
       
    87     iQueueFiles.push(TPlacedEntry(fileName, "" , isExecutable));
       
    88     iMutex.unlock();
       
    89     iCond.notify_all();
       
    90 }
       
    91 
       
    92 void SymbolGenerator::AddEntry(const TPlacedEntry& aEntry)
       
    93 {
       
    94     iMutex.lock();
       
    95     iQueueFiles.push(aEntry);
       
    96     iMutex.unlock();
       
    97     iCond.notify_all();
       
    98 }
       
    99 
       
   100 void SymbolGenerator::SetFinished() 
       
   101 { 
       
   102 
       
   103 	iFinished = true; 
       
   104 	iCond.notify_all();
       
   105 }
       
   106 TPlacedEntry SymbolGenerator::GetNextPlacedEntry()
       
   107 {
       
   108 	TPlacedEntry pe("", "", false);
       
   109 	if(1)
       
   110 	{
       
   111 		boost::mutex::scoped_lock lock(iMutex);
       
   112 		while(!iFinished && iQueueFiles.empty())
       
   113 			iCond.wait(lock);
       
   114 		if(!iQueueFiles.empty())
       
   115 		{
       
   116 			pe = iQueueFiles.front();
       
   117 			iQueueFiles.pop();
       
   118         	}
       
   119     	}
       
   120 	return pe;
       
   121 }
       
   122 void SymbolGenerator::thrd_func(){
       
   123     	boost::thread_group threads;
       
   124 	SymbolWorker worker;
       
   125     	for(int i=0; i < gThreadNum; i++)
       
   126     	{
       
   127     		threads.create_thread(worker);
       
   128     	}
       
   129     	threads.join_all();
       
   130 	SymbolGenerator::GetInstance()->FlushSymbolFileContent();
       
   131         }
       
   132 SymbolGenerator::SymbolGenerator() : boost::thread(thrd_func),iFinished(false) {
       
   133 	if(gGenBsymbols)
       
   134 	{
       
   135 		iSymbolType = ESymBsym;
       
   136 	}
       
   137 	else
       
   138 	{
       
   139 		iSymbolType = ESymCommon;
       
   140 	}
       
   141     }
       
   142 SymbolGenerator::~SymbolGenerator(){
       
   143     if(joinable())
       
   144         join();
       
   145     iSymFile.flush();
       
   146     iSymFile.close();
       
   147 }
       
   148 void SymbolGenerator::FlushSymbolFileContent()
       
   149 {
       
   150     if(iSymbolType == ESymCommon)
       
   151     {
       
   152 	return;
       
   153     }
       
   154     TBsymHeader tmpBsymHeader;
       
   155     memset(&tmpBsymHeader, 0, sizeof(tmpBsymHeader));
       
   156     tmpBsymHeader.iMagic[0] = 'B';
       
   157     tmpBsymHeader.iMagic[1] = 'S';
       
   158     tmpBsymHeader.iMagic[2] = 'Y';
       
   159     tmpBsymHeader.iMagic[3] = 'M';
       
   160     tmpBsymHeader.iMajorVer[0] = BsymMajorVer >> 8;
       
   161     tmpBsymHeader.iMajorVer[1] = BsymMajorVer & 0xff;
       
   162     tmpBsymHeader.iMinorVer[0] = BsymMinorVer >> 8;
       
   163     tmpBsymHeader.iMinorVer[1] = BsymMinorVer & 0xff;
       
   164     if(ByteOrderUtil::IsLittleEndian())
       
   165     {
       
   166 	    tmpBsymHeader.iEndiannessFlag = 0;
       
   167     }
       
   168     else
       
   169     {
       
   170 	    tmpBsymHeader.iEndiannessFlag = 1;
       
   171     }
       
   172     tmpBsymHeader.iCompressionFlag = 1;
       
   173     //count the space for TDbgUnitEntries and TSymbolEntries
       
   174     int fileCount = iMapFileInfoSet.size();
       
   175     TUint32 sizeNeeded = fileCount * sizeof(TDbgUnitEntry);
       
   176     for(int i = 0; i < fileCount; i++)
       
   177     {
       
   178     	sizeNeeded += iMapFileInfoSet[i].iSymbolPCEntrySet.size() * sizeof(TSymbolEntry);
       
   179     }
       
   180     //write string to the temporary memory area
       
   181     MemoryWriter mWriter;
       
   182     mWriter.SetOffset(sizeNeeded);
       
   183     mWriter.SetStringTableStart(sizeNeeded);
       
   184     mWriter.AddEmptyString();
       
   185 
       
   186     //first to prepare the file info entries TDbgUnitEntry
       
   187     TUint32 startSymbolIndex = 0;
       
   188     for(int i = 0; i < fileCount; i++)
       
   189     {
       
   190     	iMapFileInfoSet[i].iDbgUnitPCEntry.iDbgUnitEntry.iStartSymbolIndex = startSymbolIndex;
       
   191     	iMapFileInfoSet[i].iDbgUnitPCEntry.iDbgUnitEntry.iPCNameOffset = mWriter.AddString(iMapFileInfoSet[i].iDbgUnitPCEntry.iPCName);
       
   192     	iMapFileInfoSet[i].iDbgUnitPCEntry.iDbgUnitEntry.iDevNameOffset = mWriter.AddString(iMapFileInfoSet[i].iDbgUnitPCEntry.iDevName);
       
   193     	startSymbolIndex += iMapFileInfoSet[i].iSymbolPCEntrySet.size();
       
   194     }
       
   195     //second to layout the symbols unit for the mapfile
       
   196     for(int i = 0; i < fileCount; i++)
       
   197     {
       
   198         int symbolcount = iMapFileInfoSet[i].iSymbolPCEntrySet.size();
       
   199         for(int j =0; j< symbolcount; j++)
       
   200         {
       
   201         	iMapFileInfoSet[i].iSymbolPCEntrySet[j].iSymbolEntry.iScopeNameOffset = mWriter.AddScopeName(iMapFileInfoSet[i].iSymbolPCEntrySet[j].iScopeName);
       
   202         	iMapFileInfoSet[i].iSymbolPCEntrySet[j].iSymbolEntry.iNameOffset = mWriter.AddString(iMapFileInfoSet[i].iSymbolPCEntrySet[j].iName);
       
   203         	iMapFileInfoSet[i].iSymbolPCEntrySet[j].iSymbolEntry.iSecNameOffset = mWriter.AddString(iMapFileInfoSet[i].iSymbolPCEntrySet[j].iSecName);
       
   204         }
       
   205     }
       
   206 
       
   207     //write out the BSym file content
       
   208     char* pstart = mWriter.GetDataPointer();
       
   209     //write out the map file info
       
   210     int unitlen = sizeof(TDbgUnitEntry);
       
   211     for(int i = 0; i < fileCount; i++)
       
   212     {
       
   213     	memcpy(pstart, &iMapFileInfoSet[i].iDbgUnitPCEntry.iDbgUnitEntry, unitlen);
       
   214     	pstart += unitlen;
       
   215     }
       
   216     //wirte out the symbol unit info
       
   217     unitlen = sizeof(TSymbolEntry);
       
   218     for(int i = 0; i < fileCount; i++)
       
   219     {
       
   220     	int symbolcount = iMapFileInfoSet[i].iSymbolPCEntrySet.size();
       
   221     	for(int j =0; j < symbolcount; j++)
       
   222     	{
       
   223     		memcpy(pstart, &iMapFileInfoSet[i].iSymbolPCEntrySet[j].iSymbolEntry, unitlen);
       
   224     		pstart += unitlen;
       
   225     	}
       
   226     }
       
   227     //write out the memory out to the symbol file
       
   228 
       
   229     int totalPages = (mWriter.GetOffset() + ( BSYM_PAGE_SIZE -1)) / 4096;
       
   230     TUint32 compressInfoLength = sizeof(TCompressedHeaderInfo) + sizeof(TPageInfo)*(totalPages -1);
       
   231     char* tmpBuffer = new char[compressInfoLength];
       
   232     TCompressedHeaderInfo * pCompressedHeaderInfo = (TCompressedHeaderInfo *) tmpBuffer;
       
   233     pCompressedHeaderInfo->iPageSize = BSYM_PAGE_SIZE;
       
   234     pCompressedHeaderInfo->iTotalPageNumber = totalPages;
       
   235     TPageInfo* tmpPage = &pCompressedHeaderInfo->iPages[0];
       
   236     for(int i = 0; i < totalPages; i++)
       
   237     {
       
   238 	    tmpPage->iPageStartOffset = i * BSYM_PAGE_SIZE;
       
   239 	    if(tmpPage->iPageStartOffset + BSYM_PAGE_SIZE < mWriter.GetOffset())
       
   240 	    {
       
   241 	    	tmpPage->iPageDataSize = BSYM_PAGE_SIZE;
       
   242 	    }
       
   243 	    else
       
   244 	    {
       
   245 		tmpPage->iPageDataSize = mWriter.GetOffset() - tmpPage->iPageStartOffset;
       
   246 	    }
       
   247 	    tmpPage++;
       
   248     }
       
   249 
       
   250     //prepare the TBsymHeader, TDbgUnitEntry and TSymbolEntry to the memory
       
   251     tmpBsymHeader.iDbgUnitOffset = sizeof(TBsymHeader) + compressInfoLength;
       
   252     tmpBsymHeader.iDbgUnitCount = fileCount;
       
   253     tmpBsymHeader.iSymbolOffset = fileCount*sizeof(TDbgUnitEntry);
       
   254     tmpBsymHeader.iSymbolCount = startSymbolIndex;
       
   255     tmpBsymHeader.iStringTableOffset = mWriter.GetStringTableStart();
       
   256     tmpBsymHeader.iStringTableBytes = mWriter.GetOffset() - tmpBsymHeader.iStringTableOffset;
       
   257     tmpBsymHeader.iUncompressSize = mWriter.GetOffset();
       
   258     //start the compress threads
       
   259     Print(EAlways, "Start compress for Bsymbol file\n");
       
   260     PageCompressWorker compressWorker(pCompressedHeaderInfo, mWriter.GetDataPointer());
       
   261     boost::thread_group threads;
       
   262     for(int i=0; i < gThreadNum; i++)
       
   263     {
       
   264 	    threads.create_thread(compressWorker);
       
   265     }
       
   266     threads.join_all();
       
   267     Print(EAlways, "Complete compress for Bsymbol file\n");
       
   268     //pack all the pages together
       
   269     tmpPage = &pCompressedHeaderInfo->iPages[0];
       
   270     TPageInfo* prePage = NULL;
       
   271     char* pchar = mWriter.GetDataPointer();
       
   272     for(int i=0; i < totalPages -1; i++)
       
   273     {
       
   274 	    prePage = tmpPage;
       
   275 	    tmpPage++;
       
   276 	    memcpy(pchar + prePage->iPageStartOffset + prePage->iPageDataSize, pchar + tmpPage->iPageStartOffset, tmpPage->iPageDataSize);
       
   277 	    tmpPage->iPageStartOffset = prePage->iPageStartOffset + prePage->iPageDataSize;
       
   278 
       
   279     }
       
   280     tmpBsymHeader.iCompressedSize = tmpPage->iPageStartOffset + tmpPage->iPageDataSize;
       
   281     mWriter.SetOffset(tmpBsymHeader.iCompressedSize);
       
   282     tmpBsymHeader.iCompressInfoOffset = sizeof(TBsymHeader);
       
   283 
       
   284     iSymFile.write((char*)&tmpBsymHeader, sizeof(TBsymHeader));
       
   285     iSymFile.write((char*)pCompressedHeaderInfo, compressInfoLength);
       
   286     iSymFile.write(mWriter.GetDataPointer(), mWriter.GetOffset());
       
   287     delete[] tmpBuffer;
       
   288     for(int i = 0; i < fileCount; i++)
       
   289     {
       
   290     	iMapFileInfoSet[i].iSymbolPCEntrySet.clear();
       
   291     }
       
   292     iMapFileInfoSet.clear();
       
   293 }
       
   294 
       
   295 SymbolWorker::SymbolWorker()
       
   296 {
       
   297 }
       
   298 SymbolWorker::~SymbolWorker()
       
   299 {
       
   300     }
       
   301 void SymbolWorker::operator()()
       
   302 {
       
   303 	SymbolProcessUnit* aSymbolProcessUnit;
       
   304 	SymbolGenerator* symbolgenerator = SymbolGenerator::GetInstance();
       
   305 	if(symbolgenerator->GetImageType() == ERomImage)
       
   306 	{
       
   307 		aSymbolProcessUnit = new CommenRomSymbolProcessUnit();
       
   308 	}
       
   309 	else
       
   310 	{
       
   311 		if(gGenBsymbols)
       
   312 		{
       
   313 			aSymbolProcessUnit = new BsymRofsSymbolProcessUnit(symbolgenerator);
       
   314 		}
       
   315 		else
       
   316 		{
       
   317 			aSymbolProcessUnit = new CommenRofsSymbolProcessUnit();
       
   318 		}
       
   319 	}
       
   320 
       
   321 	while(1)
       
   322 	{
       
   323 		if(symbolgenerator->HasFinished() && symbolgenerator->IsEmpty())
       
   324 		{
       
   325 			break;
       
   326                 }
       
   327 		TPlacedEntry pe = symbolgenerator->GetNextPlacedEntry();
       
   328 		if(pe.iFileName.empty())
       
   329 			continue;
       
   330 
       
   331 		aSymbolProcessUnit->ProcessEntry(pe);
       
   332 
       
   333 		symbolgenerator->LockOutput();
       
   334 		aSymbolProcessUnit->FlushStdOut(cout);
       
   335 		aSymbolProcessUnit->FlushSymbolContent(symbolgenerator->GetOutputFileStream());
       
   336 		symbolgenerator->UnlockOutput();
       
   337 	}
       
   338 	delete aSymbolProcessUnit;
       
   339 }
       
   340 TCompressedHeaderInfo* PageCompressWorker::pHeaderInfo = NULL;
       
   341 int PageCompressWorker::currentPage = 0;
       
   342 boost::mutex PageCompressWorker::m_mutex;
       
   343 int PageCompressWorker::m_error = 0;
       
   344 char* PageCompressWorker::iChar = NULL;
       
   345 
       
   346 PageCompressWorker::PageCompressWorker(TCompressedHeaderInfo* aHeaderInfo, char* aChar) 
       
   347 {
       
   348 	pHeaderInfo = aHeaderInfo;
       
   349 	iChar = aChar;
       
   350 }
       
   351 
       
   352 PageCompressWorker::~PageCompressWorker() {}
       
   353 void PageCompressWorker::operator()()
       
   354 {
       
   355 	int tobecompress = 0;
       
   356 	CBytePair bpe;
       
   357 	while(1)
       
   358 	{
       
   359 		m_mutex.lock();
       
   360 		tobecompress =currentPage;
       
   361 		currentPage++;
       
   362 		m_mutex.unlock();
       
   363 		if(tobecompress >= (int) pHeaderInfo->iTotalPageNumber)
       
   364 			break;
       
   365 		TPageInfo* current = &pHeaderInfo->iPages[0] + tobecompress;
       
   366 		TUint8* in = (TUint8*)(iChar + current->iPageStartOffset);
       
   367 		TUint8* out = in;
       
   368 		TInt outSize = BytePairCompress(out, in, current->iPageDataSize, &bpe);
       
   369 		if(outSize == KErrTooBig)
       
   370 		{
       
   371 			outSize = BSYM_PAGE_SIZE;
       
   372 		}
       
   373 		if(outSize < 0)
       
   374 		{
       
   375 			m_mutex.lock();
       
   376 			m_error = -1;
       
   377 			m_mutex.unlock();
       
   378 			break;
       
   379 		}
       
   380 		current->iPageDataSize = outSize;
       
   381 	}
       
   382 	
       
   383 }
       
   384