--- /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);
+ }
+ }
+ }
+}