diff -r c7c26511138f -r 360bd6b35136 imgtools/romtools/maksym/maksymrofs.pl --- a/imgtools/romtools/maksym/maksymrofs.pl Wed Jun 16 16:51:40 2010 +0300 +++ b/imgtools/romtools/maksym/maksymrofs.pl Wed Jun 23 16:56:47 2010 +0800 @@ -1,409 +1,385 @@ -# -# Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). -# All rights reserved. -# This component and the accompanying materials are made available -# under the terms of the License "Eclipse Public License v1.0" -# which accompanies this distribution, and is available -# at the URL "http://www.eclipse.org/legal/epl-v10.html". -# -# Initial Contributors: -# Nokia Corporation - initial contribution. -# -# Contributors: -# -# Description: -# Produces symbolic information given a ROFS log file and .map files for relevant binary files -# - -require 5.003_07; -no strict 'vars'; -use English; -use FindBin; # for FindBin::Bin - -my $PerlLibPath; # fully qualified pathname of the directory containing our Perl modules - -BEGIN { - # check user has a version of perl that will cope require 5.005_03; - # establish the path to the Perl libraries: currently the same directory as this script - $PerlLibPath = $FindBin::Bin; # X:/epoc32/tools - $PerlLibPath =~ s/\//\\/g; # X:\epoc32\tools - $PerlLibPath .= "\\"; -} - -use lib $PerlLibPath; -use Modload; -Load_SetModulePath($PerlLibPath); - -# Globals -my $maksym = ""; -my $rofsbuild; -my $debug = 0; - -&args; -&main; -exit 0; - -sub CompareAddrs() -{ - return -1 if ($a < $b); - return 1 if ($a > $b); - return 0; -} - -# -# main -# -sub main() -{ - open (ROFS, "<$rofsbuild") or die "ERROR: Can't open rofsbuild log file \"$rofsbuild\"\n"; - if ($maksym ne "") - { - open (SYM, ">$maksym") or die "ERROR: Can't open output file \"$maksym\"\n"; - print "Creating $maksym...\n" - } - - my $curretnLine; - while ($currentLine = ) - { - # Check that the given log file is from a rofs image and set up the name for the symbol file - if ($currentLine =~ /^Creating Rofs image (\S*)/) - { - if ($maksym eq "") - { - # For backwards compatibility, replace trailing .img with .symbol - # if no trailing .img, just append .symbol anyway - $maksym = $1; - $maksym =~ s/(\.img)?$/.symbol/i; - close SYM; - open (SYM, ">$maksym") or die "ERROR: Can't open output file \"$maksym\"\n"; - print "\nCreating $maksym...\n" - } - next; - } - - # found at end of file - if ($currentLine =~ /^Writing Rom image/) - { - close SYM; - $maksym = ""; - next; - } - - # Data file - if ($currentLine =~ /^File \'(.*)\' size: \S+\s*$/) - { - my $file = $1; - $file =~ /([^\\]+)$/; - printf SYM "\nFrom $file\n\n00000000 0000 $1\n"; - } - - # Executable file - elsif ($currentLine =~ /^Compressed executable File \'(.*)\' size: \S+\s*, mode:\S+\s*$/) - { - ProcessCompressedLine($1); - } - } - close SYM; - close ROFS; -} - -sub ProcessCompressedLine -{ - my ($file) = @_; - - my $mapfile; - my $mapfile2; - print SYM "\nFrom $file\n\n"; - - # Look in map file for symbols in .text and relocate them - $mapfile2 = $file.".map"; - $mapfile = $file; - $mapfile =~ s/\.\w+$/\.map/; - if (!(open (MAP, "$mapfile2") || open (MAP, "$mapfile"))) - { - print "$file\nWarning: Can't open \"$mapfile2\" or \"$mapfile\"\n"; - # couldn't find map file so output in format that is used for non-binary files - my $BinSize = GetSizeFromBinFile($file); - $file =~ /([^\\]+)$/; - printf "00000000 %04x $1\n", $BinSize; - printf SYM "00000000 %04x $1\n", $BinSize; - } - else - { - my @maplines; - while ($_ = ) - { - push @maplines, $_; - } - close MAP; - # See if we're dealing with the RVCT output - if ($file =~m/ARMV5/i) - { - ProcessArmv5File($file, \@maplines); - } - elsif( ($file =~ /GCCE/i) || ($file =~ /ARM4/i) ) - { - ProcessGcceOrArm4File($file, \@maplines); - } - else - { - print "\nWarning: cannot determine linker type used to create $file\n"; - $file =~ /([^\\]+)$/; - printf SYM "00000000 0000 $1\n"; - } - } -} - -sub ProcessArmv5File -{ - my ($file, $mapLines) = @_; - my @maplines = @$mapLines; - if ($maplines[0] !~ /^ARM Linker/) - { - print "\nWarning: expecting $file to be generated by ARM linker\n"; - # file not in format produced by ARMV5 linker so treat file as non-binary file - $file =~ /([^\\]+)$/; - printf SYM "00000000 0000 $1\n"; - } - else - { - # scroll down to the global symbols - while ($_ = shift @maplines) - { - if ($_ =~ /Global Symbols/) - { - last; - } - } - - my %syms; - my $baseOffset; # offset to subtract from each address so that the first entry has address 0x0 - - foreach (@maplines) - { - # name address ignore size section - if (/^\s*(.+)\s*(0x\S+)\s+[^\d]*(\d+)\s+(.*)$/) - { - my $sym = $1; - my $addr = hex($2); - my $size = sprintf("%04x",$3); - my $section = $4; - $size = sprintf("%04x", 8) if ($section =~ /\(StubCode\)/); - - # it is possible that there will be more than one entry in a log file for a - # particular address, this is because aliases are included. - # The following code checks that the correct function (i.e. the one with - # non-zero size) is being included in the symbol file. - if(exists $syms{$addr}) - { # an entry at this address exists, replace if it is an alias - if( ($size != 0) && ($addr > 0) ) - { - if( ! defined $baseOffset ) - { - $baseOffset = $addr; - } - $syms{$addr - $baseOffset} = "$size $sym $section"; - } - } - else - { # no entry at this address so create one regardless of whether size is zero - if( $addr > 0 ) - { - if( ! defined $baseOffset ) - { - $baseOffset = $addr; - } - $syms{$addr - $baseOffset} = "$size $sym $section"; - } - } - - } - } - - # Write symbols in address order - my @addrs = sort CompareAddrs keys %syms; - for ($i = 0; $i < @addrs ; $i++) - { - my $thisaddr = $addrs[$i]; - printf SYM "%08x %s\n", - $thisaddr, $syms{$thisaddr}; - } - } -} - -sub ProcessGcceOrArm4File -{ - my ($file, $mapLines) = @_; - my @maplines = @$mapLines; - my %syms; - my $stubhex=1; - - # Find text section - while (($_ = shift @maplines) && !(/^\.text\s+/)) - { - } - - /^\.text\s+(\w+)\s+\w+/ or die "ERROR: Can't get .text section info for \"$file\"\n"; - - my $imgtext=hex($1); - - # Slurp symbols 'til the end of the text section - foreach (@maplines) - { - - # blank line marks the end of the text section - last if (/^$/); - - # .text - # .text$something - # - # LONG 0x0 - - if (/^\s(\.text)?\s+(0x\w+)\s+(0x\w+)\s+(.*)$/io) - { - my $address = hex($2); - my $length = hex($3); - my $libraryfile = $4; - next if ($libraryfile =~ /^LONG 0x/); - - $syms{$address+$length} = ' '; # impossible symbol as end marker - - #set $stubhex value as $address if there is a match - if ($libraryfile =~ /.*lib\(.*d\d*s_?\d{5}.o\)$/io) - { - $stubhex=$address; - } - next; - } - - # - if (/^\s+(\w+)\s\s+([a-zA-Z_].+)/o) - { - my $addr = hex($1); - my $symbol = $2; - $symbol = "stub $symbol" if ($addr == $stubhex); - $syms{$addr} = $symbol; - next; - } - } - - # Write symbols in address order - @addrs = sort CompareAddrs keys %syms; - for ($i = 0; $i < @addrs - 1; $i++) - { - my $symbol = $syms{$addrs[$i]}; - next if ($symbol eq ' '); - printf SYM "%08x %04x %s\n", - $addrs[$i] - $imgtext, $addrs[$i+1]-$addrs[$i], $symbol; - } - # last address assumed to be imgtext+lentext - - close MAP; -} - -# -# args - get command line args -# -sub args -{ - my $arg; - my @args; - my $flag; - - &help if (!@ARGV); - - while (@ARGV) - { - $arg = shift @ARGV; - - if ($arg=~/^[\-\/](\S*)$/) - { - $flag=$1; - - if ($flag=~/^[\?h]$/i) - { - &help; - } - elsif ($flag=~/^d$/i) - { - $debug = 1; - } - else - { - print "\nERROR: Unknown flag \"-$flag\"\n"; - &usage; - exit 1; - } - } - else - { - push @args,$arg; - } - } - - if (@args) - { - $rofsbuild = shift @args; - if (@args) - { - $maksym = shift @args; - if (@args) - { - print "\nERROR: Incorrect argument(s) \"@args\"\n"; - &usage; - exit 1; - } - } - } -} - -sub help () -{ - my $build; - - &Load_ModuleL('E32TPVER'); - print "\nmaksymrofs - Produce symbolic information given a ROFS image (Build ", - &E32tpver, ")\n"; - &usage; - exit 0; -} - -sub usage () -{ - print < [] - -Where: - Log file from rofsbuild tool. - Output file. Defaults to imagename.symbol. -EOF - ; - exit 0; -} - -sub GetSizeFromBinFile () -{ - my ($file) = @_; - my $tmpfile = "temp.info"; - system("readimage $file -o $tmpfile"); - return 0 if (!-e $tmpfile); - - open (TMP, "<$tmpfile"); - my $line; - my $size = 0; - while ($line = ) - { - print $line; - if ($line =~ /^Code size\W+(\w+)$/) - { - $size = hex($1); - last; - } - } - close TMP; - unlink $tmpfile; - return $size; -} - +# +# Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of the License "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# Produces symbolic information given a ROFS log file and .map files for relevant binary files +# + +require 5.003_07; +no strict 'vars'; +use English; +use FindBin; # for FindBin::Bin + +# Version +my $MajorVersion = 1; +my $MinorVersion = 1; +my $PatchVersion = 0; + +# Globals +my $maksym = ""; +my $rofsbuild; +my $debug = 0; + +&args; +&main; +exit 0; + +sub CompareAddrs() +{ + return -1 if ($a < $b); + return 1 if ($a > $b); + return 0; +} + +# +# main +# +sub main() +{ + open (ROFS, "<$rofsbuild") or die "ERROR: Can't open rofsbuild log file \"$rofsbuild\"\n"; + if ($maksym ne "") + { + open (SYM, ">$maksym") or die "ERROR: Can't open output file \"$maksym\"\n"; + print "Creating $maksym...\n" + } + + my $curretnLine; + while ($currentLine = ) + { + # Check that the given log file is from a rofs image and set up the name for the symbol file + if ($currentLine =~ /^Creating Rofs image (\S*)/) + { + if ($maksym eq "") + { + # For backwards compatibility, replace trailing .img with .symbol + # if no trailing .img, just append .symbol anyway + $maksym = $1; + $maksym =~ s/(\.img)?$/.symbol/i; + close SYM; + open (SYM, ">$maksym") or die "ERROR: Can't open output file \"$maksym\"\n"; + print "\nCreating $maksym...\n" + } + next; + } + + # found at end of file + if ($currentLine =~ /^Writing Rom image/) + { + close SYM; + $maksym = ""; + next; + } + + # Data file + if ($currentLine =~ /^File \'(.*)\' size: \S+\s*$/) + { + my $file = $1; + $file =~ /([^\\]+)$/; + printf SYM "\nFrom $file\n\n00000000 0000 $1\n"; + } + + # Executable file + elsif ($currentLine =~ /^Compressed executable File \'(.*)\' size: \S+\s*, mode:\S+\s*$/) + { + ProcessCompressedLine($1); + } + } + close SYM; + close ROFS; +} + +sub ProcessCompressedLine +{ + my ($file) = @_; + + my $mapfile; + my $mapfile2; + print SYM "\nFrom $file\n\n"; + + # Look in map file for symbols in .text and relocate them + $mapfile2 = $file.".map"; + $mapfile = $file; + $mapfile =~ s/\.\w+$/\.map/; + if (!(open (MAP, "$mapfile2") || open (MAP, "$mapfile"))) + { + print "$file\nWarning: Can't open \"$mapfile2\" or \"$mapfile\"\n"; + # couldn't find map file so output in format that is used for non-binary files + my $BinSize = GetSizeFromBinFile($file); + $file =~ /([^\\]+)$/; + printf "00000000 %04x $1\n", $BinSize; + printf SYM "00000000 %04x $1\n", $BinSize; + } + else + { + my @maplines; + while ($_ = ) + { + push @maplines, $_; + } + close MAP; + # See if we're dealing with the RVCT output + if ($file =~m/ARMV5/i) + { + ProcessArmv5File($file, \@maplines); + } + elsif( ($file =~ /GCCE/i) || ($file =~ /ARM4/i) ) + { + ProcessGcceOrArm4File($file, \@maplines); + } + else + { + print "\nWarning: cannot determine linker type used to create $file\n"; + $file =~ /([^\\]+)$/; + printf SYM "00000000 0000 $1\n"; + } + } +} + +sub ProcessArmv5File +{ + my ($file, $mapLines) = @_; + my @maplines = @$mapLines; + if ($maplines[0] !~ /^ARM Linker/) + { + print "\nWarning: expecting $file to be generated by ARM linker\n"; + # file not in format produced by ARMV5 linker so treat file as non-binary file + $file =~ /([^\\]+)$/; + printf SYM "00000000 0000 $1\n"; + } + else + { + # scroll down to the global symbols + while ($_ = shift @maplines) + { + if ($_ =~ /Global Symbols/) + { + last; + } + } + + my %syms; + my $baseOffset; # offset to subtract from each address so that the first entry has address 0x0 + + foreach (@maplines) + { + # name address ignore size section + if (/^\s*(.+)\s*(0x\S+)\s+[^\d]*(\d+)\s+(.*)$/) + { + my $sym = $1; + my $addr = hex($2); + my $size = sprintf("%04x",$3); + my $section = $4; + $size = sprintf("%04x", 8) if ($section =~ /\(StubCode\)/); + + # it is possible that there will be more than one entry in a log file for a + # particular address, this is because aliases are included. + # The following code checks that the correct function (i.e. the one with + # non-zero size) is being included in the symbol file. + if($addr > 0) { + if( ! defined $baseOffset ) { + $baseOffset = $addr; + } + # no entry at this address so create one regardless of whether size is zero + # an entry at this address exists, replace if it is an alias + if( (! exists $syms{$addr-$baseOffset}) || !($size eq "0000")) { + $syms{$addr - $baseOffset} = "$size $sym $section"; + } + } + } + } + + # Write symbols in address order + my @addrs = sort CompareAddrs keys %syms; + for ($i = 0; $i < @addrs ; $i++) + { + my $thisaddr = $addrs[$i]; + printf SYM "%08x %s\n", + $thisaddr, $syms{$thisaddr}; + } + } +} + +sub ProcessGcceOrArm4File +{ + my ($file, $mapLines) = @_; + my @maplines = @$mapLines; + my %syms; + my $stubhex=1; + + # Find text section + while (($_ = shift @maplines) && !(/^\.text\s+/)) + { + } + + /^\.text\s+(\w+)\s+\w+/ or die "ERROR: Can't get .text section info for \"$file\"\n"; + + my $imgtext=hex($1); + + # Slurp symbols 'til the end of the text section + foreach (@maplines) + { + + # blank line marks the end of the text section + last if (/^$/); + + # .text + # .text$something + # + # LONG 0x0 + + if (/^\s(\.text)?\s+(0x\w+)\s+(0x\w+)\s+(.*)$/io) + { + my $address = hex($2); + my $length = hex($3); + my $libraryfile = $4; + next if ($libraryfile =~ /^LONG 0x/); + + $syms{$address+$length} = ' '; # impossible symbol as end marker + + #set $stubhex value as $address if there is a match + if ($libraryfile =~ /.*lib\(.*d\d*s_?\d{5}.o\)$/io) + { + $stubhex=$address; + } + next; + } + + # + if (/^\s+(\w+)\s\s+([a-zA-Z_].+)/o) + { + my $addr = hex($1); + my $symbol = $2; + $symbol = "stub $symbol" if ($addr == $stubhex); + $syms{$addr} = $symbol; + next; + } + } + + # Write symbols in address order + @addrs = sort CompareAddrs keys %syms; + for ($i = 0; $i < @addrs - 1; $i++) + { + my $symbol = $syms{$addrs[$i]}; + next if ($symbol eq ' '); + printf SYM "%08x %04x %s\n", + $addrs[$i] - $imgtext, $addrs[$i+1]-$addrs[$i], $symbol; + } + # last address assumed to be imgtext+lentext + + close MAP; +} + +# +# args - get command line args +# +sub args +{ + my $arg; + my @args; + my $flag; + + &help if (!@ARGV); + + while (@ARGV) + { + $arg = shift @ARGV; + + if ($arg=~/^[\-](\S*)$/) + { + $flag=$1; + + if ($flag=~/^[\?h]$/i) + { + &help; + } + elsif ($flag=~/^d$/i) + { + $debug = 1; + } + else + { + print "\nERROR: Unknown flag \"-$flag\"\n"; + &usage; + exit 1; + } + } + else + { + push @args,$arg; + } + } + + if (@args) + { + $rofsbuild = shift @args; + if (@args) + { + $maksym = shift @args; + if (@args) + { + print "\nERROR: Incorrect argument(s) \"@args\"\n"; + &usage; + exit 1; + } + } + } +} + +sub help () +{ + my $build; + + print "\nmaksymrofs - Produce symbolic information given a ROFS image V${MajorVersion}.${MinorVersion}.${PatchVersion}\n"; + &usage; + exit 0; +} + +sub usage () +{ + print < [] + +Where: + Log file from rofsbuild tool. + Output file. Defaults to imagename.symbol. +EOF + ; + exit 0; +} + +sub GetSizeFromBinFile () +{ + my ($file) = @_; + my $tmpfile = "temp.info"; + system("readimage $file -o $tmpfile"); + return 0 if (!-e $tmpfile); + + open (TMP, "<$tmpfile"); + my $line; + my $size = 0; + while ($line = ) + { + print $line; + if ($line =~ /^Code size\W+(\w+)$/) + { + $size = hex($1); + last; + } + } + close TMP; + unlink $tmpfile; + return $size; +} +