imgtools/romtools/rofsbuild/symbolgenerator.cpp
changeset 654 7c11c3d8d025
parent 600 6d08f4a05d93
child 662 60be34e1b006
child 664 44b0e894b7ab
equal deleted inserted replaced
653:8ee61c1e0c5c 654:7c11c3d8d025
       
     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>
     1 #include <boost/regex.hpp>
    19 #include <boost/regex.hpp>
     2 #define MAX_LINE 65535
    20 #define MAX_LINE 65535
     3 #include "symbolgenerator.h"
    21 #include "symbolgenerator.h"
     4 #include "e32image.h"
    22 #include "e32image.h"
     5 
    23 
     6 #if defined(__LINUX__)
    24 #if defined(__LINUX__)
     7 #define PATH_SEPARATOR '/'
    25 #define PATH_SEPARATOR '/'
     8 #else
    26 #else
     9 #define PATH_SEPARATOR '\\'
    27 #define PATH_SEPARATOR '\\'
    10 #endif
    28 #endif
       
    29 extern TInt gThreadNum;
    11 
    30 
    12 boost::mutex SymbolGenerator::iMutexSingleton;
    31 boost::mutex SymbolGenerator::iMutexSingleton;
    13 SymbolGenerator* SymbolGenerator::iInst = NULL;
    32 SymbolGenerator* SymbolGenerator::iInst = NULL;
    14 SymbolGenerator* SymbolGenerator::GetInstance(){
    33 SymbolGenerator* SymbolGenerator::GetInstance(){
    15     iMutexSingleton.lock();
    34     iMutexSingleton.lock();
    18     }
    37     }
    19     iMutexSingleton.unlock();
    38     iMutexSingleton.unlock();
    20     return iInst;
    39     return iInst;
    21 }
    40 }
    22 void SymbolGenerator::Release() {
    41 void SymbolGenerator::Release() {
       
    42     if(iInst != NULL) {
       
    43         iInst->join();
       
    44     }
    23     iMutexSingleton.lock();
    45     iMutexSingleton.lock();
    24     if(iInst != NULL) {
    46     if(iInst != NULL) {
    25         delete iInst;
    47         delete iInst;
    26         iInst = NULL;
    48         iInst = NULL;
    27     }
    49     }
    38     iMutex.lock();
    60     iMutex.lock();
    39     iQueueFiles.push(TPlacedEntry(fileName,isExecutable));
    61     iQueueFiles.push(TPlacedEntry(fileName,isExecutable));
    40     iMutex.unlock();
    62     iMutex.unlock();
    41     iCond.notify_all();
    63     iCond.notify_all();
    42 }
    64 }
    43 void SymbolGenerator::ProcessExecutable( const string& fileName ){
    65 void SymbolGenerator::SetFinished() 
    44     char str[MAX_LINE];
    66 { 
    45     string outString;
    67 
    46     outString = "\nFrom    ";
    68 	iFinished = true; 
    47     outString += fileName + "\n\n";
    69 	iCond.notify_all();
    48     iSymFile.write(outString.c_str(),outString.length());
       
    49     string mapFile2 = fileName+".map";
       
    50     size_t dot = fileName.rfind('.');
       
    51     string mapFile = fileName.substr(0,dot)+".map";
       
    52     ifstream fMap;
       
    53     fMap.open(mapFile2.c_str());
       
    54     if(!fMap.is_open()) {
       
    55         fMap.open(mapFile.c_str());
       
    56     }
    70     }
    57 
    71 TPlacedEntry SymbolGenerator::GetNextPlacedEntry()
    58     if(!fMap.is_open()) {
    72 {
    59         printf("%s\nWarning: Can't open \"%s\" or \"%s\"\n",fileName.c_str(),mapFile2.c_str(),mapFile.c_str());
    73 	TPlacedEntry pe("", false);
    60         int binSize = GetSizeFromBinFile(fileName);
    74 	if(1)
    61         memset(str,0,sizeof(str));
    75 	{
    62         sprintf(str,"%04x", binSize);
    76 		boost::mutex::scoped_lock lock(iMutex);
    63         outString = "00000000    ";
    77 		while(!iFinished && iQueueFiles.empty())
    64         outString += str;
    78 			iCond.wait(lock);
    65         outString += "    ";
    79 		if(!iQueueFiles.empty())
    66         outString += fileName.substr(fileName.rfind(PATH_SEPARATOR)+1)+"\n";
    80 		{
    67         iSymFile.write(outString.c_str(),outString.length());
    81 			pe = iQueueFiles.front();
    68     }
    82 			iQueueFiles.pop();
    69     else {
       
    70 		if(!fMap.good()) fMap.clear();
       
    71         boost::regex regARMV5("ARMV5", boost::regex::icase);
       
    72         boost::regex regGCCEoARMV4("(GCCE|ARMV4)", boost::regex::icase);
       
    73         boost::cmatch what;
       
    74         if(regex_search(fileName, what, regARMV5)) {
       
    75             ProcessArmv5File(fileName, fMap);
       
    76         }
       
    77         else if(regex_search(fileName, what, regGCCEoARMV4)) {
       
    78             ProcessGcceOrArm4File(fileName, fMap);
       
    79         }
       
    80         else {
       
    81             printf("\nWarning: cannot determine linker type used to create %s\n",fileName.c_str());
       
    82             outString = "00000000    0000    ";
       
    83             outString += fileName.substr(fileName.rfind(PATH_SEPARATOR)+1)+"\n";
       
    84             iSymFile.write(outString.c_str(),outString.length());
       
    85         }
    83         }
    86     }
    84     }
       
    85 	return pe;
    87 }
    86 }
    88 void SymbolGenerator::ProcessDatafile( const string& fileName ){
    87 void SymbolGenerator::thrd_func(){
    89     string line = "\nFrom    "+fileName+"\n\n00000000    0000    "+fileName.substr(fileName.rfind(PATH_SEPARATOR)+1)+"\n";
    88     	boost::thread_group threads;
    90     iSymFile.write(line.c_str(),line.length());
    89 	SymbolWorker worker;
    91 }
    90     	for(int i=0; i < gThreadNum; i++)
    92 void SymbolGenerator::ProcessArmv5File( const string& fileName, ifstream& aMap ){
    91     	{
    93     aMap.seekg (0, ios::beg);
    92     		threads.create_thread(worker);
    94     char str[MAX_LINE];
       
    95     string outString;
       
    96     aMap.getline(str,MAX_LINE);
       
    97     boost::cmatch what;
       
    98     boost::regex reg("^ARM Linker");
       
    99     if(!regex_search(str, what, reg)) {
       
   100         printf("\nWarning: expecting %s to be generated by ARM linker\n", fileName.c_str());
       
   101         outString = "00000000    0000    "+fileName.substr(fileName.rfind(PATH_SEPARATOR)+1)+"\n";
       
   102         iSymFile.write(outString.c_str(),outString.length());
       
   103     }
    93     }
   104     reg.assign("Global Symbols");
    94     	threads.join_all();
   105     while(aMap.getline(str,MAX_LINE)) {
       
   106         if(regex_search(str, what, reg)) {
       
   107             break;
       
   108         }
    95         }
       
    96 SymbolGenerator::SymbolGenerator() : boost::thread(thrd_func),iFinished(false) {
   109     }
    97     }
   110 
    98 SymbolGenerator::~SymbolGenerator(){
   111     reg.assign("^\\s*(.+)\\s*0x(\\S+)\\s+[^\\d]*(\\d+)\\s+(.*)$");
    99     if(joinable())
   112     string sSym,sTmp,sSection;
   100         join();
   113     unsigned int addr,size,baseOffset = 0;
   101     iSymFile.flush();
   114     map<unsigned int,string> syms;
   102     iSymFile.close();
   115     char symString[MAX_LINE];
       
   116     while(aMap.getline(str,MAX_LINE)) {
       
   117         if(regex_search(str, what, reg)) {
       
   118             sSym.assign(what[1].first,what[1].second-what[1].first);
       
   119             sTmp.assign(what[2].first,what[2].second-what[2].first);
       
   120             addr = strtol(sTmp.c_str(), NULL, 16);
       
   121             sTmp.assign(what[3].first,what[3].second-what[3].first);
       
   122             size = strtol(sTmp.c_str(), NULL, 10);
       
   123             sSection.assign(what[4].first,what[4].second-what[4].first);
       
   124             if(sSection.find("(StubCode)") != string::npos)
       
   125                 size = 8;
       
   126             if(addr > 0) {
       
   127                 memset(symString,0,sizeof(symString));
       
   128                 sprintf(symString,"%04x    ",size);
       
   129                 outString = symString;
       
   130                 outString += sSym+" ";
       
   131                 outString += sSection;
       
   132                 if(baseOffset == 0) 
       
   133                     baseOffset = addr;
       
   134                 unsigned int k = addr - baseOffset;
       
   135                 if( (syms.find(k) == syms.end()) || size != 0) 
       
   136                     syms[k] = outString;
       
   137             }
   103             }
   138             // end of addr>0
   104 SymbolWorker::SymbolWorker()
   139         }
   105 {
   140         // end of regex_search
   106         // end of regex_search
   141     }
   107     }
       
   108 SymbolWorker::~SymbolWorker()
       
   109 {
       
   110     }
       
   111 void SymbolWorker::operator()()
       
   112 {
       
   113 	SymbolProcessUnit* aSymbolProcessUnit = new CommenSymbolProcessUnit();
       
   114 	SymbolGenerator* symbolgenerator = SymbolGenerator::GetInstance();
   142 
   115 
   143     map<unsigned int,string>::iterator it;
   116 	while(1)
   144     for(it = syms.begin(); it != syms.end(); it++) {
   117 	{
   145         memset(str,0,sizeof(str));
   118 		if(symbolgenerator->HasFinished() && symbolgenerator->IsEmpty())
   146         sprintf(str,"%08x",it->first);
   119 		{
   147         outString = str;
       
   148         outString += "    ";
       
   149         outString += it->second+"\n";
       
   150         iSymFile.write(outString.c_str(),outString.length());
       
   151     }
       
   152 }
       
   153 void SymbolGenerator::ProcessGcceOrArm4File( const string& fileName, ifstream& aMap ){
       
   154     aMap.seekg (0, ios_base::beg);
       
   155     char str[MAX_LINE];
       
   156     aMap.getline(str,MAX_LINE);
       
   157     boost::cmatch what;
       
   158     boost::regex reg("^\\.text\\s+");
       
   159     while(aMap.getline(str,MAX_LINE)) {
       
   160         if(regex_search(str, what, reg)) {
       
   161             break;
       
   162         }
       
   163     }
       
   164 
   120 
   165     reg.assign("^\\.text\\s+(\\w+)\\s+\\w+");
   121                 break;
   166     if(!regex_search(str, what, reg)) {
   122                     }
   167         printf("ERROR: Can't get .text section info for \"%s\"\n",fileName.c_str());
       
   168     }
       
   169     else {
       
   170         string sTmp, sLibFile;
       
   171         sTmp.assign(what[1].first,what[1].second-what[1].first);
       
   172         unsigned int imgText = strtol(sTmp.c_str(), NULL, 16);
       
   173 
   123 
   174         reg.assign("^LONG 0x.*", boost::regex::icase);
       
   175         boost::cmatch what1;
       
   176         boost::regex reg1("^\\s(\\.text)?\\s+(0x\\w+)\\s+(0x\\w+)\\s+(.*)$", boost::regex::icase);
       
   177         boost::regex reg2("^\\s+(\\w+)\\s\\s+([a-zA-Z_].+)", boost::regex::icase);
       
   178         boost::regex reg3(".*lib\\(.*d\\d*s_?\\d{5}.o\\)$", boost::regex::icase);
       
   179 
   124 
   180         map<unsigned int,string> syms;
       
   181         unsigned int addr, len, stubhex;
       
   182 
   125 
   183         while(aMap.getline(str,MAX_LINE)) {
       
   184             if(strlen(str) == 0)
       
   185                 break;
       
   186             else if(regex_search(str, what, reg1)) {
       
   187                 sLibFile.assign(what[4].first,what[4].second-what[4].first);
       
   188                 if(!regex_search(sLibFile, what1, reg)) {
       
   189                     sTmp.assign(what[2].first,what[2].second-what[2].first);
       
   190                     addr = strtol(sTmp.c_str(), NULL, 16);
       
   191                     sTmp.assign(what[3].first,what[3].second-what[3].first);
       
   192                     len = strtol(sTmp.c_str(), NULL, 16);
       
   193                     syms[addr+len] = "";
       
   194                     if(regex_search(sLibFile, what, reg3)) {
       
   195                         stubhex = addr;
       
   196                     }
       
   197                 }
       
   198             }
       
   199             else if(regex_search(str, what, reg2)) {
       
   200                 sTmp.assign(what[1].first,what[1].second-what[1].first);
       
   201                 addr = strtol(sTmp.c_str(), NULL, 16);
       
   202                 sTmp.assign(what[2].first,what[2].second-what[2].first);
       
   203                 syms[addr] = (addr == stubhex)? ("stub "+sTmp) : sTmp;
       
   204             }
       
   205         }
       
   206 
   126 
   207         map<unsigned int,string>::iterator it = syms.begin();
   127 		TPlacedEntry pe = symbolgenerator->GetNextPlacedEntry();
   208         map<unsigned int,string>::iterator itp = it++;
       
   209         string outString;
       
   210         for(; it != syms.end(); itp = it++) {
       
   211             if(itp->second != "") {
       
   212                 memset(str,0,sizeof(str));
       
   213                 sprintf(str,"%08x    %04x    ",(itp->first-imgText), (it->first-itp->first));
       
   214                 outString = str;
       
   215                 outString += it->second+"\n";
       
   216                 iSymFile.write(outString.c_str(),outString.length());
       
   217             }
       
   218         }
       
   219     }
       
   220 }
       
   221 int SymbolGenerator::GetSizeFromBinFile( const string& fileName ){
       
   222     TInt ret = 0;
       
   223     ifstream aIf(fileName.c_str(), ios_base::binary);
       
   224     if( !aIf.is_open() ) {
       
   225         printf("Warning: Cannot open file \n");
       
   226     }
       
   227     else {
       
   228         E32ImageFile e32Image;
       
   229         TUint32 aSz;
       
   230 
   128 
   231         aIf.seekg(0,ios_base::end);
       
   232         aSz = aIf.tellg();
       
   233 
       
   234         e32Image.Adjust(aSz);
       
   235         e32Image.iFileSize = aSz;
       
   236 
       
   237         aIf.seekg(0,ios_base::beg);
       
   238         aIf >> e32Image;
       
   239         ret = e32Image.iOrigHdr->iCodeSize;
       
   240     }
       
   241     return ret;
       
   242 }
       
   243 void SymbolGenerator::thrd_func(){
       
   244     SymbolGenerator* me = GetInstance();
       
   245 
       
   246     TPlacedEntry pe("",false);
       
   247     while(1) {
       
   248         if(1) {
       
   249             //scope the code block with if(1) for lock
   129             //scope the code block with if(1) for lock
   250             boost::mutex::scoped_lock lock(me->iMutex);
       
   251             while(me->iQueueFiles.empty())
       
   252                 me->iCond.wait(lock);
       
   253             /*
   130             /*
   254             if(me->iQueueFiles.empty()) {
   131             if(me->iQueueFiles.empty()) {
   255                 boost::this_thread::sleep(boost::posix_time::milliseconds(10));
   132                 boost::this_thread::sleep(boost::posix_time::milliseconds(10));
   256                 continue;
   133                 continue;
   257             }
   134             }
   258             */
   135             */
   259 
   136 
   260             pe = me->iQueueFiles.front();
       
   261             me->iQueueFiles.pop();
       
   262         }
       
   263 
   137 
   264         if(pe.iFileName == "")
   138         if(pe.iFileName == "")
   265             break;
   139 			continue;
   266         else if(pe.iExecutable) 
   140         else if(pe.iExecutable) 
   267             me->ProcessExecutable(pe.iFileName);
   141 			aSymbolProcessUnit->ProcessExecutableFile(pe.iFileName);
   268         else
   142         else
   269             me->ProcessDatafile(pe.iFileName);
   143 			aSymbolProcessUnit->ProcessDataFile(pe.iFileName);
   270     }
   144 		symbolgenerator->LockOutput();
       
   145 		aSymbolProcessUnit->FlushStdOut(cout);
       
   146 		aSymbolProcessUnit->FlushSymbolContent(symbolgenerator->GetOutputFileStream());
       
   147 		symbolgenerator->UnlockOutput();
   271 }
   148 }
   272 SymbolGenerator::SymbolGenerator() : boost::thread(thrd_func) {
   149 	delete aSymbolProcessUnit;
   273 }
   150 }
   274 SymbolGenerator::~SymbolGenerator(){
       
   275     if(joinable())
       
   276         join();
       
   277     iSymFile.flush();
       
   278     iSymFile.close();
       
   279 }