os/kernelhwsrv/kerneltest/e32utils/d_exc/printsym.pl
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kerneltest/e32utils/d_exc/printsym.pl	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,210 @@
     1.4 +#
     1.5 +# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
     1.6 +# All rights reserved.
     1.7 +# This component and the accompanying materials are made available
     1.8 +# under the terms of the License "Eclipse Public License v1.0"
     1.9 +# which accompanies this distribution, and is available
    1.10 +# at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.11 +#
    1.12 +# Initial Contributors:
    1.13 +# Nokia Corporation - initial contribution.
    1.14 +#
    1.15 +# Contributors:
    1.16 +#
    1.17 +# Description:
    1.18 +#
    1.19 +# Perl script to decode ROM symbols
    1.20 +#
    1.21 +# Usage: perl printsym.pl symbolfile
    1.22 +#
    1.23 +# Converts various forms of text from STDIN and write to stdout
    1.24 +
    1.25 +use strict;
    1.26 +
    1.27 +add_object(0xF8000000,0xFFF00000, "ROM");
    1.28 +
    1.29 +die "Usage: printsym.pl romsymbolfile\n" unless @ARGV;
    1.30 +
    1.31 +my %addresslist;
    1.32 +my %address;
    1.33 +
    1.34 +read_rom_symbols($ARGV[0]);
    1.35 +shift;
    1.36 +
    1.37 +## need to add more file types here... especially .map files
    1.38 +
    1.39 +
    1.40 +# We've accumulated the ranges of objects indexed by start address,
    1.41 +# with a companion list of addresses subdivided by the leading byte
    1.42 +# Now sort them numerically...
    1.43 +
    1.44 +sub numerically { $a <=> $b }
    1.45 +foreach my $key (keys %addresslist)
    1.46 +{
    1.47 +	@{$addresslist{$key}} = sort numerically @{$addresslist{$key}};
    1.48 +}
    1.49 +
    1.50 +# read lines from STDIN and decode them
    1.51 +
    1.52 +print "Please enter data to be decoded\n";
    1.53 +
    1.54 +while (my $line=<STDIN>)
    1.55 +	{
    1.56 +	next if ($line =~ /^\s+$/);		# skip blank lines
    1.57 +	print "\n";
    1.58 +	if ($line =~ /(?:^|\s)(([0-9A-Fa-f]{2} ){4,})/)	# pairs of hex digits separated by spaces = hex dump?
    1.59 +		{
    1.60 +		hexbytes($1);
    1.61 +		print "\n";
    1.62 +		next;
    1.63 +		}
    1.64 +	if ($line =~ /[0-9A-Fa-f]{8}\s+/)	# groups of hex words
    1.65 +		{
    1.66 +		hexwords($line);
    1.67 +		print "\n";
    1.68 +		next;
    1.69 +		}
    1.70 +	print "???\n";
    1.71 +	}
    1.72 +
    1.73 +#############################################################################
    1.74 +
    1.75 +sub add_object
    1.76 +	{
    1.77 +	my ($base, $max, $name) = @_;
    1.78 +	$address{$base} = [ $base, $max, $name ];
    1.79 +	my $key=$base>>20;
    1.80 +	my $maxkey=$max>>20;
    1.81 +	while ($key <= $maxkey)		# allowing for objects that span the boundary
    1.82 +		{
    1.83 +		push @{$addresslist{$key}}, $base;
    1.84 +		$key+=1;
    1.85 +		}
    1.86 +	}
    1.87 +
    1.88 +sub match_addr
    1.89 +#
    1.90 +# Try matching one of the named areas in the addresslist
    1.91 +#
    1.92 +	{
    1.93 +	my ($word) = @_;
    1.94 +
    1.95 +	if ($word < 1024*1024)
    1.96 +		{
    1.97 +		return 0;
    1.98 +		}
    1.99 +
   1.100 +	# Optimization - try looking up the address directly
   1.101 +
   1.102 +	my $base;
   1.103 +	my $max;
   1.104 +	my $name;
   1.105 +	if(defined $address{$word}) {
   1.106 +		($base, $max, $name) = @{$address{$word}};
   1.107 +	}
   1.108 +	if (!(defined $base))
   1.109 +		{
   1.110 +		my $key=$word>>20;
   1.111 +		my $regionbase;
   1.112 +		foreach $base (@{$addresslist{$key}})
   1.113 +			{
   1.114 +			if ($base <= $word)
   1.115 +				{
   1.116 +				$regionbase = $base;
   1.117 +				next;
   1.118 +				}
   1.119 +			if ($base > $word)
   1.120 +				{
   1.121 +				last;
   1.122 +				}
   1.123 +			}
   1.124 +		if(defined $regionbase)
   1.125 +			{
   1.126 +			($base, $max, $name) = @{$address{$regionbase}};
   1.127 +			}
   1.128 +		}
   1.129 +	if (defined $base && defined $max && $base <= $word && $max >= $word)
   1.130 +		{
   1.131 +		printf "%s + 0x%x", $name, $word - $base;
   1.132 +		return 1;
   1.133 +		}
   1.134 +	return 0;
   1.135 +	}
   1.136 +
   1.137 +# Handle a MAKSYM.LOG file for a ROM
   1.138 +#
   1.139 +# NB. Wanted to do 
   1.140 +#
   1.141 +#   open ROMIMAGE, "cxxfilt <$romimage |" or open ROMIMAGE, $romimage or die
   1.142 +#
   1.143 +# but this uses "/bin/sh cxxfilt <$romimage" which works up to the point where the
   1.144 +# shell can't load cxxfilt.
   1.145 +#
   1.146 +sub read_rom_symbols
   1.147 +	{
   1.148 +	my ($romimage)=@_;
   1.149 +	open ROMSYMBOLS, $romimage or print "Can't open $romimage\n" and return;
   1.150 +
   1.151 +	my $a;
   1.152 +	my $b;
   1.153 +	while (my $line = <ROMSYMBOLS>)
   1.154 +		{
   1.155 +		if(!($line =~ /^[0-9A-Fa-f]{8}/))
   1.156 +			{
   1.157 +			next;
   1.158 +			}
   1.159 +		# 8 bytes for the address
   1.160 +		
   1.161 +		$a = substr $line,0,8;
   1.162 +		if(!($a =~ /[0-9A-Fa-f]{8}/))
   1.163 +			{
   1.164 +			next;
   1.165 +			}
   1.166 +		# 4 bytes for the length
   1.167 +		$b = substr $line,12,4;
   1.168 +		if(!($b =~ /[0-9A-Fa-f]{4}/))
   1.169 +			{
   1.170 +			next;
   1.171 +			}
   1.172 +		# rest of line is symbol
   1.173 +		my $symbol = substr $line,20;
   1.174 +		chomp $symbol;
   1.175 +
   1.176 +		my $base=hex($a);
   1.177 +		my $length=hex($b);
   1.178 +		if ($base < 0x50000000) 
   1.179 +			{
   1.180 +			next;	# skip this line
   1.181 +			}
   1.182 +		if ($length==0xffffffff)
   1.183 +			{
   1.184 +			$length=100;	# MAKSYM bug? choose a rational length
   1.185 +			}
   1.186 +		add_object($base, $base+$length-1, $symbol);
   1.187 +		}
   1.188 +	print "ROM Symbols from $romimage\n";
   1.189 +	}
   1.190 +
   1.191 +sub dumpword
   1.192 +	{
   1.193 +	my ($word) = @_;
   1.194 +	my $data = pack "V", @_[0];
   1.195 +	$data =~ tr [\040-\177]/./c;
   1.196 +	printf "= %08x %4s  ", $word, $data;
   1.197 +	match_addr($word);
   1.198 +	printf "\n";
   1.199 +	}
   1.200 +
   1.201 +sub hexbytes
   1.202 +	{
   1.203 +	my @bytes = split /\s+/, @_[0];
   1.204 +	my $wordcount = @bytes/4;
   1.205 +	map { dumpword($_) } (unpack "V$wordcount", (pack "H2"x($wordcount*4), @bytes));
   1.206 +	}
   1.207 +sub hexwords
   1.208 +	{
   1.209 +	my @words = grep /[0-9A-Fa-f]{8}/, split( /[^0-9A-Fa-f]+/, @_[0]);
   1.210 +	my $wordcount = @words;
   1.211 +	map { dumpword($_) } (unpack "N$wordcount", (pack "H8"x($wordcount), @words));
   1.212 +	}
   1.213 +