imgtools/romtools/maksym/maksym.pl
changeset 590 360bd6b35136
parent 0 044383f39525
child 694 c3fbb20e86f0
--- a/imgtools/romtools/maksym/maksym.pl	Wed Jun 16 16:51:40 2010 +0300
+++ b/imgtools/romtools/maksym/maksym.pl	Wed Jun 23 16:56:47 2010 +0800
@@ -1,408 +1,397 @@
-#
-# Copyright (c) 1996-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: 
-# Produces symbolic information given a ROM image
-#
-
-require 5.003_07;
-no strict 'vars';
-use English;
-use FindBin;		# for FindBin::Bin
-
-my $PerlLibPath;    # fully qualified pathname of the directory containing our Perl modules
-
-BEGIN {
-    # check user has a version of perl that will cope require 5.005_03;
-    # establish the path to the Perl libraries: currently the same directory as this script
-    $PerlLibPath = $FindBin::Bin; # X:/epoc32/tools
-    $PerlLibPath =~ s/\//\\/g;	# X:\epoc32\tools
-    $PerlLibPath .= "\\";
-}
-
-use lib $PerlLibPath;
-use Modload;
-Load_SetModulePath($PerlLibPath);
-
-# Globals
-my $maksym = "";
-my $rombuild;
-my $debug = 0;
-
-&args;
-&main;
-
-exit 0;
-
-sub CompareAddrs()
-{
-    return -1 if ($a < $b);
-    return 1 if ($a > $b);
-    return 0;
-}
-
-#
-# main
-#
-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";
-
-      # 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;
-}
-
-#
-# args - get command line args
-#
-sub args
-{
-    my $arg;
-    my @args;
-    my $flag;
-
-    &help if (!@ARGV);
-
-    while (@ARGV) {
-	$arg = shift @ARGV;
-
-	if ($arg=~/^[\-\/](\S*)$/) {
-	    $flag=$1;
-
-	    if ($flag=~/^[\?h]$/i) {
-		&help;
-	    } elsif ($flag=~/^d$/i) {
-		$debug = 1;
-	    } else {
-		print "\nERROR: Unknown flag \"-$flag\"\n";
-		&usage;
-		exit 1;
-	    }
-	} else {
-	    push @args,$arg;
-	}
-    }
-
-    if (@args) {
-	$rombuild = shift @args;
-	if (@args) {
-	    $maksym = shift @args;
-	    if (@args) {
-		print "\nERROR: Incorrect argument(s) \"@args\"\n";
-		&usage;
-		exit 1;
-	    }
-	}
-    }
-}
-
-sub help ()
-{
-    my $build;
-
-    &Load_ModuleL('E32TPVER');
-    print "\nmaksym - Produce symbolic information given a ROM image (Build ",
-	&E32tpver, ")\n";
-    &usage;
-    exit 0;
-}
-
-sub usage ()
-{
-    print <<EOF
-
-Usage:
-  maksym <logfile> [<outfile>]
-
-Where:
-  <logfile>   Log file from rombuild tool.
-  <outfile>   Output file. Defaults to imagename.symbol.
-EOF
-    ;
-    exit 0;
-}
+#
+# Copyright (c) 1996-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: 
+# Produces symbolic information given a ROM image
+#
+
+require 5.003_07;
+no strict 'vars';
+use English;
+use FindBin;		# for FindBin::Bin
+
+# Version
+my $MajorVersion = 1;
+my $MinorVersion = 1;
+my $PatchVersion = 0;
+
+# Globals
+my $maksym = "";
+my $rombuild;
+my $debug = 0;
+
+&args;
+&main;
+
+exit 0;
+
+sub CompareAddrs()
+{
+    return -1 if ($a < $b);
+    return 1 if ($a > $b);
+    return 0;
+}
+
+#
+# main
+#
+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";
+
+      # 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;
+}
+
+#
+# args - get command line args
+#
+sub args
+{
+    my $arg;
+    my @args;
+    my $flag;
+
+    &help if (!@ARGV);
+
+    while (@ARGV) {
+	$arg = shift @ARGV;
+
+	if ($arg=~/^[\-](\S*)$/) {
+	    $flag=$1;
+
+	    if ($flag=~/^[\?h]$/i) {
+		&help;
+	    } elsif ($flag=~/^d$/i) {
+		$debug = 1;
+	    } else {
+		print "\nERROR: Unknown flag \"-$flag\"\n";
+		&usage;
+		exit 1;
+	    }
+	} else {
+	    push @args,$arg;
+	}
+    }
+
+    if (@args) {
+	$rombuild = shift @args;
+	if (@args) {
+	    $maksym = shift @args;
+	    if (@args) {
+		print "\nERROR: Incorrect argument(s) \"@args\"\n";
+		&usage;
+		exit 1;
+	    }
+	}
+    }
+}
+
+sub help ()
+{
+    my $build;
+
+    print "\nmaksym - Produce symbolic information given a ROM image V${MajorVersion}.${MinorVersion}.${PatchVersion}\n";
+    &usage;
+    exit 0;
+}
+
+sub usage ()
+{
+    print <<EOF
+
+Usage:
+  maksym <logfile> [<outfile>]
+
+Where:
+  <logfile>   Log file from rombuild tool.
+  <outfile>   Output file. Defaults to imagename.symbol.
+EOF
+    ;
+    exit 0;
+}