os/kernelhwsrv/kerneltest/e32utils/d_exc/printsym.pl
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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