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 +