imgtools/romtools/rofsbuild/symbolgenerator.cpp
changeset 600 6d08f4a05d93
child 654 7c11c3d8d025
child 655 3f65fd25dfd4
equal deleted inserted replaced
599:fa7a3cc6effd 600:6d08f4a05d93
       
     1 #include <boost/regex.hpp>
       
     2 #define MAX_LINE 65535
       
     3 #include "symbolgenerator.h"
       
     4 #include "e32image.h"
       
     5 
       
     6 #if defined(__LINUX__)
       
     7 #define PATH_SEPARATOR '/'
       
     8 #else
       
     9 #define PATH_SEPARATOR '\\'
       
    10 #endif
       
    11 
       
    12 boost::mutex SymbolGenerator::iMutexSingleton;
       
    13 SymbolGenerator* SymbolGenerator::iInst = NULL;
       
    14 SymbolGenerator* SymbolGenerator::GetInstance(){
       
    15     iMutexSingleton.lock();
       
    16     if(iInst == NULL) {
       
    17         iInst = new SymbolGenerator();
       
    18     }
       
    19     iMutexSingleton.unlock();
       
    20     return iInst;
       
    21 }
       
    22 void SymbolGenerator::Release() {
       
    23     iMutexSingleton.lock();
       
    24     if(iInst != NULL) {
       
    25         delete iInst;
       
    26         iInst = NULL;
       
    27     }
       
    28     iMutexSingleton.unlock();
       
    29 }
       
    30 void SymbolGenerator::SetSymbolFileName( const string& fileName ){
       
    31     if(iSymFile.is_open())
       
    32         iSymFile.close();
       
    33     string s = fileName.substr(0,fileName.rfind('.'))+".symbol";
       
    34     printf("* Writing %s - ROFS symbol file\n", s.c_str());
       
    35     iSymFile.open(s.c_str());
       
    36 }
       
    37 void SymbolGenerator::AddFile( const string& fileName, bool isExecutable ){
       
    38     iMutex.lock();
       
    39     iQueueFiles.push(TPlacedEntry(fileName,isExecutable));
       
    40     iMutex.unlock();
       
    41     iCond.notify_all();
       
    42 }
       
    43 void SymbolGenerator::ProcessExecutable( const string& fileName ){
       
    44     char str[MAX_LINE];
       
    45     string outString;
       
    46     outString = "\nFrom    ";
       
    47     outString += fileName + "\n\n";
       
    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     }
       
    57 
       
    58     if(!fMap.is_open()) {
       
    59         printf("%s\nWarning: Can't open \"%s\" or \"%s\"\n",fileName.c_str(),mapFile2.c_str(),mapFile.c_str());
       
    60         int binSize = GetSizeFromBinFile(fileName);
       
    61         memset(str,0,sizeof(str));
       
    62         sprintf(str,"%04x", binSize);
       
    63         outString = "00000000    ";
       
    64         outString += str;
       
    65         outString += "    ";
       
    66         outString += fileName.substr(fileName.rfind(PATH_SEPARATOR)+1)+"\n";
       
    67         iSymFile.write(outString.c_str(),outString.length());
       
    68     }
       
    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         }
       
    86     }
       
    87 }
       
    88 void SymbolGenerator::ProcessDatafile( const string& fileName ){
       
    89     string line = "\nFrom    "+fileName+"\n\n00000000    0000    "+fileName.substr(fileName.rfind(PATH_SEPARATOR)+1)+"\n";
       
    90     iSymFile.write(line.c_str(),line.length());
       
    91 }
       
    92 void SymbolGenerator::ProcessArmv5File( const string& fileName, ifstream& aMap ){
       
    93     aMap.seekg (0, ios::beg);
       
    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     }
       
   104     reg.assign("Global Symbols");
       
   105     while(aMap.getline(str,MAX_LINE)) {
       
   106         if(regex_search(str, what, reg)) {
       
   107             break;
       
   108         }
       
   109     }
       
   110 
       
   111     reg.assign("^\\s*(.+)\\s*0x(\\S+)\\s+[^\\d]*(\\d+)\\s+(.*)$");
       
   112     string sSym,sTmp,sSection;
       
   113     unsigned int addr,size,baseOffset = 0;
       
   114     map<unsigned int,string> syms;
       
   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             }
       
   138             // end of addr>0
       
   139         }
       
   140         // end of regex_search
       
   141     }
       
   142 
       
   143     map<unsigned int,string>::iterator it;
       
   144     for(it = syms.begin(); it != syms.end(); it++) {
       
   145         memset(str,0,sizeof(str));
       
   146         sprintf(str,"%08x",it->first);
       
   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 
       
   165     reg.assign("^\\.text\\s+(\\w+)\\s+\\w+");
       
   166     if(!regex_search(str, what, reg)) {
       
   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 
       
   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 
       
   180         map<unsigned int,string> syms;
       
   181         unsigned int addr, len, stubhex;
       
   182 
       
   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 
       
   207         map<unsigned int,string>::iterator it = syms.begin();
       
   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 
       
   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
       
   250             boost::mutex::scoped_lock lock(me->iMutex);
       
   251             while(me->iQueueFiles.empty())
       
   252                 me->iCond.wait(lock);
       
   253             /*
       
   254             if(me->iQueueFiles.empty()) {
       
   255                 boost::this_thread::sleep(boost::posix_time::milliseconds(10));
       
   256                 continue;
       
   257             }
       
   258             */
       
   259 
       
   260             pe = me->iQueueFiles.front();
       
   261             me->iQueueFiles.pop();
       
   262         }
       
   263 
       
   264         if(pe.iFileName == "")
       
   265             break;
       
   266         else if(pe.iExecutable) 
       
   267             me->ProcessExecutable(pe.iFileName);
       
   268         else
       
   269             me->ProcessDatafile(pe.iFileName);
       
   270     }
       
   271 }
       
   272 SymbolGenerator::SymbolGenerator() : boost::thread(thrd_func) {
       
   273 }
       
   274 SymbolGenerator::~SymbolGenerator(){
       
   275     if(joinable())
       
   276         join();
       
   277     iSymFile.flush();
       
   278     iSymFile.close();
       
   279 }