[Feature]Upload Modem source code

Change-Id: Id4294f30faced84d3e6fd6d5e61e1111bf287a37
diff --git a/mcu/tools/ROParser.pl b/mcu/tools/ROParser.pl
new file mode 100644
index 0000000..0ed8c2e
--- /dev/null
+++ b/mcu/tools/ROParser.pl
@@ -0,0 +1,1385 @@
+#*--------------------------------------------------------------------------*

+#* Global variables

+#*--------------------------------------------------------------------------*

+my $LISFILE      = $ARGV[0];

+my $rootdir = @ARGV[1];

+my $mcudir = @ARGV[2];

+my $branch = @ARGV[3];

+my @filearray;

+my @disarray;

+my @unusedroarray;

+my @resultarray;

+my @symbolarray;

+my $printmode = "dec";

+my $outputfilename;

+my $unusedfilename;

+#*--------------------------------------------------------------------------*

+#* Code Body

+#*--------------------------------------------------------------------------*

+

+$initialtime = time();

+

+warn "

+==============================================================================

+ [Program]    ROParser.pl

+ [Version]    V3.0

+ [Date]       2008-04-09

+ [Author]     yikuan.huang\@mediatek.com

+ [Copyright]  Copyright (C) 2008 MediaTek Incorporation. All Rights Reserved.

+==============================================================================

+";

+

+unless(defined($branch)){

+	usage();

+}

+startview($branch);

+determinefilename();

+print "start to parse LIS file......\n";

+parselisfile();

+print "finish parsing LIS file......\n";

+

+print "start to disassemble...\n";

+traversefile($rootdir);

+disassemble();

+print "finish disassembling!\n";

+

+print "start to get unusedRO...\n";

+getunusedRO();

+print "finish getting unusedRO...\n";

+

+print "start to parse dis file...\n";

+parsedisfile();

+print "finish parsing dis file...\n";

+

+print "start to dump resule to files...\n";

+dump_resulte_to_file();

+print "finish dumping resule to files!\n";

+

+$finishtime = time(); 

+$exectime = $finishtime - $initialtime;

+print "Total execution time: ".$exectime." seconds\n";

+

+

+

+#****************************************************************************

+# FUNCTION

+#  determinefilename

+# DESCRIPTION

+#  This function determine the name of output file

+#****************************************************************************

+sub determinefilename{

+    @filepart = split /\\/,$LISFILE;

+	$outputfilename = $filepart[-1];

+	$unusedfilename  = $filepart[-1];

+	if($filepart[-1] =~ /(\S+)lis/){

+		$outputfilename = $1;

+	}

+	$unusedfilename = $outputfilename;

+	$outputfilename = $outputfilename."txt";

+	$unusedfilename =~ s/\.//;

+	$unusedfilename = $unusedfilename."unusedRO.txt";

+}

+#****************************************************************************

+# FUNCTION

+#  parselisfile

+# DESCRIPTION

+#  This function parse LIS file

+#****************************************************************************

+sub parselisfile{

+#****************************************************************************

+# Parse LIS file content

+#****************************************************************************

+my (@ref_obj, @ref_func, @dec_obj, @dec_region, @content , @symbol);	# referencing obj, referencing function, declaration obj, declaraion region, referenced content

+my ($i, $ref_count ,$j, $switch);

+

+die "$LISFILE does not exist!\n" if (!-e $LISFILE);

+

+

+open (FILE_HANDLE, "<$LISFILE") or die "Fail to open $LISFILE\n";

+$i = 0;

+$j = 0;

+$switch = 0;

+while (<FILE_HANDLE>) {

+	if (/(\S+)\((\S+)\)\srefers\sto\s(\S+)\((\S+)\)\sfor\s(\S+)\s*/) {	# AAA.obj(i.func/pragma) refers to BBB.obj(i.func/pragma/region) for content

+		$ref_obj[$i] = $1;		# AAA

+		$ref_func[$i] = $2;		# i.func/pragma

+		$dec_obj[$i] = $3;		# BBB

+		$dec_region[$i] = $4;	# i.func/pragma/region

+		$content[$i] = $5;		# content

+		$i++;									# should be indexed with the same $i

+	}

+	if (/Local Symbols/){

+		$switch = 1;

+	}

+	if (/================================================================================/){

+		$switch = 0;

+	}

+	if ($switch == 1){

+		$_ = trim($_);

+		if(/(\S+)(\s*)(\S+)(\s*)(\S+)(\s*)(\S+)(\s*)(\S+)/){

+			$symbol[$j] = $1;

+			$j++;

+		}

+	}

+}

+$ref_count = $i;

+close FILE_HANDLE or die "Fail to close $LISFILE\n";

+

+@symbol = reverse sort @symbol;

+

+#****************************************************************************

+# Further parse the reference table to find constdata

+#****************************************************************************

+my $ref_data;

+my %constdata;

+$i = 0;

+foreach $ref_data (@content) {

+	if ($ref_data eq ".constdata\$1") {	# AAA.obj(i.func/pragma) refers to BBB.obj(i.func/pragma/region) for .constdata$1

+		$constdata{$i} = $ref_data;				# constdata{$i} = .constdata$1, $i is the index of constdata references

+	}

+	$i++;

+}

+

+

+#****************************************************************************

+# Find unused RO data

+#****************************************************************************

+my (%unused_RO_func, %unused_RO_pragma);

+

+$i = 0;

+while ($i < $ref_count) {

+	if (defined $constdata{$i}) {

+		my $is_In_Symbol_Table = 0;

+		my $funcname = $ref_func[$i];

+		foreach (@symbol){

+			my $tablefuncname = $_;

+			if($funcname eq $tablefuncname){

+				$is_In_Symbol_Table = 1;

+				last;

+			}

+			if($funcname gt $tablefuncname){

+				$is_In_Symbol_Table = 0;

+				last;

+			}

+		}

+		if ($is_In_Symbol_Table == 0) {

+			if ($ref_func[$i] =~ /i.(\S+)/) {	# function case

+				$unused_RO_func{$ref_func[$i]} = $ref_obj[$i];

+			}

+			else{

+				$unused_RO_pragma{$ref_func[$i]} = $ref_obj[$i];

+			}

+			#print $ref_func[$i]."...".$ref_obj[$i]."\n";

+		}

+	}

+	$i++;

+}

+

+#****************************************************************************

+# Output unreferenced functions that contain unused RO data

+#****************************************************************************

+open (FILE_HANDLE, ">$unusedfilename") or die "Fail to open $unusedfilename\n";

+my $ref_data;

+print FILE_HANDLE "Unreferenced functions that contain unused RO data: \n";

+foreach $ref_data (sort {$unused_RO_func{$a} cmp $unused_RO_func{$b}} keys %unused_RO_func) {

+	print FILE_HANDLE "$ref_data ($unused_RO_func{$ref_data})\n";

+}

+

+print FILE_HANDLE "\nOther pragmas that contains unreferenced functions with RO data: \n";

+foreach $ref_data (sort {$unused_RO_pragma{$a} cmp $unused_RO_pragma{$b}} keys %unused_RO_pragma) {

+	print FILE_HANDLE "$ref_data ($unused_RO_pragma{$ref_data})\n";

+}

+

+close FILE_HANDLE or die "Fail to close output.txt\n";

+

+

+}

+

+

+

+#****************************************************************************

+# FUNCTION

+#  dump_resulte_to_file

+# DESCRIPTION

+#  This function dumps the result of RO parser to file(result.txt)

+#****************************************************************************

+sub dump_resulte_to_file{

+	#*--------------------------------------------------------------------------*

+	#* Local variables

+	#*--------------------------------------------------------------------------*

+	$resultfuncname;

+	$resultobjname;

+    $resultconstantstring;

+	$resultstringsize;

+	$resultconstantdata;

+	$resultdatasize;

+	$resultfilepath;

+	$resultowner;

+	#*--------------------------------------------------------------------------*

+	#* Code Body

+	#*--------------------------------------------------------------------------*

+	%ownerhash;

+	open(RESULT,">$outputfilename") || die "File open error!\n";

+	# Set the data format

+format RESULT =

+  @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<< @<<<<<<<<<<

+  $resultfuncname,$resultobjname,$resultconstantstring,$resultstringsize,$resultconstantdata,$resultdatasize,$resultowner

+.

+	foreach (@resultarray){

+		my $resulthash = $_;

+		$resultfuncname = $resulthash->{"funcname"};

+		$resultobjname = $resulthash->{"objname"};

+		$resultconstantstring = $resulthash->{"constantstring"};

+		$resultstringsize = $resulthash->{"stringsize"};

+		$resultconstantdata = $resulthash->{"constantdata"};

+		$resultdatasize = $resulthash->{"datasize"};

+		$resultfilepath = get_objpath_by_objname($resultobjname);

+		if(defined $ownerhash{$resultfilepath}){

+			

+		}

+		else{

+			$ownerhash{$resultfilepath} = getOwner($resultfilepath);

+		}

+		$resultowner = $ownerhash{$resultfilepath};

+		if($printmode eq "dec"){

+			if($resultstringsize =~ /0x(\w+)/){

+				$resultstringsize = hex($1);

+			}

+			if($resultdatasize =~ /0x(\w+)/){

+				$resultdatasize = hex($1);

+			}

+		}

+		#print $resultfuncname." ".$resultobjname." ".$resultconstantstring." ".$resultstringsize." ".$resultconstantdata." ".$resultdatasize."\n";

+		write(RESULT);

+	}	

+	close(RESULT);

+	

+	#delete unusedRO file

+	#unlink($unusedfilename);

+}

+

+#****************************************************************************

+# FUNCTION

+#  check_global_table

+# DESCRIPTION

+#  This function check whether the offset is in the global symbol table

+#****************************************************************************

+sub check_global_table(){

+	$_ = $_[0];

+	s/0x//;

+	my $offset = hex($_);

+	my $objname = $_[1];

+	my $result = "0";

+	#print $offset." ... ".$objname."\n";

+	foreach (@symbolarray){

+		my $symbolhash = $_;

+		$symbolojbname = $symbolhash->{"objname"};

+		$symbolname = $symbolhash->{"symbolname"};

+		$symbolvalue = $symbolhash->{"symbolvalue"};

+		$symbolsize = $symbolhash->{"symbolsize"};

+		$symbolstart = $symbolhash->{"symbolstart"};

+		$symbolend = $symbolhash->{"symbolend"};

+		if($symbolojbname eq $objname){

+			if(($offset>=$symbolstart) && ( $offset<$symbolend)){

+				$result = $symbolname.":".$symbolsize;

+				last;

+			}

+		}

+	}

+	return $result;

+}

+

+

+#****************************************************************************

+# FUNCTION

+#  parsedisfile

+# DESCRIPTION 

+#  This function parse the dis file which appears in @unusedroarray , and create the result

+#****************************************************************************

+sub parsedisfile(){

+	#*--------------------------------------------------------------------------*

+	#* Code Body

+	#*--------------------------------------------------------------------------*

+	foreach	(@unusedroarray){		

+		my $gethash = $_;

+		my $getobjname = $gethash->{"objname"};

+		my $getfuncname = $gethash->{"funcname"};

+		my $getdisfilepath = $gethash->{"disfilepath"};

+		my $firstaddress;

+		my $offset;

+		my $constdatasecnum;

+		if(defined($getdisfilepath)){

+			@symbolarray = ();

+			open(FILE,"<$getdisfilepath") || die "File open error - $getdisfilepath!\n";

+			@data = <FILE>;

+		  	my $funcswitch = 0;

+		  	my $getoffset = 0;

+		  	my $findconstdatasec = 0;

+		  	my $constdataswitch = 0;

+		  	my $hasvalue = 0;

+

+		  	

+		  	my $thisoffset;

+		  	my $targetoffset;

+		  	

+		  	my $hasequal = 0;

+

+		  	my @blockarray;

+		  	my @indexarray;

+		  	my @firstaddressarray;

+		  	my $index = 0;

+		  	my $targetindex = 0;

+		  	my $maxlength = 16;

+		  	

+		  	my $hasglobal = 0;

+			

+			#&parse_for_global_symbol_table(@data);

+			my $currentsecnum;		#store section number temporarily

+			my @secnum; 			#store section number in one dis file

+		#****************************************************************************

+		# 1 >>> First round : scan the dis file, and get all the section number which has .constdata

+		# For example,  ** Section #10

+		#

+    	#			Name        : .constdata

+		# We find the ".constdata", and get it's previous section number - 10

+		# Store all the section number into @secnum

+		#****************************************************************************

+		foreach(@data){

+	  		# Find each section number, and record it in the $currentsecnum

+	  		if($_ =~ /\*\* Section #(\d+)/){

+	  			$currentsecnum = $1;

+	  		}

+	  		# Find the .constdata, record the previous section number into @secnum 

+	  		if(index($_,"Name        : .constdata")>=0){

+	  			push @secnum, $currentsecnum;

+	  		}	

+	  	}

+	  	

+	  	#****************************************************************************

+		# 2 >>> Second round : scan the dis file, get the data row from the symbol table

+		# For example,

+		# Symbol table .symtab (121 symbols, 112 local)

+      	#  Symbol Name                Value      Bind  Sec  Type  Size

+    	# ========================================================================

+      	# 1  $t                         0x00000000   Lc    5  Code

+      	# ................................

+      	# ========================================================================

+      	# 

+      	# We find "Symbol table" first, and record the data between two "=======" lines

+      	#****************************************************************************

+	  	$isSym = 0;	

+	   	$switch = 0;

+	   	

+	  	foreach(@data){

+	  		# Find the symbol table 

+	  		if(index($_,"Symbol table .symtab")>=0){

+	  				$isSym = 1;

+	  				next;

+	  		}

+	  		if((index($_,"=================")>=0)&&($isSym eq 1)){

+	  				$switch = 1;

+	  				$isSym = 0;

+	  				next;

+	  		}

+	  		if((index($_,"==================")>=0)&&($isSym eq 0)){

+	  			$switch = 0;

+	  			next;

+	  		}

+	  		if($switch eq 1){

+	  			my %symbolhash;

+	  			#if it has 7 values

+	  			if(/\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/){

+	  				#print $1."\n".$2."\n".$3."\n".$4."\n".$5."\n".$6."\n".$7."\n";

+	  				#print "\n";

+	  				if(matchsecnum($5,@secnum) eq 1){

+		  				%symbolhash ={};

+						$symbolhash{"objname"}= $getobjname;

+						$symbolhash{"symbolname"}= $2;

+						$symbolhash{"symbolvalue"}= $3;

+						$symbolhash{"symbolsize"}= $7;

+						if(index($symbolhash{"symbolsize"},"0x")>=0){

+								$_ = $symbolhash{"symbolvalue"};

+								s/0x//;

+								$symbolhash{"symbolstart"} = hex($_);

+								$_ = $symbolhash{"symbolsize"};

+								s/0x//;

+								$symbolhash{"symbolend"} = $symbolhash{"symbolstart"} + hex($_);

+							push @symbolarray, \%symbolhash;

+						}

+	  				}

+	  				next;

+	  			}

+	  			#if it has 6 values

+	  			elsif(/\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/){

+	  				#print $1."\n".$2."\n".$3."\n".$4."\n".$5."\n".$6."\n";

+	  				#print "\n";

+	  				if(matchsecnum($5,@secnum) eq 1){

+		  				%symbolhash ={};

+						$symbolhash{"objname"}= $getobjname;

+						$symbolhash{"symbolname"}= $2;

+						$symbolhash{"symbolvalue"}= $3;

+	  				}

+	  				next;

+	  			}

+	  			

+	  			# across two line!!

+	  			else{

+	  				# second line: 5 values

+	  				if(/\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/){

+	  					#print $1."\n".$2."\n".$3."\n".$4."\n".$5."\n";

+						if(matchsecnum($3,@secnum) eq 1){

+							$symbolhash{"objname"}= $getobjname;

+							$symbolhash{"symbolvalue"}= $1;

+							$symbolhash{"symbolsize"}= $5;

+							if(index($symbolhash{"symbolsize"},"0x")>=0){

+								$_ = $symbolhash{"symbolvalue"};

+								s/0x//;

+								$symbolhash{"symbolstart"} = hex($_);

+								$_ = $symbolhash{"symbolsize"};

+								s/0x//;

+								$symbolhash{"symbolend"} = $symbolhash{"symbolstart"} + hex($_);

+								push @symbolarray, \%symbolhash;

+							}

+							%symbolhash ={};

+						}

+	  					next;

+	  				}

+	  				# second line: 4 values

+	  				if(/\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/){

+	  					#print $1."\n".$2."\n".$3."\n".$4."\n";

+	  					if(matchsecnum($3,@secnum) eq 1){

+		  					$symbolhash{"objname"}= $getobjname;

+							$symbolhash{"symbolvalue"}= $1;	

+							if(index($symbolhash{"symbolsize"},"0x")>=0){

+			  					$_ = $symbolhash{"symbolvalue"};

+								s/0x//;

+								$symbolhash{"symbolstart"} = hex($_);

+								$_ = $symbolhash{"symbolsize"};

+								s/0x//;

+								$symbolhash{"symbolend"} = $symbolhash{"symbolstart"} + hex($_);

+		  						push @symbolarray, \%symbolhash;

+							}

+		  					%symbolhash ={};

+	  					}

+	  					next;

+	  				}

+	  				# first line: 2 values

+	  				if(/\s+(\S+)\s+(\S+)/){

+	  					#print $1."\n".$2."\n";

+	  					$symbolhash{"symbolname"}= $2;

+	  					next

+	  				}

+	  			}

+	  		}

+

+	  	}

+				

+

+						

+		  	foreach(@data){

+		  		# open the section

+		  		if($_ =~ /Name        : i.$getfuncname\n/){

+		  			$funcswitch = 1;

+		  			$findconstdatasec = 1;

+		  			next;

+		  		}

+		  		if($_ =~ /Name        : $getfuncname\n/){

+		  			$funcswitch = 1;

+		  			$findconstdatasec = 1;

+		  			next;

+		  		}

+		  		

+		  		if(($funcswitch == 1)&&($_ =~ /.constdata$1/)){

+		  				# if the address has 4 digits

+		  				$isExist = "false";

+		  				if($_ =~ /= 0x(\w\w\w\w)]/){

+		  					$firstaddress = $1;

+		  					foreach $address(@firstaddressarray){

+		  						if($address eq $firstaddress){

+		  							$isExist = "true";

+		  						}

+		  					}

+		  					if($isExist eq "false"){

+		  						push @firstaddressarray, $firstaddress;

+		  					}

+		  					next;

+		  				}

+		  				# if the address has 3 digits

+		  				if($_ =~ /= 0x(\w\w\w)]/){

+		  					$firstaddress = $1;

+		  					foreach $address(@firstaddressarray){

+		  						if($address eq $firstaddress){

+		  							$isExist = "true";

+		  						}

+		  					}

+		  					if($isExist eq "false"){

+		  						push @firstaddressarray, $firstaddress;

+		  					}

+		  					next;

+		  				}

+		  				# if the address has 2 digits

+		  				if($_ =~ /= 0x(\w\w)]/){

+		  					$firstaddress = $1;

+		  					foreach $address(@firstaddressarray){

+		  						if($address eq $firstaddress){

+		  							$isExist = "true";

+		  						}

+		  					}

+		  					if($isExist eq "false"){

+		  						push @firstaddressarray, $firstaddress;

+		  					}

+		  					next;

+		  				}

+		  				# if the address has 1 digits

+		  				if($_ =~ /= 0x(\w)]/){

+		  					$firstaddress = $1;

+		  					foreach $address(@firstaddressarray){

+		  						if($address eq $firstaddress){

+		  							$isExist = "true";

+		  						}

+		  					}

+		  					if($isExist eq "false"){

+		  						push @firstaddressarray, $firstaddress;

+		  					}

+		  					next;

+		  				}

+		  		}

+		  		# close the section

+		  		if(($funcswitch == 1)&&index($_,"====================================") >= 0){

+		  			$funcswitch = 0;

+		  		}

+		  	}

+

+

+#print $getdisfilepath."\n";

+#print @firstaddressarray."\n";

+foreach(@firstaddressarray){

+	$firstaddress = $_;

+	$stringlength = 0;

+	$stringresult = "";

+		  	foreach(@data){

+		  		# open the section

+		  		if($_ =~ /Name        : i.$getfuncname\n/){

+		  			$funcswitch = 1;

+		  			$findconstdatasec = 1;

+		  			next;

+		  		}

+		  		if($_ =~ /Name        : $getfuncname\n/){

+		  			$funcswitch = 1;

+		  			$findconstdatasec = 1;

+		  			next;

+		  		} 		

+		  		if(($funcswitch == 1)&&($firstaddress ne "")&&($_ =~ /0x0+$firstaddress:/)){

+					my @linearray = split;

+					if($linearray[1] =~ /00(\S+)/){

+						$offset = "0x".$1;

+						$getoffset = 1;

+						# check whether the offset is in the global symbol table

+							$returndata = &check_global_table($offset,$getobjname);

+	

+							unless($returndata eq "0"){

+								my %resulthash ={};

+			    				$resulthash{"funcname"}= $getfuncname;

+							    $resulthash{"objname"}= $getobjname;

+							    if($returndata =~ /(\S+):(\S+)/){

+							    	$resulthash{"constantdata"} = $1;

+							    	$resulthash{"datasize"}= $2;

+							    }

+							    push @resultarray, \%resulthash;

+							    $hasglobal = 1;

+								last;

+							}

+						next;

+					}

+				}

+				# close the section

+		  		if(($funcswitch == 1)&&index($_,"====================================") >= 0){

+		  			$funcswitch = 0;

+		  		}

+		  		

+		  		# find the section number of .constdata

+		  		if(($findconstdatasec == 1)&&(index($_,".constdata$1")>=0)){

+		  			if(/#(\d+) '.constdata'/){

+		  				$constdatasecnum = $1;

+		  				$findconstdatasec = 0;

+		  				next;

+		  			}

+		  			

+		  		}

+		  	    # find .constdata block

+		  		if(($getoffset==1)&&($_ =~ /\*\* Section #${constdatasecnum}$/)){

+		  			$constdataswitch = 1;

+		  			#$getoffset == 0;

+		  			next;

+		  		}

+

+

+		  

+		  		# find the string in the .constdata block

+		  		if(($constdataswitch == 1)&&($_ =~ /0x(\S+):/)){

+					# if match the offset

+					if(index($_,$offset.":")>=0){	

+						$hasequal = 1; 

+						$targetindex = $index;

+					}

+					

+					push @indexarray,$index;

+					push @blockarray,trim($_);

+					$index++;

+	   			}	

+					  

+		  		if(($constdataswitch == 1)&&(index($_,"====================================") >= 0)){

+	  				$constdataswitch = 0;

+		  		}

+		  	}

+		 

+		 	if($hasglobal == 1){

+		 		next;

+		 	}

+		 	if($getoffset == 0){

+		 		$resulthash{"funcname"}= $getfuncname;

+				$resulthash{"objname"}= "(".$getobjname.")";

+				push @resultarray, \%resulthash;

+		 		next;

+		 	}

+		 

+		  	# start to parse the block data

+		 	  		

+		  	# if find the offset match the target offset

+		  	if($hasequal == 1){  		

+		  		$line = trim($blockarray[$targetindex]);

+		  		$moreswitch = 1;

+		  		#$stringlength = 0;

+		  		while($moreswitch == 1){ 

+			  		@stringarray = split /\s+/,$line;

+				  	# remove the first and last item

+				  	shift(@stringarray);

+				  	pop(@stringarray);

+				  	$thislength = 0;

+				  	if(scalar(@stringarray) == 0){

+				  		$moreswitch = 0;

+				  	}

+				  	foreach $hexvalue(@stringarray){ 	

+				  		if(is_ascii($hexvalue)){

+				  			$thislength++;

+				  			if($thislength <= $maxlength){

+				  				$stringresult = $stringresult.hex_to_ascii($hexvalue);

+				  			}

+				  			# need to consider next line

+				  			if($thislength == $maxlength){

+				  				$targetindex = $targetindex + 1;

+				  				if($targetindex < scalar(@blockarray)){

+				  					$line = trim($blockarray[$targetindex]);

+				  					$stringlength += $thislength;

+				  				}

+				  			}

+				  			

+				  		}

+				  		else{

+				  			if(($hexvalue eq "00")&&($stringlength != 0)){

+				  					$stringlength += 1;

+				  			}

+				  			$stringlength += $thislength;

+				  			$moreswitch = 0;

+				  			last;

+				  		}

+				   }

+		  	   }

+			   # save the result

+				my %resulthash ={};

+				if($stringlength > 0){

+					$resulthash{"funcname"}= $getfuncname;

+					$resulthash{"objname"}= $getobjname;

+					$resulthash{"constantstring"} = $stringresult;

+					$resulthash{"stringsize"}= "0x".dec2hex($stringlength);

+				}

+				else{

+					$resulthash{"funcname"}= "(".$getfuncname.")";

+					$resulthash{"objname"}= $getobjname;

+				}

+				push @resultarray, \%resulthash;

+		  	}

+		  	

+		  	# if no offset match the target offset

+		  	else{

+		   		my $findbetween = 0;

+		  		for($i=0;$i<@blockarray;$i++){

+		  			$line = trim($blockarray[$i]);

+		  			$nextarget = $i;

+			  		@stringarray = split /\s+/,$line;

+					# get the offset value of this line

+					$_ = shift(@stringarray);

+					s/0x//;

+					$thisoffset = hex($_);

+					# get the offset value of next line

+					$nextoffset = 0;

+					if($i != (@blockarray-1)){

+			  			@temparray = split /\s+/,trim($blockarray[$i+1]);

+			  			$_ = shift(@temparray);

+			  			s/0x//;

+						$nextoffset = hex($_);

+					}

+					# get the target offset

+					$_ = $offset;

+					s/0x//;

+					$targetoffset = hex($_);

+					

+					$difference = $targetoffset - $thisoffset;

+					

+					if(($targetoffset > $thisoffset)&&($targetoffset < $nextoffset)){

+

+						$findbetween = 1;

+						$moreswitch = 0;

+		  				#$stringlength = 0;

+					  	@stringarray = split /\s+/,$line;

+						# remove the first and last item

+						shift(@stringarray);

+						pop(@stringarray);

+						# remove the first different items

+					  	for($j=0;$j<$difference;$j++){

+					  		shift(@stringarray);

+					  	}

+						$thislength = 0;

+						$moreswitch = 0;

+						foreach $hexvalue(@stringarray){ 

+						  	if(is_ascii($hexvalue)){

+						  		$thislength++;

+						  		if($thislength <= ($maxlength-$difference)){

+						  			$stringresult = $stringresult.hex_to_ascii($hexvalue);

+						  		}

+						  		# need to consider next line

+						  		if($thislength == ($maxlength-$difference)){

+						  			$nextarget = $nextarget + 1;

+						  			if($nextarget < scalar(@blockarray)){

+						  				$line = trim($blockarray[$nextarget]);

+						  				$moreswitch = 1;

+						  				$stringlength += $thislength;

+						  			}

+						  		}

+						  		

+						  	}

+						  	else{

+						  		if(($hexvalue eq "00")&&($stringlength != 0)){

+				  					$stringlength += 1;

+				  				}

+						  		$stringlength += $thislength;

+						  		$moreswitch = 0;

+						  		last;

+						  	}

+						}

+				  	    while($moreswitch == 1){

+						  	@stringarray = split /\s+/,$line;

+						  	# remove the first and last item

+						  	shift(@stringarray);

+						  	pop(@stringarray);

+						  	$thislength = 0;

+						  	if(scalar(@stringarray) == 0){

+						  		$moreswitch = 0;

+						  	}

+						  	foreach $hexvalue(@stringarray){ 	

+						  		if(is_ascii($hexvalue)){

+						  			$thislength++;

+						  			if($thislength <= $maxlength){

+						  				$stringresult = $stringresult.hex_to_ascii($hexvalue);

+						  			}

+						  			# need to consider next line

+						  			if($thislength == $maxlength){

+						  				$nextarget = $nextarget + 1;

+						  				if($nextarget < @blockarray){

+						  					$line = trim($blockarray[$nextarget]);

+						  					$stringlength += $thislength;

+						  				}

+						  			}

+						  			

+						  		}

+						  		else{

+						  			if(($hexvalue eq "00")&&($stringlength != 0)){

+				  					$stringlength += 1;

+				  					}

+						  			$stringlength += $thislength;

+						  			$moreswitch = 0;

+						  			last;

+						  		}

+						   }

+				  	    }

+						# save the result

+						my %resulthash ={};

+						if($stringlength > 0){

+							$resulthash{"funcname"}= $getfuncname;

+							$resulthash{"objname"}= $getobjname;

+							$resulthash{"constantstring"} = $stringresult;

+							$resulthash{"stringsize"}= "0x".dec2hex($stringlength);

+						}

+						else{

+							$resulthash{"funcname"}= "(".$getfuncname.")";

+							$resulthash{"objname"}= $getobjname;

+						}

+						push @resultarray, \%resulthash;

+						last;

+					}

+		  		}

+		  		# if no offset is between two offsets

+				if($findbetween == 0){

+					if($#blockarray != -1){

+						$line = trim($blockarray[$#blockarray]);

+						@stringarray = split /\s+/,$line;

+						# get the offset value of this line

+						$_ = shift(@stringarray);

+						s/0x//;

+						$thisoffset = hex($_);

+						# get the target offset

+						$_ = $offset;

+						s/0x//;

+						$targetoffset = hex($_);

+						# calculate the difference

+						$difference = $targetoffset - $thisoffset;

+						# remove the first and last item

+						shift(@stringarray);

+						pop(@stringarray);

+						# remove the first different items

+					  	for($j=0;$j<$difference;$j++){

+					  		shift(@stringarray);

+					  	}

+						foreach $hexvalue(@stringarray){ 

+						  	if(is_ascii($hexvalue)){

+						  		$stringlength++;

+						  		if($stringlength <= ($maxlength-$difference)){

+						  			$stringresult = $stringresult.hex_to_ascii($hexvalue);

+						  		}

+						  	}

+						}

+						# save the result

+						my %resulthash ={};

+						if($stringlength > 0){

+							$resulthash{"funcname"}= $getfuncname;

+							$resulthash{"objname"}= $getobjname;

+							$resulthash{"constantstring"} = $stringresult;

+							$resulthash{"stringsize"}= "0x".dec2hex($stringlength);

+						}

+						else{

+							$resulthash{"funcname"}= "(".$getfuncname.")";

+							$resulthash{"objname"}= $getobjname;

+						}

+						push @resultarray, \%resulthash;

+					}

+				}

+				

+		  	}

+		  	

+		  	

+			

+}	#close for firstaddressarray 

+		  	close(FILE);

+		}

+	}

+}

+#****************************************************************************

+# FUNCTION

+#  getunusedRO

+# DESCRIPTION

+#  Parse unusedRO.txt, and get the function name and obj filename

+#****************************************************************************

+sub getunusedRO{

+	#*--------------------------------------------------------------------------*

+	#* Code Body

+	#*--------------------------------------------------------------------------*

+	open(FILE,"<$unusedfilename") || die "File open error!\n";

+

+	@data = <FILE>;

+	foreach(@data){

+		    #skip the line that contains :

+	  		if(index($_,":") >= 0){

+	  			next;

+	  		}

+	  		# Find each section number, and record it in the $currentsecnum

+	  		if($_ =~ /(\S+)\s\((\S+)\)/){ 			

+	  			#print $1." ".$2."\n";

+	  			my %unusedrohash ={};

+			    $unusedrohash{"funcname"}= $1;

+			    $unusedrohash{"objname"}= $2;

+			    $unusedrohash{"disfilepath"} = get_dispath_by_objname($2);

+			    push @unusedroarray, \%unusedrohash;

+	  		}

+	}

+	close(FILE);

+	

+}

+

+#****************************************************************************

+# FUNCTION

+#  get_dispath_by_objname

+# DESCRIPTION

+#  Find the corresponding disfile by obj name

+#****************************************************************************

+sub get_dispath_by_objname(){

+	#*--------------------------------------------------------------------------*

+	#* Local variables

+	#*--------------------------------------------------------------------------*

+	my $objname = $_[0];	

+	#*--------------------------------------------------------------------------*

+	#* Code Body

+	#*--------------------------------------------------------------------------*

+	foreach	(@disarray){		

+		my $gethash = $_;

+		my $getobjname = $gethash->{"objname"};

+		my $getdisfilepath = $gethash->{"disfilepath"};

+		#if($objname =~ /(\S+).o$/){

+		#	$objname = $1.".obj";		

+		#}

+		

+		if($getobjname eq $objname){

+			return $getdisfilepath;

+		}

+	}

+	return undef;

+}

+

+#****************************************************************************

+# FUNCTION

+#  get_objpath_by_objname

+# DESCRIPTION

+#  Find the corresponding objfile by obj name

+#****************************************************************************

+sub get_objpath_by_objname(){

+	#*--------------------------------------------------------------------------*

+	#* Local variables

+	#*--------------------------------------------------------------------------*

+	my $objname = $_[0];	

+	#*--------------------------------------------------------------------------*

+	#* Code Body

+	#*--------------------------------------------------------------------------*

+	foreach	(@disarray){		

+		my $gethash = $_;

+		my $getobjname = $gethash->{"objname"};

+		my $getobjfilepath = $gethash->{"objfilepath"};

+		#if($objname =~ /(\S+).o$/){

+		#	$objname = $1.".obj";		

+		#}

+		

+		if($getobjname eq $objname){

+			return $getobjfilepath;

+		}

+	}

+	return undef;

+}

+#****************************************************************************

+# FUNCTION

+#  dimp_symboltable_to_file

+# DESCRIPTION

+#  This function dumps the the data of symbolarray to file(symboltable.txt)

+#****************************************************************************

+sub dump_symboltable_to_file{

+	#*--------------------------------------------------------------------------*

+	#* Local variables

+	#*--------------------------------------------------------------------------*

+	my $disfilename;

+	my $symbolname;

+	my $symbolvalue;

+	my $symbolsize;

+	

+	#*--------------------------------------------------------------------------*

+	#* Code Body

+	#*--------------------------------------------------------------------------*

+	open(FILE,">symboltable.txt") || die "File open error!\n";

+	

+	# Set the data format

+format FILE =

+  @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  @<<<<<<<<<<<< @<<<<<<<<<<

+  $disfilename,$symbolname, $symbolvalue,$symbolsize

+.

+	foreach (@symbolarray){

+		my $symbolhash = $_;

+		$disfilename = $symbolhash->{"objname"};

+		$symbolname = $symbolhash->{"symbolname"};

+		$symbolvalue = $symbolhash->{"symbolvalue"};

+		$symbolsize = $symbolhash->{"symbolsize"};

+		# Remove the empty line

+		unless($symbolname eq ""){

+			write(FILE);

+		}

+	}	

+	close(FILE);

+}

+

+#****************************************************************************

+# FUNCTION

+#  matchsecnum

+# DESCRIPTION

+#  This function determine whether the section number is in the secnum array

+# PARAMETERS

+#  $secnum			section number

+#  @secnumarray		section number array

+# RETURNS

+#  result			return 1 for success; return 0 for fail

+#****************************************************************************

+sub matchsecnum{

+	#*--------------------------------------------------------------------------*

+	#* Local variables

+	#*--------------------------------------------------------------------------*

+	my $result = 0;

+	my $secnum = $_[0];

+	my @secnumarray = $_[1];

+	#*--------------------------------------------------------------------------*

+	#* Code Body

+	#*--------------------------------------------------------------------------*

+	foreach (@secnumarray){

+		if($secnum == $_){

+			$result = 1;

+			return $result;

+		}

+	}

+	return $result;

+}

+sub trim($)

+{

+	my $string = shift;

+	$string =~ s/^\s+//;

+	$string =~ s/\s+$//;

+	return $string;

+}

+#****************************************************************************

+# FUNCTION

+#  disassemble

+# DESCRIPTION

+#  This function disassemble all the obj files in the root directory

+#****************************************************************************

+sub disassemble{

+	  foreach (@filearray){

+		#*--------------------------------------------------------------------------*

+		#* Local variables

+		#*--------------------------------------------------------------------------*

+		my $myhash = $_;

+		my $filename = $myhash->{"filename"};

+		my $filepath = $myhash->{"filepath"};

+		#*--------------------------------------------------------------------------*

+		#* Code Body

+		#*--------------------------------------------------------------------------*

+		$_ = $filename;

+		s/.obj/.dis/;        

+		my $newfilename = $_;

+		$_ = $filepath;

+		s/$filename/$newfilename/;

+		

+		#Start to Disassemble (obj=>dis)

+		

+		#If the dis file doesn't exist, disassemble the obj file

+		unless(-e $_){

+			#system("start C:\\Progra~1\\ARM\\ADSv1_2\\Bin\\fromelf -cdrstvz ".$myhash->{"filepath"}.">".$_);

+			system("C:\\Progra~1\\ARM\\ADSv1_2\\Bin\\fromelf -cdrstvz ".$myhash->{"filepath"}.">".$_); 

+			print "C:\\Progra~1\\ARM\\ADSv1_2\\Bin\\fromelf -cdrstvz ".$myhash->{"filepath"}.">".$_."\n";

+                        #sleep(1);

+		}

+		

+	    my %filehash ={};

+		$filehash{"objname"}= $filename;

+		$filehash{"objfilepath"}= $filepath;

+		$filehash{"disfilepath"}= $_;

+		push @disarray, \%filehash;

+

+}

+

+	

+}

+

+

+#****************************************************************************

+# FUNCTION

+#  traversefile

+# DESCRIPTION

+#  This function scan the root directory , find all the obj files

+# PARAMETERS

+#  #sub_DIR root directory

+#****************************************************************************

+  sub traversefile{

+	#*--------------------------------------------------------------------------*

+	#* Local variables

+	#*--------------------------------------------------------------------------*	

+	my $sub_DIR_id ;

+	my $sub_DIR ;

+	my $sub_SRC_FILE;

+	my @dirarray;

+	my $i;

+	my $count=0;

+	my $newdir;

+ 	

+ 	$sub_DIR = $_[0];  # root directory

+	#*--------------------------------------------------------------------------*

+	#* Code Body

+	#*--------------------------------------------------------------------------*	

+	

+  	#if $sub_DIR is a directory

+  	if(-d ($sub_DIR)){

+  			opendir(sub_DIR_id, $sub_DIR) or die " cannot open directory :($sub_DIR)\n";

+			 while ( defined ($sub_SRC_FILE = readdir(sub_DIR_id)) )

+			  {		 

+				#exclude . and ..

+			    if (($sub_SRC_FILE ne "\.") && ($sub_SRC_FILE ne "\.\."))

+			    { 	

+			    	my $path = $sub_DIR."\\".$sub_SRC_FILE;

+			    	unless(-d ($path)){

+			    		$_ = $path;

+			    		#Only count obj file

+			    		if(/.obj$/i){

+			    			my %filehash ={};

+			    			$filehash{"filename"}= $sub_SRC_FILE;

+			    			$filehash{"filepath"}= $path;

+			    			push @filearray, \%filehash;

+			    		}

+			    	}

+					@dirarray[$count]=$sub_DIR."\\".$sub_SRC_FILE;

+					$count++;

+			   	} 

+			 }	 

+			 for($i=0;$i<$count;$i++){

+			 	 $newdir = @dirarray[$i];

+			 	 traversefile($newdir);

+			 }

+ }

+#****************************************************************************

+# FUNCTION

+#  hex_to_ascii

+# DESCRIPTION

+#  This function convert each two-digit hex number back to an ASCII character

+#****************************************************************************

+sub hex_to_ascii ($){

+    (my $str = shift) =~ s/([a-fA-F0-9]{2})/chr(hex $1)/eg;

+    return $str;

+}

+#****************************************************************************

+# FUNCTION

+#  is_ascii

+# DESCRIPTION

+#  This function check whether the param is a ascii code

+#****************************************************************************

+sub is_ascii($){

+	$param = hex_to_ascii($_[0]);

+	$asciinum = ord($param);

+	if((($asciinum>=32)&&($asciinum<=126))||($asciinum==10)){

+		return 1;

+	}

+	else{

+		return 0;

+	}

+}

+

+    sub dec2hex {

+    # parameter passed to

+    # the subfunction

+    my $decnum = $_[0];

+    # the final hex number

+    my $hexnum;

+    my $tempval;

+    while ($decnum != 0) {

+    # get the remainder (modulus function)

+    # by dividing by 16

+    $tempval = $decnum % 16;

+    # convert to the appropriate letter

+    # if the value is greater than 9

+    if ($tempval > 9) {

+    $tempval = chr($tempval + 55);

+    }

+    # 'concatenate' the number to 

+    # what we have so far in what will

+    # be the final variable

+    $hexnum = $tempval . $hexnum ;

+    # new actually divide by 16, and 

+    # keep the integer value of the 

+    # answer

+    $decnum = int($decnum / 16); 

+    # if we cant divide by 16, this is the

+    # last step

+    if ($decnum < 16) {

+    # convert to letters again..

+    if ($decnum > 9) {

+    $decnum = chr($decnum + 55);

+    }

+    

+    # add this onto the final answer.. 

+    # reset decnum variable to zero so loop

+    # will exit

+    $hexnum = $decnum . $hexnum; 

+    $decnum = 0 

+    }

+    }

+    return $hexnum;

+    } # end sub

+ 

+

+

+}

+

+sub getOwner(){

+	$cc_mcu_path = "M:\\".$branch."_int\\MAUI_SW\\mcu";

+	$fullfilepath = shift @_;

+	@part = split /\\/,$fullfilepath;

+	$obj_parse = $part[-1];

+	$lib_parse = $part[-2].".lib";

+	$owner = "";

+	$filepath = getfilepath($lib_parse,$obj_parse,$mcudir);

+	

+	if($mcudir eq ".\\"){

+		$_ = $filepath;

+		s/.\\/\\/;

+		$cc_mcu_path = $cc_mcu_path.$_;

+	}

+	else{

+		if($filepath =~ /(\S+)mcu(\S+)/){

+			$cc_mcu_path = $cc_mcu_path.$2;

+		}

+	}

+

+  if (!-e ){

+  	$new_cc_mcu_path = $cc_mcu_path."pp";

+  	if (-e $new_cc_mcu_path){

+  		$cc_mcu_path = $new_cc_mcu_path;

+  	}

+  }

+	$owner = get_owner_from_CC_server($cc_mcu_path);

+	return $owner;

+}

+sub getfilepath

+{

+    my ($mcu_path, $lis_path);

+	 $lib_file = shift @_;

+	 $obj_file = shift @_;

+	 $mcu_path = shift @_;

+	my ($lib_tmp, $obj_tmp);

+

+	### get lis file path

+	$lib_file =~ /(.*).lib/;

+	$lib_tmp = $1;

+

+	# search source file path for object file

+	# query from lis file

+

+

+	if ((lc($lib_file) eq "conn_app.lib")||(lc($lib_file) eq "inet_app.lib")||(lc($lib_file) eq "mmi_app.lib")||(lc($lib_file) eq "mmi_framework.lib")||(lc($lib_file) eq "media_app.lib"))    ## find file path in the official release code base

+	{

+			$lis_path = $mcu_path . "make\\plutommi\\$lib_tmp\\$lib_tmp.lis";

+	}

+	else

+	{

+		 $lis_path = $mcu_path . "make\\$lib_tmp\\$lib_tmp.lis";

+	}

+

+	### get c file path

+	$obj_file =~ /(.*).obj/;

+	$obj_tmp = $1;

+	

+	my $c_file = "$obj_tmp" . ".c";

+

+	my $success = open (LIS_FILE, "<$lis_path") or warn "cannot open $lis_path\n";

+

+	if($success)

+	{

+		# read whole file

+		my $backup = $/;

+		undef $/;

+		my $reading = <LIS_FILE>;

+		$/ = $backup;

+

+		if ($reading =~ /(.*\\)$c_file/i)

+		{

+			#print "HIT2: $1\n";

+			$c_file = $mcu_path. $1 . $c_file;

+			#print "C_FILE: $c_file\n";

+		}

+		else

+		{

+			print "Assert: $c_file is NOT MATCHED in $lis_path !\n";

+		}

+	}

+

+	return $c_file;

+}

+

+

+#****************************************************************************

+# Get owner of the source of a label from CC server

+# Support when file is merged from subsidiary branch

+#****************************************************************************

+sub get_owner_from_CC_server

+{

+   my ($src) = @_;

+   my $result;

+   my $CQ_owner;

+   my $cmd1;

+   my $tmp3;

+   my $tmp4;

+   my $tmp5;

+   my $cmd2=();

+   

+   if($src=~/(.+)\\(.+)/g )

+   {

+       $tmp3=$1;

+       $tmp4=$2;

+       my $file_name;

+

+       $tmp5="M: & cd ".$tmp3." & ";

+

+       $tmp4=~s/\./\\\./;

+       if(!(-d $tmp3))

+       { 

+       	  $CQ_owner="ccadmin"; 

+       	  return $CQ_owner;

+       }     

+                     

+       #opendir (TMP3_DIR, $tmp3) or die "can't open directory $tmp3: $!";

+       opendir (TMP3_DIR, $tmp3);

+       while ( defined ($file_name = readdir(TMP3_DIR)) )

+       {

+	   if ($file_name=~/^$tmp4$/i)

+	   { 

+	      $tmp4=$file_name;

+	      last;

+	   }  

+       }

+       closedir TMP3_DIR;     

+       $cmd2=();

+       

+       $cmd2=$tmp5.'cleartool describe -fmt "Onwer: %Lu\nActivity: %[activity]p\n"'." ".$tmp4;

+

+       $result=`$cmd2`;

+    }

+

+   if($result=~/Onwer: (.+)\.Domain Users/i)

+   {  

+       $CQ_owner=$1;

+       if($CQ_owner=~/ccadmin/i)

+       {

+       	  $cmd2=();

+          $cmd2=$tmp5."cleartool describe ".$tmp4."\|find \"Merge\"";

+

+       	  $result=`$cmd2`;

+       	  if($result=~/Merge <- ([^\s]+)/i)

+       	  {

+       	  	$tmp4=$1;

+

+       	  	$cmd2='cleartool describe -fmt "Onwer: %Lu\nActivity: %[activity]p\n"'." ".$tmp4;

+       	  	$result=`$cmd2`;

+       	  	if($result=~/Onwer: (.+)\.Domain Users/i)

+                {

+                	$CQ_owner=$1;

+                	#print "Merge file owner:$CQ_owner \n";

+                } 

+       	  }

+       }      

+   }

+   return $CQ_owner;  

+} # sub get_owner_from_CC_server

+

+

+sub usage

+{

+    print "perl ROParser.pl <LIS filepath> <obj root path> <mcu path> <branch>\n";

+    exit(0);

+}

+

+sub startview(){

+  $view = $branch."_int";

+	$result = `cleartool startview $view 2>&1`;

+	print $result;

+	if($result =~ /cleartool: Error:/){

+		exit(0);

+	}

+}
\ No newline at end of file