kerneltest/e32utils/d_exc/printsym.pl
changeset 0 a41df078684a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32utils/d_exc/printsym.pl	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,210 @@
+#
+# Copyright (c) 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:
+#
+# Perl script to decode ROM symbols
+#
+# Usage: perl printsym.pl symbolfile
+#
+# Converts various forms of text from STDIN and write to stdout
+
+use strict;
+
+add_object(0xF8000000,0xFFF00000, "ROM");
+
+die "Usage: printsym.pl romsymbolfile\n" unless @ARGV;
+
+my %addresslist;
+my %address;
+
+read_rom_symbols($ARGV[0]);
+shift;
+
+## need to add more file types here... especially .map files
+
+
+# We've accumulated the ranges of objects indexed by start address,
+# with a companion list of addresses subdivided by the leading byte
+# Now sort them numerically...
+
+sub numerically { $a <=> $b }
+foreach my $key (keys %addresslist)
+{
+	@{$addresslist{$key}} = sort numerically @{$addresslist{$key}};
+}
+
+# read lines from STDIN and decode them
+
+print "Please enter data to be decoded\n";
+
+while (my $line=<STDIN>)
+	{
+	next if ($line =~ /^\s+$/);		# skip blank lines
+	print "\n";
+	if ($line =~ /(?:^|\s)(([0-9A-Fa-f]{2} ){4,})/)	# pairs of hex digits separated by spaces = hex dump?
+		{
+		hexbytes($1);
+		print "\n";
+		next;
+		}
+	if ($line =~ /[0-9A-Fa-f]{8}\s+/)	# groups of hex words
+		{
+		hexwords($line);
+		print "\n";
+		next;
+		}
+	print "???\n";
+	}
+
+#############################################################################
+
+sub add_object
+	{
+	my ($base, $max, $name) = @_;
+	$address{$base} = [ $base, $max, $name ];
+	my $key=$base>>20;
+	my $maxkey=$max>>20;
+	while ($key <= $maxkey)		# allowing for objects that span the boundary
+		{
+		push @{$addresslist{$key}}, $base;
+		$key+=1;
+		}
+	}
+
+sub match_addr
+#
+# Try matching one of the named areas in the addresslist
+#
+	{
+	my ($word) = @_;
+
+	if ($word < 1024*1024)
+		{
+		return 0;
+		}
+
+	# Optimization - try looking up the address directly
+
+	my $base;
+	my $max;
+	my $name;
+	if(defined $address{$word}) {
+		($base, $max, $name) = @{$address{$word}};
+	}
+	if (!(defined $base))
+		{
+		my $key=$word>>20;
+		my $regionbase;
+		foreach $base (@{$addresslist{$key}})
+			{
+			if ($base <= $word)
+				{
+				$regionbase = $base;
+				next;
+				}
+			if ($base > $word)
+				{
+				last;
+				}
+			}
+		if(defined $regionbase)
+			{
+			($base, $max, $name) = @{$address{$regionbase}};
+			}
+		}
+	if (defined $base && defined $max && $base <= $word && $max >= $word)
+		{
+		printf "%s + 0x%x", $name, $word - $base;
+		return 1;
+		}
+	return 0;
+	}
+
+# Handle a MAKSYM.LOG file for a ROM
+#
+# NB. Wanted to do 
+#
+#   open ROMIMAGE, "cxxfilt <$romimage |" or open ROMIMAGE, $romimage or die
+#
+# but this uses "/bin/sh cxxfilt <$romimage" which works up to the point where the
+# shell can't load cxxfilt.
+#
+sub read_rom_symbols
+	{
+	my ($romimage)=@_;
+	open ROMSYMBOLS, $romimage or print "Can't open $romimage\n" and return;
+
+	my $a;
+	my $b;
+	while (my $line = <ROMSYMBOLS>)
+		{
+		if(!($line =~ /^[0-9A-Fa-f]{8}/))
+			{
+			next;
+			}
+		# 8 bytes for the address
+		
+		$a = substr $line,0,8;
+		if(!($a =~ /[0-9A-Fa-f]{8}/))
+			{
+			next;
+			}
+		# 4 bytes for the length
+		$b = substr $line,12,4;
+		if(!($b =~ /[0-9A-Fa-f]{4}/))
+			{
+			next;
+			}
+		# rest of line is symbol
+		my $symbol = substr $line,20;
+		chomp $symbol;
+
+		my $base=hex($a);
+		my $length=hex($b);
+		if ($base < 0x50000000) 
+			{
+			next;	# skip this line
+			}
+		if ($length==0xffffffff)
+			{
+			$length=100;	# MAKSYM bug? choose a rational length
+			}
+		add_object($base, $base+$length-1, $symbol);
+		}
+	print "ROM Symbols from $romimage\n";
+	}
+
+sub dumpword
+	{
+	my ($word) = @_;
+	my $data = pack "V", @_[0];
+	$data =~ tr [\040-\177]/./c;
+	printf "= %08x %4s  ", $word, $data;
+	match_addr($word);
+	printf "\n";
+	}
+
+sub hexbytes
+	{
+	my @bytes = split /\s+/, @_[0];
+	my $wordcount = @bytes/4;
+	map { dumpword($_) } (unpack "V$wordcount", (pack "H2"x($wordcount*4), @bytes));
+	}
+sub hexwords
+	{
+	my @words = grep /[0-9A-Fa-f]{8}/, split( /[^0-9A-Fa-f]+/, @_[0]);
+	my $wordcount = @words;
+	map { dumpword($_) } (unpack "N$wordcount", (pack "H8"x($wordcount), @words));
+	}
+