feature bsym format symbol rombuild support
authormarvin shi <marvin.shi@nokia.com>
Tue, 30 Nov 2010 17:14:57 +0800
changeset 714 e5a58c351011
parent 713 7b7f0409fc00
child 715 e0739b8406dd
feature bsym format symbol rombuild support
imgtools/buildrom/group/release.txt
imgtools/buildrom/tools/buildrom.pm
imgtools/imglib/host/h_utl.cpp
imgtools/imglib/symbolutil/logparser.cpp
imgtools/imglib/symbolutil/symbolgenerator.cpp
imgtools/imglib/symbolutil/symbolgenerator.h
imgtools/imglib/symbolutil/symbolprocessunit.cpp
imgtools/imglib/symbolutil/symbolprocessunit.h
imgtools/romtools/group/release.txt
imgtools/romtools/maksym/maksym.pl
imgtools/romtools/maksym/maksymrofs.pl
imgtools/romtools/rofsbuild/rofsbuild.cpp
imgtools/romtools/rombuild/r_build.cpp
imgtools/romtools/rombuild/r_rom.cpp
imgtools/romtools/rombuild/r_rom.h
imgtools/romtools/rombuild/rombuild.cpp
--- a/imgtools/buildrom/group/release.txt	Tue Nov 30 14:05:41 2010 +0800
+++ b/imgtools/buildrom/group/release.txt	Tue Nov 30 17:14:57 2010 +0800
@@ -1,3 +1,8 @@
+Version 3.33.0 (BUILDROM)
+===============
+Released by Marvin Shi, 30/11/2010
+	1) Feature add option for -bsymbols
+
 Version 3.32.2 (BUILDROM)
 ===============
 Released by Ross Qin, 30/11/2010
--- a/imgtools/buildrom/tools/buildrom.pm	Tue Nov 30 14:05:41 2010 +0800
+++ b/imgtools/buildrom/tools/buildrom.pm	Tue Nov 30 17:14:57 2010 +0800
@@ -67,8 +67,8 @@
 my $enforceFeatureManager = 0; # Flag to make Feature Manager mandatory if SYMBIAN_FEATURE_MANAGER macro is defined. 
 
 my $BuildromMajorVersion = 3 ;
-my $BuildromMinorVersion = 32;
-my $BuildromPatchVersion = 2;
+my $BuildromMinorVersion = 33;
+my $BuildromPatchVersion = 0;
 
 
 sub print_usage
@@ -134,6 +134,7 @@
    -geninc                          -- generate INC file
    -gendep                          -- generate dependence graph for rom image
    -nosymbols                       -- disable creation of symbol file
+   -bsymbols                        -- create symbol file in bsym format
    -noimage                         -- disable creation of ROM/ROFS/DataDrive Image
    -j<digit>                        -- do the main job with <digit> threads
    -cache                           -- allow the ROFSBUILD to reuse/generate cached executable files
@@ -296,6 +297,7 @@
 my $geninc = "";
 my $gendep = "";
 my $nosymbols = "";
+my $bsymbols = "";
 my $noimage = "";
 my $customizedPlat = undef;
 my $opt_jobs= "";
@@ -1049,6 +1051,11 @@
 			$nosymbols=1;
 			next;	
 		}
+		if ($arg =~ /^-bsymbols$/)
+		{
+			$bsymbols=1;
+			next;	
+		}
 		if ($arg =~ /^-geninc$/)
 		{
 			$geninc=1;
@@ -4563,7 +4570,17 @@
 			if ($xip)
 			{
 				is_existinpath("rombuild", romutl::DIE_NOT_FOUND);
-				$rombuild .= " -symbols" unless($nosymbols) ;
+				unless($nosymbols)
+				{
+					if($bsymbols)
+					{
+						$rombuild .= " -bsymbols";
+					}
+					else
+					{
+						$rombuild .= " -symbols";
+					}
+				}
 				run_rombuilder($rombuild.$compress, $obeyfile, $thisdir."ROMBUILD.LOG");
 			}
 			elsif($opt_xiponly == 0)
@@ -4589,7 +4606,14 @@
 					is_existinpath("rofsbuild", romutl::DIE_NOT_FOUND);
 					if(!$nosymbols)
 					{
+						if($bsymbols)
+						{
+							$rofsbuild .= " -bsymbols";
+						}
+						else
+						{
 						$rofsbuild .= " -symbols";
+						}
 					}			
 					run_rombuilder($rofsbuild.$compress, $obeyfile, $thisdir."ROFSBUILD.LOG");
 				}
--- a/imgtools/imglib/host/h_utl.cpp	Tue Nov 30 14:05:41 2010 +0800
+++ b/imgtools/imglib/host/h_utl.cpp	Tue Nov 30 17:14:57 2010 +0800
@@ -75,6 +75,7 @@
 
 void HPrint::SetLogFile(const char* aFileName)
 	{
+	iLogFile.clear();
 	iLogFile.open(aFileName);
 	}
 
--- a/imgtools/imglib/symbolutil/logparser.cpp	Tue Nov 30 14:05:41 2010 +0800
+++ b/imgtools/imglib/symbolutil/logparser.cpp	Tue Nov 30 17:14:57 2010 +0800
@@ -96,6 +96,18 @@
 					}
 				}
 			}
+			else if(linebuf.compare(0,15,"Executable File") == 0)
+			{
+				if(linebuf.find("size:", 26) != string::npos)
+				{
+					size_t startpos = linebuf.find('\'') ;
+					size_t endpos   = linebuf.rfind('\'');
+					if((startpos!=string::npos) && (endpos!=string::npos))
+					{
+						symgen->AddFile(linebuf.substr(startpos+1,endpos-startpos-1), true);
+					}
+				}
+			}
 			else if(linebuf.compare(0,26,"Compressed executable File") == 0)
 			{
 				if(linebuf.find("size:", 26) != string::npos)
--- a/imgtools/imglib/symbolutil/symbolgenerator.cpp	Tue Nov 30 14:05:41 2010 +0800
+++ b/imgtools/imglib/symbolutil/symbolgenerator.cpp	Tue Nov 30 17:14:57 2010 +0800
@@ -33,11 +33,14 @@
 boost::mutex SymbolGenerator::iMutexSingleton;
 SymbolGenerator* SymbolGenerator::iInst = NULL;
 SymbolGenerator* SymbolGenerator::GetInstance(){
-    iMutexSingleton.lock();
-    if(iInst == NULL) {
-        iInst = new SymbolGenerator();
+    if(iInst == NULL)
+    {
+    	iMutexSingleton.lock();
+    	if(iInst == NULL) {
+        	iInst = new SymbolGenerator();
+    	}
+    	iMutexSingleton.unlock();
     }
-    iMutexSingleton.unlock();
     return iInst;
 }
 void SymbolGenerator::Release() {
@@ -99,7 +102,7 @@
 
 void SymbolGenerator::SetFinished() 
 { 
-
+	boost::mutex::scoped_lock lock(iMutex);
 	iFinished = true; 
 	iCond.notify_all();
 }
@@ -142,6 +145,10 @@
 SymbolGenerator::~SymbolGenerator(){
     if(joinable())
         join();
+    for(int i=0; i < (int)iLogMessages.size(); i++)
+    {
+	    cout << iLogMessages[i];
+    }
     iSymFile.flush();
     iSymFile.close();
 }
@@ -304,7 +311,14 @@
 	SymbolGenerator* symbolgenerator = SymbolGenerator::GetInstance();
 	if(symbolgenerator->GetImageType() == ERomImage)
 	{
-		aSymbolProcessUnit = new CommenRomSymbolProcessUnit();
+		if(gGenBsymbols)
+		{
+			aSymbolProcessUnit = new BsymRomSymbolProcessUnit(symbolgenerator);
+		}
+		else
+		{
+			aSymbolProcessUnit = new CommenRomSymbolProcessUnit();
+		}
 	}
 	else
 	{
@@ -331,7 +345,7 @@
 		aSymbolProcessUnit->ProcessEntry(pe);
 
 		symbolgenerator->LockOutput();
-		aSymbolProcessUnit->FlushStdOut(cout);
+		aSymbolProcessUnit->FlushStdOut(symbolgenerator->iLogMessages);
 		aSymbolProcessUnit->FlushSymbolContent(symbolgenerator->GetOutputFileStream());
 		symbolgenerator->UnlockOutput();
 	}
--- a/imgtools/imglib/symbolutil/symbolgenerator.h	Tue Nov 30 14:05:41 2010 +0800
+++ b/imgtools/imglib/symbolutil/symbolgenerator.h	Tue Nov 30 17:14:57 2010 +0800
@@ -55,6 +55,7 @@
         void FlushSymbolFileContent();
 	void SetImageType(TImageType aImageType) {	iImageType = aImageType; };
 	TImageType GetImageType() {	return iImageType; };
+	stringlist iLogMessages;
     private:
         SymbolGenerator();
         ~SymbolGenerator();
--- a/imgtools/imglib/symbolutil/symbolprocessunit.cpp	Tue Nov 30 14:05:41 2010 +0800
+++ b/imgtools/imglib/symbolutil/symbolprocessunit.cpp	Tue Nov 30 17:14:57 2010 +0800
@@ -40,14 +40,14 @@
 	else
 		ProcessDataFile(aEntry.iFileName);
 }
-// CommenRomSymbolProcessUnit start
-void CommenRomSymbolProcessUnit::FlushStdOut(ostream& aOut)
+void SymbolProcessUnit::FlushStdOut(stringlist& aList)
 {
 	for(int i = 0; i < (int) iStdoutLog.size(); i++)
 	{
-		aOut << iStdoutLog[i];
+		aList.push_back(iStdoutLog[i]);
 	}
 }
+// CommenRomSymbolProcessUnit start
 
 void CommenRomSymbolProcessUnit::FlushSymbolContent(ostream &aOut)
 {
@@ -484,7 +484,9 @@
 			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));
-		}		
+		}
+		lastName = name;
+		lastAddr = addr;		
 	}
 
 	vector<pair<int,char*> >::iterator it; 
@@ -559,13 +561,6 @@
 	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++)
@@ -808,13 +803,6 @@
 	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);
@@ -997,3 +985,408 @@
         }
     }
 }
+
+// BsymRomSymbolProcessUnit start
+
+void BsymRomSymbolProcessUnit::ProcessEntry(const TPlacedEntry& aEntry)
+{
+	iPlacedEntry = aEntry;
+	SymbolProcessUnit::ProcessEntry(aEntry);
+	iMapFileInfo.iDbgUnitPCEntry.iPCName = aEntry.iFileName;
+	iMapFileInfo.iDbgUnitPCEntry.iDevName = aEntry.iDevFileName;
+}
+
+void BsymRomSymbolProcessUnit::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, "\nWarning: Can't open \"%s\" or \"%s\"\n",mapFile2.c_str(),mapFile.c_str());
+		iStdoutLog.push_back(str);
+	    TSymbolPCEntry tmpEntry;
+	    tmpEntry.iSymbolEntry.iAddress = iPlacedEntry.iCodeAddress;
+	    tmpEntry.iSymbolEntry.iLength = iPlacedEntry.iTotalSize;
+	    tmpEntry.iName = aFile.substr(aFile.rfind(PATH_SEPARATOR)+1);
+		iMapFileInfo.iSymbolPCEntrySet.push_back(tmpEntry);
+	    iMapFileInfo.iDbgUnitPCEntry.iDbgUnitEntry.iDataSymbolCount++;
+	}
+	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 BsymRomSymbolProcessUnit::ProcessArmv5File(const string& fileName, 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
+	size_t allocBytes;
+	boost::regex regScope("^\\s*(\\w+)\\s*::\\s*(.*)$");
+	boost::cmatch what;
+	for( ArmSymMap::iterator it = symbols.begin(); it != symbols.end() ; it++){
+		TSymbolPCEntry tmpEntry;
+		TUint32 thisAddr = it->first ;
+		TUint32 romAddr ;
+		ArmSymbolInfo& info = it->second; 
+		if (thisAddr >= textSectAddr && thisAddr <= (textSectAddr + iPlacedEntry.iTextSize)) {
+			romAddr = thisAddr - textSectAddr + iPlacedEntry.iCodeAddress ;
+			tmpEntry.iSymbolEntry.iAddress = romAddr;
+			iMapFileInfo.iDbgUnitPCEntry.iDbgUnitEntry.iCodeSymbolCount++;
+		} 
+		else if ( iPlacedEntry.iDataAddress && 
+			( thisAddr >= dataSectAddr && thisAddr <= (dataSectAddr + iPlacedEntry.iTextSize))) {
+			romAddr = thisAddr-dataSectAddr + iPlacedEntry.iDataBssLinearBase;
+			tmpEntry.iSymbolEntry.iAddress = romAddr;
+			iMapFileInfo.iDbgUnitPCEntry.iDbgUnitEntry.iDataSymbolCount++;
+		} 
+		else if ( iPlacedEntry.iDataBssLinearBase && 
+			( thisAddr >= dataSectAddr && thisAddr <= (dataSectAddr+ iPlacedEntry.iTotalDataSize))) {
+			romAddr = thisAddr - dataSectAddr + iPlacedEntry.iDataBssLinearBase;
+			tmpEntry.iSymbolEntry.iAddress = romAddr;
+			iMapFileInfo.iDbgUnitPCEntry.iDbgUnitEntry.iBssSymbolCount++;
+		} 
+		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 ;
+		}
+		tmpEntry.iSymbolEntry.iLength = info.size;
+		if(regex_search(info.name.c_str(), what, regScope))
+		{
+			tmpEntry.iScopeName.assign(what[1].first, what[1].second-what[1].first);
+			tmpEntry.iName.assign(what[2].first, what[2].second-what[2].first);
+		}
+		else
+		{
+			tmpEntry.iScopeName = "";
+			tmpEntry.iName = info.name;
+		}
+		tmpEntry.iSecName = info.section;
+		iMapFileInfo.iSymbolPCEntrySet.push_back(tmpEntry);
+	} 
+}
+
+void BsymRomSymbolProcessUnit::ProcessGcceOrArm4File(const string& fileName, 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); 
+			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()) {
+		TSymbolPCEntry tmpEntry;		
+		TUint32 addr = it->first ; 
+		unsigned int fixedupAddr = lastAddr - codeAddr + iPlacedEntry.iCodeAddress;
+		TUint size = addr - lastAddr ;
+		if(!lastSymName.empty()) {
+			tmpEntry.iSymbolEntry.iAddress = fixedupAddr;
+			tmpEntry.iSymbolEntry.iLength = size;
+			tmpEntry.iScopeName = "";
+			tmpEntry.iName = lastSymName;
+			tmpEntry.iSecName = "";
+			iMapFileInfo.iDbgUnitPCEntry.iDbgUnitEntry.iCodeSymbolCount++;
+		}		
+		lastAddr = addr ;
+		lastSymName = it->second;
+		it ++ ;
+	}
+}
+
+void BsymRomSymbolProcessUnit::ProcessX86File(const string& fileName, 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;
+	vector<pair<int, char*> >lines ;
+	while(aMap.good() && (!aMap.eof())){
+		TSymbolPCEntry tmpEntry;
+		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;
+			tmpEntry.iSymbolEntry.iAddress = romAddr;
+			tmpEntry.iSymbolEntry.iLength = size;
+			tmpEntry.iName = lastName;
+			iMapFileInfo.iSymbolPCEntrySet.push_back(tmpEntry);
+			iMapFileInfo.iDbgUnitPCEntry.iDbgUnitEntry.iCodeSymbolCount++;
+		}
+		lastName = name;
+		lastAddr = addr;		
+	}
+	if(!lastName.empty()){
+		TSymbolPCEntry tmpEntry;
+		unsigned int romAddr = lastAddr + iPlacedEntry.iCodeAddress;
+		tmpEntry.iSymbolEntry.iAddress = romAddr;
+		tmpEntry.iSymbolEntry.iLength = 0;
+		tmpEntry.iName = lastName;
+		iMapFileInfo.iSymbolPCEntrySet.push_back(tmpEntry);
+		iMapFileInfo.iDbgUnitPCEntry.iDbgUnitEntry.iCodeSymbolCount++;
+	}
+}
+
+void BsymRomSymbolProcessUnit::FlushSymbolContent(ostream &aOut)
+{
+	iSymbolGeneratorPtr->AppendMapFileInfo(iMapFileInfo);
+}
+
+void BsymRomSymbolProcessUnit::ResetContentLog()
+{
+	iStdoutLog.clear();
+	iMapFileInfo.iDbgUnitPCEntry.iPCName = "";
+	iMapFileInfo.iDbgUnitPCEntry.iDevName = "";
+	iMapFileInfo.iDbgUnitPCEntry.iDbgUnitEntry.Reset();
+	iMapFileInfo.iSymbolPCEntrySet.clear();
+}
+
+void BsymRomSymbolProcessUnit::ProcessDataFile(const string& aFile)
+{
+	ResetContentLog();
+	string basename = aFile.substr(aFile.rfind(PATH_SEPARATOR)+1);
+	TSymbolPCEntry tmpEntry;
+	tmpEntry.iSymbolEntry.iAddress = iPlacedEntry.iDataAddress;
+	tmpEntry.iSymbolEntry.iLength = 0;
+	tmpEntry.iName = basename;
+	iMapFileInfo.iSymbolPCEntrySet.push_back(tmpEntry);
+	iMapFileInfo.iDbgUnitPCEntry.iDbgUnitEntry.iDataSymbolCount++;
+}
--- a/imgtools/imglib/symbolutil/symbolprocessunit.h	Tue Nov 30 14:05:41 2010 +0800
+++ b/imgtools/imglib/symbolutil/symbolprocessunit.h	Tue Nov 30 17:14:57 2010 +0800
@@ -53,12 +53,14 @@
 public:
 	virtual void ProcessExecutableFile(const string& aFile) = 0;
 	virtual void ProcessDataFile(const string& afile) = 0;
-	virtual void FlushStdOut(ostream& aOut) = 0;
+	virtual void FlushStdOut(stringlist& aList);
 	virtual void FlushSymbolContent(ostream &aOut) = 0;
 	virtual void ResetContentLog() = 0;
 	virtual ~SymbolProcessUnit() {}
 	virtual void ProcessEntry(const TPlacedEntry& aEntry);
 	int GetSizeFromBinFile( const string& fileName );
+protected:
+	stringlist iStdoutLog;
 };
 
 class CommenRomSymbolProcessUnit : public SymbolProcessUnit
@@ -66,7 +68,6 @@
 public:
 	virtual void ProcessExecutableFile(const string& aFile);
 	virtual void ProcessDataFile(const string& afile);
-	virtual void FlushStdOut(ostream& aOut);
 	virtual void FlushSymbolContent(ostream &aOut);
 	virtual void ResetContentLog();
 	virtual void ProcessEntry(const TPlacedEntry& aEntry);
@@ -75,7 +76,6 @@
 	void ProcessGcceOrArm4File( const string& fileName, ifstream& aMap );
 	void ProcessX86File( const string& fileName, ifstream& aMap );
 private:
-	stringlist iStdoutLog;
 	stringlist iSymbolContentLog;
 	TPlacedEntry iPlacedEntry;
 };
@@ -85,14 +85,12 @@
 public:
 	virtual void ProcessExecutableFile(const string& aFile);
 	virtual void ProcessDataFile(const string& afile);
-	virtual void FlushStdOut(ostream& aOut);
 	virtual void FlushSymbolContent(ostream &aOut);
 	virtual void ResetContentLog();
 private:
 	void ProcessArmv5File( const string& fileName, ifstream& aMap );
 	void ProcessGcceOrArm4File( const string& fileName, ifstream& aMap );
 private:
-	stringlist iStdoutLog;
 	stringlist iSymbolContentLog;
 };
 
@@ -105,7 +103,6 @@
 	BsymRofsSymbolProcessUnit(){}
 	virtual void ProcessExecutableFile(const string& aFile);
 	virtual void ProcessDataFile(const string& afile);
-	virtual void FlushStdOut(ostream& aOut);
 	virtual void FlushSymbolContent(ostream &aOut);
 	virtual void ResetContentLog();
 	virtual void ProcessEntry(const TPlacedEntry& aEntry);
@@ -113,8 +110,27 @@
 	void ProcessArmv5File( const string& fileName, ifstream& aMap );
 	void ProcessGcceOrArm4File( const string& fileName, ifstream& aMap );
 private:
-	stringlist iStdoutLog;
 	MapFileInfo iMapFileInfo;
 	SymbolGenerator* iSymbolGeneratorPtr;
 };
+
+class BsymRomSymbolProcessUnit : public SymbolProcessUnit
+{
+public:
+	BsymRomSymbolProcessUnit(SymbolGenerator* aSymbolGeneratorPtr): iSymbolGeneratorPtr(aSymbolGeneratorPtr){}
+	virtual void ProcessExecutableFile(const string& aFile);
+	virtual void ProcessDataFile(const string& afile);
+	virtual void FlushSymbolContent(ostream &aOut);
+	virtual void ResetContentLog();
+	virtual void ProcessEntry(const TPlacedEntry& aEntry);
+private:
+	void ProcessArmv5File( const string& fileName, ifstream& aMap );
+	void ProcessGcceOrArm4File( const string& fileName, ifstream& aMap );
+	void ProcessX86File( const string& fileName, ifstream& aMap );
+private:
+	MapFileInfo iMapFileInfo;
+	SymbolGenerator* iSymbolGeneratorPtr;
+	TPlacedEntry iPlacedEntry;
+};
+
 #endif
--- a/imgtools/romtools/group/release.txt	Tue Nov 30 14:05:41 2010 +0800
+++ b/imgtools/romtools/group/release.txt	Tue Nov 30 17:14:57 2010 +0800
@@ -1,3 +1,10 @@
+Version 2.20.0 (ROMBUILD)
+===============
+Released by Marvin Shi, 30/11/2010
+	1) Feature bsym symbol file rombuild support
+	2) ou1cimx1#662919 rombuild hung when creating image by helium 
+	3) ou1cimx1#664530 rombuild log output mixted 
+
 Version 2.19.3 (ROMBUILD)
 ===============
 Released by Ross Qin, 30/11/2010
--- a/imgtools/romtools/maksym/maksym.pl	Tue Nov 30 14:05:41 2010 +0800
+++ b/imgtools/romtools/maksym/maksym.pl	Tue Nov 30 17:14:57 2010 +0800
@@ -55,8 +55,7 @@
 
   if(($maksym ne "") && ($maksym ne $symbolfile))
   {
-	  copy($symbolfile, $maksym);
-	  unlink $symbolfile;
+	 	rename($symbolfile, $maksym);
   }
 }
 
--- a/imgtools/romtools/maksym/maksymrofs.pl	Tue Nov 30 14:05:41 2010 +0800
+++ b/imgtools/romtools/maksym/maksymrofs.pl	Tue Nov 30 17:14:57 2010 +0800
@@ -15,8 +15,115 @@
 # Produces symbolic information given a ROFS log file and .map files for relevant binary files
 #
 
-shift @ARGV;
-my $logfile = shift @ARGV;
-my $command = "rofsbuild -loginput=$logfile";
-system ($command);
+require 5.003_07;
+no strict 'vars';
+use English;
+use FindBin;		# for FindBin::Bin
+
+# Version
+my $MajorVersion = 1;
+my $MinorVersion = 1;
+my $PatchVersion = 0;
+
+# Globals
+my $maksym = "";
+my $rofsbuild;
+my $debug = 0;
+
+&args;
+&main;
 exit 0;
+
+#
+# main
+#
+sub main()
+{
+	my $symbolfile = $rofsbuild;
+  	$symbolfile =~ s/\.log$/\.symbol/i;
+  	my @cmdres = `rofsbuild -loginput=$rofsbuild`;
+  	print "@cmdres\n";
+	if(($maksym ne "") && ($maksym ne $symbolfile))
+ 	{
+	 	rename($symbolfile, $maksym);
+  	}
+}
+#
+# args - get command line args
+#
+sub args
+{
+	my $arg;
+	my @args;
+	my $flag;
+
+	&help if (!@ARGV);
+
+	while (@ARGV) 
+	{
+		$arg = shift @ARGV;
+
+		if ($arg=~/^[\-](\S*)$/) 
+		{
+			$flag=$1;
+
+			if ($flag=~/^[\?h]$/i) 
+			{
+				&help;
+			}
+			elsif ($flag=~/^d$/i) 
+			{
+				$debug = 1;
+			}
+		       	else 
+			{
+				print "\nERROR: Unknown flag \"-$flag\"\n";
+				&usage;
+				exit 1;
+			}
+		}
+		else 
+		{
+			push @args,$arg;
+		}
+	}
+
+	if (@args)
+	{
+		$rofsbuild = shift @args;
+		if (@args) 
+		{
+			$maksym = shift @args;
+			if (@args) 
+			{
+				print "\nERROR: Incorrect argument(s) \"@args\"\n";
+				&usage;
+				exit 1;
+			}
+		}
+	}
+}
+
+sub help ()
+{
+	my $build;
+
+	print "\nmaksymrofs - Produce symbolic information given a ROFS image V${MajorVersion}.${MinorVersion}.${PatchVersion}\n";
+	&usage;
+	exit 0;
+}
+
+sub usage ()
+{
+    print <<EOF
+
+Usage:
+  maksymrofs <logfile> [<outfile>]
+
+Where:
+  <logfile>   Log file from rofsbuild tool.
+  <outfile>   Output file. Defaults to imagename.symbol.
+EOF
+    ;
+    exit 0;
+}
--- a/imgtools/romtools/rofsbuild/rofsbuild.cpp	Tue Nov 30 14:05:41 2010 +0800
+++ b/imgtools/romtools/rofsbuild/rofsbuild.cpp	Tue Nov 30 17:14:57 2010 +0800
@@ -89,9 +89,9 @@
 TBool gIsOBYUTF8 = EFalse;
 TBool gKeepGoing = EFalse;
 void PrintVersion() {
-	printf("\nROFSBUILD - Rofs/Datadrive image builder");
-	printf(" V%d.%d.%d\n", RofsbuildMajorVersion, RofsbuildMinorVersion, RofsbuildPatchVersion);
-	printf("%s\n\n", "Copyright (c) 1996-2010 Nokia Corporation.");
+	Print(EAlways,"\nROFSBUILD - Rofs/Datadrive image builder");
+	Print(EAlways, " V%d.%d.%d\n", RofsbuildMajorVersion, RofsbuildMinorVersion, RofsbuildPatchVersion);
+	Print(EAlways, "Copyright (c) 1996-2010 Nokia Corporation.");
 }
 
 char HelpText[] = 
@@ -166,7 +166,7 @@
 					gSmrFileName.assign(&argv[i][5]);
 				}
 				else {
-					printf ("ERROR: SMR obey file is missing\n");
+					Print (EError, "SMR obey file is missing\n");
 				}
 			} else if (stricmp(argv[i], "-K") == 0) {
 				gKeepGoing = ETrue;
@@ -245,7 +245,7 @@
 				if((stricmp(&argv[i][13], "UTF8")==0) || (stricmp(&argv[i][13], "UTF-8")==0))
 					gIsOBYUTF8 = ETrue;
 				else
-					printf("ERROR: Invalid encoding %s, default system internal encoding will be used.\n", &argv[i][13]);
+					Print(EError, "Invalid encoding %s, default system internal encoding will be used.\n", &argv[i][13]);
 			}
 			else if (stricmp(argv[i], "-UNCOMPRESS") == 0) {
 				gCompress = ECompressionUncompress;
@@ -253,7 +253,7 @@
 			else if( stricmp(argv[i], "-COMPRESSIONMETHOD") == 0 ) {
 				// next argument should a be method
 				if( (i+1) >= argc || argv[i+1][0] == '-') {
-					printf("ERROR: Missing compression method! Set it to default (no compression)!");
+					Print (EError, "Missing compression method! Set it to default (no compression)!");
 					gCompressionMethod = 0;
 				}
 				else {
@@ -271,7 +271,7 @@
 						gCompressionMethod = KUidCompressionBytePair;	
 					}
 					else {
-						printf("ERROR: Unknown compression method! Set it to default (no compression)!");
+						Print (EError, "Unknown compression method! Set it to default (no compression)!");
 						gCompress = ECompressionUnknown;
 						gCompressionMethod = 0;		
 					}
@@ -283,7 +283,7 @@
 				gUseCoreImage = ETrue;
 				// next argument should be image filename
 				if ((i+1 >= argc) || argv[i+1][0] == '-')
-					printf("ERROR: Missing image file name");
+					Print (EError, "Missing image file name");
 				else {
 					i++;
 					gImageFilename.assign(argv[i]);
@@ -295,7 +295,7 @@
 					gDriveFilename.assign(&argv[i][11]);	
 				}
 				else {
-					printf("ERROR: Drive obey file is missing\n"); 
+					Print (EError, "Drive obey file is missing\n"); 
 				}
 			}
 			else if (argv[i][1] == '?') {
@@ -307,7 +307,7 @@
 			else if( stricmp(argv[i], "-LOGLEVEL") == 0) {
 				// next argument should a be loglevel
 				if( (i+1) >= argc || argv[i+1][0] == '-') {
-					printf ("ERROR: Missing loglevel!");
+					Print (EError, "Missing loglevel!");
 					gLogLevel = DEFAULT_LOG_LEVEL;
 				}
 				else {
@@ -319,7 +319,7 @@
 					else if (strcmp(argv[i], "0") == 0)
 						gLogLevel = DEFAULT_LOG_LEVEL;
 					else
-						printf("ERROR: Only loglevel 0, 1 or 2 is allowed!");
+						Print(EError, "Only loglevel 0, 1 or 2 is allowed!");
 				}
 			}
 			else if( stricmp(argv[i], "-LOGLEVEL2") == 0)
@@ -338,13 +338,13 @@
 			}
 			else {
 #ifdef WIN32
-				printf ("WARNING: Unrecognised option %s\n",argv[i]);
+				Print (EWarning, "Unrecognised option %s\n",argv[i]);
 #else
 				if(0 == access(argv[i],R_OK)){
 					filename.assign(argv[i]);
 				}
 				else {
-					printf("WARNING: Unrecognised option %s\n",argv[i]);
+					Print (EWarning, "Unrecognised option %s\n",argv[i]);
 				}
 #endif				
 
@@ -371,7 +371,7 @@
 				Print (EAlways, ReallyHelpText);
 			}
 			else if (filename.empty()){
-				printf("WARNING: Obey filename is missing\n");
+				Print(EAlways, "Obey filename is missing\n");
 			}
 	}	
 }
@@ -499,8 +499,8 @@
 	if (pCPUNum != NULL)
 		gCPUNum = atoi(pCPUNum);
 #endif		
-	if(gCPUNum > MAXIMUM_THREADS)
-		gCPUNum = MAXIMUM_THREADS;
+	if(gCPUNum > MAXIMUM_THREADS >> 1)
+		gCPUNum = MAXIMUM_THREADS >> 1;
 	PrintVersion();
 	processCommandLine(argc, argv);
 	if(gThreadNum == 0) {
--- a/imgtools/romtools/rombuild/r_build.cpp	Tue Nov 30 14:05:41 2010 +0800
+++ b/imgtools/romtools/rombuild/r_build.cpp	Tue Nov 30 17:14:57 2010 +0800
@@ -1581,6 +1581,15 @@
 	}
 }
 
+char* TRomBuilderEntry::GetSystemFullName()
+{
+	TBool aIgnoreHiddenAttrib = ETrue;
+	TInt aLen = iRomNode->FullNameLength(aIgnoreHiddenAttrib);
+	char * aBuf = new char[aLen+1];
+	iRomNode->GetFullName(aBuf, aIgnoreHiddenAttrib);
+	return aBuf;
+}
+
 /**
 * TRomFile iRomEntry is a linked list through the various
 * distinct TRomEntry objects which may exist for the associated file
--- a/imgtools/romtools/rombuild/r_rom.cpp	Tue Nov 30 14:05:41 2010 +0800
+++ b/imgtools/romtools/rombuild/r_rom.cpp	Tue Nov 30 17:14:57 2010 +0800
@@ -37,6 +37,7 @@
 extern TInt gThreadNum;
 extern string gDepInfoFile;
 extern TBool gGenDepGraph;
+extern TBool gGenBsymbols;
 
 TUint32 DeflateCompressCheck(char *bytes,TInt size,ostream &os);
 void DeflateCompress(char *bytes,TInt size,ostream &os);
@@ -1307,7 +1308,7 @@
 		}
 
 	TInt fileCount=0;
-	if(gGenSymbols && !iSymGen) {
+	if((gGenSymbols || gGenBsymbols )&& !iSymGen) {
 		string filename(iObey->GetFileName());
 		iSymGen = SymbolGenerator::GetInstance();
 		iSymGen ->SetImageType(ERomImage);
@@ -1439,6 +1440,9 @@
 			TPlacedEntry context ;
 			context.iFileName = current->iFileName ;
 			context.iDataAddress = savedAddr ;
+			char* fullname = current->GetSystemFullName();
+			context.iDevFileName = fullname;
+			delete fullname;
 			iSymGen->AddEntry(context); 
 		}
 		return;
@@ -1454,6 +1458,9 @@
 			TPlacedEntry context ;
 			context.iFileName = current->iFileName ;
 			context.iDataAddress = savedAddr ;
+			char* fullname = current->GetSystemFullName();
+			context.iDevFileName = fullname;
+			delete fullname;
 			iSymGen->AddEntry(context); 
 		}		
 		return ;
@@ -1517,6 +1524,9 @@
 	if(iSymGen){
 		TPlacedEntry context  ;
 		context.iFileName = current->iFileName ;		
+		char* fullname = current->GetSystemFullName();
+		context.iDevFileName = fullname;
+		delete fullname;
 		context.iTotalSize = section1size;
 		context.iCodeAddress = header->iCodeAddress; 
 		context.iDataAddress = header->iDataAddress; 
--- a/imgtools/romtools/rombuild/r_rom.h	Tue Nov 30 14:05:41 2010 +0800
+++ b/imgtools/romtools/rombuild/r_rom.h	Tue Nov 30 17:14:57 2010 +0800
@@ -389,6 +389,7 @@
 	void FixupRomEntries(TInt aSize);
 	TRomEntry* RomEntry() const {return iRomNode->RomEntry(); };
 	void DisplaySize(TPrintType aWhere);
+	char* GetSystemFullName();
 public:
 	inline TBool Primary() const
 		{return iRomImageFlags & KRomImageFlagPrimary;}
--- a/imgtools/romtools/rombuild/rombuild.cpp	Tue Nov 30 14:05:41 2010 +0800
+++ b/imgtools/romtools/rombuild/rombuild.cpp	Tue Nov 30 17:14:57 2010 +0800
@@ -33,8 +33,8 @@
 const TInt KRomLoaderHeaderCOFF=2;
 
 static const TInt RombuildMajorVersion=2;
-static const TInt RombuildMinorVersion=19;
-static const TInt RombuildPatchVersion=3;
+static const TInt RombuildMinorVersion=20;
+static const TInt RombuildPatchVersion=0;
 static TBool SizeSummary=EFalse;
 static TPrintType SizeWhere=EAlways;
 static string compareROMName = "";
@@ -75,6 +75,7 @@
 	"                                      unpaged 	compress unpaged section only\n\n"	
 	"        -j<digit>                     do the main job with <digit> threads\n"
 	"        -symbols                      generate symbol file\n"
+	"        -bsymbols                     generate binary symbol file\n"
 	"        -compressionmethod <method>   method one of none|inflate|bytepair to set the compression\n"
 	"        -no-sorted-romfs              do not add sorted entries arrays (6.1 compatible)\n"
 	"        -oby-charset=<charset> used character set in which OBY was written\n"
@@ -137,6 +138,8 @@
 			char* arg = argv[i] + 1;
 			if (stricmp(arg, "symbols") == 0)  
 				gGenSymbols = ETrue; 
+			if (stricmp(arg, "bsymbols") == 0)  
+				gGenBsymbols = ETrue; 
 			else if (stricmp(arg, "v") == 0)
 				H.iVerbose = ETrue;
 			else if (stricmp(arg, "sl") == 0 || stricmp(arg, "slog") == 0) {
@@ -373,6 +376,11 @@
 		}
 	if (paramFileFlag)
 		return;
+	if( gGenSymbols && gGenBsymbols)
+	{
+		Print(EWarning, "Optiont symbols and bsymbols cannot be used at the same time, the  common symbols file will be created this time!");
+		gGenBsymbols = EFalse;
+	}
 	if (filename.empty() && loginput.empty()) {
  		PrintVersion();
 		cout << HelpText;
@@ -462,7 +470,7 @@
 		
 
     if(gThreadNum == 0) {
- 		if(gCPUNum > 0 && gCPUNum <= MAXIMUM_THREADS) {
+ 		if(gCPUNum > 0 && gCPUNum <= MAXIMUM_THREADS >> 1) {
  			printf("The double number of processors (%d) is used as the number of concurrent jobs.\n", gCPUNum * 2);
 			gThreadNum = gCPUNum * 2;
 		}