sl@0: # sl@0: # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: # All rights reserved. sl@0: # This component and the accompanying materials are made available sl@0: # under the terms of the License "Eclipse Public License v1.0" sl@0: # which accompanies this distribution, and is available sl@0: # at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: # sl@0: # Initial Contributors: sl@0: # Nokia Corporation - initial contribution. sl@0: # sl@0: # Contributors: sl@0: # sl@0: # Description: sl@0: # sl@0: # Perl script to decode ROM symbols sl@0: # sl@0: # Usage: perl printsym.pl symbolfile sl@0: # sl@0: # Converts various forms of text from STDIN and write to stdout sl@0: sl@0: use strict; sl@0: sl@0: add_object(0xF8000000,0xFFF00000, "ROM"); sl@0: sl@0: die "Usage: printsym.pl romsymbolfile\n" unless @ARGV; sl@0: sl@0: my %addresslist; sl@0: my %address; sl@0: sl@0: read_rom_symbols($ARGV[0]); sl@0: shift; sl@0: sl@0: ## need to add more file types here... especially .map files sl@0: sl@0: sl@0: # We've accumulated the ranges of objects indexed by start address, sl@0: # with a companion list of addresses subdivided by the leading byte sl@0: # Now sort them numerically... sl@0: sl@0: sub numerically { $a <=> $b } sl@0: foreach my $key (keys %addresslist) sl@0: { sl@0: @{$addresslist{$key}} = sort numerically @{$addresslist{$key}}; sl@0: } sl@0: sl@0: # read lines from STDIN and decode them sl@0: sl@0: print "Please enter data to be decoded\n"; sl@0: sl@0: while (my $line=) sl@0: { sl@0: next if ($line =~ /^\s+$/); # skip blank lines sl@0: print "\n"; sl@0: if ($line =~ /(?:^|\s)(([0-9A-Fa-f]{2} ){4,})/) # pairs of hex digits separated by spaces = hex dump? sl@0: { sl@0: hexbytes($1); sl@0: print "\n"; sl@0: next; sl@0: } sl@0: if ($line =~ /[0-9A-Fa-f]{8}\s+/) # groups of hex words sl@0: { sl@0: hexwords($line); sl@0: print "\n"; sl@0: next; sl@0: } sl@0: print "???\n"; sl@0: } sl@0: sl@0: ############################################################################# sl@0: sl@0: sub add_object sl@0: { sl@0: my ($base, $max, $name) = @_; sl@0: $address{$base} = [ $base, $max, $name ]; sl@0: my $key=$base>>20; sl@0: my $maxkey=$max>>20; sl@0: while ($key <= $maxkey) # allowing for objects that span the boundary sl@0: { sl@0: push @{$addresslist{$key}}, $base; sl@0: $key+=1; sl@0: } sl@0: } sl@0: sl@0: sub match_addr sl@0: # sl@0: # Try matching one of the named areas in the addresslist sl@0: # sl@0: { sl@0: my ($word) = @_; sl@0: sl@0: if ($word < 1024*1024) sl@0: { sl@0: return 0; sl@0: } sl@0: sl@0: # Optimization - try looking up the address directly sl@0: sl@0: my $base; sl@0: my $max; sl@0: my $name; sl@0: if(defined $address{$word}) { sl@0: ($base, $max, $name) = @{$address{$word}}; sl@0: } sl@0: if (!(defined $base)) sl@0: { sl@0: my $key=$word>>20; sl@0: my $regionbase; sl@0: foreach $base (@{$addresslist{$key}}) sl@0: { sl@0: if ($base <= $word) sl@0: { sl@0: $regionbase = $base; sl@0: next; sl@0: } sl@0: if ($base > $word) sl@0: { sl@0: last; sl@0: } sl@0: } sl@0: if(defined $regionbase) sl@0: { sl@0: ($base, $max, $name) = @{$address{$regionbase}}; sl@0: } sl@0: } sl@0: if (defined $base && defined $max && $base <= $word && $max >= $word) sl@0: { sl@0: printf "%s + 0x%x", $name, $word - $base; sl@0: return 1; sl@0: } sl@0: return 0; sl@0: } sl@0: sl@0: # Handle a MAKSYM.LOG file for a ROM sl@0: # sl@0: # NB. Wanted to do sl@0: # sl@0: # open ROMIMAGE, "cxxfilt <$romimage |" or open ROMIMAGE, $romimage or die sl@0: # sl@0: # but this uses "/bin/sh cxxfilt <$romimage" which works up to the point where the sl@0: # shell can't load cxxfilt. sl@0: # sl@0: sub read_rom_symbols sl@0: { sl@0: my ($romimage)=@_; sl@0: open ROMSYMBOLS, $romimage or print "Can't open $romimage\n" and return; sl@0: sl@0: my $a; sl@0: my $b; sl@0: while (my $line = ) sl@0: { sl@0: if(!($line =~ /^[0-9A-Fa-f]{8}/)) sl@0: { sl@0: next; sl@0: } sl@0: # 8 bytes for the address sl@0: sl@0: $a = substr $line,0,8; sl@0: if(!($a =~ /[0-9A-Fa-f]{8}/)) sl@0: { sl@0: next; sl@0: } sl@0: # 4 bytes for the length sl@0: $b = substr $line,12,4; sl@0: if(!($b =~ /[0-9A-Fa-f]{4}/)) sl@0: { sl@0: next; sl@0: } sl@0: # rest of line is symbol sl@0: my $symbol = substr $line,20; sl@0: chomp $symbol; sl@0: sl@0: my $base=hex($a); sl@0: my $length=hex($b); sl@0: if ($base < 0x50000000) sl@0: { sl@0: next; # skip this line sl@0: } sl@0: if ($length==0xffffffff) sl@0: { sl@0: $length=100; # MAKSYM bug? choose a rational length sl@0: } sl@0: add_object($base, $base+$length-1, $symbol); sl@0: } sl@0: print "ROM Symbols from $romimage\n"; sl@0: } sl@0: sl@0: sub dumpword sl@0: { sl@0: my ($word) = @_; sl@0: my $data = pack "V", @_[0]; sl@0: $data =~ tr [\040-\177]/./c; sl@0: printf "= %08x %4s ", $word, $data; sl@0: match_addr($word); sl@0: printf "\n"; sl@0: } sl@0: sl@0: sub hexbytes sl@0: { sl@0: my @bytes = split /\s+/, @_[0]; sl@0: my $wordcount = @bytes/4; sl@0: map { dumpword($_) } (unpack "V$wordcount", (pack "H2"x($wordcount*4), @bytes)); sl@0: } sl@0: sub hexwords sl@0: { sl@0: my @words = grep /[0-9A-Fa-f]{8}/, split( /[^0-9A-Fa-f]+/, @_[0]); sl@0: my $wordcount = @words; sl@0: map { dumpword($_) } (unpack "N$wordcount", (pack "H8"x($wordcount), @words)); sl@0: } sl@0: