kerneltest/e32utils/d_exc/printsym.pl
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 #
       
     2 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 # All rights reserved.
       
     4 # This component and the accompanying materials are made available
       
     5 # under the terms of the License "Eclipse Public License v1.0"
       
     6 # which accompanies this distribution, and is available
       
     7 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 #
       
     9 # Initial Contributors:
       
    10 # Nokia Corporation - initial contribution.
       
    11 #
       
    12 # Contributors:
       
    13 #
       
    14 # Description:
       
    15 #
       
    16 # Perl script to decode ROM symbols
       
    17 #
       
    18 # Usage: perl printsym.pl symbolfile
       
    19 #
       
    20 # Converts various forms of text from STDIN and write to stdout
       
    21 
       
    22 use strict;
       
    23 
       
    24 add_object(0xF8000000,0xFFF00000, "ROM");
       
    25 
       
    26 die "Usage: printsym.pl romsymbolfile\n" unless @ARGV;
       
    27 
       
    28 my %addresslist;
       
    29 my %address;
       
    30 
       
    31 read_rom_symbols($ARGV[0]);
       
    32 shift;
       
    33 
       
    34 ## need to add more file types here... especially .map files
       
    35 
       
    36 
       
    37 # We've accumulated the ranges of objects indexed by start address,
       
    38 # with a companion list of addresses subdivided by the leading byte
       
    39 # Now sort them numerically...
       
    40 
       
    41 sub numerically { $a <=> $b }
       
    42 foreach my $key (keys %addresslist)
       
    43 {
       
    44 	@{$addresslist{$key}} = sort numerically @{$addresslist{$key}};
       
    45 }
       
    46 
       
    47 # read lines from STDIN and decode them
       
    48 
       
    49 print "Please enter data to be decoded\n";
       
    50 
       
    51 while (my $line=<STDIN>)
       
    52 	{
       
    53 	next if ($line =~ /^\s+$/);		# skip blank lines
       
    54 	print "\n";
       
    55 	if ($line =~ /(?:^|\s)(([0-9A-Fa-f]{2} ){4,})/)	# pairs of hex digits separated by spaces = hex dump?
       
    56 		{
       
    57 		hexbytes($1);
       
    58 		print "\n";
       
    59 		next;
       
    60 		}
       
    61 	if ($line =~ /[0-9A-Fa-f]{8}\s+/)	# groups of hex words
       
    62 		{
       
    63 		hexwords($line);
       
    64 		print "\n";
       
    65 		next;
       
    66 		}
       
    67 	print "???\n";
       
    68 	}
       
    69 
       
    70 #############################################################################
       
    71 
       
    72 sub add_object
       
    73 	{
       
    74 	my ($base, $max, $name) = @_;
       
    75 	$address{$base} = [ $base, $max, $name ];
       
    76 	my $key=$base>>20;
       
    77 	my $maxkey=$max>>20;
       
    78 	while ($key <= $maxkey)		# allowing for objects that span the boundary
       
    79 		{
       
    80 		push @{$addresslist{$key}}, $base;
       
    81 		$key+=1;
       
    82 		}
       
    83 	}
       
    84 
       
    85 sub match_addr
       
    86 #
       
    87 # Try matching one of the named areas in the addresslist
       
    88 #
       
    89 	{
       
    90 	my ($word) = @_;
       
    91 
       
    92 	if ($word < 1024*1024)
       
    93 		{
       
    94 		return 0;
       
    95 		}
       
    96 
       
    97 	# Optimization - try looking up the address directly
       
    98 
       
    99 	my $base;
       
   100 	my $max;
       
   101 	my $name;
       
   102 	if(defined $address{$word}) {
       
   103 		($base, $max, $name) = @{$address{$word}};
       
   104 	}
       
   105 	if (!(defined $base))
       
   106 		{
       
   107 		my $key=$word>>20;
       
   108 		my $regionbase;
       
   109 		foreach $base (@{$addresslist{$key}})
       
   110 			{
       
   111 			if ($base <= $word)
       
   112 				{
       
   113 				$regionbase = $base;
       
   114 				next;
       
   115 				}
       
   116 			if ($base > $word)
       
   117 				{
       
   118 				last;
       
   119 				}
       
   120 			}
       
   121 		if(defined $regionbase)
       
   122 			{
       
   123 			($base, $max, $name) = @{$address{$regionbase}};
       
   124 			}
       
   125 		}
       
   126 	if (defined $base && defined $max && $base <= $word && $max >= $word)
       
   127 		{
       
   128 		printf "%s + 0x%x", $name, $word - $base;
       
   129 		return 1;
       
   130 		}
       
   131 	return 0;
       
   132 	}
       
   133 
       
   134 # Handle a MAKSYM.LOG file for a ROM
       
   135 #
       
   136 # NB. Wanted to do 
       
   137 #
       
   138 #   open ROMIMAGE, "cxxfilt <$romimage |" or open ROMIMAGE, $romimage or die
       
   139 #
       
   140 # but this uses "/bin/sh cxxfilt <$romimage" which works up to the point where the
       
   141 # shell can't load cxxfilt.
       
   142 #
       
   143 sub read_rom_symbols
       
   144 	{
       
   145 	my ($romimage)=@_;
       
   146 	open ROMSYMBOLS, $romimage or print "Can't open $romimage\n" and return;
       
   147 
       
   148 	my $a;
       
   149 	my $b;
       
   150 	while (my $line = <ROMSYMBOLS>)
       
   151 		{
       
   152 		if(!($line =~ /^[0-9A-Fa-f]{8}/))
       
   153 			{
       
   154 			next;
       
   155 			}
       
   156 		# 8 bytes for the address
       
   157 		
       
   158 		$a = substr $line,0,8;
       
   159 		if(!($a =~ /[0-9A-Fa-f]{8}/))
       
   160 			{
       
   161 			next;
       
   162 			}
       
   163 		# 4 bytes for the length
       
   164 		$b = substr $line,12,4;
       
   165 		if(!($b =~ /[0-9A-Fa-f]{4}/))
       
   166 			{
       
   167 			next;
       
   168 			}
       
   169 		# rest of line is symbol
       
   170 		my $symbol = substr $line,20;
       
   171 		chomp $symbol;
       
   172 
       
   173 		my $base=hex($a);
       
   174 		my $length=hex($b);
       
   175 		if ($base < 0x50000000) 
       
   176 			{
       
   177 			next;	# skip this line
       
   178 			}
       
   179 		if ($length==0xffffffff)
       
   180 			{
       
   181 			$length=100;	# MAKSYM bug? choose a rational length
       
   182 			}
       
   183 		add_object($base, $base+$length-1, $symbol);
       
   184 		}
       
   185 	print "ROM Symbols from $romimage\n";
       
   186 	}
       
   187 
       
   188 sub dumpword
       
   189 	{
       
   190 	my ($word) = @_;
       
   191 	my $data = pack "V", @_[0];
       
   192 	$data =~ tr [\040-\177]/./c;
       
   193 	printf "= %08x %4s  ", $word, $data;
       
   194 	match_addr($word);
       
   195 	printf "\n";
       
   196 	}
       
   197 
       
   198 sub hexbytes
       
   199 	{
       
   200 	my @bytes = split /\s+/, @_[0];
       
   201 	my $wordcount = @bytes/4;
       
   202 	map { dumpword($_) } (unpack "V$wordcount", (pack "H2"x($wordcount*4), @bytes));
       
   203 	}
       
   204 sub hexwords
       
   205 	{
       
   206 	my @words = grep /[0-9A-Fa-f]{8}/, split( /[^0-9A-Fa-f]+/, @_[0]);
       
   207 	my $wordcount = @words;
       
   208 	map { dumpword($_) } (unpack "N$wordcount", (pack "H8"x($wordcount), @words));
       
   209 	}
       
   210