imgtools/romtools/rofsbuild/symbolprocessunit.cpp
changeset 700 c22eff170fac
parent 699 9ca650050cf0
parent 698 e3ee96a3961c
child 701 170c8b305768
equal deleted inserted replaced
699:9ca650050cf0 700:c22eff170fac
     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 #include <boost/regex.hpp>
       
    18 #include "symbolprocessunit.h"
       
    19 #include "e32image.h"
       
    20 #define MAX_LINE 65535
       
    21 
       
    22 #if defined(__LINUX__)
       
    23 #define PATH_SEPARATOR '/'
       
    24 #else
       
    25 #define PATH_SEPARATOR '\\'
       
    26 #endif
       
    27 
       
    28 void CommenSymbolProcessUnit::ProcessExecutableFile(const string& aFile)
       
    29 {
       
    30 	ResetContentLog();
       
    31 	char str[MAX_LINE];
       
    32 	string outString;
       
    33 	outString = "\nFrom    ";
       
    34 	outString += aFile + "\n\n";
       
    35 	iSymbolContentLog.push_back(outString);
       
    36 	string mapFile2 = aFile+".map";
       
    37 	size_t dot = aFile.rfind('.');
       
    38 	string mapFile = aFile.substr(0,dot)+".map";
       
    39 	ifstream fMap;
       
    40 	fMap.open(mapFile2.c_str());
       
    41 	if(!fMap.is_open()) {
       
    42 		fMap.open(mapFile.c_str());
       
    43 	}
       
    44 
       
    45 	if(!fMap.is_open()) {
       
    46 		sprintf(str, "%s\nWarning: Can't open \"%s\" or \"%s\"\n",aFile.c_str(),mapFile2.c_str(),mapFile.c_str());
       
    47 		iStdoutLog.push_back(str);
       
    48 	    int binSize = GetSizeFromBinFile(aFile);
       
    49 	    memset(str,0,sizeof(str));
       
    50 	    sprintf(str,"%04x", binSize);
       
    51 	    outString = "00000000    ";
       
    52 	    outString += str;
       
    53 	    outString += "    ";
       
    54 	    outString += aFile.substr(aFile.rfind(PATH_SEPARATOR)+1)+"\n";
       
    55 	    iSymbolContentLog.push_back(outString);
       
    56 	}
       
    57 	else {
       
    58 		if(!fMap.good()) fMap.clear();
       
    59 	    boost::regex regARMV5("ARMV5", boost::regex::icase);
       
    60 	    boost::regex regGCCEoARMV4("(GCCE|ARMV4)", boost::regex::icase);
       
    61 	    boost::cmatch what;
       
    62 	    if(regex_search(aFile, what, regARMV5)) {
       
    63 	        ProcessArmv5File(aFile, fMap);
       
    64 	    }
       
    65 	    else if(regex_search(aFile, what, regGCCEoARMV4)) {
       
    66 	        ProcessGcceOrArm4File(aFile, fMap);
       
    67 	    }
       
    68 	    else {
       
    69 	        sprintf(str, "\nWarning: cannot determine linker type used to create %s\n",aFile.c_str());
       
    70 	        iStdoutLog.push_back(str);
       
    71 	        outString = "00000000    0000    ";
       
    72 	        outString += aFile.substr(aFile.rfind(PATH_SEPARATOR)+1)+"\n";
       
    73 	        iSymbolContentLog.push_back(outString);
       
    74 	        }
       
    75 	    }
       
    76 }
       
    77 void CommenSymbolProcessUnit::ProcessDataFile(const string& aFile)
       
    78 {
       
    79 	ResetContentLog();
       
    80 	string line = "\nFrom    "+aFile+"\n\n00000000    0000    "+aFile.substr(aFile.rfind(PATH_SEPARATOR)+1)+"\n";
       
    81 	iSymbolContentLog.push_back(line);
       
    82 }
       
    83 void CommenSymbolProcessUnit::FlushStdOut(ostream& aOut)
       
    84 {
       
    85 	for(int i = 0; i < (int) iStdoutLog.size(); i++)
       
    86 	{
       
    87 		aOut << iStdoutLog[i];
       
    88 	}
       
    89 }
       
    90 void CommenSymbolProcessUnit::FlushSymbolContent(ostream &aOut)
       
    91 {
       
    92 	for(int i = 0; i < (int) iSymbolContentLog.size(); i++)
       
    93 	{
       
    94 		aOut << iSymbolContentLog[i];
       
    95 	}
       
    96 }
       
    97 void CommenSymbolProcessUnit::ResetContentLog()
       
    98 {
       
    99 	iStdoutLog.clear();
       
   100 	iSymbolContentLog.clear();
       
   101 }
       
   102 void CommenSymbolProcessUnit::ProcessArmv5File( const string& fileName, ifstream& aMap ){
       
   103     aMap.seekg (0, ios::beg);
       
   104     char str[MAX_LINE];
       
   105     char outbuffer[MAX_LINE];
       
   106     string outString;
       
   107     aMap.getline(str,MAX_LINE);
       
   108     boost::cmatch what;
       
   109     boost::regex reg("^ARM Linker");
       
   110     if(!regex_search(str, what, reg)) {
       
   111         sprintf(outbuffer, "\nWarning: expecting %s to be generated by ARM linker\n", fileName.c_str());
       
   112         iStdoutLog.push_back(outbuffer);
       
   113         outString = "00000000    0000    "+fileName.substr(fileName.rfind(PATH_SEPARATOR)+1)+"\n";
       
   114         iSymbolContentLog.push_back(outString);
       
   115     }
       
   116     reg.assign("Global Symbols");
       
   117     while(aMap.getline(str,MAX_LINE)) {
       
   118         if(regex_search(str, what, reg)) {
       
   119             break;
       
   120         }
       
   121     }
       
   122 
       
   123     reg.assign("^\\s*(.+)\\s*0x(\\S+)\\s+[^\\d]*(\\d+)\\s+(.*)$");
       
   124     string sSym,sTmp,sSection;
       
   125     unsigned int addr,size,baseOffset = 0;
       
   126     map<unsigned int,string> syms;
       
   127     char symString[MAX_LINE];
       
   128     while(aMap.getline(str,MAX_LINE)) {
       
   129         if(regex_search(str, what, reg)) {
       
   130             sSym.assign(what[1].first,what[1].second-what[1].first);
       
   131             sTmp.assign(what[2].first,what[2].second-what[2].first);
       
   132             addr = strtol(sTmp.c_str(), NULL, 16);
       
   133             sTmp.assign(what[3].first,what[3].second-what[3].first);
       
   134             size = strtol(sTmp.c_str(), NULL, 10);
       
   135             sSection.assign(what[4].first,what[4].second-what[4].first);
       
   136             if(sSection.find("(StubCode)") != string::npos)
       
   137                 size = 8;
       
   138             if(addr > 0) {
       
   139                 memset(symString,0,sizeof(symString));
       
   140                 sprintf(symString,"%04x    ",size);
       
   141                 outString = symString;
       
   142                 outString += sSym+" ";
       
   143                 outString += sSection;
       
   144                 if(baseOffset == 0)
       
   145                     baseOffset = addr;
       
   146                 unsigned int k = addr - baseOffset;
       
   147                 if( (syms.find(k) == syms.end()) || size != 0)
       
   148                     syms[k] = outString;
       
   149             }
       
   150             // end of addr>0
       
   151         }
       
   152         // end of regex_search
       
   153     }
       
   154 
       
   155     map<unsigned int,string>::iterator it;
       
   156     for(it = syms.begin(); it != syms.end(); it++) {
       
   157         memset(str,0,sizeof(str));
       
   158         sprintf(str,"%08x",it->first);
       
   159         outString = str;
       
   160         outString += "    ";
       
   161         outString += it->second+"\n";
       
   162         iSymbolContentLog.push_back(outString);
       
   163     }
       
   164 }
       
   165 void CommenSymbolProcessUnit::ProcessGcceOrArm4File( const string& fileName, ifstream& aMap ){
       
   166     aMap.seekg (0, ios_base::beg);
       
   167     char str[MAX_LINE];
       
   168     char outbuffer[MAX_LINE];
       
   169     aMap.getline(str,MAX_LINE);
       
   170     boost::cmatch what;
       
   171     boost::regex reg("^\\.text\\s+");
       
   172     while(aMap.getline(str,MAX_LINE)) {
       
   173         if(regex_search(str, what, reg)) {
       
   174             break;
       
   175         }
       
   176     }
       
   177 
       
   178     reg.assign("^\\.text\\s+(\\w+)\\s+\\w+");
       
   179     if(!regex_search(str, what, reg)) {
       
   180         sprintf(outbuffer, "ERROR: Can't get .text section info for \"%s\"\n",fileName.c_str());
       
   181         iStdoutLog.push_back(outbuffer);
       
   182     }
       
   183     else {
       
   184         string sTmp, sLibFile;
       
   185         sTmp.assign(what[1].first,what[1].second-what[1].first);
       
   186         unsigned int imgText = strtol(sTmp.c_str(), NULL, 16);
       
   187 
       
   188         reg.assign("^LONG 0x.*", boost::regex::icase);
       
   189         boost::cmatch what1;
       
   190         boost::regex reg1("^\\s(\\.text)?\\s+(0x\\w+)\\s+(0x\\w+)\\s+(.*)$", boost::regex::icase);
       
   191         boost::regex reg2("^\\s+(\\w+)\\s\\s+([a-zA-Z_].+)", boost::regex::icase);
       
   192         boost::regex reg3(".*lib\\(.*d\\d*s_?\\d{5}.o\\)$", boost::regex::icase);
       
   193 
       
   194         map<unsigned int,string> syms;
       
   195         unsigned int addr, len, stubhex;
       
   196 
       
   197         while(aMap.getline(str,MAX_LINE)) {
       
   198             if(strlen(str) == 0)
       
   199                 break;
       
   200             else if(regex_search(str, what, reg1)) {
       
   201                 sLibFile.assign(what[4].first,what[4].second-what[4].first);
       
   202                 if(!regex_search(sLibFile, what1, reg)) {
       
   203                     sTmp.assign(what[2].first,what[2].second-what[2].first);
       
   204                     addr = strtol(sTmp.c_str(), NULL, 16);
       
   205                     sTmp.assign(what[3].first,what[3].second-what[3].first);
       
   206                     len = strtol(sTmp.c_str(), NULL, 16);
       
   207                     syms[addr+len] = "";
       
   208                     if(regex_search(sLibFile, what, reg3)) {
       
   209                         stubhex = addr;
       
   210                     }
       
   211                 }
       
   212             }
       
   213             else if(regex_search(str, what, reg2)) {
       
   214                 sTmp.assign(what[1].first,what[1].second-what[1].first);
       
   215                 addr = strtol(sTmp.c_str(), NULL, 16);
       
   216                 sTmp.assign(what[2].first,what[2].second-what[2].first);
       
   217                 syms[addr] = (addr == stubhex)? ("stub "+sTmp) : sTmp;
       
   218             }
       
   219         }
       
   220 
       
   221         map<unsigned int,string>::iterator it = syms.begin();
       
   222         map<unsigned int,string>::iterator itp = it++;
       
   223         string outString;
       
   224         for(; it != syms.end(); itp = it++) {
       
   225             if(itp->second != "") {
       
   226                 memset(str,0,sizeof(str));
       
   227                 sprintf(str,"%08x    %04x    ",(itp->first-imgText), (it->first-itp->first));
       
   228                 outString = str;
       
   229                 outString += it->second+"\n";
       
   230                 iSymbolContentLog.push_back(outString);
       
   231             }
       
   232         }
       
   233     }
       
   234 }
       
   235 int CommenSymbolProcessUnit::GetSizeFromBinFile( const string& fileName ){
       
   236     TInt ret = 0;
       
   237     char outbuffer[MAX_LINE];
       
   238     ifstream aIf(fileName.c_str(), ios_base::binary);
       
   239     if( !aIf.is_open() ) {
       
   240         printf(outbuffer, "Warning: Cannot open file \n");
       
   241         iStdoutLog.push_back(outbuffer);
       
   242     }
       
   243     else {
       
   244         E32ImageFile e32Image;
       
   245         TUint32 aSz;
       
   246 
       
   247         aIf.seekg(0,ios_base::end);
       
   248         aSz = aIf.tellg();
       
   249 
       
   250         e32Image.Adjust(aSz);
       
   251         e32Image.iFileSize = aSz;
       
   252 
       
   253         aIf.seekg(0,ios_base::beg);
       
   254         aIf >> e32Image;
       
   255         ret = e32Image.iOrigHdr->iCodeSize;
       
   256     }
       
   257     return ret;
       
   258 }