merge from SF
authorkelvzhu
Tue, 23 Nov 2010 10:47:23 +0800
changeset 702 341ab25bc4ef
parent 674 37ee82a83d43 (current diff)
parent 701 170c8b305768 (diff)
child 705 67449e76cb84
merge from SF
imgtools/romtools/rofsbuild/inc/logging/loggingexception.hpp
imgtools/romtools/rofsbuild/inc/logging/logparser.hpp
imgtools/romtools/rofsbuild/src/logging/loggingexception.cpp
imgtools/romtools/rofsbuild/src/logging/logparser.cpp
imgtools/romtools/rofsbuild/symbolgenerator.cpp
imgtools/romtools/rofsbuild/symbolgenerator.h
imgtools/romtools/rofsbuild/symbolprocessunit.cpp
imgtools/romtools/rofsbuild/symbolprocessunit.h
imgtools/romtools/rombuild/symbolgenerator.cpp
imgtools/romtools/rombuild/symbolgenerator.h
--- a/bintools/elftools/elftran/elf_reloc.cpp	Fri Nov 12 14:49:36 2010 +0000
+++ b/bintools/elftools/elftran/elf_reloc.cpp	Tue Nov 23 10:47:23 2010 +0800
@@ -128,7 +128,7 @@
 		checkreloc(aElfFile, *data, codeRelocs[i]->r_offset);
 		//*data=FixAddress(aElfFile, *data, codeRelocs[i]);
 		}
-// fix defect
+
 	for (TInt j=0; j<numberOfDataRelocs; j++)
 	        {
 		data=aElfFile.DataPtrFromAddr(dataRelocs[j]->r_offset);
--- a/bintools/evalid/EvalidCompare.pm	Fri Nov 12 14:49:36 2010 +0000
+++ b/bintools/evalid/EvalidCompare.pm	Tue Nov 23 10:47:23 2010 +0800
@@ -62,7 +62,8 @@
       'Unknown library' => 'identical',
       'chm file' => 'chm_file',
 	  'Header file' => 'header',
-	  'Distribution Policy' => 'distpol'
+	  'Distribution Policy' => 'distpol',
+	  'Rofs image' => 'img'
      );
 
 
@@ -83,7 +84,8 @@
       ignore => {filter => \&FilterAll},
       chm_file => {expandor => 'hh -decompile %TEMPDIR% %FILE%', rawretry => 1},
 	  header => {filter => \&FilterCVSTags},
-	  distpol => {filter => \&DistributionPolicyFilter}
+	  distpol => {filter => \&DistributionPolicyFilter},
+      img => {expandor => 'readimage -z %TEMPDIR% %FILE%', rawretry => 1}
      );
 
 
@@ -93,6 +95,7 @@
 
 my $log;
 my $verbose;
+my $keepgoing;
 my $toRoot;
 my $dumpDir;
 
@@ -108,6 +111,8 @@
   my $file2 = shift;
   $verbose = defined($_[0]) ? shift : 0;
   $log = defined($_[0]) ? shift : *STDOUT;
+  $keepgoing = defined($_[0]) ? shift : 0;
+  
   # Try binary compare first (to keep semantics the same as evalid)...
   if (DoCompareFiles($file1, $file2, 'unknown format')) {
     return 1,'identical';
@@ -354,6 +359,11 @@
     return "chm file";
   }
 
+  if ($typeBuf =~/^(ROFS|ROFx)/) {
+    # img file
+    return "Rofs image";
+  }
+
   if ($file =~ m/\.(iby|h|hby|hrh|oby|rsg|cpp)$/i) {
     return "Header file";
   }
@@ -811,34 +821,62 @@
           }, $tempdir2;
   
   #Work out the if the two file lists are different
+  my @tmpfiles;
   foreach my $file (sort keys %iFileList1)
   {
     if (! defined $iFileList2{$file})
     {
       # If the filename does not exist in the second filelist the compressed files cannot be the same.
       print ($log "Did not find $file in $file2\n") if ($verbose);
-      return 0;
+      if(!$keepgoing){
+      	return 0;
+      }else{
+      	push @tmpfiles, $file;
+      }
     } else {
       delete $iFileList2{$file}
     }
   }
+  foreach my $file (@tmpfiles)
+  {
+   	delete $iFileList1{$file};
+  }
   
   # There are extra files in the second compressed file therefore the compressed files cannot be the same.
   if (scalar(keys %iFileList2) > 0)
   {
     print ($log "$file2 contained more files than $file1\n") if ($verbose);
-    return 0;
+    if (!$keepgoing){
+	    return 0;
+	  }else{
+	  	foreach my $file (sort keys %iFileList2){
+	  		print ($log "Dig not find $file in $file1\n") if ($verbose);
+	  	}
+	  }
   }
   
   print($log "Comparing content\n") if ($verbose);
   #filelist1 and filelist2 contain all the same filenames, now compare the contents of each file
-  my $same = -1; # Variable to store collated result of comparison, assume an error
+  my $same = 1; # Variable to store collated result of comparison, assume an error
   foreach my $file (keys %iFileList1)
   {
-    my $type; 
-    ($same, $type) = CompareFiles($tempdir1.$file,$tempdir2.$file, $verbose, $log);
+  	my $tmpsame;
+  	my $type;
+    ($tmpsame, $type) = CompareFiles($tempdir1.$file,$tempdir2.$file, $verbose, $log, $keepgoing);
     print ($log "Comparing $tempdir1.$file against $tempdir2.$file\n") if ($verbose);
-    last if ($same == 0); # do not bother comparing more files if one of the expanded files is different.
+    if (!$keepgoing){
+	    if ($tmpsame == 0){ # do not bother comparing more files if one of the expanded files is different.
+	    	$same = 0;
+	    	last;
+	    }
+	  }else{
+	  	if ($tmpsame == 0){
+	  		print ($log "Failed\n\n") if ($verbose);
+	  		$same = 0;
+	  	}else{
+	  		print ($log "OK\n\n") if ($verbose);
+	  	}
+	  }
   }
   
   #Cleanup the temporary directories
--- a/bintools/evalid/EvalidCompare.pm.bak	Fri Nov 12 14:49:36 2010 +0000
+++ b/bintools/evalid/EvalidCompare.pm.bak	Tue Nov 23 10:47:23 2010 +0800
@@ -62,7 +62,8 @@
       'Unknown library' => 'identical',
       'chm file' => 'chm_file',
 	  'Header file' => 'header',
-	  'Distribution Policy' => 'distpol'
+	  'Distribution Policy' => 'distpol',
+	  'Rofs image' => 'img'
      );
 
 
@@ -83,7 +84,8 @@
       ignore => {filter => \&FilterAll},
       chm_file => {expandor => 'hh -decompile %TEMPDIR% %FILE%', rawretry => 1},
 	  header => {filter => \&FilterCVSTags},
-	  distpol => {filter => \&DistributionPolicyFilter}
+	  distpol => {filter => \&DistributionPolicyFilter},
+      img => {expandor => 'readimage -z %TEMPDIR% %FILE%', rawretry => 1}
      );
 
 
@@ -93,6 +95,7 @@
 
 my $log;
 my $verbose;
+my $keepgoing;
 my $toRoot;
 my $dumpDir;
 
@@ -108,6 +111,8 @@
   my $file2 = shift;
   $verbose = defined($_[0]) ? shift : 0;
   $log = defined($_[0]) ? shift : *STDOUT;
+  $keepgoing = defined($_[0]) ? shift : 0;
+  
   # Try binary compare first (to keep semantics the same as evalid)...
   if (DoCompareFiles($file1, $file2, 'unknown format')) {
     return 1,'identical';
@@ -240,7 +245,7 @@
     open (FILE, $file) or die "Error: Couldn't open \"$file\" for reading: $!\n";
     binmode (FILE);
     
-    while ($typeBuf =~ /^.{48}([0-9 ]{9})\x60\x0A(......)/s) {
+    while ($typeBuf =~ /^.{48}([0-9 ]{9}).\x60\x0A(......)/s) {
       # $1 is the size of the archive member, $2 is first 6 bytes of the file
       # There may be several different sorts of file in the archive, and we
       # need to scan through until we find a type we recognize:
@@ -354,6 +359,11 @@
     return "chm file";
   }
 
+  if ($typeBuf =~/^(ROFS|ROFx)/) {
+    # img file
+    return "Rofs image";
+  }
+
   if ($file =~ m/\.(iby|h|hby|hrh|oby|rsg|cpp)$/i) {
     return "Header file";
   }
@@ -811,34 +821,62 @@
           }, $tempdir2;
   
   #Work out the if the two file lists are different
+  my @tmpfiles;
   foreach my $file (sort keys %iFileList1)
   {
     if (! defined $iFileList2{$file})
     {
       # If the filename does not exist in the second filelist the compressed files cannot be the same.
       print ($log "Did not find $file in $file2\n") if ($verbose);
-      return 0;
+      if(!$keepgoing){
+      	return 0;
+      }else{
+      	push @tmpfiles, $file;
+      }
     } else {
       delete $iFileList2{$file}
     }
   }
+  foreach my $file (@tmpfiles)
+  {
+   	delete $iFileList1{$file};
+  }
   
   # There are extra files in the second compressed file therefore the compressed files cannot be the same.
   if (scalar(keys %iFileList2) > 0)
   {
     print ($log "$file2 contained more files than $file1\n") if ($verbose);
-    return 0;
+    if (!$keepgoing){
+	    return 0;
+	  }else{
+	  	foreach my $file (sort keys %iFileList2){
+	  		print ($log "Dig not find $file in $file1\n") if ($verbose);
+	  	}
+	  }
   }
   
   print($log "Comparing content\n") if ($verbose);
   #filelist1 and filelist2 contain all the same filenames, now compare the contents of each file
-  my $same = -1; # Variable to store collated result of comparison, assume an error
+  my $same = 1; # Variable to store collated result of comparison, assume an error
   foreach my $file (keys %iFileList1)
   {
-    my $type; 
-    ($same, $type) = CompareFiles($tempdir1.$file,$tempdir2.$file, $verbose, $log);
-    print ($log "Comparing $tempdir1.$file against $tempdir2.$file\n") if ($verbose);
-    last if ($same == 0); # do not bother comparing more files if one of the expanded files is different.
+  	my $tmpsame;
+  	my $type;
+    ($tmpsame, $type) = CompareFiles($tempdir1.$file,$tempdir2.$file, $verbose, $log, $keepgoing);
+    print ($log "Comparing $tempdir1.$file against $tempdir2.$file, $tmpsame, $keepgoing\n") if ($verbose);
+    if (!$keepgoing){
+	    if ($tmpsame == 0){ # do not bother comparing more files if one of the expanded files is different.
+	    	$same = 0;
+	    	last;
+	    }
+	  }else{
+	  	if ($tmpsame == 0){
+	  		print ($log "Failed\n\n") if ($verbose);
+	  		$same = 0;
+	  	}else{
+	  		print ($log "OK\n\n") if ($verbose);
+	  	}
+	  }
   }
   
   #Cleanup the temporary directories
--- a/bintools/evalid/evalid.lis	Fri Nov 12 14:49:36 2010 +0000
+++ b/bintools/evalid/evalid.lis	Tue Nov 23 10:47:23 2010 +0800
@@ -116,3 +116,4 @@
 Failed 1 of 47 comparisons
 ----------------
 
+FAILED: left\ok\Image_file\rofs.img	and right\ok\Image_file\rofs.img  (Rofs image)
--- a/bintools/evalid/evalid.pl	Fri Nov 12 14:49:36 2010 +0000
+++ b/bintools/evalid/evalid.pl	Tue Nov 23 10:47:23 2010 +0800
@@ -27,13 +27,14 @@
 my $passed=0;
 my $failed=0;
 
-GetOptions("c", "v", "l=s", "g", "f", "m", "u", "x=s@", "i=s@", "d=s");
+GetOptions("c", "v", "l=s", "k", "g", "f", "m", "u", "x=s@", "i=s@", "d=s");
 $opt_v = $opt_v; # To keep -w quiet.
 $opt_g = $opt_g; # To keep -w quiet.
 $opt_f = $opt_f; # To keep -w quiet.
 $opt_m = $opt_m; # To keep -w quiet.
 $opt_u = $opt_u; # To keep -w quiet.
 $opt_d = $opt_d; # To keep -w quiet.
+$opt_k = $opt_k; # To keep -w quiet.
 
 unless ((@ARGV > 1) && (@ARGV < 4))
 	{
@@ -61,6 +62,7 @@
 	-v            -- verbose information about failed comparisons
 	-c            -- print results to standard output
 	-l <logfile>  -- append results to <logfile>
+	-k            -- keep going
 
 The default is equivalent to "-l evalid.lis"
 
@@ -311,7 +313,7 @@
 		return;
 		}
 
-	my ($same, $type) = EvalidCompare::CompareFiles($left, $right, $opt_v, $log);
+	my ($same, $type) = EvalidCompare::CompareFiles($left, $right, $opt_v, $log, $opt_k);
 	if ($same)
 		{
 		identical($left, $right, $type);
--- a/bintools/evalid/evalid.txt	Fri Nov 12 14:49:36 2010 +0000
+++ b/bintools/evalid/evalid.txt	Tue Nov 23 10:47:23 2010 +0800
@@ -238,3 +238,18 @@
 
 When using the MD5 comparing functionality EVALID processes the contents of the temporary directory
 using the standard EVALID process but amalgamates the results in to one MD5 signiture.
+
+--------
+(ROFS IMAGE file)
+
+EVALID applies "readimage -z" to each file expanding it to a temporary directory and then compares
+the contents of the temporary directory using the following process:
+
+When directly comparing two Rofs image files EVALID will first compare the file listing of the temporary
+directories and return failed if the file listing is not identical.
+If the file listing are identical it will then compare the contents of the two temporary directories
+using the normal EVALID process.
+
+When "-k" (keepgoing) option is specified, EVALID will first compare the file listing. If "-v" option sepcified,
+list the files which do not exist in both directories. Then it will compare the contents of the directories.
+If "-v" option specified, it will report the result for every file in the directories.
Binary file bintools/evalid/left/fail/Image_file/rofs.img has changed
Binary file bintools/evalid/left/ok/Image_file/rofs.img has changed
Binary file bintools/evalid/right/fail/Image_file/rofs.img has changed
Binary file bintools/evalid/right/ok/Image_file/rofs.img has changed
--- a/bintools/evalid/tools_evalid.history.xml	Fri Nov 12 14:49:36 2010 +0000
+++ b/bintools/evalid/tools_evalid.history.xml	Tue Nov 23 10:47:23 2010 +0800
@@ -19,6 +19,10 @@
   <purpose>
   </purpose>
 	
+	<feature title="Rofs image comparison" revision="009">
+     EVALID : add Rofs image file comparison support
+  </feature>
+
 	<defect number="Bug 2413" title="evalid not so happy identifying libs created by new mwldsym2.exe" revision="008">
      EVALID : evalid not so happy identifying libs created by new mwldsym2.exe
   </defect>
--- a/bintools/evalid/tools_evalid.history.xml.bak	Fri Nov 12 14:49:36 2010 +0000
+++ b/bintools/evalid/tools_evalid.history.xml.bak	Tue Nov 23 10:47:23 2010 +0800
@@ -18,6 +18,14 @@
 <relnotes name="EVALID">
   <purpose>
   </purpose>
+	
+	<feature title="Rofs image comparison" revision="008">
+     EVALID : add Rofs image file comparison support
+  </feature>
+
+	<defect number="Bug 2413" title="evalid not so happy identifying libs created by new mwldsym2.exe" revision="008">
+     EVALID : evalid not so happy identifying libs created by new mwldsym2.exe
+  </defect>
 
   <defect number="DEF120580" title="EVALID : x86 static library comparisons sometimes fail when they shouldn't" revision="007">
      EVALID : x86 static library comparisons sometimes fail when they shouldn't
--- a/bintools/rcomp/src/messages.cpp	Fri Nov 12 14:49:36 2010 +0000
+++ b/bintools/rcomp/src/messages.cpp	Tue Nov 23 10:47:23 2010 +0800
@@ -252,8 +252,8 @@
 	Add(new Message(LT_044_Message, LT_044, "044", true, KWarning));
 
 	/* This warning has been added to hopefully fix a long standing defect where labels which 
-	 * have not been declared are silently included in the emitted resource file. More 
-	 * details at defect INC061459 */
+	 * have not been declared are silently included in the emitted resource file.  
+	 */
 	const String LT_045_Message = "the following label is used but has not been declared: ";
 	Add(new Message(LT_045_Message, LT_045, "045", true, KWarning));
 
--- a/bintools/rcomp/src/rcompl.cpp	Fri Nov 12 14:49:36 2010 +0000
+++ b/bintools/rcomp/src/rcompl.cpp	Tue Nov 23 10:47:23 2010 +0800
@@ -236,7 +236,7 @@
 static int yy_start = 0;	/* start state number */
 
 /* Flag which is used to allow yywrap()'s to do buffer switches
- * instead of setting up a fresh yyin.  A bit of a hack ...
+ * instead of setting up a fresh yyin.  
  */
 static int yy_did_buffer_switch_on_eof;
 
--- a/deprecated/etouch/etouch.cpp	Fri Nov 12 14:49:36 2010 +0000
+++ b/deprecated/etouch/etouch.cpp	Tue Nov 23 10:47:23 2010 +0800
@@ -21,7 +21,7 @@
 #endif //__MSVCDOTNET__
 
 #if defined(__VC32__) || defined(__TOOLS2__)
- #include <sys\utime.h>
+ #include <sys/utime.h>
 #else
  #include <utime.h>
 #endif
--- a/e32tools/elf2e32/group/release.txt	Fri Nov 12 14:49:36 2010 +0000
+++ b/e32tools/elf2e32/group/release.txt	Tue Nov 23 10:47:23 2010 +0800
@@ -4,6 +4,16 @@
 NOTESRC_RELEASE_REASON
 Postlinker(elf2e32) Release
 
+version 2.2 build(8)
+===============
+Released by Jason Cui, 17/11/2010
+	1) [RC] Failure ou1cimx1#612374 created : elf2e32.exe puts wrong name in library .dso file
+
+version 2.2 build(7)
+===============
+Released by Lorence Wang, 17/11/2010
+	1) Bug3494 elf2e32 treatment of ARM$$INIT_ARRAY$$Base can break GCCE builds
+
 version 2.2 build(6)
 ===============
 Released by Marvin Shi, 26/10/2010
--- a/e32tools/elf2e32/include/h_ver.h	Fri Nov 12 14:49:36 2010 +0000
+++ b/e32tools/elf2e32/include/h_ver.h	Tue Nov 23 10:47:23 2010 +0800
@@ -18,7 +18,7 @@
 
 const TInt MajorVersion=2;
 const TInt MinorVersion=2;
-const TInt Build=6;
+const TInt Build=7;
 
 #endif
 
--- a/e32tools/elf2e32/source/deffile.cpp	Fri Nov 12 14:49:36 2010 +0000
+++ b/e32tools/elf2e32/source/deffile.cpp	Tue Nov 23 10:47:23 2010 +0800
@@ -463,27 +463,27 @@
 		IsWord(iLine + iOffset, aCurrentPos);
 
 		char *cmt = strchr(iLine + iOffset, ';');
-		char *aAlias = strchr(iLine + iOffset, '=');
+		char *aExport = strchr(iLine + iOffset, '=');
 
-		if( aAlias && (!cmt || (aAlias < cmt)) )
+		if( aExport && (!cmt || (aExport < cmt)) )
 		{
-			int aAliasPos = aAlias - (iLine+ iOffset);
+			int aExportPos = aExport - (iLine+ iOffset);
 
 			//Check if alias name is also supplied, they should be separated 
-			// by whitespace, i.e., SymbolName=AliasName is valid while, 
-			// SymbolName =AliasName is invalid.
-			if( aAliasPos > aCurrentPos)
+			// by whitespace, i.e., ExportName=SymbolName is valid while,
+			// ExportName =SymbolName is invalid.
+			if( aExportPos > aCurrentPos)
 			{
 				char *aToken = (iLine + iOffset + aCurrentPos);
 				throw DEFFileError(UNRECOGNIZEDTOKEN, iFileName, iLineNum, aToken);
 			}
 
-			aSymbolName = new char[aAliasPos+1];
-			strncpy(aSymbolName, iLine + iOffset, aAliasPos);
-			aSymbolName[aAliasPos] = '\0';
-			char *aExportName = new char[aCurrentPos - aAliasPos + 1];
-			strncpy(aExportName, aAlias +1, (aCurrentPos - aAliasPos));
-			aExportName[(aCurrentPos - aAliasPos)] = '\0';
+			char* aExportName = new char[aExportPos+1];
+			strncpy(aExportName, iLine+iOffset, aExportPos);
+			aExportName[aExportPos] = '\0';
+			aSymbolName = new char[aCurrentPos - aExportPos + 1];
+			strncpy(aSymbolName, aExport +1, (aCurrentPos - aExportPos));
+			aSymbolName[(aCurrentPos - aExportPos-1)] = '\0';
 			iSymbol->ExportName(aExportName);
 		}
 		else
--- a/e32tools/elf2e32/source/e32imagefile.cpp	Fri Nov 12 14:49:36 2010 +0000
+++ b/e32tools/elf2e32/source/e32imagefile.cpp	Tue Nov 23 10:47:23 2010 +0800
@@ -495,7 +495,7 @@
 		aRelocsSize = Align(rsize + sizeof(E32RelocSection), sizeof(uint32));
 
 		uint32 aBase = (*aRelocList.begin())->iSegment->p_vaddr;
-		//add for cleanup to be done later..
+		
 		cleanupStack.push_back(aRelocs);
 		aRelocs =	new char [aRelocsSize];
 		memset(aRelocs, 0, aRelocsSize);
--- a/e32tools/elf2e32/source/pl_elfexecutable.cpp	Fri Nov 12 14:49:36 2010 +0000
+++ b/e32tools/elf2e32/source/pl_elfexecutable.cpp	Tue Nov 23 10:47:23 2010 +0800
@@ -1438,7 +1438,7 @@
 
 	try {
 
-		bool limitSymbolFound = false;
+		bool specialSymbolFound = false;
 
 		// If Symbol is absolute then assume it came from linker and is a
 		// limit symbol.
@@ -1448,19 +1448,21 @@
 		}
 		else
 		{
+			// does the symbol point to the address after the end of the code or data segments?
 			if( (iCodeSegmentHdr && aSym->st_value == (iCodeSegmentHdr->p_vaddr + iCodeSegmentHdr->p_memsz)) ||
 				(iDataSegmentHdr && aSym->st_value == (iDataSegmentHdr->p_vaddr + iDataSegmentHdr->p_memsz)) )
 			{
-				//If Symbol is a $$Limit symbol, then consider the open boundary.
-				String limitstr = iStringTable + aSym->st_name;
-				if (limitstr.rfind("$$Limit",limitstr.length()) != String::npos)
+				//If Symbol contains $$, it is linker generated so consider the open boundary.
+ 				//e.g. SHT$$INIT_ARRAY$$Limit and sometimes SHT$$INIT_ARRAY$$Base 
+ 				String aSymstr = iStringTable + aSym->st_name;
+ 				if (aSymstr.rfind("$$",aSymstr.length()) != String::npos)
 				{
 					aHdr = SegmentFromAbs(aSym->st_value);
-					limitSymbolFound = true;
+					specialSymbolFound = true;
 				}
 			}
 
-			if(!limitSymbolFound )
+			if(!specialSymbolFound )
 			{
 				aHdr = Segment(aSym->st_value);
 			}
--- a/e32tools/elf2e32/source/pl_elfproducer.cpp	Fri Nov 12 14:49:36 2010 +0000
+++ b/e32tools/elf2e32/source/pl_elfproducer.cpp	Tue Nov 23 10:47:23 2010 +0800
@@ -172,7 +172,10 @@
 	while(aItr != aEnd) {
 		String		aSymName("");
 		aSym = *aItr;
-		aSymName = aSym->SymbolName();
+		if(aSym->ExportName())
+			aSymName = aSym->ExportName();
+		else
+			aSymName = aSym->SymbolName();
 		//set symbol info..
 		iElfDynSym[aIdx].st_name = iDSOSymNameStrTbl.size();
 
@@ -183,7 +186,10 @@
 
 		//set version table info...
 		iVersionTbl[aIdx] = DEFAULT_VERSION;
-		AddToHashTable(aSym->SymbolName(), aIdx);
+		if(aSym->ExportName())
+			AddToHashTable(aSym->ExportName(), aIdx);
+		else
+			AddToHashTable(aSym->SymbolName(), aIdx);
 		aItr++;aIdx++;
 	}
 
--- a/imgtools/buildrom/group/BLD.INF	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/buildrom/group/BLD.INF	Tue Nov 23 10:47:23 2010 +0800
@@ -59,6 +59,7 @@
 ../tools/featuresdat.pm		/epoc32/tools/featuresdat.pm
 ../tools/features.pl		/epoc32/tools/features.pl
 ../tools/features.pm		/epoc32/tools/features.pm
+../tools/featureconfigurator.pl		/epoc32/tools/featureconfigurator.pl
 
 #ifndef TOOLS2_LINUX 
 ../tools/features.cmd		/epoc32/tools/features.cmd
--- a/imgtools/buildrom/group/release.txt	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/buildrom/group/release.txt	Tue Nov 23 10:47:23 2010 +0800
@@ -1,3 +1,8 @@
+Version 3.32.0 (BUILDROM)
+===============
+Released by Ross Qin, 18/11/2010
+	1) Moving feature configuration out of the buildrom scope.
+	
 Version 3.31.0 (BUILDROM)
 ===============
 Released by Lorence Wang, 20/10/2010
--- a/imgtools/buildrom/tools/buildrom	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/buildrom/tools/buildrom	Tue Nov 23 10:47:23 2010 +0800
@@ -1,2 +1,8 @@
 #!/bin/sh
-perl -S buildrom.pl $@
+PRGDIR=`dirname "$0"`
+
+PRGDIR=`cd "$PRGDIR"; pwd`
+
+
+perl "$PRGDIR/buildrom.pl" $@
+
--- a/imgtools/buildrom/tools/buildrom.pm	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/buildrom/tools/buildrom.pm	Tue Nov 23 10:47:23 2010 +0800
@@ -67,7 +67,7 @@
 my $enforceFeatureManager = 0; # Flag to make Feature Manager mandatory if SYMBIAN_FEATURE_MANAGER macro is defined. 
 
 my $BuildromMajorVersion = 3 ;
-my $BuildromMinorVersion = 31;
+my $BuildromMinorVersion = 32;
 my $BuildromPatchVersion = 0;
 
 
@@ -75,13 +75,18 @@
 {
 
 	# Option "-fm" will be supported instead of option "-f|fr" if SYMBIAN_FEATURE_MANAGER macro is defined.
-	my $featuresOptionUsage = "-ffeatureuids or -fr=featureuids -- feature registry database XML file name";
+	my $featuresOptionUsage = "-ffeatureuids or -fr=featureuids -- [obsolete] Feature registry database XML file name\n". 
+							   "                                       Please use featureconfigurator.pl to configurate features.\n\n".
+							   "   -nofm                            -- Don't perform feature configuration \n\n"; 
 	if ($enforceFeatureManager) 
 	{
-		$featuresOptionUsage = "-fm=featuredatabasefile          -- feature manager/feature registry database XML file name.\n".
-							   "\t\t\t\t    Multiple XML files can be passed seperated by commas.\n".
-							   "   -nofm=featuresdatafile           -- don't generate features data file.".
-							   " Instead use pre-built features data file.";
+		$featuresOptionUsage = "-fm=featuredatabasefile          -- [obsolete] Feature manager/feature registry database XML file name.\n".
+							   "                                       Multiple XML files can be passed seperated by commas.\n". 
+							   "                                       Please use featureconfigurator.pl to configurate features.\n\n".				
+							   "   -nofm=featuresdatafile           -- [obsolete] Don't generate features data file.\n".
+							   "                                       Use pre-built features data file instead.\n". 
+							   "                                       Please use featureconfigurator.pl to configurate features.\n\n".
+							   "   -nofm                            -- Don't perform feature configuration\n\n";							  
 	}
 
 #........1.........2.........3.........4.........5.........6.........7.....
@@ -117,7 +122,8 @@
    -p                               -- preserves the intermediate files pertaining to data drive, Z drive and BMCONV
    -spi                             -- enable producing SPI files
    -spiplacement                    -- enable positioning of spi file
-   -w                               -- warn if file has been selected from a different directory 
+   -w                               -- warn if file has been selected from a different directory
+   
    $featuresOptionUsage
    -etool                           -- external tool specification (xx is tool's perl module)
    -compress                        -- compression type of ROM image:
@@ -159,7 +165,9 @@
    -prependepocroot                 -- if there is no EPOCROOT## before /epoc32/, prepend EPOCROOT## to epoc32.
    -stdcpp                          -- ignore symbian customized cpp and try to find another cpp in the PATH.(for Windows only)
    -cpp=xxx                         -- specify a CPP preprocessor used by Buildrom.
-   -xiponly                      -- just create the XIP ROM image without creating the ROFS image.
+   -xiponly                         -- just create the XIP ROM image without creating the ROFS image.
+   -nopreprocess                    -- Input oby files have been or don't need to be preprocessed,
+                                       don't preprocess the input oby files.
    -inputoby=<finalOBYfile>         -- Ignore BUILDROM config phase, invoke Rombuild/Rofsbuild using <finalOBYfile>.
                                     <finalOBYfile> must contain one and ONLY one of romsize/rofssize/dataimagename/imagename keywords,
                                     The keywords will be used to identify the OBY type.
@@ -278,6 +286,7 @@
 my $featuremanager = 0; #Flag to enable support for feature manager database XML file and to generate  
 			# features data file.
 my $noFeatureManager = 0; # Flag to stop the generation of features.dat file and use pre-built features.dat if provided.
+my $noFeatureConf  = 0 ;
 my $preBuiltFeaturesDataFile  = ''; # To store the name of pre-built features.dat file provided with "-nofm" option.
 
 #Image Content XML file that supports specific feature to be added
@@ -359,6 +368,7 @@
 my $preprocessor = "cpp";
 my $opt_xiponly = 0;
 my $ignoreconfig = 0;
+my $nopreprocess = 0;
 my $romcount = 0;
 
 sub match_obyfile
@@ -755,8 +765,7 @@
 
 	my ($paramFileFlag, @argList); 
 
-	if (defined @_)
-	{
+	if (defined @_ && scalar(@_) > 0) {
 		($paramFileFlag, @argList) = @_;
 	}
 	else
@@ -783,13 +792,15 @@
 		}
 	}
 	# first searching argList for keepgoing option
+	my @newArgList = ();
 	foreach my $arg (@argList) {
-		if ( $arg =~ /^-k$/i || $arg =~ /^-keepgoing$/i )
-	  {
-			$opt_k = 1;		
-  		next;	
-		}
-		if ($arg =~ /^-workdir=(.*)/)
+		if ( $arg =~ /^-k$/i || $arg =~ /^-keepgoing$/i ) {
+			$opt_k = 1;	 
+		}
+		elsif($arg =~ /^-nopreprocess$/i ) {
+			$nopreprocess = 1 ; 
+		}
+		elsif ($arg =~ /^-workdir=(.*)/)
 		{
 			my $workdir = $1;
 			if (!-d $workdir)
@@ -806,11 +817,13 @@
 				$thisdir =~ s-\/-\\-g;
 			}
 			$opt_workdir = 1;
-			chdir "$currentdir";
-			next;	
+			chdir "$currentdir"; 
+		}
+		else {
+			push @newArgList, $arg ;
 		}
 	}
-	foreach my $arg (@argList)
+	foreach my $arg (@newArgList)
 	{
 	    if ($arg =~ /^-argfile=(.*)/) 
 		{
@@ -927,6 +940,7 @@
 				$errors++;
 				next;
 			}
+			$noFeatureConf = 0;
 			$featureXml = $1;
 			$xmlrequired = 1;
 			$featuremanager = 1;
@@ -978,14 +992,18 @@
 	    	}
 	    	next;
 	    }
-		if ($arg =~ /^-nofm(=(.*))?$/)
-		{
-			if (!$enforceFeatureManager) 
-			{
-				print "Unknown arg: $arg\n";
+		if ($arg =~ /^-nofm(=(.*))?$/) {
+			if(!$1) {
+                $noFeatureConf = 1 ;
+				next ;
+            }
+			 
+			if (!$enforceFeatureManager)  {
+				print "Unsupported option: $arg\n";
 				$errors++;
 				next;
-			}
+			} 
+			$noFeatureConf = 0;
    			$noFeatureManager = 1;
             #DEF125375 If caller is simply giving -nofm without any parameter, a warning message will be given.
             if(!$2)
@@ -1050,42 +1068,49 @@
 			$checkcase_test=1;
 			next;	
 		}
-		if ($arg =~ /^-workdir=(.*)/)
-		{
-			next;
-		}
+		 
 		if ($arg =~ /^-stdcpp$/)
-		{
-			if (&is_linux)
-			{
-				print "Warning: option -stdcpp only apply for Windows\n";
-				next;
+		{	
+			if($nopreprocess) {
+				print STDERR "Warning: -stdcpp option is invalid because the -nopreprocess option set.\n";
 			}
-			if ($cppoption)
-			{
-				die "Error: -stdcpp option and -cpp=xxx option cannot be used at the same time.\n";
+			else {
+				if (&is_linux)
+				{
+					print "Warning: option -stdcpp only apply for Windows\n";
+					next;
+				}
+				if ($cppoption)
+				{
+					die "Error: -stdcpp option and -cpp=xxx option cannot be used at the same time.\n";
+				}
+				$stdcpp = 1;
 			}
-			$stdcpp = 1;
 			next;
 		}
 		if ($arg =~ /^-cpp=(.*)/)
 		{
-			if ($stdcpp)
-			{
-				die "Error: -stdcpp option and -cpp=xxx option cannot be used at the same time.\n";
-			}
-			if ($cppoption)
-			{
-				print "Warning: -cpp option has been set before. The previous configuration will be overwritten!\n";
+			if($nopreprocess) {
+				print STDERR "Warning: -cpp option is invalid because the -nopreprocess option set.\n";
 			}
-			$cppoption = 1;
-			$preprocessor = $1;
-			$preprocessor =~ s-\\-\/-g;
-			$preprocessor =~ s-EPOCROOT##\/?-$epocroot-g;
-			if (-d $preprocessor)
-			{
-				$preprocessor .= "\/" unless $preprocessor =~ /\/$/;
-				$preprocessor .= "cpp";
+			else {
+				if ($stdcpp)
+				{
+					die "Error: -stdcpp option and -cpp=xxx option cannot be used at the same time.\n";
+				}
+				if ($cppoption)
+				{
+					print "Warning: -cpp option has been set before. The previous configuration will be overwritten!\n";
+				}
+				$cppoption = 1;
+				$preprocessor = $1;
+				$preprocessor =~ s-\\-\/-g;
+				$preprocessor =~ s-EPOCROOT##\/?-$epocroot-g;
+				if (-d $preprocessor)
+				{
+					$preprocessor .= "\/" unless $preprocessor =~ /\/$/;
+					$preprocessor .= "cpp";
+				}
 			}
 			next;
 		}
@@ -1265,11 +1290,6 @@
 			}
 			next;
 		}
-		if ( $arg =~ /^-k$/i || $arg =~ /^-keepgoing$/i )
-	    {
-			$opt_k = 1;
-			next;
-	    }
 		if ( $arg =~ /^-r$/i || $arg =~ /^-retainfolder$/i )
 	    {
 			$opt_r = 1;
@@ -1391,98 +1411,122 @@
 
 sub preprocessing_phase
 {
-	my $temp1OBYFile = $thisdir."tmp1.oby";
-	unlink "$temp1OBYFile";
-
-#	Macro "ROM_FEATURE_MANAGEMENT" is defined when "-f|fr" or "-fm" is used
-	if (defined ($featureXml))
-	{
-		$cppargs .= " -DROM_FEATURE_MANAGEMENT ";
-	}
-
-	# add pre-include file and include directories for feature variants
-	if ($featureVariant{'VALID'})
-	{
-		$cppargs .= " -I.";
-		my $incRef = $featureVariant{'ROM_INCLUDES'};
-		if ($incRef)
+	if($nopreprocess == 0) {
+		my $temp1OBYFile = $thisdir."tmp1.oby";
+		unlink "$temp1OBYFile";
+
+	#	Macro "ROM_FEATURE_MANAGEMENT" is defined when "-f|fr" or "-fm" is used
+		if (defined ($featureXml))
 		{
-			foreach (@$incRef)
+			$cppargs .= " -DROM_FEATURE_MANAGEMENT ";
+		}
+
+		# add pre-include file and include directories for feature variants
+		if ($featureVariant{'VALID'})
+		{
+			$cppargs .= " -I.";
+			my $incRef = $featureVariant{'ROM_INCLUDES'};
+			if ($incRef)
+			{
+				foreach (@$incRef)
+				{
+					$cppargs .= " -I \"$_\"";
+				}
+			}
+			my $HRH = $featureVariant{'VARIANT_HRH'};
+			if ($HRH)
 			{
-		    	$cppargs .= " -I \"$_\"";
+				$cppargs .= " -include \"$HRH\"";
 			}
 		}
-		my $HRH = $featureVariant{'VARIANT_HRH'};
-		if ($HRH)
+		else
+		{
+			# no feature variant so use the standard includes
+			$cppargs .= " -I. -I \"$rominclude\"";
+		}
+
+		if ($stdcpp)
+		{
+			$preprocessor = find_stdcpp();
+		}
+		print "* $preprocessor -Wno-endif-labels -o $temp1OBYFile $cppargs\n" if ($opt_v);
+		
+		is_existinpath("$preprocessor", romutl::DIE_NOT_FOUND);
+		$errors = 0;
+		open CPP, "| $preprocessor -Wno-endif-labels -o $temp1OBYFile $cppargs" or die "* Can't execute cpp";
+		foreach my $arg (@obyfiles)
 		{
-		    $cppargs .= " -include \"$HRH\"";
-		}
-	}
-	else
-	{
-		# no feature variant so use the standard includes
-		$cppargs .= " -I. -I \"$rominclude\"";
-	}
-
-	if ($stdcpp)
-	{
-		$preprocessor = find_stdcpp();
+			print CPP "\n#line 1 \"$arg\"\n";
+		
+			if(open(OBY, $arg)) {
+				print "* reading $arg\n" if ($opt_v);
+				while ($line=<OBY>) {
+					print CPP $line;
+				}
+				close OBY;
+			}
+			else {
+				print STDERR "* Can't open $arg\n";
+				if(!$opt_k){			
+					close CPP;
+					exit(1);
+				}
+			}
+		}
+		close CPP;
+		my $cpp_status = $?;
+		die "* cpp failed\n" if ($cpp_status != 0 || !-f "$temp1OBYFile");
+
+		if( defined ($image_content))
+		{
+			#Read the OBY file that was generated by the pre-processor
+			&ReadPreprocessedFile($temp1OBYFile);
+
+	#		Check if the static dependencies of the OBY binaries are resolved.
+			&ImageContentHandler::UpdateObyBinaryStaticDep();
+			
+			#Now append the files collected from cdfs.
+			&ImageContentHandler::GenObyFile($temp1OBYFile);
+		}
+
+		if($obycharset =~ /utf-?8/i)
+		{
+			my $utf8file = $thisdir."tmp1utf8.oby";
+			open INFILE, "<$temp1OBYFile" or die "* Can't open file $temp1OBYFile";
+			open CHARSETTRAN, "| charsettran -to=hostcharset > $utf8file" or die "* Can't execute charsetran";
+			while(<INFILE>)
+			{
+				print CHARSETTRAN $_;
+			}
+			close CHARSETTRAN;
+			close INFILE;	
+			unlink $temp1OBYFile  or die "* Can't remove file $temp1OBYFile";
+			rename 	$utf8file, $temp1OBYFile or die "* Can't rename file $utf8file to file $temp1OBYFile";
+		}
+		@obydata = ();
+		# load tmp1.oby here
+		open TMP1, "$temp1OBYFile" or die("* Can't open $temp1OBYFile\n");
+		while(<TMP1>) { 
+			push @obydata,$_;
+		}
+		close TMP1 ;
 	}
-	print "* $preprocessor -Wno-endif-labels -o $temp1OBYFile $cppargs\n" if ($opt_v);
-	
-	is_existinpath("$preprocessor", romutl::DIE_NOT_FOUND);
-	$errors = 0;
-	open CPP, "| $preprocessor -Wno-endif-labels -o $temp1OBYFile $cppargs" or die "* Can't execute cpp";
-	foreach my $arg (@obyfiles)
-	{
-		print CPP "\n#line 1 \"$arg\"\n";
-	
-		if(open(OBY, $arg)) {
-			print "* reading $arg\n" if ($opt_v);
-			while ($line=<OBY>) {
-				print CPP $line;
-			}
-			close OBY;
-		}
-		else {
-			print STDERR "* Can't open $arg\n";
-			if(!$opt_k){			
-				close CPP;
-				exit(1);
+	else {
+		foreach my $arg (@obyfiles) {		
+			if(open(OBY, $arg)) {
+				print "* reading $arg\n" if ($opt_v);
+				while (<OBY>) {
+					push @obydata,$_;
+				}
+				close OBY;
 			}
-		}
-	}
-	close CPP;
-	my $cpp_status = $?;
-	die "* cpp failed\n" if ($cpp_status != 0 || !-f "$temp1OBYFile");
-
-	if( defined ($image_content))
-	{
-		#Read the OBY file that was generated by the pre-processor
-		&ReadPreprocessedFile($temp1OBYFile);
-
-#		Check if the static dependencies of the OBY binaries are resolved.
-		&ImageContentHandler::UpdateObyBinaryStaticDep();
-		
-		#Now append the files collected from cdfs.
-		&ImageContentHandler::GenObyFile($temp1OBYFile);
-	}
-
-	# Setup default rom configuration
-	$romimage[0] = {xip=>1, compress=>0, extension=>0, composite=>"none",uncompress=>0 };
-	if($obycharset =~ /utf-?8/i)
-	{
-		my $utf8file = $thisdir."tmp1utf8.oby";
-		open INFILE, "<$temp1OBYFile" or die "* Can't open file $temp1OBYFile";
-		open CHARSETTRAN, "| charsettran -to=hostcharset > $utf8file" or die "* Can't execute charsetran";
-		while(<INFILE>)
-		{
-			print CHARSETTRAN $_;
-		}
-		close CHARSETTRAN;
-		close INFILE;	
-		unlink $temp1OBYFile  or die "* Can't remove file $temp1OBYFile";
-		rename 	$utf8file, $temp1OBYFile or die "* Can't rename file $utf8file to file $temp1OBYFile";
+			else {
+				print STDERR "* Can't open $arg\n";
+				if(!$opt_k){	 
+					exit(1);
+				}
+			}
+		}
 	}
 }
 
@@ -1553,50 +1597,46 @@
 		$substitutionData{"RIGHT_NOW"} = sprintf("%02d/%02d/%04d %02d:%02d:%02d", $mday, $mon+1, $year+1900, $hour, $min, $sec);
 		$substitutionData{"EPOCROOT"} = $epocroot;
 		@substitutionOrder = ("TODAY", "RIGHT_NOW", "EPOCROOT");
-	}
-
-	my $temp1OBYFile = $thisdir."tmp1.oby";
-	
-	open TMP1, "$temp1OBYFile" or die("* Can't open $temp1OBYFile\n");
-	while ($line=<TMP1>)
-	{
-		if(($line =~ /^\s*romsize\s*=/i) || ( $line=~ /^\s*rom_image/i) || ($line =~ /^\s*data_image/i))
-		{
+	}	 
+	 
+	foreach $line(@obydata) {
+		if(($line =~ /^\s*romsize\s*=/i) || ( $line=~ /^\s*rom_image/i) || ($line =~ /^\s*data_image/i)) {
 			$onlysmrimage = 0;
 			last;
 		}
 	}
-	close TMP1;	
-	if ($enforceFeatureManager && (!$featuremanager) && (!$noFeatureManager) )
-	{
-		my $defaultFeatureDbFlag = 0;
-		open TMP1, "$temp1OBYFile" or die("* Can't open $temp1OBYFile\n");
-		while ($line=<TMP1>)
-		{
-			if ($line=~/^\s*defaultfeaturedb\s*=?\s*(\S+)/i)
-			{	
-				# Get the default value for featuredatabasefile
-                
-				$featureXml = "$epocroot$1";
-				$featureXml =~ s-\\-\/-g;
-				$featuremanager = 1;				
-				$defaultFeatureDbFlag = 1;
-				load_featuresutil();				
-				last;
+	if($noFeatureConf == 0) { 
+		if ($enforceFeatureManager && (!$featuremanager) && (!$noFeatureManager) ) {
+			my $defaultFeatureDbFlag = 0;
+			foreach $line(@obydata) { 
+				if ($line=~/^\s*defaultfeaturedb\s*=?\s*(\S+)/i)
+				{	
+					# Get the default value for featuredatabasefile
+					
+					$featureXml = "$epocroot$1";
+					$featureXml =~ s-\\-\/-g;
+					$featuremanager = 1;				
+					$defaultFeatureDbFlag = 1;
+					load_featuresutil();				
+					last;
+				}
 			}
-		}
-		close TMP1;
-
-		if(!$defaultFeatureDbFlag && !$onlysmrimage)
-		{
-			print "Error: Neither option \"-fm|-nofm\" nor default value for featuredatabase file is provided.\n";
-			exit(1);			
+		 
+
+			if(!$defaultFeatureDbFlag && !$onlysmrimage)
+			{
+				print "Error: Neither option \"-fm|-nofm\" nor default value for featuredatabase file is provided.\n";
+				exit(1);			
+			}
 		}
 	}
-
-	open TMP1, "$temp1OBYFile" or die("* Can't open $temp1OBYFile\n");
-	while ($line=<TMP1>)
-	{
+	
+	# Setup default rom configuration
+	$romimage[0] = {xip=>1, compress=>0, extension=>0, composite=>"none",uncompress=>0 }; 
+		
+	my @savedObyData = @obydata;
+	@obydata = ();
+	foreach  $line(@savedObyData) {
 		track_source($line);
 		$line =~ s-\\-\/-g;
 
@@ -1653,19 +1693,19 @@
  				}
  			}
 		}
-
-		if($line =~ /^\s*FEATURE\s*(.*)/i || $line =~ /^\s*EXCLUDE_FEATURE\s*(.*)/i)
-		{
-			# Process the feature keywords only when "-f|fr" or "-fm" is passed to buildrom
-			if(defined ($featureXml))
-			{
-				push @obydata, "$line";
+		if($noFeatureConf == 0) { 
+			if($line =~ /^\s*FEATURE\s*(.*)/i || $line =~ /^\s*EXCLUDE_FEATURE\s*(.*)/i) {
+				# Process the feature keywords only when "-f|fr" or "-fm" is passed to buildrom
+				if(defined ($featureXml))
+				{
+					push @obydata, "$line";
+				}
+				else
+				{
+					push @obydata, "REM handled $line";
+				}
+				next;
 			}
-			else
-			{
-				push @obydata, "REM handled $line";
-			}
-			next;
 		}
 
 		if ($line=~/^\s*DEFINE\s+(\w+)\s+(\S+)/i)
@@ -2659,14 +2699,14 @@
 my $spicount=0; #counts number of spi files in each rom image
 my $filescount=0; #counts number of data files
 my $hidefilescount=0; #counts number of data files to be hidden
-my $romimage=0; #number of rom image currently working with
+my $romimagecount=0; #number of rom image currently working with
 
 sub locateexisting 
 { # if an SPI file of this type exists in a base image then returns name of SPI file from the array
-	my ($romimage, $spifile, $base) =@_;
+	my ($index, $spifile, $base) =@_;
 	my $i=0;
 	while(defined $spiarray[$base][$i]) {
-		if($spiarray[$base][$i]{spi} eq $spiarray[$romimage][$spifile]{spi}) {
+		if($spiarray[$base][$i]{spi} eq $spiarray[$index][$spifile]{spi}) {
 			my $spiname;
 			my $spiextension;
 			if($spiarray[$base][$i]{spifile} =~ /(.*)\.(.*)$/) {
@@ -2684,27 +2724,27 @@
 
 sub create 
 { #called to create SPI file and store in specified directory
-	my ($romimage, $spifile, $base) =@_; #$romimage = current rom image number, $spifile = current spifile number, $base=number of rom image basing on
+	my ($index, $spifile, $base) =@_; #$index = current rom image number, $spifile = current spifile number, $base=number of rom image basing on
 	my $existingspi = "";
 	if(defined($base)) { # checks core image for an existing SPI file of this type, if an existing file exists then $existingspi is set to -i<name of existing spi file> which will later be passed to spitool.pm
-		$existingspi = locateexisting($romimage, $spifile, $base);
+		$existingspi = locateexisting($index, $spifile, $base);
 		if($existingspi ne "") {
 			$existingspi = "-i$existingspi";
 			
 		}
 	}
-	if($spiarray[$romimage][$spifile]{spifile} =~ /(.+)\.(.*)$/) {
-		my $targetspi="$1-$romimage-$spifile\.$2"; #add romimage number and identifier for spi file to spi file name to distinguish from other spi files
+	if($spiarray[$index][$spifile]{spifile} =~ /(.+)\.(.*)$/) {
+		my $targetspi="$1-$index-$spifile\.$2"; #add romimage number and identifier for spi file to spi file name to distinguish from other spi files
 		my @dataforspi; # array to store names of data files to include in spi file
 		my @hidedatainspi; # array to store names of data files that are to be hidden in spi file
 		for(my $k=0;$k<scalar @datafiles;$k++) {
-			if($datafiles[$k]{rom}==$romimage && $datafiles[$k]{spifile} == $spifile) {
+			if($datafiles[$k]{rom}==$index && $datafiles[$k]{spifile} == $spifile) {
 				push @dataforspi, $datafiles[$k]{data}; #push name of data file onto array if correct romimage and spi type
 			}
 		}
 
 		for(my $j=0;$j<scalar @hidedatafiles;$j++) {
-			if($hidedatafiles[$j]{rom}==$romimage && $hidedatafiles[$j]{spifile} == $spifile)
+			if($hidedatafiles[$j]{rom}==$index && $hidedatafiles[$j]{spifile} == $spifile)
 			{
 				push @hidedatainspi, $hidedatafiles[$j]{data}; #push name of data file to be hidden onto array if correct romimage and spi type
 			}
@@ -2740,7 +2780,7 @@
 		{
 			if ($line=~/^\s*REM \s*ROM_IMAGE\[(\d)\]/) # specify which romimage following lines are part of
 			{
-				$romimage=$1;
+				$romimagecount=$1;
 				$spicount=0;
 			}	elsif ($line =~ /^\s*REM/i)
 			{
@@ -2751,36 +2791,36 @@
 				my $flag=1;
 				my $i;
 				for($i=0;$i<$spicount && $flag;$i++) { #loop to see if name of spi file already added to this romimage in array
-					if($spiarray[$romimage][$i]{spi} eq $targetspi) {
+					if($spiarray[$romimagecount][$i]{spi} eq $targetspi) {
 						$flag=0;
 					}
 				}
 			
 				if($flag) { # adds spi file if not yet listed for this romimage in array
-					$spiarray[$romimage][$spicount++]={spifile=>$3, spidir=>$4, spi=>$4.$3};
+					$spiarray[$romimagecount][$spicount++]={spifile=>$3, spidir=>$4, spi=>$4.$3};
 					$i=$spicount;
 				}
-					$datafiles[$filescount++]= {data=>$1, rom=>$romimage, spifile=>$i-1}; 
+					$datafiles[$filescount++]= {data=>$1, rom=>$romimagecount, spifile=>$i-1}; 
                         } elsif ($spiplacement && $line =~/^\s*SPI_POSITION/i){
         			# mark the image index at which the SPI_POSITION keyword has occured in order to avoid writing duplicate
         			# entries of the spi file.
-        			$spipositionflag{$romimage} = 1;
+        			$spipositionflag{$romimagecount} = 1;
         		} elsif ($line=~/^\s*spidatahide\s*=\s*(\S+)\s+(\S+)\s(\S+)\s*$/)	{
 				#spidatahide=\epoc32\data\Z\Resource\Plugins\Obexclasscontroller.RSC ecom.spi \private\10003a3f\
 				my $targetspi=$3.$2;
 				my $flag=1;
 				my $i;
 				for($i=0;$i<$spicount && $flag;$i++) { #loop to see if name of spi file already added to this romimage in array
-					if($spiarray[$romimage][$i]{spi} eq $targetspi) {
+					if($spiarray[$romimagecount][$i]{spi} eq $targetspi) {
 						$flag=0;
 					}
 				}
 			
 				if($flag) { # adds spi file if not yet listed for this romimage in array
-					$spiarray[$romimage][$spicount++]={spifile=>$2, spidir=>$3, spi=>$3.$2};
+					$spiarray[$romimagecount][$spicount++]={spifile=>$2, spidir=>$3, spi=>$3.$2};
 					$i=$spicount;
 				}
-					$hidedatafiles[$hidefilescount++]= {data=>$1, rom=>$romimage, spifile=>$i-1}; 
+					$hidedatafiles[$hidefilescount++]= {data=>$1, rom=>$romimagecount, spifile=>$i-1}; 
 			}
 
 		}
@@ -2970,10 +3010,13 @@
 #
 sub featurefile_creation_phase
 {
-	if($onlysmrimage)
-	{
+	if($onlysmrimage){
 		return;
 	}
+	if($noFeatureConf) {
+		checkcase() if ($checkcase);
+		return ;
+	}
 	# Set the name and Rom Image location of feature file.
 	if ($enforceFeatureManager) 
 	{
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/buildrom/tools/featureconfigurator.pl	Tue Nov 23 10:47:23 2010 +0800
@@ -0,0 +1,998 @@
+#
+# 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: 
+# This package is to build rom image
+#
+
+use FindBin;		# for FindBin::Bin
+my $PerlLibPath;    # fully qualified pathname of the directory containing our Perl modules
+my $PerlEPOCPath;
+
+BEGIN {
+# check user has a version of perl that will cope
+	require 5.005_03;
+# establish the path to the Perl libraries
+    $PerlLibPath = $FindBin::Bin;	
+#    $PerlLibPath =~ s/\//\\/g;
+    $PerlLibPath .= "\\";
+    $PerlLibPath =~ s/\\/\//g;
+    
+    $PerlEPOCPath = $ENV{EPOCROOT};
+    $PerlEPOCPath =~ s/\\/\//g;
+    $PerlEPOCPath .= "\/" unless $PerlEPOCPath =~ /\/$/;
+    $PerlEPOCPath .= "epoc32\/tools\/";
+}
+use lib $PerlEPOCPath."build/lib/";
+use lib $PerlEPOCPath;
+use lib $PerlLibPath;
+use strict;
+use romutl;
+use romosvariant;
+# Work out the relative path to the epoc32 directory 
+use Cwd; 
+use File::Basename;
+# global variables specific to data drive image generation. 
+use File::Path ;					# Module to provide functions to remove or create directories in a convenient way.
+use File::Find; 
+use features;
+use flexmodload;	     # To load modules dynamically
+
+my $enforceFeatureManager = 0; # Flag to make Feature Manager mandatory if SYMBIAN_FEATURE_MANAGER macro is defined. 
+
+my $BuildromMajorVersion = 0 ;
+my $BuildromMinorVersion = 2;
+my $BuildromPatchVersion = 0;
+
+my $outputoby = "output.oby" ;
+
+
+sub print_usage {
+
+	# Option "-fm" will be supported instead of option "-f|fr" if SYMBIAN_FEATURE_MANAGER macro is defined.
+	my $featuresOptionUsage = "-f<featureuids> or\n".
+	"   -fr=<featureuids>            -- feature registry database XML file name\n";
+	if ($enforceFeatureManager) {
+		$featuresOptionUsage = "-fm=<featuredbfile>          -- feature manager/feature registry database XML file name.\n".
+							   "                                   Multiple XML files can be passed seperated by commas.\n".
+							   "   -nofm=<featuresdatafile>     -- don't generate features data file.\n".
+							   "                                   Instead use pre-built features data file.\n";
+	}
+
+#........1.........2.........3.........4.........5.........6.........7.....
+	print <<USAGE_EOF;
+
+FEATURECONFIGURATOR - feature configuration tool V$BuildromMajorVersion.$BuildromMinorVersion.$BuildromPatchVersion
+
+Usage:
+
+  featureconfigurator [options] obyfile [obyfile2 ...]   
+
+Configurate features from *.iby/*.oby files and output a 
+consolidated obyfile for buildrom's use. 
+
+This is a front end of buildrom, which partly implements 
+functionalities of buildrom.
+
+
+
+The available options are
+
+   -h                           -- Print this message
+
+   $featuresOptionUsage
+   -oby-charset=<charset>       -- Used character set in which OBY was written
+
+   -k or -keepgoing             -- Enable keepgoing,continue to config features
+                                   and create oby file.
+
+   -argfile=xxx                 -- Specify argument-file name containing list of 
+                                   command-line arguments to featureconfigurator
+   -workdir=xxx                 -- Specify a directory for generated files. 
+                                   The working directory will not be changed even this option is used.
+   
+   -I<directory>                -- Use <directory> for the referenced IBY/OBY files
+   -D<xxx>                      -- Define xxx for C++ preprocessor
+
+   -stdcpp                      -- Ignore symbian customized cpp and try to find 
+                                   another cpp in the PATH.(for Windows only)
+   -cpp=<xxx>                   -- Use xxx as path of CPP preprocessor.
+ 
+   -o<xxx.oby>                  -- Output oby file name is set to xxx.oby
+                                   If this argument is not given, then output oby file is
+                                   "output.oby". output files are placed under workdir.
+								   
+	-s                          -- strict option, any missing files will stop buildrom
+	-v                          -- verbose
+	-noiby[=<n>]                -- if n = 0, then create iby files, otherwise don't create iby files, "-noiby=0" is default
+	-w                          -- suppress cpp warnings.
+
+USAGE_EOF
+
+}
+
+
+my $PerlEPOCPath = &get_epocroot()."epoc32\/tools\/";   # fully qualified pathname of the directory containing EPOC Perl modules
+
+ 
+
+my $xmlrequired = 0; # assume xml required is false. Used to determine if xml
+                     # modules should be loaded.
+
+
+my @tempfiles;  	
+my $preserve = 0; 	#flag to indicate if temporary files should be preserved
+my $uppath="x";	    	# will be initialised when first needed
+
+my $epocroot = &get_epocroot;
+
+my @obyfiles;
+my $cppargs = "-nostdinc -undef";
+my $opt_k = 0;
+my $opt_v = 0; 
+my $opt_w = 0 ;
+my $strict = 0;
+my $line;
+my $errors = 0;
+my $thisdir=cwd;
+$thisdir=~s-\\-\/-go;		    # separator from Perl 5.005_02+ is forward slash
+$thisdir.= "\/" unless $thisdir =~ /\/$/;
+$thisdir =~ s-\/-\\-g if (&is_windows); 
+my $workdir = $thisdir ;
+my $rominclude = $epocroot."epoc32\/rom\/include\/";
+$rominclude = &get_epocdrive().$rominclude unless $rominclude =~ /^.:/;
+$rominclude =~s-\\-\/-g;
+
+my @xmlDBFile = ();
+my $noiby = 0;
+my @obydata;
+
+my @featurefilearray; #2d array storing names and locations of feature files in each rom image
+my @featureslist; #array of hashes, stores all the features which are to go into the feature files
+my $featurefilecount=0; #counts number of feature files in each rom image
+my $featurescount=0; #counts number of features
+my $dir; # Stores the ROM image location of features.dat/featreg.cfg files
+my $featurefilename; # Stores the name of feature file to be generated(i.e. "features.dat" or "featreg.cfg")
+
+my $featuremanager = 0; #Flag to enable support for feature manager database XML file and to generate  
+			# features data file.
+my $noFeatureManager = 0; # Flag to stop the generation of features.dat file and use pre-built features.dat if provided.
+my $preBuiltFeaturesDataFile  = ''; # To store the name of pre-built features.dat file provided with "-nofm" option.
+
+#Image Content XML file that supports specific feature to be added
+my $image_content = undef;
+#Feature list XML file that acts as database containing all features details
+my $featureXml = undef; 
+my $customizedPlat = undef; 
+
+#Summary of files(both executables and data files) currently includes 
+#	host and ROM file names, 
+#	size of the file in ROM
+#	whether the file is hidden
+# This option is added so that the above additional information is emitted by rombuild/rofsbuild tools
+# only when supplied with this option so that the existing tools don't get affected.
+my $logLevel="";
+ 
+
+# Feature Variation modules and data
+my %featureVariant;
+
+
+my $opt_workdir = 0; 
+my $stdcpp = 0;
+my $obycharset;
+my $cppoption = 0;
+my $preprocessor = "cpp"; 
+
+sub is_fullpath {
+
+my $path = shift ;
+	if (&is_windows) {
+		if( $path =~ /^[a-z]:/i) {
+			return 1 ;
+		}
+		elsif($path =~ /^\\/) {
+			return 1 ;
+		}
+		else {
+			return 0 ;
+		}			
+	}
+	else {
+		return 1 if($path =~ /^\//) ;
+		return 0;
+	}
+
+}
+
+sub match_obyfile
+{
+	my ($obyfile) = @_;
+	if (-f $obyfile)
+	{
+		push @obyfiles, $obyfile;
+		return 1;
+	}
+
+	# search for the oby file in the list of include directories
+	my @otherDirs = ($rominclude);
+
+	if ($featureVariant{'VALID'})
+	{
+		my $dirRef = $featureVariant{'ROM_INCLUDES'};
+
+		@otherDirs = @$dirRef if ($dirRef);
+	}
+	foreach my $dir (@otherDirs)
+	{
+		print "$dir/$obyfile\n" if ($opt_v);
+		if (-f "$dir/$obyfile")
+		{
+		    push @obyfiles, "$dir/$obyfile";
+		    return 1;
+		}
+	}
+	return 0;
+}
+ 
+# Subroutine to process parameter-file
+sub parameterFileProcessor
+{
+	my $paramFile = shift(@_);	
+	my @paramFileParamaters = ();	
+
+	my $fileOpenFlag = 1;
+	open FILE,"<", $paramFile or $fileOpenFlag = 0;
+	
+	if(!$fileOpenFlag)
+	{
+		print "Error: Could not open parameter-file \"$paramFile\" for reading.\n";
+		return;
+	}
+	
+	# Parse parameter-file and collect all the parameters in an array
+	while(my $line = <FILE>)
+	{
+		# Read the line till character ';'(used for providing comments in the file) or EOL
+		$line = $1 if ($line =~ /(.*);/); 
+		
+		# Split the parameters specified in a line based on white-spaces		
+		my @paramaters = split(/(\s)/,$line);	
+		
+		my $flag = 0;
+		my $argWithQuotes='';
+
+		foreach my $value (@paramaters) 
+		{	
+			# If the parameter doesn't conatian double quotes then push it 
+			# to the list of parameters.
+			if(($value !~ /\"/) && (!$argWithQuotes)) 
+			{
+				if ($value !~ /^\s*$/) 
+				{
+					push @paramFileParamaters,$value;
+				}		
+			}
+			# If the parameter is in the form  -fm="faturedb.xml" then remove
+			# double quotes and push it to the list of parameters.
+			elsif(($value =~ /\".*\"/))
+			{
+				$value =~ s/\"//g;
+				push @paramFileParamaters,$value;
+			}
+			# If the parameter is in the form  -fm="fature  db.xml" then read
+			# the parameter starting from opening quote till the closing quote.
+			elsif( ($value =~ /\"/) && $argWithQuotes) 
+			{
+				$argWithQuotes .= $value;
+				$argWithQuotes =~ s/\"//g;
+				push @paramFileParamaters,$argWithQuotes;
+				$argWithQuotes='';		
+			}
+			else
+			{
+				$argWithQuotes .= $value;
+			}
+		}		
+	}
+
+	close FILE;	
+	if (!@paramFileParamaters)
+	{
+		print "Warning: No parameters specified in paramer-file \"$paramFile\".\n";		
+		return;
+	}
+	
+	my $paramFileFlag = 1;
+
+	# Invoke subroutine "process_cmdline_arguments" to process the parameters read from
+	# the parameter file.
+	&process_cmdline_arguments($paramFileFlag, @paramFileParamaters);
+
+}
+
+# Processes the command line arguments passed to buildrom tool
+
+sub process_cmdline_arguments
+{
+ 
+	my ($paramFileFlag, @argList); 
+
+	if (defined @_) {
+		($paramFileFlag, @argList) = @_;
+	}
+	else {
+		if(scalar(@ARGV) == 0){
+			my @hrhMacros = &get_variantmacrolist;	
+			$enforceFeatureManager = 1 if (grep /^SYMBIAN_FEATURE_MANAGER\s*$/, @hrhMacros);
+			print_usage();
+			exit 1;				
+		}
+		
+		@argList = @ARGV;
+	}
+
+	if (!defined $paramFileFlag)  {
+	
+		# Enforce Feature Manager if macro SYMBIAN_FEATURE_MANAGER is defined in the HRH file.
+		my @hrhMacros = &get_variantmacrolist;	
+		$enforceFeatureManager = 1 if (grep /^SYMBIAN_FEATURE_MANAGER\s*$/, @hrhMacros);
+		# Process the parameters of parameter-file if passed.
+		foreach my $arg (@argList) {
+			if ($arg =~ /^-h/i) {
+				print_usage();
+				exit 1;				
+			}
+		}
+		# Process the parameters of parameter-file if passed.
+		foreach my $arg (@argList) {
+			&parameterFileProcessor($1) if ($arg =~ /^-argfile=(.*)/) ;
+		}
+	}
+	# first searching argList for keepgoing option
+	my @newArgList = () ;
+	foreach my $arg (@argList) {
+		if ( $arg =~ /^-k$/i || $arg =~ /^-keepgoing$/i ) {
+			$opt_k = 1;	 
+		}
+		elsif ($arg =~ /^-s$/) {
+			$strict = 1; 
+	    }
+		elsif ($arg =~ /^-v$/) {
+			$opt_v =1; 
+	    }
+		elsif( $arg =~ /^-w$/) {
+			$opt_w = 1 ;
+		}
+		elsif ($arg =~ /^-workdir=(.*)/) {			
+			$workdir = $1;
+			$workdir = $thisdir.$workdir unless(&is_fullpath($workdir)) ;
+			$workdir.= "\/" unless $workdir =~ /\/$/;
+			mkdir($workdir) unless (-d $workdir); 
+		}else {
+			push @newArgList, $arg ;
+		}
+	}
+	foreach my $arg (@newArgList)
+	{
+	    if ($arg =~ /^-argfile=(.*)/)  {
+			&parameterFileProcessor($1) if (defined $paramFileFlag); 
+		}
+		elsif ($arg =~ /^-DFEATUREVARIANT=(.*)/) {
+			my $varname = $1;			
+			if ($varname =~ /^\.(.*)$/) {
+				# for testing, locate the VAR file in the current directory
+				%featureVariant = get_variant($1, ".");
+			}
+			else {
+				%featureVariant = get_variant($varname);
+			}
+			if (!$featureVariant{'VALID'}) {
+			    print "FEATUREVARIANT $varname is not VALID\n";
+				$errors++;
+			}
+			if ($featureVariant{'VIRTUAL'}) {
+			    print "FEATUREVARIANT $varname is VIRTUAL\n";
+				$errors++;
+			}
+			addDrivesToFeatureVariantPaths(); 
+		}
+		elsif ($arg =~ /^-[DI]/) {
+			$cppargs .= " $arg";  
+	    } 
+	    elsif ($arg =~/^-oby-charset=(.*)$/i) {
+		$obycharset = $1; 
+	    }
+		elsif($arg =~ /^-o(.*)/i)   {
+			$outputoby = $1;  
+		} 
+		elsif ($arg =~ /^-noiby(=(\d))$/i ) {
+			if(!$1) {
+				$noiby = 1;
+			}
+			else {
+				if(!$2) {
+					print "Warning: No value for \"-noiby=\" option, use default.\n";
+				}
+				else {
+					$noiby = $2 ;
+				}
+			}
+		}
+		#Process feature manager database xml file 
+	    elsif($arg =~ /^-fm=(.*)/) {
+			if (!$enforceFeatureManager) {
+				print "Unknown arg: $arg\n";
+				$errors++;
+				next;
+			}
+			$featureXml = $1;			
+			$xmlrequired = 1;
+			$featuremanager = 1;
+			if ($featureXml =~ /^$/)  {
+				print "Error: No filename specified with \"-fm=\" option.\n";
+			} 
+			else {			
+				@xmlDBFile = split /,/,$featureXml if($noiby == 0);
+			} 
+	    }
+		elsif ($arg =~ /^-nofm(=(.*))?$/) {
+			if (!$enforceFeatureManager)  {
+				print "Unknown arg: $arg\n";
+				$errors++;
+				next;
+			}
+   			$noFeatureManager = 1; 
+            if(!$2) {
+                print "Warning: No filename specified with \"-nofm=\" option, feature data file might not be included.\n";
+            }
+            else {
+                $preBuiltFeaturesDataFile = $2;						
+            } 	
+		}
+		#Process feature registry database xml file 
+	    elsif($arg =~ /^-fr=(.*)/ || $arg =~ /^-f(.*)/) {
+			if ($enforceFeatureManager)
+			{
+				print "Error: Option \"-f|-fr\" is no longer supported.\n";
+				$errors++;
+				next;
+			}			
+			$featureXml = $1;
+			$xmlrequired = 1;			
+			print "Error: No filename specified with \"-f|-fr\" option.\n" if ($featureXml =~ /^$/) ;
+	    } 
+		elsif ($arg =~ /^-stdcpp$/i) {
+			if (&is_linux) {
+				print "Warning: option -stdcpp only apply for Windows\n"; 
+			}
+			if ($cppoption) {
+				print "Error: -stdcpp option and -cpp=xxx option cannot be used at the same time.\n";
+				exit (1);
+			}
+			$stdcpp = 1; 
+		}
+		elsif ($arg =~ /^-cpp=(.*)/) {
+			if ($stdcpp) {
+				print "Error: -stdcpp option and -cpp=xxx option cannot be used at the same time.\n";
+				exit (1);
+			}
+			print "Warning: -cpp option has been set before. The previous configuration will be overwritten!\n" if ($cppoption);
+			$cppoption = 1;
+			$preprocessor = $1;
+			$preprocessor =~ s-\\-\/-g;
+			$preprocessor =~ s-EPOCROOT##\/?-$epocroot-g;
+			if (-d $preprocessor) {
+				$preprocessor .= "\/" unless $preprocessor =~ /\/$/;
+				$preprocessor .= "cpp";
+			} 
+		} 
+	    elsif ($arg =~ /^-/)  {
+			print "Unknown arg: $arg\n";
+			$errors++;
+			next;
+	    }
+		else {
+			# It's an OBY file
+			next if (match_obyfile($arg));
+			next if (match_obyfile("$arg.oby"));
+			print "Cannot find oby file: $arg\n";
+			$errors++ if(!$opt_k);
+		}	    
+	}
+
+	return if (defined $paramFileFlag) ;
+	if (@obyfiles<1 ) {
+	    print "Missing obyfile argument\n";
+	    $errors++ if(!$opt_k);
+	}
+	if(defined($obycharset)) {
+		print "Warning: Ignoring not supportted charset $obycharset, local charset will be used as default!\n" unless($obycharset =~ /utf-?8/i);
+	}
+
+	if ($errors) {
+	    print_usage();
+	    exit 1;
+	}
+	
+	if ($noFeatureManager && $featuremanager)  {
+		print "Warning: Ignoring \"-nofm\" option, as both \"-nofm\" and \"-fm\" options are provided.\n";			
+		$noFeatureManager = 0;
+	}
+
+	# Adding variant specific macros by including a HRH file
+	# (only required if no Feature Variant is used)
+	if (!$featureVariant{'VALID'}) {
+	    my $variantMacroHRHFile = get_variantmacroHRHfile();
+	    if($variantMacroHRHFile){
+	        my $variantFilePath = split_path('Path',$variantMacroHRHFile);
+	        $cppargs .= " -I " . &append_driveandquote($variantFilePath) . " -include " . &append_driveandquote($variantMacroHRHFile); 
+	        print "in cmd process $cppargs\n" if ($opt_v);
+	    }
+	}
+	# load the required modules if xml is required
+	if ($xmlrequired == 1) {
+	    load_featuresutil() if (defined ($featureXml));	    
+	}
+}
+
+#----------------------------------------------------------------------------------
+# Preprocessing phase	
+#
+# Concatentate the specified .oby files and pass them through cpp
+# to get the raw ROM specification in tmp1.oby
+
+sub preprocessing_phase
+{
+	 
+	
+	my $temp1OBYFile = $workdir."tmp1.oby";
+	unlink "$temp1OBYFile";
+
+#	Macro "ROM_FEATURE_MANAGEMENT" is defined when "-f|fr" or "-fm" is used
+	$cppargs .= " -w" if($opt_w) ;
+	$cppargs .= " -DROM_FEATURE_MANAGEMENT " if (defined ($featureXml));
+
+	# add pre-include file and include directories for feature variants
+	if ($featureVariant{'VALID'})
+	{
+		$cppargs .= " -I.";
+		my $incRef = $featureVariant{'ROM_INCLUDES'};
+		if ($incRef) {
+			foreach (@$incRef) {
+				$cppargs .= " -I \"$_\"";
+			}
+		}
+		my $HRH = $featureVariant{'VARIANT_HRH'};
+		$cppargs .= " -include \"$HRH\"" if ($HRH);
+	}
+	else {
+		# no feature variant so use the standard includes
+		$cppargs .= " -I. -I \"$rominclude\"";
+	}
+
+	$preprocessor = find_stdcpp() if ($stdcpp);
+	print "* $preprocessor -Wno-endif-labels -o $temp1OBYFile $cppargs\n" if ($opt_v);
+	
+	is_existinpath("$preprocessor", romutl::DIE_NOT_FOUND);
+	$errors = 0; 
+	open CPP, "| $preprocessor -Wno-endif-labels -o $temp1OBYFile $cppargs" or die "* Can't execute cpp";
+	foreach my $arg (@obyfiles) {
+		print CPP "\n#line 1 \"$arg\"\n";
+	
+		if(open(OBY, $arg)) {
+			print "* reading $arg\n" if ($opt_v);
+			while ($line=<OBY>) {
+				print CPP $line;
+			}
+			close OBY;
+		}
+		else {
+			print STDERR "* Can't open $arg\n";
+			if(!$opt_k){			
+				close CPP;
+				exit(1);
+			}
+		}
+	}
+	close CPP;
+	my $cpp_status = $?;
+	die "* cpp failed\n" if ($cpp_status != 0 || !-f "$temp1OBYFile");
+	
+
+	if( defined ($image_content)) {
+		#Read the OBY file that was generated by the pre-processor
+		&ReadPreprocessedFile($temp1OBYFile);
+
+#		Check if the static dependencies of the OBY binaries are resolved.
+		&ImageContentHandler::UpdateObyBinaryStaticDep();
+		
+		#Now append the files collected from cdfs.
+		&ImageContentHandler::GenObyFile($temp1OBYFile);
+	}
+
+ 
+	if($obycharset =~ /utf-?8/i) {
+		my $utf8file = $workdir."tmp1utf8.oby";
+		open INFILE, "<$temp1OBYFile" or die "* Can't open file $temp1OBYFile";
+		open CHARSETTRAN, "| charsettran -to=hostcharset > $utf8file" or die "* Can't execute charsetran";
+		while(<INFILE>) {
+			print CHARSETTRAN $_;
+		}
+		close CHARSETTRAN;
+		close INFILE;	
+		unlink $temp1OBYFile  or die "* Can't remove file $temp1OBYFile";
+		rename 	$utf8file, $temp1OBYFile or die "* Can't rename file $utf8file to file $temp1OBYFile";
+	}
+	
+	open TMPOBY, "<$temp1OBYFile" or die "*cpp output can not be read.\n"; 
+	@obydata = <TMPOBY> ;
+	close TMPOBY;
+ 
+
+	
+}
+ 
+sub load_featuresutil
+{
+	&FlexLoad_ModuleL("featuresutil");
+			
+	# Parse the feature database XML file
+	if(!&featuresutil::parseXMLDatabase($featureXml, $featuremanager, $strict))
+	{
+		$featureXml = undef;
+		exit(1) if($strict);
+	}
+}
+
+#----------------------------------------------------------------------------------
+# Feature registry configuration file/Features data file generation phase
+#
+# If feature registry configuration files/features data files are required then creates these files for
+# each ROM/ROFS image
+#
+sub featurefile_creation_phase
+{
+		# Set the name and Rom Image location of feature file.
+	if ($enforceFeatureManager)  {
+		# features data file location
+		$dir = "private\/10205054\/";
+		$featurefilename = "features.dat";
+	}
+	else {
+		# feature registry configuration file location
+		$dir = "private\/102744CA\/"; 
+		$featurefilename = "featreg.cfg";
+	}
+	my $onlysmrimage  = 1 ;
+	
+	foreach $line(@obydata) {		
+		if(($line =~ /^\s*romsize\s*=/i) || ( $line=~ /^\s*rom_image/i) || ($line =~ /^\s*data_image/i)) {
+			$onlysmrimage = 0;
+			last;
+		}
+	}	
+	if ($enforceFeatureManager && (!$featuremanager) && (!$noFeatureManager) ) {
+		my $defaultFeatureDbFlag = 0;
+		foreach $line(@obydata) { 
+			if ($line=~/^\s*defaultfeaturedb\s*=?\s*(\S+)/i) {	
+				# Get the default value for featuredatabasefile
+				
+				$featureXml = "$epocroot$1";
+				$featureXml =~ s-\\-\/-g;
+				$featuremanager = 1;				
+				$defaultFeatureDbFlag = 1;
+				load_featuresutil();				
+				last;
+			}
+		}
+		if(!$defaultFeatureDbFlag && !$onlysmrimage)
+		{
+			print "Error: Neither option \"-fm|-nofm\" nor default value for featuredatabase file is provided.\n";
+			exit(1);			
+		}
+	}
+	my @newobydata = ();
+	if (defined ($featureXml))  {
+		my $featurefilecount=0;
+		my $romimage=0;
+
+		foreach $line (@obydata) {
+			# specify which romimage following lines are part of
+			if ($line=~/^\s*ROM_IMAGE\[(\d)\]/) {
+				$romimage=$1;
+				$featurefilecount=0;
+			}
+			elsif ($line =~ /^\s*REM/i || $line =~ /^\s*\r?\n$/ ){
+				next ;
+				# ignore empty
+			}
+			elsif($line =~ /^\s*(FEATURE)\s*(\S*)\s*(.*)/i || $line =~ /^\s*(EXCLUDE_FEATURE)\s*(\S*)\s*(.*)/i) {
+				
+				# FEATURE  <feature_name>  [ SF  <status falgs> ] [ UD  <user data> ]
+				my $feature = $1;
+				my $featurevalue = $2;
+				my $featureargs = $3;
+				my $reservedbit = 0;
+				my %featureflags=();			 
+				# Options 'SF' and 'UD' will be supported only for "-fm" option
+				if ($featuremanager)  {
+					# [ SF  <status falgs> ] [ UD  <user data> ]
+					$featureargs =~	/(\S*)\s*(\S*)\s*(\S*)\s*(\S*)\s*/ ;
+
+					# Store the values of 'SF' and 'UD', or any invalid option, if provided					
+					$featureflags{uc($1)} = $2 if ($1);  
+					$featureflags{uc($3)} = $4 if ($3); 
+
+					# Generate a warning if the option provided with Feature/Exclude_Feature keyword is  
+					# not 'SF' or 'UD'.
+					foreach my $Key (keys %featureflags) {						
+						if ($Key !~ /^(SF|UD)$/) {
+							print "Warning: Invalid argument \"$Key\" specified for feature $featurevalue\n";
+							delete $featureflags{$Key};
+							next;
+						}						
+					}							
+				}				
+				# In verbose mode, generate warning if "SF|UD" arguments or invalid arguments are specified
+				# for "-f|fr" option.
+				elsif ($featureargs && $opt_v) {
+					print "Invalid argument(s) \"$featureargs\" provided for feature \"$featurevalue\"\n";
+					foreach my $Key (keys %featureflags) {
+						delete $featureflags{$Key};
+					}
+				}				
+				
+				# The feature file name is of the format featreg.cfg[x-y] or features.dat[x-y] 
+				# where x is the romimage id, y is always 0, reserved for future use.
+				my $targetfeaturefile;
+				if (($romimage == 0) && ($reservedbit == 0)) {
+
+					# Core image will not have the mangled name
+				 	$targetfeaturefile = $featurefilename;
+				}
+				else {
+				 	$targetfeaturefile = $featurefilename . "\[". $romimage . "\-$reservedbit\]";
+				}
+				my $flag=1;
+				my $featureflag;
+				if ($feature =~ /^FEATURE$/i) {
+					$featureflag = 1;
+				}
+				else {
+					$featureflag = 0;
+				}
+
+				my $i;
+ 				# loop to see if name of feature file already added to this romimage in array
+				for($i=0;$i<$featurefilecount && $flag;$i++) {
+					$flag=0 if($featurefilearray[$romimage][$i]{cfgfile} eq $targetfeaturefile);
+				}
+			
+				if($flag) { # adds feature file if not yet listed for this romimage in array
+					$featurefilearray[$romimage][$featurefilecount++]={cfgfile=>$targetfeaturefile, cfgdir=>$dir};
+					$i=$featurefilecount;
+				}
+
+				$featureslist[$featurescount]= {feature=>$featurevalue, include=>$featureflag, rom=>$romimage, cfgfile=>$i-1};
+				
+				# Store the value of 'SF' in 'featureslist' array
+				$featureslist[$featurescount]->{SF} = $featureflags{SF} if (defined $featureflags{SF}) ;
+				# Store the value of 'UD' in 'featureslist' array
+				$featureslist[$featurescount]->{UD} = $featureflags{UD} if (defined $featureflags{UD}) ;
+				$featurescount++;
+			}
+		}
+
+		# Create Feature File
+		for(my $i=0;$i<scalar @featurefilearray;$i++) {
+			my $j=0;
+			while(defined $featurefilearray[$i][$j])
+			{
+				my $targetfeaturefile = $workdir.$featurefilearray[$i][$j]{cfgfile}; 
+				if (!(&featuresutil::createFeatureFile($i,$j,$targetfeaturefile,\@featureslist,$featuremanager)))  {
+					$featurefilearray[$i][$j]{cfgfile}= undef;
+					exit(1) if($strict);					
+				}
+				$j++;
+			}
+		} 
+		my $flag=1;
+        	my $imageIdx=0;
+
+		# Add feature files to ROM image, adds lines to obey file to specify existing locations
+		# of feature files and target locations. 
+		
+		# features.dat will be written to the end of rom/rofs
+		my @lastFLs = ();
+		my $lastRomIndex = 0 ;
+		
+		foreach $line (@obydata) {
+			if($line =~/^\s*ROM_IMAGE\[(\d)\]/i) {
+				my $index=$1;
+						
+				if($lastRomIndex != $index) {
+					foreach my $fl(@lastFLs) {
+						push @newobydata,$fl ;
+					}
+					@lastFLs = ();
+					$lastRomIndex = $index ;
+				}
+				push @newobydata, "\n" . $line . "\n";	
+				my $j=0;
+				while(defined $featurefilearray[$index][$j]) {
+					$flag = 0 if($index == 0);
+					# Put in feature files for current ROM_IMAGE
+					my $targetfeaturefile = $featurefilearray[$index][$j]{cfgfile};
+					# Rom images will not have mangled name for feature files
+				 					
+					# Rofsbuild will set attribute 'exattrib=U' in the entry record when this field is used.
+					# File Server when asked for a directory listing would notice the attribute and will return the 
+					# list with mangled names. Hence, mangled name for feature files should not be put in ROM_IMAGE.
+					my $exattribute = "" ;					
+					if (defined $targetfeaturefile ) {
+						$exattribute = "exattrib=U" if($index > 0);
+						push @lastFLs, "ROM_IMAGE[$index] data=" . $workdir . $targetfeaturefile . " \"". $featurefilearray[$index][$j]{cfgdir} .$featurefilename .  "\"\t\t" . $exattribute . "\n";
+						$featurefilearray[$index][$j]{cfgfile} = undef ;
+					}
+					$j++;
+				}
+			}
+			elsif($line !~ /^\s*(FEATURE)\s*/i && $line !~ /^\s*(EXCLUDE_FEATURE)\s*/i && $line !~/^\s*defaultfeaturedb\s*=?\s*(\S+)/i) {
+				# Put in all other lines except the FEATURE and EXCLUDE_FEATURE keywords
+				push @newobydata, $line;
+			}
+			else {
+				push @newobydata, " "; 
+			}
+			 
+		}
+		foreach my $fl(@lastFLs) {
+			push @newobydata,$fl ;
+		}
+		if($flag) { 
+			# Put in feature files for ROM_IMAGE[0] if it is the only ROM_IMAGE
+			my $k=0;
+			while(defined $featurefilearray[0][$k])
+			{ 
+				my $targetfeaturefile = $featurefilearray[0][$k]{cfgfile};
+				if (defined $targetfeaturefile)
+				{
+					push @newobydata, "data=" . $workdir . $targetfeaturefile . " \"" . $featurefilearray[0][$k]{cfgdir} . $targetfeaturefile . "\"\n";
+					$featurefilearray[0][$k]{cfgfile} = undef ;
+				}
+				$k++;
+			}
+		}
+	}
+	elsif ($enforceFeatureManager && $noFeatureManager && $preBuiltFeaturesDataFile) {
+        print "Valid: $preBuiltFeaturesDataFile\n";
+		if (-e $preBuiltFeaturesDataFile)  { 
+			my $flag = 1;
+			foreach my $line (@obydata)
+			{
+				# Put in the pre-built features data file in ROM_IMAGE[0] 
+				if($line =~/^\s*ROM_IMAGE\[1\]/i)
+				{
+					push @newobydata, "data=$preBuiltFeaturesDataFile" . " \"" . $dir . $featurefilename . "\"\n";
+					$flag =0;
+				}
+				push @newobydata, $line;
+			}
+			if($flag)
+			{ 
+				# Put in the pre-built features data file in ROM_IMAGE[0] if it is the only ROM_IMAGE
+				push @newobydata, "data=$preBuiltFeaturesDataFile" . " \"" . $dir . $featurefilename . "\"\n";
+			}
+		}
+		else
+		{
+			print "Error: File \"$preBuiltFeaturesDataFile\" doesn't exist.\n";
+			exit(1);
+		}
+	}
+	elsif ($enforceFeatureManager) {
+	    print "Error: no feature data file or pre-built feature data file is provided!";
+	    exit(1);
+	}
+	
+		my $output ;
+	if(&is_windows) {
+		if($outputoby =~ /^[\\\/]/ || $outputoby =~ /^[a-zA-Z]:/)  {
+			$output = $outputoby ;
+		}
+		else {
+			$output = $workdir.$outputoby;
+		}
+	}
+	else {
+		if($outputoby =~ /^[\/]/ )  {
+			$output = $outputoby ;
+		}
+		else {
+			$output = $workdir.$outputoby;
+		}
+	} 
+	unlink $output if(-e $output);
+	print "* Writing $output...\n" if($opt_v);
+	unless(open FOUT, ">$output"){
+		print "Error: Can not write to $output.\n";
+		exit(1);
+	}
+	foreach(@newobydata){
+		chomp ;
+		print FOUT "$_\n";
+	} 
+	close FOUT ; 
+	print "* Done.\n" if($opt_v);
+}
+
+# make sure that all the absolute feature variant paths include a
+# drive letter. This is required because cpp will not work with
+# absolute paths starting with slashes.
+sub addDrivesToFeatureVariantPaths
+{
+	return unless $featureVariant{'VALID'};
+
+	my $current = &get_epocdrive;
+	my $drive = $1 if ($current =~ /^(.:)/);
+
+	# pre-include file
+	my $HRH = $featureVariant{'VARIANT_HRH'};
+	$featureVariant{'VARIANT_HRH'} = $drive . $HRH if ($HRH =~ /^[\\\/]/);
+
+	# ROM include path
+	my $dirRef = $featureVariant{'ROM_INCLUDES'};
+	return unless $dirRef;
+	my $i = 0;
+
+	foreach my $dir (@$dirRef)
+	{
+		$$dirRef[$i] = $drive . $dir if ($dir =~ /^[\\\/]/);
+		$i++;
+	}
+}
+#
+# Process the given absolute path
+# Add backslash at the end if required
+# @param - path to be processed
+#
+sub processPath
+{
+	my ($path) = shift;
+	
+	return if( $$path =~ /(\\$)/ );
+	return if( $$path =~ /(\/$)/ );
+	$$path .= "/";
+}
+
+# Main block for buildrom module invocation
+
+
+# Processes the buildrom command line parameters.
+&process_cmdline_arguments; 
+if(scalar(@xmlDBFile) > 0) { 
+	&processPath(\$epocroot);
+	&processPath(\$thisdir);
+	&features::set_DefaultPath($epocroot, \$thisdir, \$thisdir, \$thisdir, \$thisdir);
+	if(&features::open_Database(@xmlDBFile)) {  
+		&features::generate_Obeyfile($workdir);	 
+	}
+}
+#Preprocessing phase
+&preprocessing_phase; 
+# Creates feature registry configuration file/features data file.
+&featurefile_creation_phase;
+
+
+1;
--- a/imgtools/buildrom/tools/features	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/buildrom/tools/features	Tue Nov 23 10:47:23 2010 +0800
@@ -1,2 +1,8 @@
 #!/bin/sh
-perl -S features.pl $@
+PRGDIR=`dirname "$0"`
+
+PRGDIR=`cd "$PRGDIR"; pwd`
+
+
+perl "$PRGDIR/features.pl" $@
+
--- a/imgtools/imglib/compress/byte_pair.cpp	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/imglib/compress/byte_pair.cpp	Tue Nov 23 10:47:23 2010 +0800
@@ -636,3 +636,12 @@
     memcpy(dst,PakBuffer,compressedSize);
     return compressedSize;
 }
+TInt BytePairDecompress(TUint8* dst, TUint8* src, TInt size, CBytePair *aBPE)
+{
+    TUint8 UnpakBuffer[MaxBlockSize];
+    ASSERT(size<=MaxBlockSize);
+    TUint8* pakEnd;
+    TInt us = aBPE->Decompress(UnpakBuffer,MaxBlockSize,src,size,pakEnd);
+    memcpy(dst,UnpakBuffer,us);
+    return us;
+}
--- a/imgtools/imglib/compress/byte_pair.h	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/imglib/compress/byte_pair.h	Tue Nov 23 10:47:23 2010 +0800
@@ -343,6 +343,7 @@
         TInt Decompress(TUint8* dst, TInt dstSize, TUint8* src, TInt srcSize, TUint8*& srcNext);
 };
 TInt BytePairCompress(TUint8* dst, TUint8* src, TInt size, CBytePair *aBPE);
+TInt BytePairDecompress(TUint8* dst, TUint8* src, TInt size, CBytePair *aBPE);
 
 #endif
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/imglib/symbolutil/bsymutil.cpp	Tue Nov 23 10:47:23 2010 +0800
@@ -0,0 +1,120 @@
+/*
+* Copyright (c) 1995-2009 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 "bsymutil.h"
+#include <stdio.h>
+
+
+MemoryWriter::MemoryWriter()
+{
+	iChar = new char[4*MaxSize];
+	iOffset = 0;
+	iTotalSize = 4*MaxSize;
+	iStringTableStart = 0;
+}
+MemoryWriter::~MemoryWriter()
+{
+	delete[] iChar;
+}
+int MemoryWriter::WriteBytes(const char* pChar, int size)
+{
+	while(iOffset + size > iTotalSize)
+	{
+		ExtendMemory();
+	}
+	memcpy(iChar + iOffset, pChar, size);
+	iOffset += size;
+	return size;
+}
+TUint32 MemoryWriter::GetOffset()
+{
+	return iOffset;
+}
+char* MemoryWriter::GetDataPointer()
+{
+	return iChar;
+}
+bool MemoryWriter::ExtendMemory()
+{
+	char* pTmp = new char[iTotalSize + MaxSize];
+	memcpy(pTmp, iChar, iOffset);
+	delete[] iChar;
+	iChar = pTmp;
+	iTotalSize += MaxSize;
+	return true;
+}
+bool MemoryWriter::SetOffset(TUint32 aOffset)
+{
+	while(aOffset > iTotalSize)
+	{
+		ExtendMemory();
+	}
+	iOffset = aOffset;
+	return true;
+}
+void MemoryWriter::AddEmptyString()
+{
+	unsigned char len = 0;
+	WriteBytes((char *)&len, 1);
+}
+TUint32 MemoryWriter::AddString(const string& aStr)
+{
+	TUint32 result = 0;
+	if(aStr.empty())
+		return result;
+	result = iOffset - iStringTableStart;
+	int len = aStr.length();
+	if(len >= 255)
+	{
+		TUint16 wlen = len;
+		unsigned char mark = 0xff;
+		WriteBytes((char*)&mark, 1);
+		WriteBytes((char*)&wlen, 2);
+		WriteBytes(aStr.c_str(), len);
+	}
+	else
+	{
+		unsigned char clen = len;
+		WriteBytes((char *)&clen, 1);
+		WriteBytes(aStr.c_str(), len);
+	}
+	return result;
+}
+TUint32 MemoryWriter::AddScopeName(const string& aStr)
+{
+	TUint32 result = 0;
+	if(aStr.empty())
+		return result;
+	if(aStr == iLastScopeName)
+	{
+		return iLastScopeNameOffset;
+	}
+	else
+	{
+		iLastScopeName = aStr;
+		iLastScopeNameOffset = AddString(aStr);
+	}
+	return iLastScopeNameOffset;
+}
+void MemoryWriter::SetStringTableStart(TUint32 aOffset)
+{
+	iStringTableStart = aOffset;
+}
+TUint32 MemoryWriter::GetStringTableStart()
+{
+	return iStringTableStart;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/imglib/symbolutil/bsymutil.h	Tue Nov 23 10:47:23 2010 +0800
@@ -0,0 +1,172 @@
+/*
+* 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: 
+*
+*/
+
+#ifndef __BSYMUTIL_H__
+#define __BSYMUTIL_H__
+
+#include <e32std.h>
+#include <vector>
+#include <string>
+
+using namespace std;
+
+const int BSYM_PAGE_SIZE = 4096;
+
+const int MaxSize = 4*1024*1024;
+const TUint16 BsymMajorVer = 3;
+const TUint16 BsymMinorVer = 0;
+struct TBsymHeader {
+	char iMagic[4]; // 'B','S','Y','M' always big-endian
+	char iMajorVer[2]; // always big-endian, currently 3
+	char iMinorVer[2]; // always big-endian, currently 0.
+	char iEndiannessFlag;
+	char iCompressionFlag;
+	char iReservered[2];
+	TUint32 iDbgUnitOffset;
+	TUint32 iDbgUnitCount;
+	TUint32 iSymbolOffset;
+	TUint32 iSymbolCount;
+	TUint32 iStringTableOffset;
+	TUint32 iStringTableBytes;
+	TUint32 iCompressedSize;
+	TUint32 iUncompressSize;
+	TUint32 iCompressInfoOffset;
+};
+struct TDbgUnitEntry {
+	TUint32 iCodeAddress;
+	TUint32 iCodeSymbolCount;
+	TUint32 iDataAddress;
+	TUint32 iDataSymbolCount;
+	TUint32 iBssAddress;
+	TUint32 iBssSymbolCount;
+	TUint32 iPCNameOffset;
+	TUint32 iDevNameOffset;
+	TUint32 iStartSymbolIndex;
+	TDbgUnitEntry()
+	{
+		iCodeAddress =0;
+		iCodeSymbolCount =0;
+		iDataAddress =0;
+		iDataSymbolCount =0;
+		iBssAddress =0;
+		iBssSymbolCount =0;
+		iPCNameOffset =0;
+		iDevNameOffset =0;
+		iStartSymbolIndex =0;
+	}
+	void Reset()
+	{
+		iCodeAddress =0;
+		iCodeSymbolCount =0;
+		iDataAddress =0;
+		iDataSymbolCount =0;
+		iBssAddress =0;
+		iBssSymbolCount =0;
+		iPCNameOffset =0;
+		iDevNameOffset =0;
+		iStartSymbolIndex =0;
+	}
+};
+struct TDbgUnitPCEntry {
+	TDbgUnitEntry iDbgUnitEntry;
+	string iPCName;
+	string iDevName;
+};
+struct TSymbolEntry {
+	TUint32 iAddress;
+	TUint32 iLength;
+	TUint32 iScopeNameOffset;
+	TUint32 iNameOffset;
+	TUint32 iSecNameOffset;
+	TSymbolEntry()
+	{
+		iAddress =0;
+		iLength =0;
+		iScopeNameOffset =0;
+		iNameOffset =0;
+		iSecNameOffset =0;
+	}
+};
+
+struct TSymbolPCEntry {
+	TSymbolEntry iSymbolEntry;
+	string iScopeName;
+	string iName;
+	string iSecName;
+};
+
+struct TPageInfo {
+	TUint32 iPageStartOffset;
+	TUint32 iPageDataSize;
+};
+
+struct TCompressedHeaderInfo
+{
+	TUint32 iPageSize;
+	TUint32 iTotalPageNumber;
+	TPageInfo iPages[1];
+};
+
+typedef vector<TDbgUnitPCEntry> TDbgUnitEntrySet;
+typedef vector<TSymbolPCEntry> TSymbolPCEntrySet;
+typedef vector<string> StringList;
+
+struct MapFileInfo
+{
+	TDbgUnitPCEntry iDbgUnitPCEntry;
+	TSymbolPCEntrySet iSymbolPCEntrySet;
+};
+
+typedef vector<MapFileInfo> MapFileInfoSet;
+class ByteOrderUtil
+{
+public:
+	static bool IsLittleEndian()
+	{
+		union {
+			unsigned int a;
+			unsigned char b;
+		} c;
+		c.a = 1;
+		return (c.b == 1);
+	}
+};
+
+class MemoryWriter
+{
+public:
+	MemoryWriter();
+	~MemoryWriter();
+	int WriteBytes(const char* pChar, int size);
+	TUint32 GetOffset();
+	char* GetDataPointer();
+	bool ExtendMemory();
+	bool SetOffset(TUint32 aOffset);
+	void AddEmptyString();
+	TUint32 AddString(const string& aStr);
+	TUint32 AddScopeName(const string& aStr);
+	void SetStringTableStart(TUint32 aOffset);
+	TUint32 GetStringTableStart();
+private:
+	char* iChar;
+	TUint32 iOffset;
+	TUint32 iStringTableStart;
+	string iLastScopeName;
+	TUint32 iLastScopeNameOffset;
+	TUint32 iTotalSize;
+};
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/imglib/symbolutil/loggingexception.cpp	Tue Nov 23 10:47:23 2010 +0800
@@ -0,0 +1,60 @@
+/*
+* Copyright (c) 1995-2009 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 "loggingexception.h"
+
+
+int LoggingException::RESOURCE_ALLOCATION_FAILURE = 1;
+int LoggingException::INVALID_LOG_FILENAME        = 2;
+int LoggingException::UNKNOWN_IMAGE_TYPE          = 3;
+
+
+LoggingException::LoggingException(int ErrorCode)
+{
+	this->errcode = ErrorCode;
+
+	return;
+}
+
+
+int LoggingException::GetErrorCode(void)
+{
+	return this->errcode;
+}
+
+
+const char* LoggingException::GetErrorMessage(void)
+{
+	if(this->errcode == LoggingException::RESOURCE_ALLOCATION_FAILURE)
+		return "Not enough system resources to initialize logging module.";
+	else if(this->errcode == LoggingException::INVALID_LOG_FILENAME)
+		return "Invalid log filename as input.";
+	else if(this->errcode == LoggingException::UNKNOWN_IMAGE_TYPE)
+		return "the image type not supported.";
+//	else if(this->errcode == CacheException::CACHE_IS_EMPTY)
+//		return "Cache is empty.";
+//	else if(this->errcode == CacheException::HARDDRIVE_FAILURE)
+//		return "A hard drive failure occurred in Cache operations.";
+
+	return "Undefined error type.";
+}
+
+
+LoggingException::~LoggingException(void)
+{
+	return;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/imglib/symbolutil/loggingexception.h	Tue Nov 23 10:47:23 2010 +0800
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 1995-2009 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:
+*
+*/
+
+
+#ifndef ROM_TOOLS_ROFSBUILD_LOGGING_LOGGINGEXCEPTION_H_
+#define ROM_TOOLS_ROFSBUILD_LOGGING_LOGGINGEXCEPTION_H_
+
+
+/*
+ * @class LoggingException
+ */
+class LoggingException
+{
+public:
+	LoggingException(int ErrorCode);
+
+	int GetErrorCode(void);
+
+	const char* GetErrorMessage(void);
+
+	static int RESOURCE_ALLOCATION_FAILURE;
+	static int INVALID_LOG_FILENAME       ;
+	static int UNKNOWN_IMAGE_TYPE	      ;
+
+	virtual ~LoggingException(void);
+protected:
+	int errcode;
+private:
+	LoggingException(void);
+
+	LoggingException& operator = (const LoggingException&);
+};
+
+
+#endif  /* defined ROM_TOOLS_ROFSBUILD_LOGGING_LOGGINGEXCEPTION_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/imglib/symbolutil/logparser.cpp	Tue Nov 23 10:47:23 2010 +0800
@@ -0,0 +1,218 @@
+/*
+* Copyright (c) 1995-2009 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 <new>
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <boost/regex.hpp>
+using namespace std;
+
+#include "loggingexception.h"
+#include "logparser.h"
+
+
+LogParser* LogParser::Only = (LogParser*)0;
+
+
+LogParser* LogParser::GetInstance(TImageType aImageType) throw (LoggingException)
+{
+	if(! LogParser::Only)
+	{
+		if(aImageType == ERomImage)
+		{
+			LogParser::Only = new (std::nothrow) RomLogParser();
+		}
+		else if(aImageType == ERofsImage)
+		{
+			LogParser::Only = new (std::nothrow) RofsLogParser();
+		}
+		else
+		{
+			throw LoggingException(LoggingException::UNKNOWN_IMAGE_TYPE);
+		}
+		if(! LogParser::Only)
+			throw LoggingException(LoggingException::RESOURCE_ALLOCATION_FAILURE);
+	}
+
+	return LogParser::Only;
+}
+
+void LogParser::Cleanup(void)
+{
+	return;
+}
+
+
+LogParser::LogParser(void)
+{
+	iImageType = EUnknownType;
+	return;
+}
+
+RofsLogParser::RofsLogParser()
+{
+	iImageType = ERofsImage;
+}
+
+void RofsLogParser::ParseSymbol(const char* LogFilename) throw (LoggingException)
+{
+	string linebuf;
+	SymbolGenerator* symgen = SymbolGenerator::GetInstance();
+	symgen->SetImageType(iImageType);
+	symgen->SetSymbolFileName(string(LogFilename));
+
+	ifstream logfd(LogFilename);
+	if(logfd.is_open())
+	{
+		while(! logfd.eof())
+		{
+			getline(logfd, linebuf);
+			if(linebuf.compare(0,4,"File") == 0)
+			{
+				if(linebuf.find("size:", 4) != 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), false);
+					}
+				}
+			}
+			else if(linebuf.compare(0,26,"Compressed 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);
+					}
+				}
+			}
+		}
+		symgen->SetFinished();
+		symgen->Release();
+	}
+	else
+	{
+		throw LoggingException(LoggingException::INVALID_LOG_FILENAME);
+	}
+
+	return;
+}
+
+RomLogParser::RomLogParser()
+{
+	iImageType = ERomImage;
+}
+
+void RomLogParser::ParseSymbol(const char* LogFilename) throw (LoggingException)
+{
+	string linebuf;
+	SymbolGenerator* symgen = SymbolGenerator::GetInstance();
+	symgen->SetImageType(iImageType);
+	symgen->SetSymbolFileName(string(LogFilename));
+
+	ifstream logfd(LogFilename);
+	if(logfd.is_open())
+	{
+		//boost::regex beginFlag("^Creating Rom image (\\S*)");
+		boost::regex endFlag("^Writing Rom image");
+		boost::regex sourceFile("^Reading resource (.*) to rom linear address (.*)");
+		boost::regex executableFile("^Processing file (.*)");
+		boost::regex codeStart("^Code start addr:\\s*(\\w+)");
+		boost::regex dataStart("^Data start addr:\\s+(\\w+)");
+		boost::regex dataBssStart("^DataBssLinearBase:\\s+(\\w+)");
+		boost::regex textSize("^Text size:\\s+(\\w+)");
+		boost::regex dataSize("^Data size:\\s+(\\w+)");
+		boost::regex bssSize("Bsssize:\\s+(\\w+)");
+		boost::regex totalDataSize("^Total data size:\\s+(\\w+)");
+		string tmpline, tmpaddr;
+		boost::cmatch what;
+		while(getline(logfd, tmpline))
+		{
+			TPlacedEntry tmpEntry;
+			if(regex_search(tmpline, what, endFlag))
+			{
+				break;
+			}
+			if(regex_search(tmpline, what, sourceFile))
+			{
+				tmpEntry.iFileName.assign(what[1].first, what[1].second-what[1].first);
+				tmpaddr.assign(what[2].first, what[2].second-what[2].first);
+				tmpEntry.iDataAddress = strtol(tmpaddr.c_str(), NULL, 16);
+				symgen->AddEntry(tmpEntry);
+			}
+			else if(regex_search(tmpline, what, executableFile))
+			{
+				tmpEntry.iFileName.assign(what[1].first, what[1].second-what[1].first);
+				while(getline(logfd, tmpline) && tmpline != "")
+				{
+					if(regex_search(tmpline, what, codeStart))
+					{
+						tmpaddr.assign(what[1].first, what[1].second-what[1].first);
+						tmpEntry.iCodeAddress = strtol(tmpaddr.c_str(), NULL, 16);
+					} 
+					else if(regex_search(tmpline, what, dataStart))
+					{
+						tmpaddr.assign(what[1].first, what[1].second-what[1].first);
+						tmpEntry.iDataAddress = strtol(tmpaddr.c_str(), NULL, 16);
+					}
+					else if(regex_search(tmpline, what, dataBssStart))
+					{
+						tmpaddr.assign(what[1].first, what[1].second-what[1].first);
+						tmpEntry.iDataBssLinearBase = strtol(tmpaddr.c_str(), NULL, 16);
+					}
+					else if(regex_search(tmpline, what, textSize))
+					{
+						tmpaddr.assign(what[1].first, what[1].second-what[1].first);
+						tmpEntry.iTextSize = strtol(tmpaddr.c_str(), NULL, 16);
+					}
+					else if(regex_search(tmpline, what, dataSize))
+					{
+						tmpaddr.assign(what[1].first, what[1].second-what[1].first);
+						tmpEntry.iDataSize = strtol(tmpaddr.c_str(), NULL, 16);
+					}
+					else if(regex_search(tmpline, what, bssSize))
+					{
+						tmpaddr.assign(what[1].first, what[1].second-what[1].first);
+						tmpEntry.iBssSize = strtol(tmpaddr.c_str(), NULL, 16);
+					}
+					else if(regex_search(tmpline, what, totalDataSize))
+					{
+						tmpaddr.assign(what[1].first, what[1].second-what[1].first);
+						tmpEntry.iTotalDataSize = strtol(tmpaddr.c_str(), NULL, 16);
+					}
+				}
+				symgen->AddEntry(tmpEntry);
+			}
+
+
+		}
+		symgen->SetFinished();
+		symgen->Release();
+	}
+	else
+	{
+		throw LoggingException(LoggingException::INVALID_LOG_FILENAME);
+	}
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/imglib/symbolutil/logparser.h	Tue Nov 23 10:47:23 2010 +0800
@@ -0,0 +1,63 @@
+/*
+* Copyright (c) 1995-2009 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:
+*
+*/
+
+
+#ifndef ROM_TOOLS_ROFSBUILD_LOGGING_LOGPARSER_H_
+#define ROM_TOOLS_ROFSBUILD_LOGGING_LOGPARSER_H_
+
+#include "loggingexception.h"
+#include "symbolgenerator.h"
+
+/**
+ * @class LogParser
+ */
+class LogParser
+{
+public:
+	static LogParser* GetInstance(TImageType aImageType) throw (LoggingException);
+
+	virtual void ParseSymbol(const char* LogFilename) throw (LoggingException) = 0;
+
+	void Cleanup(void);
+	virtual ~LogParser() {}
+protected:
+	LogParser(void);
+	static LogParser* Only;
+	TImageType iImageType;
+private:
+	LogParser(const LogParser&);
+
+	LogParser& operator = (const LogParser&);
+};
+
+class RofsLogParser : public LogParser
+{
+public:
+	virtual void ParseSymbol(const char* LogFilename) throw (LoggingException);
+	RofsLogParser(void);
+};
+
+class RomLogParser : public LogParser
+{
+public:
+	virtual void ParseSymbol(const char* LogFilename) throw (LoggingException);
+	RomLogParser(void);
+};
+
+
+
+#endif  /* defined ROM_TOOLS_ROFSBUILD_LOGGING_LOGPARSER_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/imglib/symbolutil/symbolgenerator.cpp	Tue Nov 23 10:47:23 2010 +0800
@@ -0,0 +1,384 @@
+/*
+* 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 <vector>
+#include <boost/regex.hpp>
+#define MAX_LINE 65535
+#include "symbolgenerator.h"
+#include "e32image.h"
+#include "h_utl.h"
+
+#if defined(__LINUX__)
+#define PATH_SEPARATOR '/'
+#else
+#define PATH_SEPARATOR '\\'
+#endif
+extern TInt gThreadNum;
+extern TBool gGenBsymbols;
+
+boost::mutex SymbolGenerator::iMutexSingleton;
+SymbolGenerator* SymbolGenerator::iInst = NULL;
+SymbolGenerator* SymbolGenerator::GetInstance(){
+    iMutexSingleton.lock();
+    if(iInst == NULL) {
+        iInst = new SymbolGenerator();
+    }
+    iMutexSingleton.unlock();
+    return iInst;
+}
+void SymbolGenerator::Release() {
+    if(iInst != NULL) {
+        iInst->join();
+    }
+    iMutexSingleton.lock();
+    if(iInst != NULL) {
+        delete iInst;
+        iInst = NULL;
+    }
+    iMutexSingleton.unlock();
+}
+void SymbolGenerator::SetSymbolFileName( const string& fileName ){
+    if(iSymFile.is_open())
+        iSymFile.close();
+    if(gGenBsymbols)
+    {
+    	string s = fileName.substr(0,fileName.rfind('.'))+".bsym";
+    	if(iImageType == ERofsImage)
+    	{
+    		printf("* Writing %s - ROFS BSymbol file\n", s.c_str());
+    	}
+    	else
+    	{
+    		printf("* Writing %s - ROM BSymbol file\n", s.c_str());
+    	}
+    	iSymFile.open(s.c_str(), ios_base::binary);
+    }
+    else
+    {
+    	string s = fileName.substr(0,fileName.rfind('.'))+".symbol";
+    	if(iImageType == ERofsImage)
+    	{
+    		printf("* Writing %s - ROFS Symbol file\n", s.c_str());
+    	}
+    	else
+    	{
+    		printf("* Writing %s - ROM Symbol file\n", s.c_str());
+    	}
+    iSymFile.open(s.c_str());
+    }
+	   
+}
+void SymbolGenerator::AddFile( const string& fileName, bool isExecutable ){
+    iMutex.lock();
+    iQueueFiles.push(TPlacedEntry(fileName, "" , isExecutable));
+    iMutex.unlock();
+    iCond.notify_all();
+}
+
+void SymbolGenerator::AddEntry(const TPlacedEntry& aEntry)
+{
+    iMutex.lock();
+    iQueueFiles.push(aEntry);
+    iMutex.unlock();
+    iCond.notify_all();
+}
+
+void SymbolGenerator::SetFinished() 
+{ 
+
+	iFinished = true; 
+	iCond.notify_all();
+}
+TPlacedEntry SymbolGenerator::GetNextPlacedEntry()
+{
+	TPlacedEntry pe("", "", false);
+	if(1)
+	{
+		boost::mutex::scoped_lock lock(iMutex);
+		while(!iFinished && iQueueFiles.empty())
+			iCond.wait(lock);
+		if(!iQueueFiles.empty())
+		{
+			pe = iQueueFiles.front();
+			iQueueFiles.pop();
+        	}
+    	}
+	return pe;
+}
+void SymbolGenerator::thrd_func(){
+    	boost::thread_group threads;
+	SymbolWorker worker;
+    	for(int i=0; i < gThreadNum; i++)
+    	{
+    		threads.create_thread(worker);
+    	}
+    	threads.join_all();
+	SymbolGenerator::GetInstance()->FlushSymbolFileContent();
+        }
+SymbolGenerator::SymbolGenerator() : boost::thread(thrd_func),iFinished(false) {
+	if(gGenBsymbols)
+	{
+		iSymbolType = ESymBsym;
+	}
+	else
+	{
+		iSymbolType = ESymCommon;
+	}
+    }
+SymbolGenerator::~SymbolGenerator(){
+    if(joinable())
+        join();
+    iSymFile.flush();
+    iSymFile.close();
+}
+void SymbolGenerator::FlushSymbolFileContent()
+{
+    if(iSymbolType == ESymCommon)
+    {
+	return;
+    }
+    TBsymHeader tmpBsymHeader;
+    memset(&tmpBsymHeader, 0, sizeof(tmpBsymHeader));
+    tmpBsymHeader.iMagic[0] = 'B';
+    tmpBsymHeader.iMagic[1] = 'S';
+    tmpBsymHeader.iMagic[2] = 'Y';
+    tmpBsymHeader.iMagic[3] = 'M';
+    tmpBsymHeader.iMajorVer[0] = BsymMajorVer >> 8;
+    tmpBsymHeader.iMajorVer[1] = BsymMajorVer & 0xff;
+    tmpBsymHeader.iMinorVer[0] = BsymMinorVer >> 8;
+    tmpBsymHeader.iMinorVer[1] = BsymMinorVer & 0xff;
+    if(ByteOrderUtil::IsLittleEndian())
+    {
+	    tmpBsymHeader.iEndiannessFlag = 0;
+    }
+    else
+    {
+	    tmpBsymHeader.iEndiannessFlag = 1;
+    }
+    tmpBsymHeader.iCompressionFlag = 1;
+    //count the space for TDbgUnitEntries and TSymbolEntries
+    int fileCount = iMapFileInfoSet.size();
+    TUint32 sizeNeeded = fileCount * sizeof(TDbgUnitEntry);
+    for(int i = 0; i < fileCount; i++)
+    {
+    	sizeNeeded += iMapFileInfoSet[i].iSymbolPCEntrySet.size() * sizeof(TSymbolEntry);
+    }
+    //write string to the temporary memory area
+    MemoryWriter mWriter;
+    mWriter.SetOffset(sizeNeeded);
+    mWriter.SetStringTableStart(sizeNeeded);
+    mWriter.AddEmptyString();
+
+    //first to prepare the file info entries TDbgUnitEntry
+    TUint32 startSymbolIndex = 0;
+    for(int i = 0; i < fileCount; i++)
+    {
+    	iMapFileInfoSet[i].iDbgUnitPCEntry.iDbgUnitEntry.iStartSymbolIndex = startSymbolIndex;
+    	iMapFileInfoSet[i].iDbgUnitPCEntry.iDbgUnitEntry.iPCNameOffset = mWriter.AddString(iMapFileInfoSet[i].iDbgUnitPCEntry.iPCName);
+    	iMapFileInfoSet[i].iDbgUnitPCEntry.iDbgUnitEntry.iDevNameOffset = mWriter.AddString(iMapFileInfoSet[i].iDbgUnitPCEntry.iDevName);
+    	startSymbolIndex += iMapFileInfoSet[i].iSymbolPCEntrySet.size();
+    }
+    //second to layout the symbols unit for the mapfile
+    for(int i = 0; i < fileCount; i++)
+    {
+        int symbolcount = iMapFileInfoSet[i].iSymbolPCEntrySet.size();
+        for(int j =0; j< symbolcount; j++)
+        {
+        	iMapFileInfoSet[i].iSymbolPCEntrySet[j].iSymbolEntry.iScopeNameOffset = mWriter.AddScopeName(iMapFileInfoSet[i].iSymbolPCEntrySet[j].iScopeName);
+        	iMapFileInfoSet[i].iSymbolPCEntrySet[j].iSymbolEntry.iNameOffset = mWriter.AddString(iMapFileInfoSet[i].iSymbolPCEntrySet[j].iName);
+        	iMapFileInfoSet[i].iSymbolPCEntrySet[j].iSymbolEntry.iSecNameOffset = mWriter.AddString(iMapFileInfoSet[i].iSymbolPCEntrySet[j].iSecName);
+        }
+    }
+
+    //write out the BSym file content
+    char* pstart = mWriter.GetDataPointer();
+    //write out the map file info
+    int unitlen = sizeof(TDbgUnitEntry);
+    for(int i = 0; i < fileCount; i++)
+    {
+    	memcpy(pstart, &iMapFileInfoSet[i].iDbgUnitPCEntry.iDbgUnitEntry, unitlen);
+    	pstart += unitlen;
+    }
+    //wirte out the symbol unit info
+    unitlen = sizeof(TSymbolEntry);
+    for(int i = 0; i < fileCount; i++)
+    {
+    	int symbolcount = iMapFileInfoSet[i].iSymbolPCEntrySet.size();
+    	for(int j =0; j < symbolcount; j++)
+    	{
+    		memcpy(pstart, &iMapFileInfoSet[i].iSymbolPCEntrySet[j].iSymbolEntry, unitlen);
+    		pstart += unitlen;
+    	}
+    }
+    //write out the memory out to the symbol file
+
+    int totalPages = (mWriter.GetOffset() + ( BSYM_PAGE_SIZE -1)) / 4096;
+    TUint32 compressInfoLength = sizeof(TCompressedHeaderInfo) + sizeof(TPageInfo)*(totalPages -1);
+    char* tmpBuffer = new char[compressInfoLength];
+    TCompressedHeaderInfo * pCompressedHeaderInfo = (TCompressedHeaderInfo *) tmpBuffer;
+    pCompressedHeaderInfo->iPageSize = BSYM_PAGE_SIZE;
+    pCompressedHeaderInfo->iTotalPageNumber = totalPages;
+    TPageInfo* tmpPage = &pCompressedHeaderInfo->iPages[0];
+    for(int i = 0; i < totalPages; i++)
+    {
+	    tmpPage->iPageStartOffset = i * BSYM_PAGE_SIZE;
+	    if(tmpPage->iPageStartOffset + BSYM_PAGE_SIZE < mWriter.GetOffset())
+	    {
+	    	tmpPage->iPageDataSize = BSYM_PAGE_SIZE;
+	    }
+	    else
+	    {
+		tmpPage->iPageDataSize = mWriter.GetOffset() - tmpPage->iPageStartOffset;
+	    }
+	    tmpPage++;
+    }
+
+    //prepare the TBsymHeader, TDbgUnitEntry and TSymbolEntry to the memory
+    tmpBsymHeader.iDbgUnitOffset = sizeof(TBsymHeader) + compressInfoLength;
+    tmpBsymHeader.iDbgUnitCount = fileCount;
+    tmpBsymHeader.iSymbolOffset = fileCount*sizeof(TDbgUnitEntry);
+    tmpBsymHeader.iSymbolCount = startSymbolIndex;
+    tmpBsymHeader.iStringTableOffset = mWriter.GetStringTableStart();
+    tmpBsymHeader.iStringTableBytes = mWriter.GetOffset() - tmpBsymHeader.iStringTableOffset;
+    tmpBsymHeader.iUncompressSize = mWriter.GetOffset();
+    //start the compress threads
+    Print(EAlways, "Start compress for Bsymbol file\n");
+    PageCompressWorker compressWorker(pCompressedHeaderInfo, mWriter.GetDataPointer());
+    boost::thread_group threads;
+    for(int i=0; i < gThreadNum; i++)
+    {
+	    threads.create_thread(compressWorker);
+    }
+    threads.join_all();
+    Print(EAlways, "Complete compress for Bsymbol file\n");
+    //pack all the pages together
+    tmpPage = &pCompressedHeaderInfo->iPages[0];
+    TPageInfo* prePage = NULL;
+    char* pchar = mWriter.GetDataPointer();
+    for(int i=0; i < totalPages -1; i++)
+    {
+	    prePage = tmpPage;
+	    tmpPage++;
+	    memcpy(pchar + prePage->iPageStartOffset + prePage->iPageDataSize, pchar + tmpPage->iPageStartOffset, tmpPage->iPageDataSize);
+	    tmpPage->iPageStartOffset = prePage->iPageStartOffset + prePage->iPageDataSize;
+
+    }
+    tmpBsymHeader.iCompressedSize = tmpPage->iPageStartOffset + tmpPage->iPageDataSize;
+    mWriter.SetOffset(tmpBsymHeader.iCompressedSize);
+    tmpBsymHeader.iCompressInfoOffset = sizeof(TBsymHeader);
+
+    iSymFile.write((char*)&tmpBsymHeader, sizeof(TBsymHeader));
+    iSymFile.write((char*)pCompressedHeaderInfo, compressInfoLength);
+    iSymFile.write(mWriter.GetDataPointer(), mWriter.GetOffset());
+    delete[] tmpBuffer;
+    for(int i = 0; i < fileCount; i++)
+    {
+    	iMapFileInfoSet[i].iSymbolPCEntrySet.clear();
+    }
+    iMapFileInfoSet.clear();
+}
+
+SymbolWorker::SymbolWorker()
+{
+}
+SymbolWorker::~SymbolWorker()
+{
+    }
+void SymbolWorker::operator()()
+{
+	SymbolProcessUnit* aSymbolProcessUnit;
+	SymbolGenerator* symbolgenerator = SymbolGenerator::GetInstance();
+	if(symbolgenerator->GetImageType() == ERomImage)
+	{
+		aSymbolProcessUnit = new CommenRomSymbolProcessUnit();
+	}
+	else
+	{
+		if(gGenBsymbols)
+		{
+			aSymbolProcessUnit = new BsymRofsSymbolProcessUnit(symbolgenerator);
+		}
+		else
+		{
+			aSymbolProcessUnit = new CommenRofsSymbolProcessUnit();
+		}
+	}
+
+	while(1)
+	{
+		if(symbolgenerator->HasFinished() && symbolgenerator->IsEmpty())
+		{
+			break;
+                }
+		TPlacedEntry pe = symbolgenerator->GetNextPlacedEntry();
+		if(pe.iFileName.empty())
+			continue;
+
+		aSymbolProcessUnit->ProcessEntry(pe);
+
+		symbolgenerator->LockOutput();
+		aSymbolProcessUnit->FlushStdOut(cout);
+		aSymbolProcessUnit->FlushSymbolContent(symbolgenerator->GetOutputFileStream());
+		symbolgenerator->UnlockOutput();
+	}
+	delete aSymbolProcessUnit;
+}
+TCompressedHeaderInfo* PageCompressWorker::pHeaderInfo = NULL;
+int PageCompressWorker::currentPage = 0;
+boost::mutex PageCompressWorker::m_mutex;
+int PageCompressWorker::m_error = 0;
+char* PageCompressWorker::iChar = NULL;
+
+PageCompressWorker::PageCompressWorker(TCompressedHeaderInfo* aHeaderInfo, char* aChar) 
+{
+	pHeaderInfo = aHeaderInfo;
+	iChar = aChar;
+}
+
+PageCompressWorker::~PageCompressWorker() {}
+void PageCompressWorker::operator()()
+{
+	int tobecompress = 0;
+	CBytePair bpe;
+	while(1)
+	{
+		m_mutex.lock();
+		tobecompress =currentPage;
+		currentPage++;
+		m_mutex.unlock();
+		if(tobecompress >= (int) pHeaderInfo->iTotalPageNumber)
+			break;
+		TPageInfo* current = &pHeaderInfo->iPages[0] + tobecompress;
+		TUint8* in = (TUint8*)(iChar + current->iPageStartOffset);
+		TUint8* out = in;
+		TInt outSize = BytePairCompress(out, in, current->iPageDataSize, &bpe);
+		if(outSize == KErrTooBig)
+		{
+			outSize = BSYM_PAGE_SIZE;
+		}
+		if(outSize < 0)
+		{
+			m_mutex.lock();
+			m_error = -1;
+			m_mutex.unlock();
+			break;
+		}
+		current->iPageDataSize = outSize;
+	}
+	
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/imglib/symbolutil/symbolgenerator.h	Tue Nov 23 10:47:23 2010 +0800
@@ -0,0 +1,94 @@
+/*
+* 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: 
+*
+*/
+
+#ifndef __SYMBOLGENERATOR_H__
+#define __SYMBOLGENERATOR_H__
+#include <queue>
+#include <string>
+#include <fstream>
+using namespace std;
+#include <boost/thread/thread.hpp>
+#include <boost/thread/condition.hpp>
+#include "symbolprocessunit.h"
+
+
+enum TSymbolType {
+	ESymCommon = 0,
+	ESymBsym ,
+};
+enum TImageType {
+	ERomImage = 0,
+	ERofsImage,
+	EUnknownType,
+};
+
+
+class SymbolGenerator : public boost::thread {
+    public:
+        static SymbolGenerator* GetInstance();
+        static void Release();
+        void SetSymbolFileName( const string& fileName );
+        void AddFile( const string& fileName, bool isExecutable );
+	void AddEntry(const TPlacedEntry& aEntry);
+        bool HasFinished()	{ return iFinished; }
+        void SetFinished();
+        bool IsEmpty() { return iQueueFiles.empty(); }
+        void LockOutput() { iOutputMutex.lock(); }
+        void UnlockOutput() { iOutputMutex.unlock(); }
+        TPlacedEntry GetNextPlacedEntry();
+        ofstream& GetOutputFileStream() { return iSymFile; };
+        void AppendMapFileInfo(MapFileInfo& aMapFileInfo) { iMapFileInfoSet.push_back(aMapFileInfo); }
+        void FlushSymbolFileContent();
+	void SetImageType(TImageType aImageType) {	iImageType = aImageType; };
+	TImageType GetImageType() {	return iImageType; };
+    private:
+        SymbolGenerator();
+        ~SymbolGenerator();
+        static void thrd_func();
+
+        queue<TPlacedEntry> iQueueFiles;
+        boost::mutex iMutex;
+        boost::mutex iOutputMutex;
+        static boost::mutex iMutexSingleton;
+        static SymbolGenerator* iInst;
+        boost::condition_variable iCond;
+        bool iFinished;
+        TSymbolType iSymbolType;
+	TImageType iImageType;
+
+        ofstream iSymFile;
+        MapFileInfoSet iMapFileInfoSet;
+};
+class SymbolWorker{
+public:
+	SymbolWorker();
+	~SymbolWorker();
+	void operator()();
+private:
+};
+class PageCompressWorker {
+public:
+	PageCompressWorker(TCompressedHeaderInfo* aHeaderInfo, char* aChar);
+	~PageCompressWorker();
+	void operator()();
+	static TCompressedHeaderInfo * pHeaderInfo;
+	static int currentPage;
+	static boost::mutex m_mutex;
+	static int m_error;
+	static char* iChar;
+};
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/imglib/symbolutil/symbolprocessunit.cpp	Tue Nov 23 10:47:23 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);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/imglib/symbolutil/symbolprocessunit.h	Tue Nov 23 10:47:23 2010 +0800
@@ -0,0 +1,120 @@
+/*
+* 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: 
+*
+*/
+#ifndef __SYMBOLPROCESSUNIT_H__
+#define __SYMBOLPROCESSUNIT_H__
+#include <vector>
+#include <string>
+#include <iostream>
+#include <fstream>
+
+#include "bsymutil.h"
+
+using namespace std;
+
+struct TPlacedEntry{
+    string iFileName;
+    string iDevFileName;
+    TUint32 iTotalSize;
+    TUint32 iCodeAddress;
+    TUint32 iDataAddress;
+    TUint32 iDataBssLinearBase;
+    TUint32 iTextSize;
+    TUint32 iDataSize;
+    TUint32 iBssSize;
+    TUint32 iTotalDataSize;
+    bool iExecutable;
+    TPlacedEntry(const string& aName, const string& aDevFileName, bool aExecutable) {
+        iFileName = aName;
+	iDevFileName = aDevFileName; 
+        iExecutable = aExecutable;
+    }
+    TPlacedEntry() {
+    }
+};
+
+typedef vector<string> stringlist;
+
+class SymbolProcessUnit
+{
+public:
+	virtual void ProcessExecutableFile(const string& aFile) = 0;
+	virtual void ProcessDataFile(const string& afile) = 0;
+	virtual void FlushStdOut(ostream& aOut) = 0;
+	virtual void FlushSymbolContent(ostream &aOut) = 0;
+	virtual void ResetContentLog() = 0;
+	virtual ~SymbolProcessUnit() {}
+	virtual void ProcessEntry(const TPlacedEntry& aEntry);
+	int GetSizeFromBinFile( const string& fileName );
+};
+
+class CommenRomSymbolProcessUnit : public SymbolProcessUnit
+{
+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);
+private:
+	void ProcessArmv5File( const string& fileName, ifstream& aMap );
+	void ProcessGcceOrArm4File( const string& fileName, ifstream& aMap );
+	void ProcessX86File( const string& fileName, ifstream& aMap );
+private:
+	stringlist iStdoutLog;
+	stringlist iSymbolContentLog;
+	TPlacedEntry iPlacedEntry;
+};
+
+class CommenRofsSymbolProcessUnit : public SymbolProcessUnit
+{
+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;
+};
+
+class SymbolGenerator;
+
+class BsymRofsSymbolProcessUnit : public SymbolProcessUnit
+{
+public:
+	BsymRofsSymbolProcessUnit(SymbolGenerator* aSymbolGeneratorPtr): iSymbolGeneratorPtr(aSymbolGeneratorPtr){}
+	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);
+private:
+	void ProcessArmv5File( const string& fileName, ifstream& aMap );
+	void ProcessGcceOrArm4File( const string& fileName, ifstream& aMap );
+private:
+	stringlist iStdoutLog;
+	MapFileInfo iMapFileInfo;
+	SymbolGenerator* iSymbolGeneratorPtr;
+};
+#endif
--- a/imgtools/romtools/group/release.txt	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/romtools/group/release.txt	Tue Nov 23 10:47:23 2010 +0800
@@ -1,3 +1,23 @@
+Version 2.19.1 (ROMBUILD)
+===============
+Released by Lorence Wang, 19/11/2010
+	1) ou1cimx1#656196 one line message of ROM tools
+
+Version 2.17.1 (ROFSBUILD)
+===============
+Released by Marvin Shi, 19/11/2010
+	1) ou1cimx1#651819 rofsbiuld fails to generate correct log info when using multi-thread 
+
+Version 2.19.0 (ROMBUILD)
+===============
+Released by Marvin Shi, 17/11/2010
+	1) feature symbol file generation from log file
+
+Version 2.17.0 (ROFSBUILD)
+===============
+Released by Marvin Shi, 17/11/2010
+	1) feature bsym format symbol file generation for rofsbuild
+
 Version 2.16.2 (ROFSBUILD)
 ===============
 Released by Ross Qin, 02/11/2010
--- a/imgtools/romtools/maksym/fixupsym	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/romtools/maksym/fixupsym	Tue Nov 23 10:47:23 2010 +0800
@@ -1,3 +1,9 @@
 #!/bin/sh
-perl -S fixupsym.pl $@
+PRGDIR=`dirname "$0"`
+
+PRGDIR=`cd "$PRGDIR"; pwd`
 
+
+perl "$PRGDIR/fixupsym.pl" $@
+
+
--- a/imgtools/romtools/maksym/hpsym	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/romtools/maksym/hpsym	Tue Nov 23 10:47:23 2010 +0800
@@ -1,3 +1,9 @@
 #!/bin/sh
-perl -S hpsym.pl $@
+PRGDIR=`dirname "$0"`
+
+PRGDIR=`cd "$PRGDIR"; pwd`
 
+
+perl "$PRGDIR/hpsym.pl" $@
+
+
--- a/imgtools/romtools/maksym/maksym	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/romtools/maksym/maksym	Tue Nov 23 10:47:23 2010 +0800
@@ -1,3 +1,9 @@
 #!/bin/sh
-perl -S maksym.pl $@
+PRGDIR=`dirname "$0"`
+
+PRGDIR=`cd "$PRGDIR"; pwd`
 
+
+perl "$PRGDIR/maksym.pl" $@
+
+
--- a/imgtools/romtools/maksym/maksym.pl	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/romtools/maksym/maksym.pl	Tue Nov 23 10:47:23 2010 +0800
@@ -19,6 +19,7 @@
 no strict 'vars';
 use English;
 use FindBin;		# for FindBin::Bin
+use File::Copy;
 
 # Version
 my $MajorVersion = 1;
@@ -47,285 +48,16 @@
 #
 sub main()
 {
-  my $file;
-  my $mapfile;
-  my $mapfile2;
-  my $text;
-  my $data;
-  my $bss;
-  my $textsize;
-  my $datasize;
-  my $bsssize;
-  my $totaldatasize;
-  my $totalsize;
-
-  open (ROM, "<$rombuild")
-    or die "ERROR: Can't open rombuild log file \"$rombuild\"\n";
-  if ($maksym ne "") {
-    open (SYM, ">$maksym")
-      or die "ERROR: Can't open output file \"$maksym\"\n";
-    print "Creating $maksym...\n";
-  }
-
-  while (<ROM>) {
-    # Start of ROM
-    if (/^Creating Rom image (\S*)/) {
-      if ($maksym eq "") {
-	# For backwards compatibility, replace trailing .img with .symbol
-	# if no trailing .img, just append .symbol anyway
-	$maksym = $1;
-	$maksym =~ s/(\.img)?$/.symbol/i;
-	close SYM;
-	open (SYM, ">$maksym")
-	  or die "ERROR: Can't open output file \"$maksym\"\n";
-	print "\nCreating $maksym...\n";
-      }
-      next;
-    }
-    # end of ROM
-    if (/^Writing Rom image/) {
-      close SYM;
-      $maksym = "";
-      next;
-    }
-    # Data file
-    if (/^Reading resource (.*) to rom linear address (.*)/) {
-      $file = $1;
-      my $data = hex($2);
-      $file =~ /([^\\]+)$/;
-      printf SYM "\nFrom    $file\n\n%08x    0000    $1\n", $data;
-    }
-    # Executable file
-    elsif (/^Processing file (.*)/) {
-      $file = $1;
-      $text = 0;
-      $data = 0;
-      $bss = 0;
-      $textsize = 0;
-      $datasize = 0;
-      $bsssize = 0;
-      $totaldatasize = 0;
-
-      # Work out final addresses of sections
-      while (defined($_=<ROM>) && !/^$/) {
-	if (/^Size:\s+(\w+)/) {
-	  $totalsize = hex($1);
-	} elsif (/^Code start addr:\s+(\w+)/) {
-	  $text = hex($1);
-	} elsif (/^Data start addr:\s+(\w+)/) {
-	  $data = hex($1);
-	} elsif (/^DataBssLinearBase:\s+(\w+)/) {
-	  $bss = hex($1);
-	} elsif (/^Text size:\s+(\w+)/) {
-	  $textsize = hex($1);
-	} elsif (/^Data size:\s+(\w+)/) {
-	  $datasize = hex($1);
-	} elsif (/^Bsssize:\s+(\w+)/) {
-	  $bsssize = hex($1);
-	} elsif (/^Total data size:\s+(\w+)/) {
-	  $totaldatasize = hex($1);
-	}
-      }
-
-      # Sanity check - text section can't be zero
-      die "ERROR: Can't find rombuild info for \"$file\"\n"
-	if (!$text);
-
-      print SYM "\nFrom    $file\n\n";
+  my $symbolfile = $rombuild;
+  $symbolfile =~ s/\.log$/\.symbol/i;
+  my @cmdres = `rombuild -loginput=$rombuild`;
+  print "@cmdres\n";
 
-      # Look in map file for symbols in .text and relocate them
-      $mapfile2 = $file.".map";
-      $mapfile = $file;
-      $mapfile =~ s/\.\w+$/\.map/;
-      if (!(open (MAP, "$mapfile2") || open (MAP, "$mapfile"))) {
-	print "$file\nWarning: Can't open \"$mapfile2\" or \"$mapfile\"\n";
-	$file =~ /([^\\]+)$/;
-	printf SYM "%08x    %04x    $1\n", $text, $totalsize;
-      } else {
-	local $/ = undef;
-	my (@maplines) = split(/\n/, <MAP>);
-	close MAP;
-	# See if we're dealing with the RVCT output
-	if ($maplines[0] =~ /^ARM Linker/) {
-	  print "$file\n";
-	 
-		my %syms;
-		my @hasharray;
-		# Starts from begining of map file.		
-		while (@maplines) {
-		  $_ = shift @maplines;
-		  if (/Global Symbols/) {
-		    last;
-		  } elsif (!/(ARM Code|Thumb Code)/) {
-		    next;
-		  }
-		# name address type size section
-		if (/^\s*(.+)\s*(0x\S+)\s+(ARM Code|Thumb Code)\s+[^\d]*(\d+)\s+(.*)$/) {
-			# Check for static methods in local symbols section.
-			my $sym = $1;
-			my $addr = hex($2);
-			my $size = sprintf("%04x",$4);
-			my $section = $5;
-			$size = sprintf("%04x", 8) if ($section =~ /\(StubCode\)/);
-			if(exists($syms{$addr})) {
-				push @{ $syms{$addr} }, "$size    $sym $section";	   
-			}
-			elsif ($addr > 0){
-				@hasharray = "$size    $sym $section";
-				$syms{$addr} = [@hasharray];
-			}
-		}
-		}	
-	
-	  foreach (@maplines) {
-	    # name address ignore size section
-	    if (/^\s*(.+)\s*(0x\S+)\s+[^\d]*(\d+)\s+(.*)$/) {
-	      my $sym = $1;
-	      my $addr = hex($2);
-	      my $size = sprintf("%04x",$3);
-	      my $section = $4;
-	      $size = sprintf("%04x", 8) if ($section =~ /\(StubCode\)/);
-		  if(exists($syms{$addr})) {
-			push @{ $syms{$addr} }, "$size    $sym $section";	   
-		  }
-	      elsif ($addr > 0) {
-			@hasharray = "$size    $sym $section"; 
-			$syms{$addr} = [@hasharray];
-		  }
-	    }
-	  } # end of foreach
-
-	  # .text gets linked at 0x00008000
-	  # .data gets linked at 0x00400000
-	  my $srctext = hex(8000);
-	  my $srcdata = hex(400000);
-	  my $j; 
-	  # Write symbols in address order
-	  my @addrs = sort CompareAddrs keys %syms;
-	  for ($i = 0; $i < @addrs ; $i++) {
-	    my $thisaddr = $addrs[$i];
-	    my $romaddr = 0;
-	    # see if its in the text segment
-		if ($thisaddr >= $srctext && $thisaddr <= ($srctext+$textsize)) {
-	      $romaddr = $thisaddr-$srctext+$text;
-	    } elsif ( $data && ( $thisaddr >= $srcdata && $thisaddr <= ($srcdata+$datasize))) {
-	      # its in the data segment
-	      # is it from .data or .bss
-
-  			# confusingly (?) $bss is the right value to use here
-			# since we're interested in where the data gets copied to
-			# in RAM rather than where it sits in ROM
-		$romaddr = $thisaddr-$srcdata+$bss;
-	      } elsif ( $bss && ( $thisaddr >= $srcdata && $thisaddr <= ($srcdata+$totaldatasize))) {
-				# its BSS
-		$romaddr = $thisaddr-$srcdata+$bss;
-	      } else {
-		my $errsym = $syms{$thisaddr}[0];
-		my $erraddr = sprintf("%08x", $thisaddr);
-		print "WARNING: Symbol $errsym @ $erraddr not in text or data segments\n";
-		print "WARNING: The map file for binary $file is out-of-sync with the binary itself\n\n";
-		next;
-	      }
-
-	    printf SYM "%08x    %s\n", $romaddr, $_ for @{$syms{$addrs[$i]}};
-	  } # end of for.
-        # See if we're dealing with the GCC output
-	} elsif ($maplines[0] =~ /^Archive member included/) {
-	  
-	  my $imgtext;
-	  my $textlen;
-	  my %syms;
-	  my $stubhex=1;
-
-	  # Find text section
-	  while (@maplines) {
-	      $_ = shift @maplines;
-	      last if /^\.text\s+/;
-	  }
-
-	  /^\.text\s+(\w+)\s+(\w+)/
-			or die "ERROR: Can't get .text section info for \"$file\"\n";
-
-		    $imgtext=hex($1);
-		    $textlen=hex($2);
-
-		    print "$file\n";
-
-		# Slurp symbols 'til the end of the text section
-		foreach (@maplines) {
-
-			# blank line marks the end of the text section
-			last if (/^$/);
-
-			# .text <addr> <len>  <library(member)>
-			# .text$something
-			#       <addr> <len>  <library(member)>
-			#       <addr> <len>  LONG 0x0
-
-			if (/^\s(\.text)?\s+(0x\w+)\s+(0x\w+)\s+(.*)$/io) {
-				my $address = hex($2);
-				my $length = hex($3);
-				my $libraryfile = $4;
-				next if ($libraryfile =~ /^LONG 0x/);
-				$syms{$address+$length} = ' ';	# impossible symbol as end marker
-
-				# EUSER.LIB(ds01423.o)
-				# EUSER.LIB(C:/TEMP/d1000s_01423.o)
-				if ($libraryfile =~ /.*lib\(.*d\d*s_?\d{5}.o\)$/io) {
-					$stubhex=$address;
-				}
-				next;
-			}
-
-			#  <addr>  <symbol name possibly including spaces>
-			if (/^\s+(\w+)\s\s+([a-zA-Z_].+)/o) {
-				my $addr = hex($1);
-				my $symbol = $2;
-				$symbol = "stub $symbol" if ($addr == $stubhex);
-				$syms{$addr} = $symbol;
-				next;
-			}
-		}
-
-		# Write symbols in address order
-		@addrs = sort CompareAddrs keys %syms;
-		for ($i = 0; $i < @addrs - 1; $i++) {
-			my $symbol = $syms{$addrs[$i]};
-			next if ($symbol eq ' ');
-			printf SYM "%08x    %04x    %s\n",
-			$addrs[$i]-$imgtext+$text, $addrs[$i+1]-$addrs[$i], $symbol;
-		}
-		# last address assumed to be imgtext+lentext
-
-		close MAP;
-	}
-	# Must be x86 output
-	else {
-		while (@maplines) {
-	      $_ = shift @maplines;
-	      last if /^  Address/;
-		}
-	    shift @maplines;
-	    
-	    my ($lastname, $lastaddr);
-		while (@maplines) {
-	      $_ = shift @maplines;
-	      last unless /^ 0001:(\w+)\s+(\S+)/;
-		  my ($addr, $name) = (hex $1, $2);
-		  if ($lastname) {
-			  my $size = $addr - $lastaddr;
-			  printf SYM "%08x    %04x    %s\n", $lastaddr + $text, $size, $lastname;
-		  }
-		  ($lastname, $lastaddr) = ($name, $addr);
-	    }	    
-	    printf SYM "%08x    %04x    %s\n", $lastaddr + $text, 0, $lastname if $lastname;
-	}
-	
-	    }
-	  }
-	}
-    close SYM;
-    close ROM;
+  if(($maksym ne "") && ($maksym ne $symbolfile))
+  {
+	  copy($symbolfile, $maksym);
+	  unlink $symbolfile;
+  }
 }
 
 #
--- a/imgtools/romtools/maksym/maksymrofs	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/romtools/maksym/maksymrofs	Tue Nov 23 10:47:23 2010 +0800
@@ -1,3 +1,9 @@
 #!/bin/sh
-perl -S maksymrofs.pl $@
+PRGDIR=`dirname "$0"`
+
+PRGDIR=`cd "$PRGDIR"; pwd`
 
+
+perl "$PRGDIR/maksymrofs.pl" $@
+
+
--- a/imgtools/romtools/readimage/src/image_handler.cpp	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/romtools/readimage/src/image_handler.cpp	Tue Nov 23 10:47:23 2010 +0800
@@ -290,7 +290,6 @@
  * @fn ImageHandler::ReadBareImage
  * @brief this function processes image type under the condition of that if an image is given without header which means the image is not self-described
  * @return type of the image.
- * @note this function is introduced for handling issues raised by DEF129908
  */
 EImageType ImageHandler::ReadBareImage(ifstream& aIfs) {
     TRomHeader romHdr ; 
--- a/imgtools/romtools/rofsbuild/fsnode.cpp	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/romtools/rofsbuild/fsnode.cpp	Tue Nov 23 10:47:23 2010 +0800
@@ -287,8 +287,7 @@
 		TShortDirEntry* entry = reinterpret_cast<TShortDirEntry*>(aClusterData);
 		if(iParent != NULL) {
 			//Make 
-			GetShortEntry(entry); 
-			//TODO: Add comments to avoid mistaken deleting.			
+			GetShortEntry(entry); 			
 			memcpy(entry->DIR_Name,".            ",sizeof(entry->DIR_Name));
 			entry ++ ;
 			iParent->GetShortEntry(entry);
--- a/imgtools/romtools/rofsbuild/inc/logging/loggingexception.hpp	Fri Nov 12 14:49:36 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
-* Copyright (c) 1995-2009 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:
-*
-*/
-
-
-#ifndef ROM_TOOLS_ROFSBUILD_LOGGING_LOGGINGEXCEPTION_H_
-#define ROM_TOOLS_ROFSBUILD_LOGGING_LOGGINGEXCEPTION_H_
-
-
-/*
- * @class LoggingException
- */
-class LoggingException
-{
-public:
-	LoggingException(int ErrorCode);
-
-	int GetErrorCode(void);
-
-	const char* GetErrorMessage(void);
-
-	static int RESOURCE_ALLOCATION_FAILURE;
-	static int INVALID_LOG_FILENAME       ;
-
-	virtual ~LoggingException(void);
-protected:
-	int errcode;
-private:
-	LoggingException(void);
-
-	LoggingException& operator = (const LoggingException&);
-};
-
-
-#endif  /* defined ROM_TOOLS_ROFSBUILD_LOGGING_LOGGINGEXCEPTION_H_ */
--- a/imgtools/romtools/rofsbuild/inc/logging/logparser.hpp	Fri Nov 12 14:49:36 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
-* Copyright (c) 1995-2009 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:
-*
-*/
-
-
-#ifndef ROM_TOOLS_ROFSBUILD_LOGGING_LOGPARSER_H_
-#define ROM_TOOLS_ROFSBUILD_LOGGING_LOGPARSER_H_
-
-
-/**
- * @class LogParser
- */
-class LogParser
-{
-public:
-	static LogParser* GetInstance(void) throw (LoggingException);
-
-	void ParseSymbol(const char* LogFilename) throw (LoggingException);
-
-	void Cleanup(void);
-protected:
-	static LogParser* Only;
-private:
-	LogParser(void);
-
-	LogParser(const LogParser&);
-
-	LogParser& operator = (const LogParser&);
-};
-
-
-
-#endif  /* defined ROM_TOOLS_ROFSBUILD_LOGGING_LOGPARSER_H_ */
--- a/imgtools/romtools/rofsbuild/r_build.cpp	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/romtools/rofsbuild/r_build.cpp	Tue Nov 23 10:47:23 2010 +0800
@@ -68,6 +68,9 @@
 extern TInt  gLogLevel;
 extern bool gCache;
 extern TBool gIsOBYUTF8;
+
+#define MAX_LINE  65535
+
 TBool gDriveImage=EFalse;	// for drive image support.
 
 
@@ -625,7 +628,7 @@
 			
 			if(offset > 0xFFFF)
 			{
-				printf("ERROR: Offset overflow: name=%s, OFFSET = %d\n", node->iName, offset);
+				printf("ERROR: Offset overflow: name=%s, OFFSET = %d\n", node->iName, (int)offset);
 				throw "fail";
 			}
 			
@@ -640,7 +643,7 @@
 			TUint32 offset = ((((TUint8*) entry) - dirBlockBase) >> 2);
 			if(offset > 0xFFFF)
 			{
-				printf("ERROR: Offset overflow: name=%s, OFFSET = %d\n", node->iName, offset);
+				printf("ERROR: Offset overflow: name=%s, OFFSET = %d\n", node->iName, (int)offset);
 				throw "fail";
 			}
 			
@@ -789,6 +792,18 @@
 		}
 	iNextNodeForSameFile = aPreviousNode;
 	}
+void TRomNode::FlushLogMessages()
+	{
+	if(iEntry)
+		{
+		for(int i = 0; i < (int)iEntry->iLogMessages.size(); i++)
+			{
+			TLogItem& aLogItem = iEntry->iLogMessages[i];
+			Print(aLogItem.iPrintType, aLogItem.iLogMessage.c_str());
+			}
+		iEntry->iLogMessages.clear();
+		}
+	}
 
 
 
@@ -862,13 +877,23 @@
 // Returns the number of bytes used, or -ve error code
 TInt TRomBuilderEntry::PlaceFile( TUint8* &aDest,TUint aMaxSize, CBytePair *aBPE ){
 
-
+	char tmpbuf[MAX_LINE];
+	TLogItem tmpLog;
 	TUint compression = 0;
 	TBool executable = iExecutable;
-	Print(ELog,"Reading file %s to image\n", iFileName );
+	sprintf(tmpbuf,"Reading file %s to image\n", iFileName );
+	tmpLog.iPrintType = ELog;
+	tmpLog.iLogMessage = tmpbuf;
+	iLogMessages.push_back(tmpLog);
+
 	TUint32 size = HFile::GetLength(iFileName);
 	if (size==0)
-		Print(EWarning, "File %s does not exist or is 0 bytes in length.\n",iFileName);
+	{
+		sprintf(tmpbuf, "File %s does not exist or is 0 bytes in length.\n",iFileName);
+		tmpLog.iPrintType = EWarning;
+		tmpLog.iLogMessage = tmpbuf;
+		iLogMessages.push_back(tmpLog);
+	}
 	if (aDest == NULL) {
 		aMaxSize = size << 1;
 		aMaxSize = (aMaxSize>0) ? aMaxSize : 2;
@@ -890,7 +915,10 @@
 		// is it really a valid E32ImageFile?
 		if (r != KErrNone)
 		{
-			Print(EWarning, "File '%s' is not a valid executable.  Placing file as data.\n", iFileName);
+			sprintf(tmpbuf, "File '%s' is not a valid executable.  Placing file as data.\n", iFileName);
+			tmpLog.iPrintType = EWarning;
+			tmpLog.iLogMessage = tmpbuf;
+			iLogMessages.push_back(tmpLog);
 			executable = EFalse;
 		}
 		else
@@ -912,7 +940,10 @@
 				while( aDllEntry ){
 					if(aDllEntry->iOrdinal != (TUint32)-1){
 						if(aDllEntry->iOrdinal < 1 || aDllEntry->iOrdinal > (TUint)f.iOrigHdr->iExportDirCount){
-							Print(EWarning, "Invalid ordinal %d specified for DLL %s\n", aDllEntry->iOrdinal, iRomNode->iName);
+							sprintf(tmpbuf, "Invalid ordinal %d specified for DLL %s\n", (unsigned int) aDllEntry->iOrdinal, iRomNode->iName);
+							tmpLog.iPrintType = EWarning;
+							tmpLog.iLogMessage = tmpbuf;
+							iLogMessages.push_back(tmpLog);
 							aDllEntry = aDllEntry->NextDllDataEntry();
 							continue;
 						}
@@ -931,7 +962,10 @@
 						}
 						else
 						{
-							Print(EWarning, "Patchdata failed as address pointed by ordinal %d of DLL %s doesn't lie within Code or Data section limits\n", aDllEntry->iOrdinal, iRomNode->iName);
+							sprintf(tmpbuf, "Patchdata failed as address pointed by ordinal %d of DLL %s doesn't lie within Code or Data section limits\n", (unsigned int) aDllEntry->iOrdinal, iRomNode->iName);
+							tmpLog.iPrintType = EWarning;
+							tmpLog.iLogMessage = tmpbuf;
+							iLogMessages.push_back(tmpLog);
 						}
 					}
 					else if(aDllEntry->iDataAddress != (TLinAddr)-1){
@@ -948,7 +982,10 @@
 						}
 						else
 						{
-							Print(EWarning, "Patchdata failed as address 0x%x of DLL %s doesn't lie within Code or Data section limits\n", aDllEntry->iOrdinal, iRomNode->iName);
+							sprintf(tmpbuf, "Patchdata failed as address 0x%x of DLL %s doesn't lie within Code or Data section limits\n", (unsigned int) aDllEntry->iOrdinal, iRomNode->iName);
+							tmpLog.iPrintType = EWarning;
+							tmpLog.iLogMessage = tmpbuf;
+							iLogMessages.push_back(tmpLog);
 						}
 					}
 					aDllEntry = aDllEntry->NextDllDataEntry();
@@ -956,7 +993,10 @@
 			}
 
 			compression = f.iHdr->CompressionType();
-			Print(ELog,"Original file:'%s' is compressed by method:%08x\n", iFileName, compression);
+			sprintf(tmpbuf,"Original file:'%s' is compressed by method:%08x\n", iFileName, compression);
+			tmpLog.iPrintType = ELog;
+			tmpLog.iLogMessage = tmpbuf;
+			iLogMessages.push_back(tmpLog);
 
 
 			TUint32 oldFileComp;
@@ -1070,12 +1110,18 @@
 
 				if( newFileComp == 0)
 				{
-					Print(ELog,"Decompressing executable '%s'\n", iFileName);
+					sprintf(tmpbuf,"Decompressing executable '%s'\n", iFileName);
 					f.iHdr->iCompressionType = 0;
+					tmpLog.iPrintType = ELog;
+					tmpLog.iLogMessage = tmpbuf;
+					iLogMessages.push_back(tmpLog);
 				}
 				else
 				{
-					Print(ELog,"Compressing executable '%s' with method:%08x\n", iFileName, newFileComp);
+					sprintf(tmpbuf,"Compressing executable '%s' with method:%08x\n", iFileName, (unsigned int) newFileComp);
+					tmpLog.iPrintType = ELog;
+					tmpLog.iLogMessage = tmpbuf;
+					iLogMessages.push_back(tmpLog);
 					f.iHdr->iCompressionType = newFileComp;
 				}
 				f.UpdateHeaderCrc();
@@ -1103,8 +1149,14 @@
 			}
 			if (overflow)
 			{
-				Print(EError, "Can't fit '%s' in image\n", iFileName);
-				Print(EError, "Overflowed by approximately 0x%x bytes.\n", size - aMaxSize);
+				sprintf(tmpbuf, "Can't fit '%s' in image\n", iFileName);
+				tmpLog.iPrintType = EError;
+				tmpLog.iLogMessage = tmpbuf;
+				iLogMessages.push_back(tmpLog);
+				sprintf(tmpbuf, "Overflowed by approximately 0x%x bytes.\n", (unsigned int) (size - aMaxSize));
+				tmpLog.iPrintType = EError;
+				tmpLog.iLogMessage = tmpbuf;
+				iLogMessages.push_back(tmpLog);
 				exit(667);
 			}
 
@@ -1124,11 +1176,27 @@
 					compression = atoi(entryref->GetCachedFileCompressionID());
 					memcpy(&iUids[0], aDest, sizeof(iUids));
 					if (compression)
-						Print(ELog,"Compressed executable File '%s' size: %08x, mode:%08x\n", iFileName, size, compression);
+					{
+						sprintf(tmpbuf,"Compressed executable File '%s' size: %08x, mode:%08x\n", iFileName, (unsigned int) size, (unsigned int) compression);
+
+						tmpLog.iPrintType = ELog;
+						tmpLog.iLogMessage = tmpbuf;
+						iLogMessages.push_back(tmpLog);
+					}
 					else if (iExecutable)
-						Print(ELog,"Executable File '%s' size: %08x\n", iFileName, size);
+					{
+						sprintf(tmpbuf,"Executable File '%s' size: %08x\n", iFileName, (unsigned int) size);
+						tmpLog.iPrintType = ELog;
+						tmpLog.iLogMessage = tmpbuf;
+						iLogMessages.push_back(tmpLog);
+					}
 					else
-						Print(ELog,"File '%s' size: %08x\n", iFileName, size);
+					{
+						sprintf(tmpbuf,"File '%s' size: %08x\n", iFileName, (unsigned int) size);
+						tmpLog.iPrintType = ELog;
+						tmpLog.iLogMessage = tmpbuf;
+						iLogMessages.push_back(tmpLog);
+					}
 					iRealFileSize = size;	// required later when directory is written
 
 					return size;
@@ -1183,7 +1251,10 @@
 					}
 					catch (CacheException ce)
 					{
-						Print(EWarning, "Cache brings up an exception (%s) when processes %s\r\n", ce.GetErrorMessage(), iFileName);
+						sprintf(tmpbuf, "Cache brings up an exception (%s) when processes %s\r\n", ce.GetErrorMessage(), iFileName);
+						tmpLog.iPrintType = EWarning;
+						tmpLog.iLogMessage = tmpbuf;
+						iLogMessages.push_back(tmpLog);
 					}
 				}
 			}
@@ -1196,8 +1267,14 @@
 	{
 		if ( size > aMaxSize )
 		{
-			Print(EError, "Can't fit '%s' in image\n", iFileName);
-			Print(EError, "Overflowed by approximately 0x%x bytes.\n", size - aMaxSize);
+			sprintf(tmpbuf, "Can't fit '%s' in image\n", iFileName);
+			tmpLog.iPrintType = EError;
+			tmpLog.iLogMessage = tmpbuf;
+			iLogMessages.push_back(tmpLog);
+			sprintf(tmpbuf, "Overflowed by approximately 0x%x bytes.\n", (unsigned int) (size - aMaxSize));
+			tmpLog.iPrintType = EError;
+			tmpLog.iLogMessage = tmpbuf;
+			iLogMessages.push_back(tmpLog);
 			exit(667);
 		}
 		size = HFile::Read(iFileName, (TAny *)aDest);
@@ -1206,11 +1283,26 @@
 	}
 
 	if (compression)
-		Print(ELog,"Compressed executable File '%s' size: %08x, mode:%08x\n", iFileName, size, compression);
+	{
+		sprintf(tmpbuf,"Compressed executable File '%s' size: %08x, mode:%08x\n", iFileName, (unsigned int) size, (unsigned int) compression);
+		tmpLog.iPrintType = ELog;
+		tmpLog.iLogMessage = tmpbuf;
+		iLogMessages.push_back(tmpLog);
+	}
 	else if (iExecutable)
-		Print(ELog,"Executable File '%s' size: %08x\n", iFileName, size);
+	{
+		sprintf(tmpbuf,"Executable File '%s' size: %08x\n", iFileName, (unsigned int) size);
+		tmpLog.iPrintType = ELog;
+		tmpLog.iLogMessage = tmpbuf;
+		iLogMessages.push_back(tmpLog);
+	}
 	else
-		Print(ELog,"File '%s' size: %08x\n", iFileName, size);
+	{
+		sprintf(tmpbuf,"File '%s' size: %08x\n", iFileName, (unsigned int) size);
+		tmpLog.iPrintType = ELog;
+		tmpLog.iLogMessage = tmpbuf;
+		iLogMessages.push_back(tmpLog);
+	}
 	iCompressEnabled = compression;
 	iRealFileSize = size;	// required later when directory is written
 
@@ -1351,3 +1443,11 @@
 		}
 
 }
+char* TRomBuilderEntry::GetSystemFullName()
+{
+	TBool aIgnoreHiddenAttrib = ETrue;
+	TInt aLen = iRomNode->FullNameLength(aIgnoreHiddenAttrib);
+	char *aBuf = new char[aLen+1];
+	iRomNode->GetFullName(aBuf, aIgnoreHiddenAttrib);
+	return aBuf;
+}
--- a/imgtools/romtools/rofsbuild/r_obey.cpp	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/romtools/rofsbuild/r_obey.cpp	Tue Nov 23 10:47:23 2010 +0800
@@ -46,7 +46,7 @@
 #include <unistd.h>
 #else
 #include <io.h> 
-#include <direct.h> //TODO: check under MinGW4 + stlport 5.2
+#include <direct.h> 
 #include <conio.h> 
 #endif
 
--- a/imgtools/romtools/rofsbuild/r_rofs.cpp	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/romtools/rofsbuild/r_rofs.cpp	Tue Nov 23 10:47:23 2010 +0800
@@ -32,6 +32,7 @@
 extern TBool gLowMem;
 extern TInt gThreadNum;
 extern TBool gGenSymbols;
+extern TBool gGenBsymbols;
 ////////////////////////////////////////////////////////////////////////
 
 
@@ -49,8 +50,10 @@
 //
 	: iObey( aObey ), iOverhead(0)
 	{
-	if(gGenSymbols)
+	if(gGenSymbols || gGenBsymbols) {
 		iSymGen = SymbolGenerator::GetInstance();
+		iSymGen->SetImageType(ERofsImage);
+	}
 	else
 		iSymGen = NULL;
 
@@ -263,6 +266,7 @@
 }
 class Worker : public boost::thread {
     public:
+    static boost::mutex iMutexOut;
     static void thrd_func(E32Rofs* rofs){
         CBytePair bpe;
 
@@ -273,7 +277,15 @@
                 p->len = p->node->PlaceFile(p->buf, (TUint32)-1, 0, &bpe);
                 //no symbol for hidden file
                 if(rofs->iSymGen && !p->node->iEntry->iHidden)
-                    rofs->iSymGen->AddFile(p->node->iEntry->iFileName,(p->node->iEntry->iCompressEnabled|| p->node->iEntry->iExecutable));
+		{
+		    char* fullsystemname= p->node->iEntry->GetSystemFullName();
+		    TPlacedEntry tmpEntry(p->node->iEntry->iFileName, fullsystemname, (p->node->iEntry->iCompressEnabled|| p->node->iEntry->iExecutable));
+		    rofs->iSymGen->AddEntry(tmpEntry);
+		    delete[] fullsystemname; 
+		}
+		iMutexOut.lock();
+		p->node->FlushLogMessages();
+		iMutexOut.unlock();
             }
             p = rofs->GetFileNode(deferred);
         }
@@ -288,6 +300,8 @@
     }
 };
 
+boost::mutex Worker::iMutexOut;
+
 TPlacingSection* E32Rofs::GetFileNode(bool &aDeferred) {
 	//get a node from the node list, the node list is protected by mutex iMuxTree.
 	//The iMuxTree also helps to make sure the order in iVPS is consistent with the node list.
--- a/imgtools/romtools/rofsbuild/r_romnode.h	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/romtools/rofsbuild/r_romnode.h	Tue Nov 23 10:47:23 2010 +0800
@@ -21,6 +21,8 @@
 
 #include <fstream>
 #include <e32std.h>
+#include <vector>
+#include <string>
 #include "rofs.h"
 #include "e32image.h"
 #include "h_utl.h"
@@ -123,7 +125,8 @@
 	TInt GetFullName(char* aBuf, TBool aIgnoreHiddenAttrib = EFalse) const;
 	static void InitializeCount();
 	// Accessor Function.
-    inline TRomNode* GetParent() const { return iParent; }
+    	inline TRomNode* GetParent() const { return iParent; }
+	void FlushLogMessages();
 
 private:
 	void Remove(TRomNode* aChild);
@@ -187,6 +190,12 @@
 
 
 class DllDataEntry;
+struct TLogItem
+	{
+		TPrintType iPrintType;
+		std::string iLogMessage;
+	};
+typedef vector<TLogItem> LogVector;
 class TRomBuilderEntry
 	{
 public:
@@ -199,6 +208,7 @@
 	inline TInt RealFileSize() const { return iRealFileSize; };
 	inline void SetRealFileSize(TInt aFileSize) { iRealFileSize=aFileSize;};
 	void DisplaySize(TPrintType aWhere);
+	char* GetSystemFullName();
 	
 private:
 	TRomBuilderEntry();
@@ -217,6 +227,7 @@
 	TUint iCompressEnabled;
 	TUint8 iUids[sizeof(TCheckedUid)];
 	TBool iHidden;
+	LogVector iLogMessages;
   	DllDataEntry* GetFirstDllDataEntry() const;
 	void SetFirstDllDataEntry(DllDataEntry *aDllDataEntry);
 
--- a/imgtools/romtools/rofsbuild/rofsbuild.cpp	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/romtools/rofsbuild/rofsbuild.cpp	Tue Nov 23 10:47:23 2010 +0800
@@ -34,8 +34,7 @@
 #include "cache/cachevalidator.hpp"
 #include "cache/cacheablelist.hpp"
 #include "cache/cachemanager.hpp"
-#include "logging/loggingexception.hpp"
-#include "logging/logparser.hpp"
+#include "logparser.h"
 #include <malloc.h>
  
 #ifndef WIN32
@@ -48,8 +47,8 @@
 #endif
 
 static const TInt RofsbuildMajorVersion=2;
-static const TInt RofsbuildMinorVersion=16;
-static const TInt RofsbuildPatchVersion=2;
+static const TInt RofsbuildMinorVersion=17;
+static const TInt RofsbuildPatchVersion=1;
 static TBool SizeSummary=EFalse;
 static TPrintType SizeWhere=EAlways;
 
@@ -61,6 +60,7 @@
 TInt gThreadNum = 0;
 TInt gCPUNum = 0;
 TBool gGenSymbols = EFalse;
+TBool gGenBsymbols = EFalse;
 TInt gCodePagingOverride = -1;
 TInt gDataPagingOverride = -1;
 TInt gLogLevel = 0;	// Information is logged based on logging level.
@@ -101,6 +101,7 @@
 	"        -compress   compress executable files where possible\n"
 	"        -j<digit> do the main job with <digit> threads\n"
 	"        -symbols generate symbol file\n"
+	"        -bsymbols generate binary symbol file\n"
 	"        -compressionmethod none|inflate|bytepair to set the compression\n"
 	"              none     uncompress the image.\n"
 	"              inflate  compress the image.\n"
@@ -165,13 +166,16 @@
 					gSmrFileName.assign(&argv[i][5]);
 				}
 				else {
-					Print (EError, "SMR obey file is missing\n");
+					printf ("ERROR: SMR obey file is missing\n");
 				}
 			} else if (stricmp(argv[i], "-K") == 0) {
 				gKeepGoing = ETrue;
 			}else if (stricmp(argv[i], "-SYMBOLS") == 0) {
 				gGenSymbols = ETrue;
 			}
+			else if (stricmp(argv[i], "-BSYMBOLS") == 0 ) {
+				gGenBsymbols = ETrue;
+			}
 			else if (((argv[i][1] | 0x20) == 's') &&  
 				(((argv[i][2]| 0x20) == 'l')||((argv[i][2] | 0x20) == 's'))) {
 					SizeSummary = ETrue;
@@ -241,7 +245,7 @@
 				if((stricmp(&argv[i][13], "UTF8")==0) || (stricmp(&argv[i][13], "UTF-8")==0))
 					gIsOBYUTF8 = ETrue;
 				else
-					Print(EError, "Invalid encoding %s, default system internal encoding will be used.\n", &argv[i][13]);
+					printf("ERROR: Invalid encoding %s, default system internal encoding will be used.\n", &argv[i][13]);
 			}
 			else if (stricmp(argv[i], "-UNCOMPRESS") == 0) {
 				gCompress = ECompressionUncompress;
@@ -249,7 +253,7 @@
 			else if( stricmp(argv[i], "-COMPRESSIONMETHOD") == 0 ) {
 				// next argument should a be method
 				if( (i+1) >= argc || argv[i+1][0] == '-') {
-					Print (EError, "Missing compression method! Set it to default (no compression)!");
+					printf("ERROR: Missing compression method! Set it to default (no compression)!");
 					gCompressionMethod = 0;
 				}
 				else {
@@ -267,7 +271,7 @@
 						gCompressionMethod = KUidCompressionBytePair;	
 					}
 					else {
-						Print (EError, "Unknown compression method! Set it to default (no compression)!");
+						printf("ERROR: Unknown compression method! Set it to default (no compression)!");
 						gCompress = ECompressionUnknown;
 						gCompressionMethod = 0;		
 					}
@@ -279,7 +283,7 @@
 				gUseCoreImage = ETrue;
 				// next argument should be image filename
 				if ((i+1 >= argc) || argv[i+1][0] == '-')
-					Print (EError, "Missing image file name");
+					printf("ERROR: Missing image file name");
 				else {
 					i++;
 					gImageFilename.assign(argv[i]);
@@ -291,7 +295,7 @@
 					gDriveFilename.assign(&argv[i][11]);	
 				}
 				else {
-					Print (EError, "Drive obey file is missing\n"); 
+					printf("ERROR: Drive obey file is missing\n"); 
 				}
 			}
 			else if (argv[i][1] == '?') {
@@ -303,7 +307,7 @@
 			else if( stricmp(argv[i], "-LOGLEVEL") == 0) {
 				// next argument should a be loglevel
 				if( (i+1) >= argc || argv[i+1][0] == '-') {
-					Print (EError, "Missing loglevel!");
+					printf ("ERROR: Missing loglevel!");
 					gLogLevel = DEFAULT_LOG_LEVEL;
 				}
 				else {
@@ -315,7 +319,7 @@
 					else if (strcmp(argv[i], "0") == 0)
 						gLogLevel = DEFAULT_LOG_LEVEL;
 					else
-						Print(EError, "Only loglevel 0, 1 or 2 is allowed!");
+						printf("ERROR: Only loglevel 0, 1 or 2 is allowed!");
 				}
 			}
 			else if( stricmp(argv[i], "-LOGLEVEL2") == 0)
@@ -334,13 +338,13 @@
 			}
 			else {
 #ifdef WIN32
-				Print (EWarning, "Unrecognised option %s\n",argv[i]);
+				printf ("WARNING: Unrecognised option %s\n",argv[i]);
 #else
 				if(0 == access(argv[i],R_OK)){
 					filename.assign(argv[i]);
 				}
 				else {
-					Print (EWarning, "Unrecognised option %s\n",argv[i]);
+					printf("WARNING: Unrecognised option %s\n",argv[i]);
 				}
 #endif				
 
@@ -353,6 +357,11 @@
 
 	if (paramFileFlag)
 		return;
+	if(gGenSymbols && gGenBsymbols)
+	{
+		printf("WARNING: Options symbols and bsymbols cannot be used at the same time, the common symbols file will be created this time!\n");
+		gGenBsymbols = EFalse;
+	}
 
 	if((gDriveImage == EFalse) && (gSmrImage ==  EFalse) && 
 		(filename.empty() || (gUseCoreImage && gImageFilename.length() == 0)) && (loginput.length() == 0)){
@@ -362,7 +371,7 @@
 				Print (EAlways, ReallyHelpText);
 			}
 			else if (filename.empty()){
-				Print(EAlways, "Obey filename is missing\n");
+				printf("WARNING: Obey filename is missing\n");
 			}
 	}	
 }
@@ -496,11 +505,11 @@
 	processCommandLine(argc, argv);
 	if(gThreadNum == 0) {
 		if(gCPUNum > 0) {
-			printf("WARNING: The number of processors (%d) is used as the number of concurrent jobs.\n", gCPUNum);
-			gThreadNum = gCPUNum;
+			printf("The double number of processors (%d) is used as the number of concurrent jobs.\n", gCPUNum * 2);
+			gThreadNum = gCPUNum * 2;
 		}
 		else {
-			printf("WARNING: Can't automatically get the valid number of concurrent jobs and %d is used.\n", DEFAULT_THREADS);
+			printf("Can't automatically get the valid number of concurrent jobs and %d is used.\n", DEFAULT_THREADS);
 			gThreadNum = DEFAULT_THREADS;
 		}
 	}
@@ -508,7 +517,7 @@
 	{
 		try
 		{
-			LogParser::GetInstance()->ParseSymbol(loginput.c_str());
+			LogParser::GetInstance(ERofsImage)->ParseSymbol(loginput.c_str());
 		}
 		catch(LoggingException le)
 		{
--- a/imgtools/romtools/rofsbuild/rofsbuild.mmp	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/romtools/rofsbuild/rofsbuild.mmp	Tue Nov 23 10:47:23 2010 +0800
@@ -23,15 +23,15 @@
 // rofsbuild
 SOURCEPATH	../rofsbuild
 SOURCE			 r_obey.cpp r_build.cpp r_rofs.cpp r_driveimage.cpp r_driveutl.cpp
-SOURCE			 rofsbuild.cpp r_coreimage.cpp r_smrimage.cpp symbolgenerator.cpp
+SOURCE			 rofsbuild.cpp r_coreimage.cpp r_smrimage.cpp
 SOURCE			 fatcluster.cpp fsnode.cpp fatimagegenerator.cpp
-SOURCE			 symbolprocessunit.cpp
+SOURCEPATH	../../imglib/symbolutil
+SOURCE			 symbolprocessunit.cpp bsymutil.cpp loggingexception.cpp logparser.cpp
+SOURCE                   symbolgenerator.cpp
 SOURCEPATH	../../imglib/host
 SOURCE			h_utl.cpp h_file.cpp h_mem.cpp utf16string.cpp
 SOURCEPATH ../rofsbuild/src/cache
 SOURCE cachemanager.cpp cacheexception.cpp cache.cpp cacheablelist.cpp cachevalidator.cpp cachegenerator.cpp cacheentry.cpp
-SOURCEPATH ../rofsbuild/src/logging
-SOURCE loggingexception.cpp logparser.cpp
 
 // executable compression
 SOURCEPATH	../../imglib/e32uid
@@ -46,7 +46,7 @@
 
 OS_LAYER_SYSTEMINCLUDE_SYMBIAN
 
-USERINCLUDE   ../../imglib/inc ../../imglib/compress
+USERINCLUDE   ../../imglib/inc ../../imglib/compress ../../imglib/symbolutil
 USERINCLUDE   ../../imglib/patchdataprocessor/include ../../imglib/parameterfileprocessor/include
 USERINCLUDE	  ../../imglib/memmap/include
 USERINCLUDE   ../../imglib/uniconv/include
--- a/imgtools/romtools/rofsbuild/src/logging/loggingexception.cpp	Fri Nov 12 14:49:36 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
-* Copyright (c) 1995-2009 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 "logging/loggingexception.hpp"
-
-
-int LoggingException::RESOURCE_ALLOCATION_FAILURE = 1;
-int LoggingException::INVALID_LOG_FILENAME        = 2;
-
-
-LoggingException::LoggingException(int ErrorCode)
-{
-	this->errcode = ErrorCode;
-
-	return;
-}
-
-
-int LoggingException::GetErrorCode(void)
-{
-	return this->errcode;
-}
-
-
-const char* LoggingException::GetErrorMessage(void)
-{
-	if(this->errcode == LoggingException::RESOURCE_ALLOCATION_FAILURE)
-		return "Not enough system resources to initialize logging module.";
-	else if(this->errcode == LoggingException::INVALID_LOG_FILENAME)
-		return "Invalid log filename as input.";
-//	else if(this->errcode == CacheException::CACHE_INVALID)
-//		return "Cache is invalid.";
-//	else if(this->errcode == CacheException::CACHE_IS_EMPTY)
-//		return "Cache is empty.";
-//	else if(this->errcode == CacheException::HARDDRIVE_FAILURE)
-//		return "A hard drive failure occurred in Cache operations.";
-
-	return "Undefined error type.";
-}
-
-
-LoggingException::~LoggingException(void)
-{
-	return;
-}
--- a/imgtools/romtools/rofsbuild/src/logging/logparser.cpp	Fri Nov 12 14:49:36 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-/*
-* Copyright (c) 1995-2009 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 <new>
-#include <iostream>
-#include <fstream>
-#include <string>
-using namespace std;
-
-#include "logging/loggingexception.hpp"
-#include "logging/logparser.hpp"
-#include "symbolgenerator.h"
-
-
-LogParser* LogParser::Only = (LogParser*)0;
-
-
-LogParser* LogParser::GetInstance(void) throw (LoggingException)
-{
-	if(! LogParser::Only)
-	{
-		LogParser::Only = new (std::nothrow) LogParser();
-		if(! LogParser::Only)
-			throw LoggingException(LoggingException::RESOURCE_ALLOCATION_FAILURE);
-	}
-
-	return LogParser::Only;
-}
-
-
-void LogParser::ParseSymbol(const char* LogFilename) throw (LoggingException)
-{
-	string linebuf;
-	SymbolGenerator* symgen = SymbolGenerator::GetInstance();
-	symgen->SetSymbolFileName(string(LogFilename));
-
-	ifstream logfd(LogFilename);
-	if(logfd.is_open())
-	{
-		while(! logfd.eof())
-		{
-			getline(logfd, linebuf);
-			if(linebuf.compare(0,4,"File") == 0)
-			{
-				if(linebuf.find("size:", 4) != 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), false);
-					}
-				}
-			}
-			else if(linebuf.compare(0,26,"Compressed 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);
-					}
-				}
-			}
-		}
-		symgen->SetFinished();
-		symgen->Release();
-	}
-	else
-	{
-		throw LoggingException(LoggingException::INVALID_LOG_FILENAME);
-	}
-
-	return;
-}
-
-
-void LogParser::Cleanup(void)
-{
-	return;
-}
-
-
-LogParser::LogParser(void)
-{
-	return;
-}
--- a/imgtools/romtools/rofsbuild/symbolgenerator.cpp	Fri Nov 12 14:49:36 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
-/*
-* 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 <vector>
-#include <boost/regex.hpp>
-#define MAX_LINE 65535
-#include "symbolgenerator.h"
-#include "e32image.h"
-
-#if defined(__LINUX__)
-#define PATH_SEPARATOR '/'
-#else
-#define PATH_SEPARATOR '\\'
-#endif
-extern TInt gThreadNum;
-
-boost::mutex SymbolGenerator::iMutexSingleton;
-SymbolGenerator* SymbolGenerator::iInst = NULL;
-SymbolGenerator* SymbolGenerator::GetInstance(){
-    iMutexSingleton.lock();
-    if(iInst == NULL) {
-        iInst = new SymbolGenerator();
-    }
-    iMutexSingleton.unlock();
-    return iInst;
-}
-void SymbolGenerator::Release() {
-    if(iInst != NULL) {
-        iInst->join();
-    }
-    iMutexSingleton.lock();
-    if(iInst != NULL) {
-        delete iInst;
-        iInst = NULL;
-    }
-    iMutexSingleton.unlock();
-}
-void SymbolGenerator::SetSymbolFileName( const string& fileName ){
-    if(iSymFile.is_open())
-        iSymFile.close();
-    string s = fileName.substr(0,fileName.rfind('.'))+".symbol";
-    printf("* Writing %s - ROFS symbol file\n", s.c_str());
-    iSymFile.open(s.c_str());
-}
-void SymbolGenerator::AddFile( const string& fileName, bool isExecutable ){
-    iMutex.lock();
-    iQueueFiles.push(TPlacedEntry(fileName,isExecutable));
-    iMutex.unlock();
-    iCond.notify_all();
-}
-void SymbolGenerator::SetFinished() 
-{ 
-
-	iFinished = true; 
-	iCond.notify_all();
-    }
-TPlacedEntry SymbolGenerator::GetNextPlacedEntry()
-{
-	TPlacedEntry pe("", false);
-	if(1)
-	{
-		boost::mutex::scoped_lock lock(iMutex);
-		while(!iFinished && iQueueFiles.empty())
-			iCond.wait(lock);
-		if(!iQueueFiles.empty())
-		{
-			pe = iQueueFiles.front();
-			iQueueFiles.pop();
-        }
-    }
-	return pe;
-}
-void SymbolGenerator::thrd_func(){
-    	boost::thread_group threads;
-	SymbolWorker worker;
-    	for(int i=0; i < gThreadNum; i++)
-    	{
-    		threads.create_thread(worker);
-    }
-    	threads.join_all();
-        }
-SymbolGenerator::SymbolGenerator() : boost::thread(thrd_func),iFinished(false) {
-    }
-SymbolGenerator::~SymbolGenerator(){
-    if(joinable())
-        join();
-    iSymFile.flush();
-    iSymFile.close();
-            }
-SymbolWorker::SymbolWorker()
-{
-        // end of regex_search
-    }
-SymbolWorker::~SymbolWorker()
-{
-    }
-void SymbolWorker::operator()()
-{
-	SymbolProcessUnit* aSymbolProcessUnit = new CommenSymbolProcessUnit();
-	SymbolGenerator* symbolgenerator = SymbolGenerator::GetInstance();
-
-	while(1)
-	{
-		if(symbolgenerator->HasFinished() && symbolgenerator->IsEmpty())
-		{
-
-                break;
-                    }
-
-
-
-
-		TPlacedEntry pe = symbolgenerator->GetNextPlacedEntry();
-
-            //scope the code block with if(1) for lock
-            /*
-            if(me->iQueueFiles.empty()) {
-                boost::this_thread::sleep(boost::posix_time::milliseconds(10));
-                continue;
-            }
-            */
-
-
-        if(pe.iFileName == "")
-			continue;
-        else if(pe.iExecutable) 
-			aSymbolProcessUnit->ProcessExecutableFile(pe.iFileName);
-        else
-			aSymbolProcessUnit->ProcessDataFile(pe.iFileName);
-		symbolgenerator->LockOutput();
-		aSymbolProcessUnit->FlushStdOut(cout);
-		aSymbolProcessUnit->FlushSymbolContent(symbolgenerator->GetOutputFileStream());
-		symbolgenerator->UnlockOutput();
-}
-	delete aSymbolProcessUnit;
-}
--- a/imgtools/romtools/rofsbuild/symbolgenerator.h	Fri Nov 12 14:49:36 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/*
-* 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: 
-*
-*/
-
-#ifndef __SYMBOLGENERATOR_H__
-#define __SYMBOLGENERATOR_H__
-#include <queue>
-#include <string>
-#include <fstream>
-using namespace std;
-#include <boost/thread/thread.hpp>
-#include <boost/thread/condition.hpp>
-#include "symbolprocessunit.h"
-
-
-struct TPlacedEntry{
-    string iFileName;
-    bool iExecutable;
-    TPlacedEntry(const string& aName, bool aExecutable) {
-        iFileName = aName;
-        iExecutable = aExecutable;
-    }
-};
-class SymbolGenerator : public boost::thread {
-    public:
-        static SymbolGenerator* GetInstance();
-        static void Release();
-        void SetSymbolFileName( const string& fileName );
-        void AddFile( const string& fileName, bool isExecutable );
-        bool HasFinished()	{ return iFinished; }
-        void SetFinished();
-        bool IsEmpty() { return iQueueFiles.empty(); }
-        void LockOutput() { iOutputMutex.lock(); }
-        void UnlockOutput() { iOutputMutex.unlock(); }
-        TPlacedEntry GetNextPlacedEntry();
-        ofstream& GetOutputFileStream() { return iSymFile; };
-    private:
-        SymbolGenerator();
-        ~SymbolGenerator();
-        static void thrd_func();
-
-        queue<TPlacedEntry> iQueueFiles;
-        boost::mutex iMutex;
-        boost::mutex iOutputMutex;
-        static boost::mutex iMutexSingleton;
-        static SymbolGenerator* iInst;
-        boost::condition_variable iCond;
-        bool iFinished;
-
-        ofstream iSymFile;
-};
-class SymbolWorker{
-public:
-	SymbolWorker();
-	~SymbolWorker();
-	void operator()();
-private:
-};
-#endif
--- a/imgtools/romtools/rofsbuild/symbolprocessunit.cpp	Fri Nov 12 14:49:36 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,258 +0,0 @@
-/*
-* 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"
-#define MAX_LINE 65535
-
-#if defined(__LINUX__)
-#define PATH_SEPARATOR '/'
-#else
-#define PATH_SEPARATOR '\\'
-#endif
-
-void CommenSymbolProcessUnit::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 CommenSymbolProcessUnit::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 CommenSymbolProcessUnit::FlushStdOut(ostream& aOut)
-{
-	for(int i = 0; i < (int) iStdoutLog.size(); i++)
-	{
-		aOut << iStdoutLog[i];
-	}
-}
-void CommenSymbolProcessUnit::FlushSymbolContent(ostream &aOut)
-{
-	for(int i = 0; i < (int) iSymbolContentLog.size(); i++)
-	{
-		aOut << iSymbolContentLog[i];
-	}
-}
-void CommenSymbolProcessUnit::ResetContentLog()
-{
-	iStdoutLog.clear();
-	iSymbolContentLog.clear();
-}
-void CommenSymbolProcessUnit::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 CommenSymbolProcessUnit::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);
-            }
-        }
-    }
-}
-int CommenSymbolProcessUnit::GetSizeFromBinFile( const string& fileName ){
-    TInt ret = 0;
-    char outbuffer[MAX_LINE];
-    ifstream aIf(fileName.c_str(), ios_base::binary);
-    if( !aIf.is_open() ) {
-        printf(outbuffer, "Warning: Cannot open file \n");
-        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;
-}
--- a/imgtools/romtools/rofsbuild/symbolprocessunit.h	Fri Nov 12 14:49:36 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
-* 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: 
-*
-*/
-#ifndef __SYMBOLPROCESSUNIT_H__
-#define __SYMBOLPROCESSUNIT_H__
-#include <vector>
-#include <string>
-#include <iostream>
-#include <fstream>
-using namespace std;
-
-
-typedef vector<string> stringlist;
-
-class SymbolProcessUnit
-{
-public:
-	virtual void ProcessExecutableFile(const string& aFile) = 0;
-	virtual void ProcessDataFile(const string& afile) = 0;
-	virtual void FlushStdOut(ostream& aOut) = 0;
-	virtual void FlushSymbolContent(ostream &aOut) = 0;
-	virtual void ResetContentLog() = 0;
-	virtual ~SymbolProcessUnit() {}
-};
-
-class CommenSymbolProcessUnit : public SymbolProcessUnit
-{
-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 );
-	int GetSizeFromBinFile( const string& fileName );
-private:
-	stringlist iStdoutLog;
-	stringlist iSymbolContentLog;
-};
-#endif
--- a/imgtools/romtools/rombuild/r_build.cpp	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/romtools/rombuild/r_build.cpp	Tue Nov 23 10:47:23 2010 +0800
@@ -1509,7 +1509,7 @@
 		}
 		// prevent the situiation which importer is primary, variant or extension, exporter is device
 		if (is_kernel && !Device() && romnode->iRomFile->iRbEntry->Device())	 {
-			Print(EWarning, "Kernel/variant/extension\n\t%s\nlinks to non-extension LDD/PDD\n\t%s\n",
+			Print(EWarning, "Kernel/variant/extension \"%s\"  links to non-extension LDD/PDD  \"%s\"\n",
 				(const char*)TModuleName(this), (const char*)TModuleName(find_info));
 		}
 		if (romnode->ABI() != my_abi) {
--- a/imgtools/romtools/rombuild/r_global.cpp	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/romtools/rombuild/r_global.cpp	Tue Nov 23 10:47:23 2010 +0800
@@ -44,7 +44,7 @@
 SCapabilitySet gPlatSecDisabledCaps={{0}}; 
 SCapabilitySet gPlatSecAllCaps={{0}};
 SDemandPagingConfig gDemandPagingConfig={0,0,0,{0}}; 
-TBool gGenInc=EFalse;	// Default to no generate INC file.  DEF095619
+TBool gGenInc=EFalse;	// Default to no generate INC file.  
 TInt gLogLevel=0;  // Information is logged based on logging level.
 					// The default is 0. So all the existing logs are generated as if gLogLevel == 0.
 					// If any extra information is required, the log level must be appropriately supplied.
--- a/imgtools/romtools/rombuild/r_global.h	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/romtools/rombuild/r_global.h	Tue Nov 23 10:47:23 2010 +0800
@@ -80,7 +80,7 @@
 extern SCapabilitySet gPlatSecDisabledCaps;
 extern SCapabilitySet gPlatSecAllCaps;
 extern SDemandPagingConfig gDemandPagingConfig;
-extern TBool gGenInc;						// DEF095619
+extern TBool gGenInc;						
 extern TBool gEnableStdPathWarning;
 extern TInt gLogLevel;
 extern TBool gLowMem;
--- a/imgtools/romtools/rombuild/r_mromimage.h	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/romtools/rombuild/r_mromimage.h	Tue Nov 23 10:47:23 2010 +0800
@@ -44,9 +44,7 @@
 	virtual TUint32 DataRunAddress() const = 0 ;
 	virtual TUint32 RomAlign() const = 0 ;
  
-#ifdef __LINUX__
 	virtual ~MRomImage() { };
-#endif
 };
 
 #endif //__R_MROMIMAGE_H__
--- a/imgtools/romtools/rombuild/r_rom.cpp	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/romtools/rombuild/r_rom.cpp	Tue Nov 23 10:47:23 2010 +0800
@@ -399,7 +399,7 @@
 
 E32Rom::~E32Rom() {
 	if(iSymGen){		
-		delete iSymGen;
+		SymbolGenerator::Release();
 		iSymGen = NULL ;
 	}
 	if(gLowMem)
@@ -699,8 +699,6 @@
 	if (r!=KErrNone)
 		{
 		Print(EError, "LoadContents failed - return code %d\n", r);
-		if(iSymGen)
-			iSymGen->WaitThreads();
 		return r;
 		}
 	iExtensionRomHeader->iRomRootDirectoryList = dummy.iRomRootDirectoryList;
@@ -708,8 +706,6 @@
 	iLoaderHeader->SetUp(iObey);
 	FinaliseExtensionHeader(aKernelRom);
 	DisplayExtensionHeader();
-	if(iSymGen)
-		iSymGen->WaitThreads();
 	return KErrNone;
 	}
 	
@@ -740,8 +736,6 @@
 	if (r!=KErrNone)
 		{
 		Print(EError, "LoadContents failed - return code %d\n", r);
-		if(iSymGen)
-			iSymGen->WaitThreads();
 		return r;
 		}
 
@@ -749,16 +743,12 @@
 	if(r!=KErrNone)
 		{
 		Print(EError, "Setup pages information failed - return code %d\n", r);
-		if(iSymGen)
-			iSymGen->WaitThreads();
 		return r;
 		}
 	
 	r = CheckUnpagedMemSize(); // check for unpaged memory overflow
 	if(r!=KErrNone)
 	{
-		if(iSymGen)
-			iSymGen->WaitThreads();
 		return r;
 	}
 	
@@ -766,8 +756,6 @@
 	if(r!=KErrNone)
 		{
 		Print(EError, "CompressPages failed - return code %d\n", r);
-		if(iSymGen)
-			iSymGen->WaitThreads();
 		return r;
 		}
 
@@ -795,8 +783,6 @@
 	TUint testCheckSum = HMem::CheckSum((TUint *)iHeader, iHeader->iRomSize);
 	Print(ELog, "Rom 32bit words sum to   %08x\n", testCheckSum);
 	if (testCheckSum != iObey->iCheckSum){
-		if(iSymGen)
-			iSymGen->WaitThreads();
 		return Print(EError, "Rom checksum is incorrect: %08x should be %08x\n",
 					testCheckSum, iObey->iCheckSum);
 	}
@@ -836,8 +822,6 @@
 					}
 			}
 		}
-	if(iSymGen)
-			iSymGen->WaitThreads();
 	return KErrNone;
 	}
 
@@ -1325,9 +1309,9 @@
 	TInt fileCount=0;
 	if(gGenSymbols && !iSymGen) {
 		string filename(iObey->GetFileName());
-		filename.erase(filename.length() - 3,3);
-		filename.append("symbol");
-		iSymGen = new SymbolGenerator(filename.c_str(),gThreadNum - 1);		
+		iSymGen = SymbolGenerator::GetInstance();
+		iSymGen ->SetImageType(ERomImage);
+		iSymGen ->SetSymbolFileName(filename);		
 	}
 		
 	//
@@ -1399,9 +1383,7 @@
 	mainptr->Extend(offset);
 	iOverhead +=offset;
 	if(iSymGen){
-		SymGenContext context ;
-		memset(&context,0,sizeof(SymGenContext));
-		iSymGen->AddEntry(context);
+		iSymGen->SetFinished();
 	}
 	return (char*)mainptr->iImagePtr;
  	}
@@ -1454,8 +1436,7 @@
 			return;		// first section has overflowed
 		current->FixupRomEntries(size);
 		if(iSymGen) {
-			SymGenContext context ;
-			memset(&context,0,sizeof(SymGenContext));
+			TPlacedEntry context ;
 			context.iFileName = current->iFileName ;
 			context.iDataAddress = savedAddr ;
 			iSymGen->AddEntry(context); 
@@ -1470,8 +1451,7 @@
 		iHeader->iHcrFileAddress =  current->iHeaderRange.iImageAddr ;
 		TRACE(TAREA, Print(ELog, "iHeader->iHcrFileAddress = %08x\n", iHeader->iHcrFileAddress));	
 		if(iSymGen) {
-			SymGenContext context ;
-			memset(&context,0,sizeof(SymGenContext));
+			TPlacedEntry context ;
 			context.iFileName = current->iFileName ;
 			context.iDataAddress = savedAddr ;
 			iSymGen->AddEntry(context); 
@@ -1535,7 +1515,7 @@
 	LoadFileToRom(current);
 	TRomImageHeader *header = current->iRomImageHeader;
 	if(iSymGen){
-		SymGenContext context  ;
+		TPlacedEntry context  ;
 		context.iFileName = current->iFileName ;		
 		context.iTotalSize = section1size;
 		context.iCodeAddress = header->iCodeAddress; 
--- a/imgtools/romtools/rombuild/rombuild.cpp	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/romtools/rombuild/rombuild.cpp	Tue Nov 23 10:47:23 2010 +0800
@@ -26,14 +26,15 @@
 
 #include "r_dir.h"
 #include "r_coreimage.h"
+#include "logparser.h"
 
 const TInt KRomLoaderHeaderNone=0;
 const TInt KRomLoaderHeaderEPOC=1;
 const TInt KRomLoaderHeaderCOFF=2;
 
 static const TInt RombuildMajorVersion=2;
-static const TInt RombuildMinorVersion=18;
-static const TInt RombuildPatchVersion=4;
+static const TInt RombuildMinorVersion=19;
+static const TInt RombuildPatchVersion=1;
 static TBool SizeSummary=EFalse;
 static TPrintType SizeWhere=EAlways;
 static string compareROMName = "";
@@ -49,11 +50,13 @@
 TBool gGenDepGraph = EFalse;
 string gDepInfoFile = "";
 TBool gGenSymbols = EFalse ;
+TBool gGenBsymbols = EFalse ;
 TBool gIsOBYUTF8 = EFalse;
+static string loginput = "";
 void PrintVersion() {
- 	Print(EAlways,"\nROMBUILD - Rom builder");
-  	Print(EAlways, " V%d.%d.%d\n", RombuildMajorVersion, RombuildMinorVersion, RombuildPatchVersion);
-  	Print(EAlways,Copyright);
+ 	printf("\nROMBUILD - Rom builder");
+  	printf(" V%d.%d.%d\n", RombuildMajorVersion, RombuildMinorVersion, RombuildPatchVersion);
+  	printf(Copyright);
 	}
 
 char HelpText[] = 
@@ -75,14 +78,15 @@
 	"        -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"
-	"        -geninc                       to generate include file for licensee tools to use\n"			// DEF095619
+	"        -geninc                       to generate include file for licensee tools to use\n"			
 	"        -loglevel<level>              level of information to log (valid levels are 0,1,2,3,4).\n" //Tools like Visual ROM builder need the host/ROM filenames, size & if the file is hidden.
 	"        -wstdpath                     warn if destination path provided for a file is not a standard path\n"
 	"        -argfile=<fileName>           specify argument-file name containing list of command-line arguments to rombuild\n"
 	"        -lowmem                       use memory-mapped file for image build to reduce physical memory consumption\n"
 	"        -coreimage=<core image file>  to pass the core image as input for extension ROM image generation\n"
 	"        -k                            to enable keepgoing when duplicate files exist in oby\n"
-	"        -logfile=<fileName>           specify log file\n";
+	"        -logfile=<fileName>           specify log file\n"
+    "        -loginput=<log filename>      specify as input a log file and produce as output symbol file.\n";
 
 
 char ReallyHelpText[] =
@@ -296,7 +300,7 @@
 				}
 			else if (stricmp(arg, "no-sorted-romfs")==0)
 				gSortedRomFs=EFalse;
-			else if (stricmp(arg, "geninc")==0)				// DEF095619
+			else if (stricmp(arg, "geninc")==0)				
 				gGenInc=ETrue;
  			else if (stricmp(arg, "wstdpath")==0)			// Warn if destination path provided for a file		
  				gEnableStdPathWarning=ETrue;					// is not a standard path as per platsec
@@ -349,6 +353,9 @@
 			else if (strnicmp(arg, "logfile=",8) ==0) {
 				romlogfile = arg + 8;
 			}
+			else if (strnicmp(arg, "loginput=",9) ==0) {
+				loginput = arg + 9;
+			}
 			else 
 #ifdef WIN32
 				cout << "Unrecognised option " << argv[i] << "\n";
@@ -366,7 +373,7 @@
 		}
 	if (paramFileFlag)
 		return;
-	if (filename.empty()) {
+	if (filename.empty() && loginput.empty()) {
  		PrintVersion();
 		cout << HelpText;
 		if (reallyHelp) {
@@ -450,29 +457,42 @@
 	ParseCapabilitiesArg(gPlatSecAllCaps, "all");
 
  	processCommandLine(argc, argv);
- 	if(filename.empty())
+ 	if(filename.empty() && loginput.empty())
    		return KErrGeneral;
 		
-	if (romlogfile[romlogfile.size()-1] == '\\' || romlogfile[romlogfile.size()-1] == '/')
-		romlogfile += "ROMBUILD.LOG";
- 	H.SetLogFile(romlogfile.c_str());
 
     if(gThreadNum == 0) {
  		if(gCPUNum > 0 && gCPUNum <= MAXIMUM_THREADS) {
- 			Print(EAlways, "The number of processors (%d) is used as the number of concurrent jobs.\n", gCPUNum);
-			gThreadNum = gCPUNum;
+ 			printf("The double number of processors (%d) is used as the number of concurrent jobs.\n", gCPUNum * 2);
+			gThreadNum = gCPUNum * 2;
 		}
 		else if(g_pCharCPUNum) {
- 			Print(EWarning, "The NUMBER_OF_PROCESSORS is invalid, and the default value %d will be used.\n", DEFAULT_THREADS);
+ 			printf("The NUMBER_OF_PROCESSORS is invalid, and the default value %d will be used.\n", DEFAULT_THREADS);
 			gThreadNum = DEFAULT_THREADS;
 		}
 		else {
- 			Print(EWarning, "The NUMBER_OF_PROCESSORS is not available, and the default value %d will be used.\n", DEFAULT_THREADS);
+ 			printf("The NUMBER_OF_PROCESSORS is not available, and the default value %d will be used.\n", DEFAULT_THREADS);
 			gThreadNum = DEFAULT_THREADS;
 		}
 	} 
 	PrintVersion();
 	
+	if(loginput.length() >= 1)
+	{
+		try
+		{
+			LogParser::GetInstance(ERomImage)->ParseSymbol(loginput.c_str());
+		}
+		catch(LoggingException le)
+		{
+			printf("ERROR: %s\r\n", le.GetErrorMessage());
+			return 1;
+		}
+		return 0;
+	}
+	if (romlogfile.empty() || romlogfile[romlogfile.size()-1] == '\\' || romlogfile[romlogfile.size()-1] == '/')
+		romlogfile += "ROMBUILD.LOG";
+ 	H.SetLogFile(romlogfile.c_str());
 	ObeyFileReader *reader=new ObeyFileReader(filename.c_str());
 	if (!reader->Open()) {
  		delete reader;
--- a/imgtools/romtools/rombuild/rombuild.mmp	Fri Nov 12 14:49:36 2010 +0000
+++ b/imgtools/romtools/rombuild/rombuild.mmp	Tue Nov 23 10:47:23 2010 +0800
@@ -24,7 +24,10 @@
 source			 r_dir.cpp r_header.cpp r_obey.cpp r_srec.cpp
 source			 r_rom.cpp rombuild.cpp r_build.cpp r_collapse.cpp
 source			 r_global.cpp r_areaset.cpp
-source			 r_coreimage.cpp r_coreimagereader.cpp symbolgenerator.cpp
+source			 r_coreimage.cpp r_coreimagereader.cpp
+sourcepath	../../imglib/symbolutil
+source		symbolgenerator.cpp symbolprocessunit.cpp bsymutil.cpp
+source 		loggingexception.cpp logparser.cpp
 sourcepath	../../imglib/e32uid
 source			e32uid.cpp
 sourcepath	../../imglib/host
@@ -38,7 +41,7 @@
 source			byte_pair.cpp
 source			pagedcompress.cpp
 
-userinclude	../../imglib/compress 	../../imglib/inc 
+userinclude	../../imglib/compress 	../../imglib/inc ../../imglib/symbolutil
 userinclude	../../imglib/patchdataprocessor/include ../../imglib/parameterfileprocessor/include
 userinclude     ../../imglib/uniconv/include
 userinclude ../../imglib/memmap/include
@@ -46,7 +49,7 @@
 
 OS_LAYER_SYSTEMINCLUDE_SYMBIAN
 
-staticlibrary	patchdataprocessor parameterfileprocessor memmap boost_thread-1.39 uniconv
+staticlibrary	patchdataprocessor parameterfileprocessor memmap boost_thread-1.39 boost_regex-1.39 uniconv
 
 #ifdef TOOLS2_LINUX
 OPTION    GCC -O2 -Wno-uninitialized -pthread
--- a/imgtools/romtools/rombuild/symbolgenerator.cpp	Fri Nov 12 14:49:36 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,553 +0,0 @@
-/*
-* 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 <e32rom.h>
-#include <algorithm>
-#include "symbolgenerator.h"
-#include "r_rom.h"
-#include <string.h>
-#include "h_utl.h"
-typedef boost::unique_lock<boost::mutex>  scoped_lock ;
-typedef boost::lock_guard<boost::mutex> guarded_lock ;
-
-SymbolGenerator::SymbolGenerator(const char* aSymbolFileName, int aMultiThreadsCount/* = 1*/) :
-iOutput(aSymbolFileName,ios_base::out |ios_base::binary |  ios_base::trunc) {
-	if(iOutput.is_open()){
-		if(aMultiThreadsCount < 1)
-			aMultiThreadsCount = 1;
-		 
-		for(int i = 0 ; i < aMultiThreadsCount ; i++){		
-			iThreads.add_thread(new boost::thread(ThreadFunc,this));
-		}
-	}
-	else {
-		cerr << "\nWarning: Can't write data to \""<<aSymbolFileName << "\" ! \nPlease make sure this file is not locked by other application or you have write permission!"<<endl;
-	} 
-}
-void SymbolGenerator::WaitThreads() {
-	iThreads.join_all(); 
-}
-SymbolGenerator::~SymbolGenerator() {
-	if(iOutput.is_open()){		
-		iOutput.flush();
-		iOutput.close();
-	}
-	for(vector<char*>::iterator i = iErrMsgs.begin() ; i != iErrMsgs.end() ; i++){
-		char* msg = *i ;
-		cerr << msg ;
-		delete []msg ;
-	}
-	iErrMsgs.clear(); 
-}
-
-void SymbolGenerator::AddEntry(const SymGenContext& aEntry){
-	if(iOutput.is_open()){
-		guarded_lock lock(iQueueMutex); 		 
-		iEntries.push(aEntry);		
-		iCond.notify_all();
-	}
-}
-void SymbolGenerator::ThreadFunc(SymbolGenerator* aInst) {		
-		SymGenContext entry ;
-		while(1){ 
-			entry.iFileName = 0;
-			if(1) {
-				scoped_lock lock(aInst->iQueueMutex);
-				while(aInst->iEntries.empty()){
-						aInst->iCond.wait(lock);
-				}
-				entry = aInst->iEntries.front();
-				if(0 == entry.iFileName)  // end , exit
-					return ;
-					
-				aInst->iEntries.pop();
-			}
-			aInst->ProcessEntry(entry);
-		}
-		
-}
-#define MAX_LINE_LENGTH 65535 
-#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++;
-	}
-}
-bool SymbolGenerator::ProcessEntry(const SymGenContext& aContext) {	
-	size_t allocBytes ;
-	if(aContext.iExecutable ) {
-		string mapFileName(aContext.iFileName);	
-		mapFileName += ".map";
-		ifstream ifs(mapFileName.c_str());
-		if(!ifs.is_open()){
-			int index = mapFileName.length() - 5 ;
-			int count = 1 ;
-			while(index > 0 && mapFileName.at(index) != '.'){
-				index -- ;
-				count ++ ;
-			}
-			mapFileName.erase(index,count);
-			ifs.open(mapFileName.c_str());
-		}
-		if(!ifs.is_open()){		
-			guarded_lock lock(iFileMutex);
-			allocBytes = mapFileName.length() + 60 ;
-			char* msg = new char[ allocBytes] ;
-			snprintf(msg,allocBytes,"\nWarning: Can't open \"%s.map\"\n",aContext.iFileName );
-			iErrMsgs.push_back(msg);
-			msg = new char[allocBytes] ;
-			int n = snprintf(msg,allocBytes,"%08x    %04x    %s\r\n",(unsigned int)aContext.iCodeAddress,(unsigned int)aContext.iTotalSize,aContext.iFileName);			
-			iOutput.write(msg,n);
-			iOutput.flush();
-			return false ;
-		} 
-		if(!ifs.good()) ifs.clear();
-		char buffer[100]; 
-		*buffer = 0;
-		//See if we're dealing with the RVCT output
-		ifs.getline(buffer,100);
-		if(!ifs.good()) { 
-			ifs.close();
-			guarded_lock lock(iFileMutex);
-			allocBytes = mapFileName.length() + 60;
-			char* msg = new char[allocBytes] ; 
-			snprintf(msg,allocBytes,"\nWarning: File \"%s\" is opened yet can not be read!",mapFileName.c_str());
-			iErrMsgs.push_back(msg);  
-			return false ;			 
-		}
-		if(strncmp(buffer,"ARM Linker",10) == 0){  			
-			return ProcessARMV5Map(ifs,aContext);
-		}
-		// See if we're dealing with the GCC output
-		else if ( 0 == strncmp(buffer,"Archive member included",23)){ 
-			return ProcessGCCMap(ifs,aContext);
-		}
-		else { // Must be x86 output
-			ifs.seekg(0,ios_base::beg);
-			return ProcessX86Map(ifs,aContext);		
-		}
-	}
-	else {
-		const char* fileName = aContext.iFileName;	  
-		size_t len = strlen(fileName);
-		size_t index = len - 1;
-		while(index > 0 && (fileName[index] != '\\' && fileName[index] != '/'))
-			index -- ;
-		const char* basename = fileName + index + 1  ;		
-		allocBytes = (len << 1) + 40 ;
-		char* msg = new char[allocBytes] ;
-		int n = snprintf(msg,allocBytes,"\r\nFrom    %s\r\n\r\n%08x    0000    %s\r\n", fileName ,(unsigned int)aContext.iDataAddress,basename);	
-		guarded_lock lock(iFileMutex);
-		iOutput.write(msg,n);
-		iOutput.flush();
-		delete []msg ;
-		return true ;
-	}
-	return true ;
-}
-struct ArmSymbolInfo {
-	string name ;
-	TUint size ;
-	string section ;
-};
-typedef multimap<TUint32,ArmSymbolInfo> ArmSymMap ;
- 
-bool SymbolGenerator::ProcessARMV5Map(ifstream& aStream, const SymGenContext& aContext) {	
-	string symName ; 
-	ArmSymMap symbols ; 
-	vector<char*> words ;
-	ArmSymbolInfo info;
-	char* lineStart ;
-	char buffer[MAX_LINE_LENGTH];  
-	while(aStream.good() && (!aStream.eof())){
-		*buffer = 0;
-		aStream.getline(buffer,MAX_LINE_LENGTH);
-		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 = strlen(aContext.iFileName);
-	while(aStream.good() && (!aStream.eof())){
-		*buffer = 0;
-		aStream.getline(buffer,MAX_LINE_LENGTH);
-		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 + aContext.iTextSize)) {
-				romAddr = thisAddr - textSectAddr + aContext.iCodeAddress ;
-		} 
-		else if ( aContext.iDataAddress && 
-			( thisAddr >= dataSectAddr && thisAddr <= (dataSectAddr + aContext.iTextSize))) {
-			romAddr = thisAddr-dataSectAddr + aContext.iDataBssLinearBase;
-		} 
-		else if ( aContext.iDataBssLinearBase && 
-			( thisAddr >= dataSectAddr && thisAddr <= (dataSectAddr+ aContext.iTotalDataSize))) {
-			romAddr = thisAddr - dataSectAddr + aContext.iDataBssLinearBase;
-		} 
-		else { 
-			guarded_lock  lock(iFileMutex);
-			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) ; 
-			iErrMsgs.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",aContext.iFileName);
-			iErrMsgs.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));
-	 
-	}  
-	guarded_lock lock(iFileMutex);	
-	allocBytes = lenOfFileName + 40;
-	char* outputLine = new char[allocBytes];
-	int n = snprintf(outputLine,allocBytes,"\r\nFrom    %s\r\n\r\n",aContext.iFileName); 
-	iOutput.write(outputLine,n);
-	delete []outputLine ;
-	for (vector<pair<int,char*> >::iterator i = lines.begin() ; i < lines.end(); i ++ ) {
-		int len = i->first ;
-		char* line = i->second; 
-		iOutput.write(line,len);
-		delete []line ;
-	}	
-	iOutput.flush();
-	return true ;
-		
-}
-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 ;
-	}	
-}
-bool  SymbolGenerator::ProcessGCCMap(ifstream& aStream, const SymGenContext& aContext){
- 	char* lineStart; 
-	vector<char*> words ;
-	char buffer[MAX_LINE_LENGTH];
-	while(aStream.good() && (!aStream.eof())){
-		aStream.getline(buffer,MAX_LINE_LENGTH);
-		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 = strlen(aContext.iFileName) + 60;
-		char* msg = new char[allocBytes];
-		snprintf(msg,allocBytes,"\nError: Can't get .text section info for \"%s\"\r\n",aContext.iFileName);
-		guarded_lock lock(iFileMutex);
-		iErrMsgs.push_back(msg);
-		return false ;
-	}
-	map<TUint32,string> symbols ;
-	TUint32 stubHex = 0;
-	//Slurp symbols 'til the end of the text section
-	while(aStream.good() && (!aStream.eof())){
-		aStream.getline(buffer,MAX_LINE_LENGTH);
-		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 + aContext.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 ++ ;
-	}
-	
-	guarded_lock lock(iFileMutex);
-	allocBytes = strlen(aContext.iFileName) + 40;
-	char* outputLine = new char[allocBytes];
-	int n = snprintf(outputLine,allocBytes,"\r\nFrom    %s\r\n\r\n",aContext.iFileName); 
-	iOutput.write(outputLine,n);
-	delete []outputLine ;
-	vector<pair<int,char*> >::iterator i; 
-	for ( i = lines.begin() ; i < lines.end(); i ++ ) {
-		int len = i->first ;
-		char* line = i->second ;
-		iOutput.write(line,len);
-		delete []line ;
-	}
-	iOutput.flush();	
-	return true ;
-}
-bool SymbolGenerator::ProcessX86Map(ifstream& aStream, const SymGenContext& aContext) {
-	char buffer[MAX_LINE_LENGTH]; 
-	char* lineStart; 
-	while(aStream.good() && (!aStream.eof())){
-		aStream.getline(buffer,MAX_LINE_LENGTH);
-		lineStart = buffer ;
-		SKIP_WS(lineStart);
-		if( 0 == strncmp(lineStart,"Address",7)) { 
-			break ;
-		}		
-	}
-	aStream.getline(buffer,MAX_LINE_LENGTH);
-	string lastName ;
-	TUint32 lastAddr = 0;
-	size_t allocBytes ;
-	vector<pair<int, char*> >lines ;
-	while(aStream.good() && (!aStream.eof())){
-		aStream.getline(buffer,MAX_LINE_LENGTH);
-		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 + aContext.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));
-		}		
-	}
-	guarded_lock lock(iFileMutex);
-	allocBytes = strlen(aContext.iFileName) + 40;
-	char* outputLine = new char[allocBytes];
-	int n = snprintf(outputLine,allocBytes,"\r\nFrom    %s\r\n\r\n",aContext.iFileName); 
-	iOutput.write(outputLine,n);
-	delete []outputLine ;
-	vector<pair<int,char*> >::iterator it; 
-	for ( it = lines.begin() ; it < lines.end(); it ++ ) {
-		int len = it->first ;
-		char* line = it->second  ;
-		iOutput.write(line,len);
-		delete []line ;
-	}	
-	if(!lastName.empty()){
-		allocBytes = lastName.length() + 40 ;
-		outputLine = new char[allocBytes];
-		unsigned int romAddr = lastAddr + aContext.iCodeAddress;
-		n = snprintf(outputLine,allocBytes,"%08x    0000    %s\r\n",romAddr,lastName.c_str());
-		iOutput.write(outputLine,n);
-		delete []outputLine ;
-	}
-	iOutput.flush();
-	return false ;
-}
--- a/imgtools/romtools/rombuild/symbolgenerator.h	Fri Nov 12 14:49:36 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
-* 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: 
-*
-*/
-
-#ifndef __SYMBOLSCREATER_H__
-#define __SYMBOLSCREATER_H__
-#include <queue>
-#include <string>
-#include <fstream>
-#include <vector>
-#include <map>
-
-using namespace std;
-
-#include <boost/thread/thread.hpp>
-#include <boost/thread/condition.hpp>
-
-struct SymGenContext {
-	const char* iFileName ;
-	TUint32	iTotalSize ;
-	TUint32 iCodeAddress; 
-	TUint32 iDataAddress; 
-	TUint32 iDataBssLinearBase;	 
-	TInt iTextSize; 
-	TInt iDataSize; 
-	TInt iBssSize;   	
-	TInt iTotalDataSize;
-	TBool iExecutable ;
-};
-
-class SymbolGenerator  {  
-public :
-		SymbolGenerator(const char* aSymbolFileName, int aMultiThreadsCount = 1);
-		~SymbolGenerator();		
-		void AddEntry(const SymGenContext& aEntry); 
-		void WaitThreads();
-private :
-		SymbolGenerator();
-		SymbolGenerator& operator = (const SymbolGenerator& aRight);
-		static void ThreadFunc(SymbolGenerator* aInst); 
-		bool ProcessEntry(const SymGenContext& aContext);
-		bool ProcessARMV5Map(ifstream& aStream, const SymGenContext& aContext);
-		bool ProcessGCCMap(ifstream& aStream, const SymGenContext& aContext);
-		bool ProcessX86Map(ifstream& aStream, const SymGenContext& aContext);
-		ofstream iOutput ; 
-		boost::thread_group iThreads ;
-		boost::condition_variable iCond;
-		boost::mutex iQueueMutex;
-		boost::mutex iFileMutex ;
-		queue<SymGenContext> iEntries ;	
-		vector<char*> iErrMsgs ;
-	
-};
-
-#endif //__ROMSYMBOLGENERATOR_H__
--- a/sbsv1/buildsystem/extension/syslibs/test/charconv_testpostbuild.mk	Fri Nov 12 14:49:36 2010 +0000
+++ b/sbsv1/buildsystem/extension/syslibs/test/charconv_testpostbuild.mk	Tue Nov 23 10:47:23 2010 +0800
@@ -11,10 +11,7 @@
 # Contributors:
 #
 # Description:
-# This postbuild script is only called when a Test Build is done.  It deletes the KDDI/AU versions of the shiftjis and j5 plugin RSC file, so
-# that only the Docomo versions remain.  This removed ambiguity over which one will load during tests - a seperate version of the KDDI/AU
-# plugins is created for test build, with a unique UID number so they may coexist for test purposes.
-# 
+# This postbuild script is only called when a Test Build is done.  
 #
 
 TMPROOT:=$(subst \,/,$(EPOCROOT))