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